1e8d8bef9SDimitry Andric //===-- APINotesYAMLCompiler.cpp - API Notes YAML Format Reader -*- C++ -*-===//
2e8d8bef9SDimitry Andric //
3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric //
7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric //
9e8d8bef9SDimitry Andric // The types defined locally are designed to represent the YAML state, which
10e8d8bef9SDimitry Andric // adds an additional bit of state: e.g. a tri-state boolean attribute (yes, no,
11e8d8bef9SDimitry Andric // not applied) becomes a tri-state boolean + present. As a result, while these
12e8d8bef9SDimitry Andric // enumerations appear to be redefining constants from the attributes table
13e8d8bef9SDimitry Andric // data, they are distinct.
14e8d8bef9SDimitry Andric //
15e8d8bef9SDimitry Andric
16e8d8bef9SDimitry Andric #include "clang/APINotes/APINotesYAMLCompiler.h"
175f757f3fSDimitry Andric #include "clang/APINotes/APINotesWriter.h"
18e8d8bef9SDimitry Andric #include "clang/APINotes/Types.h"
19e8d8bef9SDimitry Andric #include "clang/Basic/LLVM.h"
20e8d8bef9SDimitry Andric #include "clang/Basic/Specifiers.h"
215f757f3fSDimitry Andric #include "llvm/ADT/StringSet.h"
225f757f3fSDimitry Andric #include "llvm/Support/SourceMgr.h"
23e8d8bef9SDimitry Andric #include "llvm/Support/VersionTuple.h"
24e8d8bef9SDimitry Andric #include "llvm/Support/YAMLTraits.h"
25bdd1243dSDimitry Andric #include <optional>
26e8d8bef9SDimitry Andric #include <vector>
275f757f3fSDimitry Andric
28e8d8bef9SDimitry Andric using namespace clang;
29e8d8bef9SDimitry Andric using namespace api_notes;
30e8d8bef9SDimitry Andric
31e8d8bef9SDimitry Andric namespace {
32e8d8bef9SDimitry Andric enum class APIAvailability {
33e8d8bef9SDimitry Andric Available = 0,
34e8d8bef9SDimitry Andric None,
35e8d8bef9SDimitry Andric NonSwift,
36e8d8bef9SDimitry Andric };
37e8d8bef9SDimitry Andric } // namespace
38e8d8bef9SDimitry Andric
39e8d8bef9SDimitry Andric namespace llvm {
40e8d8bef9SDimitry Andric namespace yaml {
41e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<APIAvailability> {
enumerationllvm::yaml::ScalarEnumerationTraits42e8d8bef9SDimitry Andric static void enumeration(IO &IO, APIAvailability &AA) {
43e8d8bef9SDimitry Andric IO.enumCase(AA, "none", APIAvailability::None);
44e8d8bef9SDimitry Andric IO.enumCase(AA, "nonswift", APIAvailability::NonSwift);
45e8d8bef9SDimitry Andric IO.enumCase(AA, "available", APIAvailability::Available);
46e8d8bef9SDimitry Andric }
47e8d8bef9SDimitry Andric };
48e8d8bef9SDimitry Andric } // namespace yaml
49e8d8bef9SDimitry Andric } // namespace llvm
50e8d8bef9SDimitry Andric
51e8d8bef9SDimitry Andric namespace {
52e8d8bef9SDimitry Andric enum class MethodKind {
53e8d8bef9SDimitry Andric Class,
54e8d8bef9SDimitry Andric Instance,
55e8d8bef9SDimitry Andric };
56e8d8bef9SDimitry Andric } // namespace
57e8d8bef9SDimitry Andric
58e8d8bef9SDimitry Andric namespace llvm {
59e8d8bef9SDimitry Andric namespace yaml {
60e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<MethodKind> {
enumerationllvm::yaml::ScalarEnumerationTraits61e8d8bef9SDimitry Andric static void enumeration(IO &IO, MethodKind &MK) {
62e8d8bef9SDimitry Andric IO.enumCase(MK, "Class", MethodKind::Class);
63e8d8bef9SDimitry Andric IO.enumCase(MK, "Instance", MethodKind::Instance);
64e8d8bef9SDimitry Andric }
65e8d8bef9SDimitry Andric };
66e8d8bef9SDimitry Andric } // namespace yaml
67e8d8bef9SDimitry Andric } // namespace llvm
68e8d8bef9SDimitry Andric
69e8d8bef9SDimitry Andric namespace {
70e8d8bef9SDimitry Andric struct Param {
71e8d8bef9SDimitry Andric unsigned Position;
72bdd1243dSDimitry Andric std::optional<bool> NoEscape = false;
73bdd1243dSDimitry Andric std::optional<NullabilityKind> Nullability;
74bdd1243dSDimitry Andric std::optional<RetainCountConventionKind> RetainCountConvention;
75e8d8bef9SDimitry Andric StringRef Type;
76e8d8bef9SDimitry Andric };
77e8d8bef9SDimitry Andric
78e8d8bef9SDimitry Andric typedef std::vector<Param> ParamsSeq;
79e8d8bef9SDimitry Andric } // namespace
80e8d8bef9SDimitry Andric
81e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
82e8d8bef9SDimitry Andric LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(NullabilityKind)
83e8d8bef9SDimitry Andric
84e8d8bef9SDimitry Andric namespace llvm {
85e8d8bef9SDimitry Andric namespace yaml {
86e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<NullabilityKind> {
enumerationllvm::yaml::ScalarEnumerationTraits87e8d8bef9SDimitry Andric static void enumeration(IO &IO, NullabilityKind &NK) {
88e8d8bef9SDimitry Andric IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull);
89e8d8bef9SDimitry Andric IO.enumCase(NK, "Optional", NullabilityKind::Nullable);
90e8d8bef9SDimitry Andric IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified);
91e8d8bef9SDimitry Andric IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult);
92e8d8bef9SDimitry Andric // TODO: Mapping this to it's own value would allow for better cross
93e8d8bef9SDimitry Andric // checking. Also the default should be Unknown.
94e8d8bef9SDimitry Andric IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified);
95e8d8bef9SDimitry Andric
96e8d8bef9SDimitry Andric // Aliases for compatibility with existing APINotes.
97e8d8bef9SDimitry Andric IO.enumCase(NK, "N", NullabilityKind::NonNull);
98e8d8bef9SDimitry Andric IO.enumCase(NK, "O", NullabilityKind::Nullable);
99e8d8bef9SDimitry Andric IO.enumCase(NK, "U", NullabilityKind::Unspecified);
100e8d8bef9SDimitry Andric IO.enumCase(NK, "S", NullabilityKind::Unspecified);
101e8d8bef9SDimitry Andric }
102e8d8bef9SDimitry Andric };
103e8d8bef9SDimitry Andric
104e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<RetainCountConventionKind> {
enumerationllvm::yaml::ScalarEnumerationTraits105e8d8bef9SDimitry Andric static void enumeration(IO &IO, RetainCountConventionKind &RCCK) {
106e8d8bef9SDimitry Andric IO.enumCase(RCCK, "none", RetainCountConventionKind::None);
107e8d8bef9SDimitry Andric IO.enumCase(RCCK, "CFReturnsRetained",
108e8d8bef9SDimitry Andric RetainCountConventionKind::CFReturnsRetained);
109e8d8bef9SDimitry Andric IO.enumCase(RCCK, "CFReturnsNotRetained",
110e8d8bef9SDimitry Andric RetainCountConventionKind::CFReturnsNotRetained);
111e8d8bef9SDimitry Andric IO.enumCase(RCCK, "NSReturnsRetained",
112e8d8bef9SDimitry Andric RetainCountConventionKind::NSReturnsRetained);
113e8d8bef9SDimitry Andric IO.enumCase(RCCK, "NSReturnsNotRetained",
114e8d8bef9SDimitry Andric RetainCountConventionKind::NSReturnsNotRetained);
115e8d8bef9SDimitry Andric }
116e8d8bef9SDimitry Andric };
117e8d8bef9SDimitry Andric
118e8d8bef9SDimitry Andric template <> struct MappingTraits<Param> {
mappingllvm::yaml::MappingTraits119e8d8bef9SDimitry Andric static void mapping(IO &IO, Param &P) {
120e8d8bef9SDimitry Andric IO.mapRequired("Position", P.Position);
121bdd1243dSDimitry Andric IO.mapOptional("Nullability", P.Nullability, std::nullopt);
122e8d8bef9SDimitry Andric IO.mapOptional("RetainCountConvention", P.RetainCountConvention);
123e8d8bef9SDimitry Andric IO.mapOptional("NoEscape", P.NoEscape);
124e8d8bef9SDimitry Andric IO.mapOptional("Type", P.Type, StringRef(""));
125e8d8bef9SDimitry Andric }
126e8d8bef9SDimitry Andric };
127e8d8bef9SDimitry Andric } // namespace yaml
128e8d8bef9SDimitry Andric } // namespace llvm
129e8d8bef9SDimitry Andric
130e8d8bef9SDimitry Andric namespace {
131e8d8bef9SDimitry Andric typedef std::vector<NullabilityKind> NullabilitySeq;
132e8d8bef9SDimitry Andric
133e8d8bef9SDimitry Andric struct AvailabilityItem {
134e8d8bef9SDimitry Andric APIAvailability Mode = APIAvailability::Available;
135e8d8bef9SDimitry Andric StringRef Msg;
136e8d8bef9SDimitry Andric };
137e8d8bef9SDimitry Andric
138e8d8bef9SDimitry Andric /// Old attribute deprecated in favor of SwiftName.
139e8d8bef9SDimitry Andric enum class FactoryAsInitKind {
140e8d8bef9SDimitry Andric /// Infer based on name and type (the default).
141e8d8bef9SDimitry Andric Infer,
142e8d8bef9SDimitry Andric /// Treat as a class method.
143e8d8bef9SDimitry Andric AsClassMethod,
144e8d8bef9SDimitry Andric /// Treat as an initializer.
145e8d8bef9SDimitry Andric AsInitializer,
146e8d8bef9SDimitry Andric };
147e8d8bef9SDimitry Andric
148e8d8bef9SDimitry Andric struct Method {
149e8d8bef9SDimitry Andric StringRef Selector;
150e8d8bef9SDimitry Andric MethodKind Kind;
151e8d8bef9SDimitry Andric ParamsSeq Params;
152e8d8bef9SDimitry Andric NullabilitySeq Nullability;
153bdd1243dSDimitry Andric std::optional<NullabilityKind> NullabilityOfRet;
154bdd1243dSDimitry Andric std::optional<RetainCountConventionKind> RetainCountConvention;
155e8d8bef9SDimitry Andric AvailabilityItem Availability;
156bdd1243dSDimitry Andric std::optional<bool> SwiftPrivate;
157e8d8bef9SDimitry Andric StringRef SwiftName;
158e8d8bef9SDimitry Andric FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
159e8d8bef9SDimitry Andric bool DesignatedInit = false;
160e8d8bef9SDimitry Andric bool Required = false;
161e8d8bef9SDimitry Andric StringRef ResultType;
162e8d8bef9SDimitry Andric };
163e8d8bef9SDimitry Andric
164e8d8bef9SDimitry Andric typedef std::vector<Method> MethodsSeq;
165e8d8bef9SDimitry Andric } // namespace
166e8d8bef9SDimitry Andric
167e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Method)
168e8d8bef9SDimitry Andric
169e8d8bef9SDimitry Andric namespace llvm {
170e8d8bef9SDimitry Andric namespace yaml {
171e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<FactoryAsInitKind> {
enumerationllvm::yaml::ScalarEnumerationTraits172e8d8bef9SDimitry Andric static void enumeration(IO &IO, FactoryAsInitKind &FIK) {
173e8d8bef9SDimitry Andric IO.enumCase(FIK, "A", FactoryAsInitKind::Infer);
174e8d8bef9SDimitry Andric IO.enumCase(FIK, "C", FactoryAsInitKind::AsClassMethod);
175e8d8bef9SDimitry Andric IO.enumCase(FIK, "I", FactoryAsInitKind::AsInitializer);
176e8d8bef9SDimitry Andric }
177e8d8bef9SDimitry Andric };
178e8d8bef9SDimitry Andric
179e8d8bef9SDimitry Andric template <> struct MappingTraits<Method> {
mappingllvm::yaml::MappingTraits180e8d8bef9SDimitry Andric static void mapping(IO &IO, Method &M) {
181e8d8bef9SDimitry Andric IO.mapRequired("Selector", M.Selector);
182e8d8bef9SDimitry Andric IO.mapRequired("MethodKind", M.Kind);
183e8d8bef9SDimitry Andric IO.mapOptional("Parameters", M.Params);
184e8d8bef9SDimitry Andric IO.mapOptional("Nullability", M.Nullability);
185bdd1243dSDimitry Andric IO.mapOptional("NullabilityOfRet", M.NullabilityOfRet, std::nullopt);
186e8d8bef9SDimitry Andric IO.mapOptional("RetainCountConvention", M.RetainCountConvention);
187e8d8bef9SDimitry Andric IO.mapOptional("Availability", M.Availability.Mode,
188e8d8bef9SDimitry Andric APIAvailability::Available);
189e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
190e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", M.SwiftPrivate);
191e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", M.SwiftName, StringRef(""));
192e8d8bef9SDimitry Andric IO.mapOptional("FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);
193e8d8bef9SDimitry Andric IO.mapOptional("DesignatedInit", M.DesignatedInit, false);
194e8d8bef9SDimitry Andric IO.mapOptional("Required", M.Required, false);
195e8d8bef9SDimitry Andric IO.mapOptional("ResultType", M.ResultType, StringRef(""));
196e8d8bef9SDimitry Andric }
197e8d8bef9SDimitry Andric };
198e8d8bef9SDimitry Andric } // namespace yaml
199e8d8bef9SDimitry Andric } // namespace llvm
200e8d8bef9SDimitry Andric
201e8d8bef9SDimitry Andric namespace {
202e8d8bef9SDimitry Andric struct Property {
203e8d8bef9SDimitry Andric StringRef Name;
204bdd1243dSDimitry Andric std::optional<MethodKind> Kind;
205bdd1243dSDimitry Andric std::optional<NullabilityKind> Nullability;
206e8d8bef9SDimitry Andric AvailabilityItem Availability;
207bdd1243dSDimitry Andric std::optional<bool> SwiftPrivate;
208e8d8bef9SDimitry Andric StringRef SwiftName;
209bdd1243dSDimitry Andric std::optional<bool> SwiftImportAsAccessors;
210e8d8bef9SDimitry Andric StringRef Type;
211e8d8bef9SDimitry Andric };
212e8d8bef9SDimitry Andric
213e8d8bef9SDimitry Andric typedef std::vector<Property> PropertiesSeq;
214e8d8bef9SDimitry Andric } // namespace
215e8d8bef9SDimitry Andric
216e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Property)
217e8d8bef9SDimitry Andric
218e8d8bef9SDimitry Andric namespace llvm {
219e8d8bef9SDimitry Andric namespace yaml {
220e8d8bef9SDimitry Andric template <> struct MappingTraits<Property> {
mappingllvm::yaml::MappingTraits221e8d8bef9SDimitry Andric static void mapping(IO &IO, Property &P) {
222e8d8bef9SDimitry Andric IO.mapRequired("Name", P.Name);
223e8d8bef9SDimitry Andric IO.mapOptional("PropertyKind", P.Kind);
224bdd1243dSDimitry Andric IO.mapOptional("Nullability", P.Nullability, std::nullopt);
225e8d8bef9SDimitry Andric IO.mapOptional("Availability", P.Availability.Mode,
226e8d8bef9SDimitry Andric APIAvailability::Available);
227e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", P.Availability.Msg, StringRef(""));
228e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", P.SwiftPrivate);
229e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", P.SwiftName, StringRef(""));
230e8d8bef9SDimitry Andric IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors);
231e8d8bef9SDimitry Andric IO.mapOptional("Type", P.Type, StringRef(""));
232e8d8bef9SDimitry Andric }
233e8d8bef9SDimitry Andric };
234e8d8bef9SDimitry Andric } // namespace yaml
235e8d8bef9SDimitry Andric } // namespace llvm
236e8d8bef9SDimitry Andric
237e8d8bef9SDimitry Andric namespace {
238e8d8bef9SDimitry Andric struct Class {
239e8d8bef9SDimitry Andric StringRef Name;
240e8d8bef9SDimitry Andric bool AuditedForNullability = false;
241e8d8bef9SDimitry Andric AvailabilityItem Availability;
242bdd1243dSDimitry Andric std::optional<bool> SwiftPrivate;
243e8d8bef9SDimitry Andric StringRef SwiftName;
244bdd1243dSDimitry Andric std::optional<StringRef> SwiftBridge;
245bdd1243dSDimitry Andric std::optional<StringRef> NSErrorDomain;
246bdd1243dSDimitry Andric std::optional<bool> SwiftImportAsNonGeneric;
247bdd1243dSDimitry Andric std::optional<bool> SwiftObjCMembers;
248e8d8bef9SDimitry Andric MethodsSeq Methods;
249e8d8bef9SDimitry Andric PropertiesSeq Properties;
250e8d8bef9SDimitry Andric };
251e8d8bef9SDimitry Andric
252e8d8bef9SDimitry Andric typedef std::vector<Class> ClassesSeq;
253e8d8bef9SDimitry Andric } // namespace
254e8d8bef9SDimitry Andric
255e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Class)
256e8d8bef9SDimitry Andric
257e8d8bef9SDimitry Andric namespace llvm {
258e8d8bef9SDimitry Andric namespace yaml {
259e8d8bef9SDimitry Andric template <> struct MappingTraits<Class> {
mappingllvm::yaml::MappingTraits260e8d8bef9SDimitry Andric static void mapping(IO &IO, Class &C) {
261e8d8bef9SDimitry Andric IO.mapRequired("Name", C.Name);
262e8d8bef9SDimitry Andric IO.mapOptional("AuditedForNullability", C.AuditedForNullability, false);
263e8d8bef9SDimitry Andric IO.mapOptional("Availability", C.Availability.Mode,
264e8d8bef9SDimitry Andric APIAvailability::Available);
265e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", C.Availability.Msg, StringRef(""));
266e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", C.SwiftPrivate);
267e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", C.SwiftName, StringRef(""));
268e8d8bef9SDimitry Andric IO.mapOptional("SwiftBridge", C.SwiftBridge);
269e8d8bef9SDimitry Andric IO.mapOptional("NSErrorDomain", C.NSErrorDomain);
270e8d8bef9SDimitry Andric IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric);
271e8d8bef9SDimitry Andric IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers);
272e8d8bef9SDimitry Andric IO.mapOptional("Methods", C.Methods);
273e8d8bef9SDimitry Andric IO.mapOptional("Properties", C.Properties);
274e8d8bef9SDimitry Andric }
275e8d8bef9SDimitry Andric };
276e8d8bef9SDimitry Andric } // namespace yaml
277e8d8bef9SDimitry Andric } // namespace llvm
278e8d8bef9SDimitry Andric
279e8d8bef9SDimitry Andric namespace {
280e8d8bef9SDimitry Andric struct Function {
281e8d8bef9SDimitry Andric StringRef Name;
282e8d8bef9SDimitry Andric ParamsSeq Params;
283e8d8bef9SDimitry Andric NullabilitySeq Nullability;
284bdd1243dSDimitry Andric std::optional<NullabilityKind> NullabilityOfRet;
285bdd1243dSDimitry Andric std::optional<api_notes::RetainCountConventionKind> RetainCountConvention;
286e8d8bef9SDimitry Andric AvailabilityItem Availability;
287bdd1243dSDimitry Andric std::optional<bool> SwiftPrivate;
288e8d8bef9SDimitry Andric StringRef SwiftName;
289e8d8bef9SDimitry Andric StringRef Type;
290e8d8bef9SDimitry Andric StringRef ResultType;
291e8d8bef9SDimitry Andric };
292e8d8bef9SDimitry Andric
293e8d8bef9SDimitry Andric typedef std::vector<Function> FunctionsSeq;
294e8d8bef9SDimitry Andric } // namespace
295e8d8bef9SDimitry Andric
296e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Function)
297e8d8bef9SDimitry Andric
298e8d8bef9SDimitry Andric namespace llvm {
299e8d8bef9SDimitry Andric namespace yaml {
300e8d8bef9SDimitry Andric template <> struct MappingTraits<Function> {
mappingllvm::yaml::MappingTraits301e8d8bef9SDimitry Andric static void mapping(IO &IO, Function &F) {
302e8d8bef9SDimitry Andric IO.mapRequired("Name", F.Name);
303e8d8bef9SDimitry Andric IO.mapOptional("Parameters", F.Params);
304e8d8bef9SDimitry Andric IO.mapOptional("Nullability", F.Nullability);
305bdd1243dSDimitry Andric IO.mapOptional("NullabilityOfRet", F.NullabilityOfRet, std::nullopt);
306e8d8bef9SDimitry Andric IO.mapOptional("RetainCountConvention", F.RetainCountConvention);
307e8d8bef9SDimitry Andric IO.mapOptional("Availability", F.Availability.Mode,
308e8d8bef9SDimitry Andric APIAvailability::Available);
309e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));
310e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", F.SwiftPrivate);
311e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
312e8d8bef9SDimitry Andric IO.mapOptional("ResultType", F.ResultType, StringRef(""));
313e8d8bef9SDimitry Andric }
314e8d8bef9SDimitry Andric };
315e8d8bef9SDimitry Andric } // namespace yaml
316e8d8bef9SDimitry Andric } // namespace llvm
317e8d8bef9SDimitry Andric
318e8d8bef9SDimitry Andric namespace {
319e8d8bef9SDimitry Andric struct GlobalVariable {
320e8d8bef9SDimitry Andric StringRef Name;
321bdd1243dSDimitry Andric std::optional<NullabilityKind> Nullability;
322e8d8bef9SDimitry Andric AvailabilityItem Availability;
323bdd1243dSDimitry Andric std::optional<bool> SwiftPrivate;
324e8d8bef9SDimitry Andric StringRef SwiftName;
325e8d8bef9SDimitry Andric StringRef Type;
326e8d8bef9SDimitry Andric };
327e8d8bef9SDimitry Andric
328e8d8bef9SDimitry Andric typedef std::vector<GlobalVariable> GlobalVariablesSeq;
329e8d8bef9SDimitry Andric } // namespace
330e8d8bef9SDimitry Andric
331e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
332e8d8bef9SDimitry Andric
333e8d8bef9SDimitry Andric namespace llvm {
334e8d8bef9SDimitry Andric namespace yaml {
335e8d8bef9SDimitry Andric template <> struct MappingTraits<GlobalVariable> {
mappingllvm::yaml::MappingTraits336e8d8bef9SDimitry Andric static void mapping(IO &IO, GlobalVariable &GV) {
337e8d8bef9SDimitry Andric IO.mapRequired("Name", GV.Name);
338bdd1243dSDimitry Andric IO.mapOptional("Nullability", GV.Nullability, std::nullopt);
339e8d8bef9SDimitry Andric IO.mapOptional("Availability", GV.Availability.Mode,
340e8d8bef9SDimitry Andric APIAvailability::Available);
341e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", GV.Availability.Msg, StringRef(""));
342e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", GV.SwiftPrivate);
343e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", GV.SwiftName, StringRef(""));
344e8d8bef9SDimitry Andric IO.mapOptional("Type", GV.Type, StringRef(""));
345e8d8bef9SDimitry Andric }
346e8d8bef9SDimitry Andric };
347e8d8bef9SDimitry Andric } // namespace yaml
348e8d8bef9SDimitry Andric } // namespace llvm
349e8d8bef9SDimitry Andric
350e8d8bef9SDimitry Andric namespace {
351e8d8bef9SDimitry Andric struct EnumConstant {
352e8d8bef9SDimitry Andric StringRef Name;
353e8d8bef9SDimitry Andric AvailabilityItem Availability;
354bdd1243dSDimitry Andric std::optional<bool> SwiftPrivate;
355e8d8bef9SDimitry Andric StringRef SwiftName;
356e8d8bef9SDimitry Andric };
357e8d8bef9SDimitry Andric
358e8d8bef9SDimitry Andric typedef std::vector<EnumConstant> EnumConstantsSeq;
359e8d8bef9SDimitry Andric } // namespace
360e8d8bef9SDimitry Andric
361e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
362e8d8bef9SDimitry Andric
363e8d8bef9SDimitry Andric namespace llvm {
364e8d8bef9SDimitry Andric namespace yaml {
365e8d8bef9SDimitry Andric template <> struct MappingTraits<EnumConstant> {
mappingllvm::yaml::MappingTraits366e8d8bef9SDimitry Andric static void mapping(IO &IO, EnumConstant &EC) {
367e8d8bef9SDimitry Andric IO.mapRequired("Name", EC.Name);
368e8d8bef9SDimitry Andric IO.mapOptional("Availability", EC.Availability.Mode,
369e8d8bef9SDimitry Andric APIAvailability::Available);
370e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", EC.Availability.Msg, StringRef(""));
371e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", EC.SwiftPrivate);
372e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", EC.SwiftName, StringRef(""));
373e8d8bef9SDimitry Andric }
374e8d8bef9SDimitry Andric };
375e8d8bef9SDimitry Andric } // namespace yaml
376e8d8bef9SDimitry Andric } // namespace llvm
377e8d8bef9SDimitry Andric
378e8d8bef9SDimitry Andric namespace {
379e8d8bef9SDimitry Andric /// Syntactic sugar for EnumExtensibility and FlagEnum
380e8d8bef9SDimitry Andric enum class EnumConvenienceAliasKind {
381e8d8bef9SDimitry Andric /// EnumExtensibility: none, FlagEnum: false
382e8d8bef9SDimitry Andric None,
383e8d8bef9SDimitry Andric /// EnumExtensibility: open, FlagEnum: false
384e8d8bef9SDimitry Andric CFEnum,
385e8d8bef9SDimitry Andric /// EnumExtensibility: open, FlagEnum: true
386e8d8bef9SDimitry Andric CFOptions,
387e8d8bef9SDimitry Andric /// EnumExtensibility: closed, FlagEnum: false
388e8d8bef9SDimitry Andric CFClosedEnum
389e8d8bef9SDimitry Andric };
390e8d8bef9SDimitry Andric } // namespace
391e8d8bef9SDimitry Andric
392e8d8bef9SDimitry Andric namespace llvm {
393e8d8bef9SDimitry Andric namespace yaml {
394e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
enumerationllvm::yaml::ScalarEnumerationTraits395e8d8bef9SDimitry Andric static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK) {
396e8d8bef9SDimitry Andric IO.enumCase(ECAK, "none", EnumConvenienceAliasKind::None);
397e8d8bef9SDimitry Andric IO.enumCase(ECAK, "CFEnum", EnumConvenienceAliasKind::CFEnum);
398e8d8bef9SDimitry Andric IO.enumCase(ECAK, "NSEnum", EnumConvenienceAliasKind::CFEnum);
399e8d8bef9SDimitry Andric IO.enumCase(ECAK, "CFOptions", EnumConvenienceAliasKind::CFOptions);
400e8d8bef9SDimitry Andric IO.enumCase(ECAK, "NSOptions", EnumConvenienceAliasKind::CFOptions);
401e8d8bef9SDimitry Andric IO.enumCase(ECAK, "CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
402e8d8bef9SDimitry Andric IO.enumCase(ECAK, "NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
403e8d8bef9SDimitry Andric }
404e8d8bef9SDimitry Andric };
405e8d8bef9SDimitry Andric } // namespace yaml
406e8d8bef9SDimitry Andric } // namespace llvm
407e8d8bef9SDimitry Andric
408e8d8bef9SDimitry Andric namespace {
409e8d8bef9SDimitry Andric struct Tag {
410e8d8bef9SDimitry Andric StringRef Name;
411e8d8bef9SDimitry Andric AvailabilityItem Availability;
412e8d8bef9SDimitry Andric StringRef SwiftName;
413bdd1243dSDimitry Andric std::optional<bool> SwiftPrivate;
414bdd1243dSDimitry Andric std::optional<StringRef> SwiftBridge;
415bdd1243dSDimitry Andric std::optional<StringRef> NSErrorDomain;
4165f757f3fSDimitry Andric std::optional<std::string> SwiftImportAs;
4175f757f3fSDimitry Andric std::optional<std::string> SwiftRetainOp;
4185f757f3fSDimitry Andric std::optional<std::string> SwiftReleaseOp;
419bdd1243dSDimitry Andric std::optional<EnumExtensibilityKind> EnumExtensibility;
420bdd1243dSDimitry Andric std::optional<bool> FlagEnum;
421bdd1243dSDimitry Andric std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
422*0fca6ea1SDimitry Andric std::optional<bool> SwiftCopyable;
423*0fca6ea1SDimitry Andric FunctionsSeq Methods;
424e8d8bef9SDimitry Andric };
425e8d8bef9SDimitry Andric
426e8d8bef9SDimitry Andric typedef std::vector<Tag> TagsSeq;
427e8d8bef9SDimitry Andric } // namespace
428e8d8bef9SDimitry Andric
429e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
430e8d8bef9SDimitry Andric
431e8d8bef9SDimitry Andric namespace llvm {
432e8d8bef9SDimitry Andric namespace yaml {
433e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<EnumExtensibilityKind> {
enumerationllvm::yaml::ScalarEnumerationTraits434e8d8bef9SDimitry Andric static void enumeration(IO &IO, EnumExtensibilityKind &EEK) {
435e8d8bef9SDimitry Andric IO.enumCase(EEK, "none", EnumExtensibilityKind::None);
436e8d8bef9SDimitry Andric IO.enumCase(EEK, "open", EnumExtensibilityKind::Open);
437e8d8bef9SDimitry Andric IO.enumCase(EEK, "closed", EnumExtensibilityKind::Closed);
438e8d8bef9SDimitry Andric }
439e8d8bef9SDimitry Andric };
440e8d8bef9SDimitry Andric
441e8d8bef9SDimitry Andric template <> struct MappingTraits<Tag> {
mappingllvm::yaml::MappingTraits442e8d8bef9SDimitry Andric static void mapping(IO &IO, Tag &T) {
443e8d8bef9SDimitry Andric IO.mapRequired("Name", T.Name);
444e8d8bef9SDimitry Andric IO.mapOptional("Availability", T.Availability.Mode,
445e8d8bef9SDimitry Andric APIAvailability::Available);
446e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
447e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
448e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
449e8d8bef9SDimitry Andric IO.mapOptional("SwiftBridge", T.SwiftBridge);
450e8d8bef9SDimitry Andric IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
4515f757f3fSDimitry Andric IO.mapOptional("SwiftImportAs", T.SwiftImportAs);
4525f757f3fSDimitry Andric IO.mapOptional("SwiftReleaseOp", T.SwiftReleaseOp);
4535f757f3fSDimitry Andric IO.mapOptional("SwiftRetainOp", T.SwiftRetainOp);
454e8d8bef9SDimitry Andric IO.mapOptional("EnumExtensibility", T.EnumExtensibility);
455e8d8bef9SDimitry Andric IO.mapOptional("FlagEnum", T.FlagEnum);
456e8d8bef9SDimitry Andric IO.mapOptional("EnumKind", T.EnumConvenienceKind);
457*0fca6ea1SDimitry Andric IO.mapOptional("SwiftCopyable", T.SwiftCopyable);
458*0fca6ea1SDimitry Andric IO.mapOptional("Methods", T.Methods);
459e8d8bef9SDimitry Andric }
460e8d8bef9SDimitry Andric };
461e8d8bef9SDimitry Andric } // namespace yaml
462e8d8bef9SDimitry Andric } // namespace llvm
463e8d8bef9SDimitry Andric
464e8d8bef9SDimitry Andric namespace {
465e8d8bef9SDimitry Andric struct Typedef {
466e8d8bef9SDimitry Andric StringRef Name;
467e8d8bef9SDimitry Andric AvailabilityItem Availability;
468e8d8bef9SDimitry Andric StringRef SwiftName;
469bdd1243dSDimitry Andric std::optional<bool> SwiftPrivate;
470bdd1243dSDimitry Andric std::optional<StringRef> SwiftBridge;
471bdd1243dSDimitry Andric std::optional<StringRef> NSErrorDomain;
472bdd1243dSDimitry Andric std::optional<SwiftNewTypeKind> SwiftType;
473e8d8bef9SDimitry Andric };
474e8d8bef9SDimitry Andric
475e8d8bef9SDimitry Andric typedef std::vector<Typedef> TypedefsSeq;
476e8d8bef9SDimitry Andric } // namespace
477e8d8bef9SDimitry Andric
478e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
479e8d8bef9SDimitry Andric
480e8d8bef9SDimitry Andric namespace llvm {
481e8d8bef9SDimitry Andric namespace yaml {
482e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<SwiftNewTypeKind> {
enumerationllvm::yaml::ScalarEnumerationTraits483e8d8bef9SDimitry Andric static void enumeration(IO &IO, SwiftNewTypeKind &SWK) {
484e8d8bef9SDimitry Andric IO.enumCase(SWK, "none", SwiftNewTypeKind::None);
485e8d8bef9SDimitry Andric IO.enumCase(SWK, "struct", SwiftNewTypeKind::Struct);
486e8d8bef9SDimitry Andric IO.enumCase(SWK, "enum", SwiftNewTypeKind::Enum);
487e8d8bef9SDimitry Andric }
488e8d8bef9SDimitry Andric };
489e8d8bef9SDimitry Andric
490e8d8bef9SDimitry Andric template <> struct MappingTraits<Typedef> {
mappingllvm::yaml::MappingTraits491e8d8bef9SDimitry Andric static void mapping(IO &IO, Typedef &T) {
492e8d8bef9SDimitry Andric IO.mapRequired("Name", T.Name);
493e8d8bef9SDimitry Andric IO.mapOptional("Availability", T.Availability.Mode,
494e8d8bef9SDimitry Andric APIAvailability::Available);
495e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
496e8d8bef9SDimitry Andric IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
497e8d8bef9SDimitry Andric IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
498e8d8bef9SDimitry Andric IO.mapOptional("SwiftBridge", T.SwiftBridge);
499e8d8bef9SDimitry Andric IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
500e8d8bef9SDimitry Andric IO.mapOptional("SwiftWrapper", T.SwiftType);
501e8d8bef9SDimitry Andric }
502e8d8bef9SDimitry Andric };
503e8d8bef9SDimitry Andric } // namespace yaml
504e8d8bef9SDimitry Andric } // namespace llvm
505e8d8bef9SDimitry Andric
506e8d8bef9SDimitry Andric namespace {
5075f757f3fSDimitry Andric struct Namespace;
5085f757f3fSDimitry Andric typedef std::vector<Namespace> NamespacesSeq;
5095f757f3fSDimitry Andric
510e8d8bef9SDimitry Andric struct TopLevelItems {
511e8d8bef9SDimitry Andric ClassesSeq Classes;
512e8d8bef9SDimitry Andric ClassesSeq Protocols;
513e8d8bef9SDimitry Andric FunctionsSeq Functions;
514e8d8bef9SDimitry Andric GlobalVariablesSeq Globals;
515e8d8bef9SDimitry Andric EnumConstantsSeq EnumConstants;
516e8d8bef9SDimitry Andric TagsSeq Tags;
517e8d8bef9SDimitry Andric TypedefsSeq Typedefs;
5185f757f3fSDimitry Andric NamespacesSeq Namespaces;
519e8d8bef9SDimitry Andric };
520e8d8bef9SDimitry Andric } // namespace
521e8d8bef9SDimitry Andric
522e8d8bef9SDimitry Andric namespace llvm {
523e8d8bef9SDimitry Andric namespace yaml {
mapTopLevelItems(IO & IO,TopLevelItems & TLI)524e8d8bef9SDimitry Andric static void mapTopLevelItems(IO &IO, TopLevelItems &TLI) {
525e8d8bef9SDimitry Andric IO.mapOptional("Classes", TLI.Classes);
526e8d8bef9SDimitry Andric IO.mapOptional("Protocols", TLI.Protocols);
527e8d8bef9SDimitry Andric IO.mapOptional("Functions", TLI.Functions);
528e8d8bef9SDimitry Andric IO.mapOptional("Globals", TLI.Globals);
529e8d8bef9SDimitry Andric IO.mapOptional("Enumerators", TLI.EnumConstants);
530e8d8bef9SDimitry Andric IO.mapOptional("Tags", TLI.Tags);
531e8d8bef9SDimitry Andric IO.mapOptional("Typedefs", TLI.Typedefs);
5325f757f3fSDimitry Andric IO.mapOptional("Namespaces", TLI.Namespaces);
533e8d8bef9SDimitry Andric }
534e8d8bef9SDimitry Andric } // namespace yaml
535e8d8bef9SDimitry Andric } // namespace llvm
536e8d8bef9SDimitry Andric
537e8d8bef9SDimitry Andric namespace {
5385f757f3fSDimitry Andric struct Namespace {
5395f757f3fSDimitry Andric StringRef Name;
5405f757f3fSDimitry Andric AvailabilityItem Availability;
5415f757f3fSDimitry Andric StringRef SwiftName;
5425f757f3fSDimitry Andric std::optional<bool> SwiftPrivate;
5435f757f3fSDimitry Andric TopLevelItems Items;
5445f757f3fSDimitry Andric };
5455f757f3fSDimitry Andric } // namespace
5465f757f3fSDimitry Andric
5475f757f3fSDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)
5485f757f3fSDimitry Andric
5495f757f3fSDimitry Andric namespace llvm {
5505f757f3fSDimitry Andric namespace yaml {
5515f757f3fSDimitry Andric template <> struct MappingTraits<Namespace> {
mappingllvm::yaml::MappingTraits5525f757f3fSDimitry Andric static void mapping(IO &IO, Namespace &T) {
5535f757f3fSDimitry Andric IO.mapRequired("Name", T.Name);
5545f757f3fSDimitry Andric IO.mapOptional("Availability", T.Availability.Mode,
5555f757f3fSDimitry Andric APIAvailability::Available);
5565f757f3fSDimitry Andric IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
5575f757f3fSDimitry Andric IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
5585f757f3fSDimitry Andric IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
5595f757f3fSDimitry Andric mapTopLevelItems(IO, T.Items);
5605f757f3fSDimitry Andric }
5615f757f3fSDimitry Andric };
5625f757f3fSDimitry Andric } // namespace yaml
5635f757f3fSDimitry Andric } // namespace llvm
5645f757f3fSDimitry Andric
5655f757f3fSDimitry Andric namespace {
566e8d8bef9SDimitry Andric struct Versioned {
567e8d8bef9SDimitry Andric VersionTuple Version;
568e8d8bef9SDimitry Andric TopLevelItems Items;
569e8d8bef9SDimitry Andric };
570e8d8bef9SDimitry Andric
571e8d8bef9SDimitry Andric typedef std::vector<Versioned> VersionedSeq;
572e8d8bef9SDimitry Andric } // namespace
573e8d8bef9SDimitry Andric
574e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
575e8d8bef9SDimitry Andric
576e8d8bef9SDimitry Andric namespace llvm {
577e8d8bef9SDimitry Andric namespace yaml {
578e8d8bef9SDimitry Andric template <> struct MappingTraits<Versioned> {
mappingllvm::yaml::MappingTraits579e8d8bef9SDimitry Andric static void mapping(IO &IO, Versioned &V) {
580e8d8bef9SDimitry Andric IO.mapRequired("Version", V.Version);
581e8d8bef9SDimitry Andric mapTopLevelItems(IO, V.Items);
582e8d8bef9SDimitry Andric }
583e8d8bef9SDimitry Andric };
584e8d8bef9SDimitry Andric } // namespace yaml
585e8d8bef9SDimitry Andric } // namespace llvm
586e8d8bef9SDimitry Andric
587e8d8bef9SDimitry Andric namespace {
588e8d8bef9SDimitry Andric struct Module {
589e8d8bef9SDimitry Andric StringRef Name;
590e8d8bef9SDimitry Andric AvailabilityItem Availability;
591e8d8bef9SDimitry Andric TopLevelItems TopLevel;
592e8d8bef9SDimitry Andric VersionedSeq SwiftVersions;
593e8d8bef9SDimitry Andric
594bdd1243dSDimitry Andric std::optional<bool> SwiftInferImportAsMember;
595e8d8bef9SDimitry Andric
596fe6060f1SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
597e8d8bef9SDimitry Andric LLVM_DUMP_METHOD void dump() /*const*/;
598fe6060f1SDimitry Andric #endif
599e8d8bef9SDimitry Andric };
600e8d8bef9SDimitry Andric } // namespace
601e8d8bef9SDimitry Andric
602e8d8bef9SDimitry Andric namespace llvm {
603e8d8bef9SDimitry Andric namespace yaml {
604e8d8bef9SDimitry Andric template <> struct MappingTraits<Module> {
mappingllvm::yaml::MappingTraits605e8d8bef9SDimitry Andric static void mapping(IO &IO, Module &M) {
606e8d8bef9SDimitry Andric IO.mapRequired("Name", M.Name);
607e8d8bef9SDimitry Andric IO.mapOptional("Availability", M.Availability.Mode,
608e8d8bef9SDimitry Andric APIAvailability::Available);
609e8d8bef9SDimitry Andric IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
610e8d8bef9SDimitry Andric IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember);
611e8d8bef9SDimitry Andric mapTopLevelItems(IO, M.TopLevel);
612e8d8bef9SDimitry Andric IO.mapOptional("SwiftVersions", M.SwiftVersions);
613e8d8bef9SDimitry Andric }
614e8d8bef9SDimitry Andric };
615e8d8bef9SDimitry Andric } // namespace yaml
616e8d8bef9SDimitry Andric } // namespace llvm
617e8d8bef9SDimitry Andric
618fe6060f1SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump()619fe6060f1SDimitry Andric LLVM_DUMP_METHOD void Module::dump() {
620e8d8bef9SDimitry Andric llvm::yaml::Output OS(llvm::errs());
621e8d8bef9SDimitry Andric OS << *this;
622e8d8bef9SDimitry Andric }
623fe6060f1SDimitry Andric #endif
624e8d8bef9SDimitry Andric
625e8d8bef9SDimitry Andric namespace {
parseAPINotes(StringRef YI,Module & M,llvm::SourceMgr::DiagHandlerTy Diag,void * DiagContext)626e8d8bef9SDimitry Andric bool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag,
627e8d8bef9SDimitry Andric void *DiagContext) {
628e8d8bef9SDimitry Andric llvm::yaml::Input IS(YI, nullptr, Diag, DiagContext);
629e8d8bef9SDimitry Andric IS >> M;
630e8d8bef9SDimitry Andric return static_cast<bool>(IS.error());
631e8d8bef9SDimitry Andric }
632e8d8bef9SDimitry Andric } // namespace
633e8d8bef9SDimitry Andric
parseAndDumpAPINotes(StringRef YI,llvm::raw_ostream & OS)634e8d8bef9SDimitry Andric bool clang::api_notes::parseAndDumpAPINotes(StringRef YI,
635e8d8bef9SDimitry Andric llvm::raw_ostream &OS) {
636e8d8bef9SDimitry Andric Module M;
637e8d8bef9SDimitry Andric if (parseAPINotes(YI, M, nullptr, nullptr))
638e8d8bef9SDimitry Andric return true;
639e8d8bef9SDimitry Andric
640e8d8bef9SDimitry Andric llvm::yaml::Output YOS(OS);
641e8d8bef9SDimitry Andric YOS << M;
642e8d8bef9SDimitry Andric
643e8d8bef9SDimitry Andric return false;
644e8d8bef9SDimitry Andric }
6455f757f3fSDimitry Andric
6465f757f3fSDimitry Andric namespace {
6475f757f3fSDimitry Andric using namespace api_notes;
6485f757f3fSDimitry Andric
6495f757f3fSDimitry Andric class YAMLConverter {
6505f757f3fSDimitry Andric const Module &M;
6515f757f3fSDimitry Andric APINotesWriter Writer;
6525f757f3fSDimitry Andric llvm::raw_ostream &OS;
6535f757f3fSDimitry Andric llvm::SourceMgr::DiagHandlerTy DiagHandler;
6545f757f3fSDimitry Andric void *DiagHandlerCtxt;
6555f757f3fSDimitry Andric bool ErrorOccured;
6565f757f3fSDimitry Andric
6575f757f3fSDimitry Andric /// Emit a diagnostic
emitError(llvm::Twine Message)6585f757f3fSDimitry Andric bool emitError(llvm::Twine Message) {
6595f757f3fSDimitry Andric DiagHandler(
6605f757f3fSDimitry Andric llvm::SMDiagnostic("", llvm::SourceMgr::DK_Error, Message.str()),
6615f757f3fSDimitry Andric DiagHandlerCtxt);
6625f757f3fSDimitry Andric ErrorOccured = true;
6635f757f3fSDimitry Andric return true;
6645f757f3fSDimitry Andric }
6655f757f3fSDimitry Andric
6665f757f3fSDimitry Andric public:
YAMLConverter(const Module & TheModule,const FileEntry * SourceFile,llvm::raw_ostream & OS,llvm::SourceMgr::DiagHandlerTy DiagHandler,void * DiagHandlerCtxt)6675f757f3fSDimitry Andric YAMLConverter(const Module &TheModule, const FileEntry *SourceFile,
6685f757f3fSDimitry Andric llvm::raw_ostream &OS,
6695f757f3fSDimitry Andric llvm::SourceMgr::DiagHandlerTy DiagHandler,
6705f757f3fSDimitry Andric void *DiagHandlerCtxt)
6715f757f3fSDimitry Andric : M(TheModule), Writer(TheModule.Name, SourceFile), OS(OS),
6725f757f3fSDimitry Andric DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),
6735f757f3fSDimitry Andric ErrorOccured(false) {}
6745f757f3fSDimitry Andric
convertAvailability(const AvailabilityItem & Availability,CommonEntityInfo & CEI,llvm::StringRef APIName)6755f757f3fSDimitry Andric void convertAvailability(const AvailabilityItem &Availability,
6765f757f3fSDimitry Andric CommonEntityInfo &CEI, llvm::StringRef APIName) {
6775f757f3fSDimitry Andric // Populate the unavailability information.
6785f757f3fSDimitry Andric CEI.Unavailable = (Availability.Mode == APIAvailability::None);
6795f757f3fSDimitry Andric CEI.UnavailableInSwift = (Availability.Mode == APIAvailability::NonSwift);
6805f757f3fSDimitry Andric if (CEI.Unavailable || CEI.UnavailableInSwift) {
6815f757f3fSDimitry Andric CEI.UnavailableMsg = std::string(Availability.Msg);
6825f757f3fSDimitry Andric } else {
6835f757f3fSDimitry Andric if (!Availability.Msg.empty())
6845f757f3fSDimitry Andric emitError(llvm::Twine("availability message for available API '") +
6855f757f3fSDimitry Andric APIName + "' will not be used");
6865f757f3fSDimitry Andric }
6875f757f3fSDimitry Andric }
6885f757f3fSDimitry Andric
convertParams(const ParamsSeq & Params,FunctionInfo & OutInfo)6895f757f3fSDimitry Andric void convertParams(const ParamsSeq &Params, FunctionInfo &OutInfo) {
6905f757f3fSDimitry Andric for (const auto &P : Params) {
6915f757f3fSDimitry Andric ParamInfo PI;
6925f757f3fSDimitry Andric if (P.Nullability)
6935f757f3fSDimitry Andric PI.setNullabilityAudited(*P.Nullability);
6945f757f3fSDimitry Andric PI.setNoEscape(P.NoEscape);
6955f757f3fSDimitry Andric PI.setType(std::string(P.Type));
6965f757f3fSDimitry Andric PI.setRetainCountConvention(P.RetainCountConvention);
6975f757f3fSDimitry Andric if (OutInfo.Params.size() <= P.Position)
6985f757f3fSDimitry Andric OutInfo.Params.resize(P.Position + 1);
6995f757f3fSDimitry Andric OutInfo.Params[P.Position] |= PI;
7005f757f3fSDimitry Andric }
7015f757f3fSDimitry Andric }
7025f757f3fSDimitry Andric
convertNullability(const NullabilitySeq & Nullability,std::optional<NullabilityKind> ReturnNullability,FunctionInfo & OutInfo,llvm::StringRef APIName)7035f757f3fSDimitry Andric void convertNullability(const NullabilitySeq &Nullability,
7045f757f3fSDimitry Andric std::optional<NullabilityKind> ReturnNullability,
7055f757f3fSDimitry Andric FunctionInfo &OutInfo, llvm::StringRef APIName) {
7065f757f3fSDimitry Andric if (Nullability.size() > FunctionInfo::getMaxNullabilityIndex()) {
7075f757f3fSDimitry Andric emitError(llvm::Twine("nullability info for '") + APIName +
7085f757f3fSDimitry Andric "' does not fit");
7095f757f3fSDimitry Andric return;
7105f757f3fSDimitry Andric }
7115f757f3fSDimitry Andric
7125f757f3fSDimitry Andric bool audited = false;
7135f757f3fSDimitry Andric unsigned int idx = 1;
7145f757f3fSDimitry Andric for (const auto &N : Nullability)
7155f757f3fSDimitry Andric OutInfo.addTypeInfo(idx++, N);
7165f757f3fSDimitry Andric audited = Nullability.size() > 0 || ReturnNullability;
7175f757f3fSDimitry Andric if (audited)
7185f757f3fSDimitry Andric OutInfo.addTypeInfo(0, ReturnNullability ? *ReturnNullability
7195f757f3fSDimitry Andric : NullabilityKind::NonNull);
7205f757f3fSDimitry Andric if (!audited)
7215f757f3fSDimitry Andric return;
7225f757f3fSDimitry Andric OutInfo.NullabilityAudited = audited;
7235f757f3fSDimitry Andric OutInfo.NumAdjustedNullable = idx;
7245f757f3fSDimitry Andric }
7255f757f3fSDimitry Andric
7265f757f3fSDimitry Andric /// Convert the common parts of an entity from YAML.
7275f757f3fSDimitry Andric template <typename T>
convertCommonEntity(const T & Common,CommonEntityInfo & Info,StringRef APIName)7285f757f3fSDimitry Andric void convertCommonEntity(const T &Common, CommonEntityInfo &Info,
7295f757f3fSDimitry Andric StringRef APIName) {
7305f757f3fSDimitry Andric convertAvailability(Common.Availability, Info, APIName);
7315f757f3fSDimitry Andric Info.setSwiftPrivate(Common.SwiftPrivate);
7325f757f3fSDimitry Andric Info.SwiftName = std::string(Common.SwiftName);
7335f757f3fSDimitry Andric }
7345f757f3fSDimitry Andric
7355f757f3fSDimitry Andric /// Convert the common parts of a type entity from YAML.
7365f757f3fSDimitry Andric template <typename T>
convertCommonType(const T & Common,CommonTypeInfo & Info,StringRef APIName)7375f757f3fSDimitry Andric void convertCommonType(const T &Common, CommonTypeInfo &Info,
7385f757f3fSDimitry Andric StringRef APIName) {
7395f757f3fSDimitry Andric convertCommonEntity(Common, Info, APIName);
7405f757f3fSDimitry Andric if (Common.SwiftBridge)
7415f757f3fSDimitry Andric Info.setSwiftBridge(std::string(*Common.SwiftBridge));
7425f757f3fSDimitry Andric Info.setNSErrorDomain(Common.NSErrorDomain);
7435f757f3fSDimitry Andric }
7445f757f3fSDimitry Andric
7455f757f3fSDimitry Andric // Translate from Method into ObjCMethodInfo and write it out.
convertMethod(const Method & M,ContextID ClassID,StringRef ClassName,VersionTuple SwiftVersion)7465f757f3fSDimitry Andric void convertMethod(const Method &M, ContextID ClassID, StringRef ClassName,
7475f757f3fSDimitry Andric VersionTuple SwiftVersion) {
7485f757f3fSDimitry Andric ObjCMethodInfo MI;
7495f757f3fSDimitry Andric convertCommonEntity(M, MI, M.Selector);
7505f757f3fSDimitry Andric
7515f757f3fSDimitry Andric // Check if the selector ends with ':' to determine if it takes arguments.
7525f757f3fSDimitry Andric bool takesArguments = M.Selector.ends_with(":");
7535f757f3fSDimitry Andric
7545f757f3fSDimitry Andric // Split the selector into pieces.
7555f757f3fSDimitry Andric llvm::SmallVector<StringRef, 4> Args;
7565f757f3fSDimitry Andric M.Selector.split(Args, ":", /*MaxSplit*/ -1, /*KeepEmpty*/ false);
7575f757f3fSDimitry Andric if (!takesArguments && Args.size() > 1) {
7585f757f3fSDimitry Andric emitError("selector '" + M.Selector + "' is missing a ':' at the end");
7595f757f3fSDimitry Andric return;
7605f757f3fSDimitry Andric }
7615f757f3fSDimitry Andric
7625f757f3fSDimitry Andric // Construct ObjCSelectorRef.
7635f757f3fSDimitry Andric api_notes::ObjCSelectorRef Selector;
7645f757f3fSDimitry Andric Selector.NumArgs = !takesArguments ? 0 : Args.size();
7655f757f3fSDimitry Andric Selector.Identifiers = Args;
7665f757f3fSDimitry Andric
7675f757f3fSDimitry Andric // Translate the initializer info.
7685f757f3fSDimitry Andric MI.DesignatedInit = M.DesignatedInit;
7695f757f3fSDimitry Andric MI.RequiredInit = M.Required;
7705f757f3fSDimitry Andric if (M.FactoryAsInit != FactoryAsInitKind::Infer)
7715f757f3fSDimitry Andric emitError("'FactoryAsInit' is no longer valid; use 'SwiftName' instead");
7725f757f3fSDimitry Andric
7735f757f3fSDimitry Andric MI.ResultType = std::string(M.ResultType);
7745f757f3fSDimitry Andric
7755f757f3fSDimitry Andric // Translate parameter information.
7765f757f3fSDimitry Andric convertParams(M.Params, MI);
7775f757f3fSDimitry Andric
7785f757f3fSDimitry Andric // Translate nullability info.
7795f757f3fSDimitry Andric convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);
7805f757f3fSDimitry Andric
7815f757f3fSDimitry Andric MI.setRetainCountConvention(M.RetainCountConvention);
7825f757f3fSDimitry Andric
7835f757f3fSDimitry Andric // Write it.
7845f757f3fSDimitry Andric Writer.addObjCMethod(ClassID, Selector, M.Kind == MethodKind::Instance, MI,
7855f757f3fSDimitry Andric SwiftVersion);
7865f757f3fSDimitry Andric }
7875f757f3fSDimitry Andric
convertContext(std::optional<ContextID> ParentContextID,const Class & C,ContextKind Kind,VersionTuple SwiftVersion)7885f757f3fSDimitry Andric void convertContext(std::optional<ContextID> ParentContextID, const Class &C,
7895f757f3fSDimitry Andric ContextKind Kind, VersionTuple SwiftVersion) {
7905f757f3fSDimitry Andric // Write the class.
791*0fca6ea1SDimitry Andric ContextInfo CI;
7925f757f3fSDimitry Andric convertCommonType(C, CI, C.Name);
7935f757f3fSDimitry Andric
7945f757f3fSDimitry Andric if (C.AuditedForNullability)
7955f757f3fSDimitry Andric CI.setDefaultNullability(NullabilityKind::NonNull);
7965f757f3fSDimitry Andric if (C.SwiftImportAsNonGeneric)
7975f757f3fSDimitry Andric CI.setSwiftImportAsNonGeneric(*C.SwiftImportAsNonGeneric);
7985f757f3fSDimitry Andric if (C.SwiftObjCMembers)
7995f757f3fSDimitry Andric CI.setSwiftObjCMembers(*C.SwiftObjCMembers);
8005f757f3fSDimitry Andric
8015f757f3fSDimitry Andric ContextID CtxID =
802*0fca6ea1SDimitry Andric Writer.addContext(ParentContextID, C.Name, Kind, CI, SwiftVersion);
8035f757f3fSDimitry Andric
8045f757f3fSDimitry Andric // Write all methods.
8055f757f3fSDimitry Andric llvm::StringMap<std::pair<bool, bool>> KnownMethods;
8065f757f3fSDimitry Andric for (const auto &method : C.Methods) {
8075f757f3fSDimitry Andric // Check for duplicate method definitions.
8085f757f3fSDimitry Andric bool IsInstanceMethod = method.Kind == MethodKind::Instance;
8095f757f3fSDimitry Andric bool &Known = IsInstanceMethod ? KnownMethods[method.Selector].first
8105f757f3fSDimitry Andric : KnownMethods[method.Selector].second;
8115f757f3fSDimitry Andric if (Known) {
8125f757f3fSDimitry Andric emitError(llvm::Twine("duplicate definition of method '") +
8135f757f3fSDimitry Andric (IsInstanceMethod ? "-" : "+") + "[" + C.Name + " " +
8145f757f3fSDimitry Andric method.Selector + "]'");
8155f757f3fSDimitry Andric continue;
8165f757f3fSDimitry Andric }
8175f757f3fSDimitry Andric Known = true;
8185f757f3fSDimitry Andric
8195f757f3fSDimitry Andric convertMethod(method, CtxID, C.Name, SwiftVersion);
8205f757f3fSDimitry Andric }
8215f757f3fSDimitry Andric
8225f757f3fSDimitry Andric // Write all properties.
8235f757f3fSDimitry Andric llvm::StringSet<> KnownInstanceProperties;
8245f757f3fSDimitry Andric llvm::StringSet<> KnownClassProperties;
8255f757f3fSDimitry Andric for (const auto &Property : C.Properties) {
8265f757f3fSDimitry Andric // Check for duplicate property definitions.
8275f757f3fSDimitry Andric if ((!Property.Kind || *Property.Kind == MethodKind::Instance) &&
8285f757f3fSDimitry Andric !KnownInstanceProperties.insert(Property.Name).second) {
8295f757f3fSDimitry Andric emitError(llvm::Twine("duplicate definition of instance property '") +
8305f757f3fSDimitry Andric C.Name + "." + Property.Name + "'");
8315f757f3fSDimitry Andric continue;
8325f757f3fSDimitry Andric }
8335f757f3fSDimitry Andric
8345f757f3fSDimitry Andric if ((!Property.Kind || *Property.Kind == MethodKind::Class) &&
8355f757f3fSDimitry Andric !KnownClassProperties.insert(Property.Name).second) {
8365f757f3fSDimitry Andric emitError(llvm::Twine("duplicate definition of class property '") +
8375f757f3fSDimitry Andric C.Name + "." + Property.Name + "'");
8385f757f3fSDimitry Andric continue;
8395f757f3fSDimitry Andric }
8405f757f3fSDimitry Andric
8415f757f3fSDimitry Andric // Translate from Property into ObjCPropertyInfo.
8425f757f3fSDimitry Andric ObjCPropertyInfo PI;
8435f757f3fSDimitry Andric convertAvailability(Property.Availability, PI, Property.Name);
8445f757f3fSDimitry Andric PI.setSwiftPrivate(Property.SwiftPrivate);
8455f757f3fSDimitry Andric PI.SwiftName = std::string(Property.SwiftName);
8465f757f3fSDimitry Andric if (Property.Nullability)
8475f757f3fSDimitry Andric PI.setNullabilityAudited(*Property.Nullability);
8485f757f3fSDimitry Andric if (Property.SwiftImportAsAccessors)
8495f757f3fSDimitry Andric PI.setSwiftImportAsAccessors(*Property.SwiftImportAsAccessors);
8505f757f3fSDimitry Andric PI.setType(std::string(Property.Type));
8515f757f3fSDimitry Andric
8525f757f3fSDimitry Andric // Add both instance and class properties with this name.
8535f757f3fSDimitry Andric if (Property.Kind) {
8545f757f3fSDimitry Andric Writer.addObjCProperty(CtxID, Property.Name,
8555f757f3fSDimitry Andric *Property.Kind == MethodKind::Instance, PI,
8565f757f3fSDimitry Andric SwiftVersion);
8575f757f3fSDimitry Andric } else {
8585f757f3fSDimitry Andric Writer.addObjCProperty(CtxID, Property.Name, true, PI, SwiftVersion);
8595f757f3fSDimitry Andric Writer.addObjCProperty(CtxID, Property.Name, false, PI, SwiftVersion);
8605f757f3fSDimitry Andric }
8615f757f3fSDimitry Andric }
8625f757f3fSDimitry Andric }
8635f757f3fSDimitry Andric
convertNamespaceContext(std::optional<ContextID> ParentContextID,const Namespace & TheNamespace,VersionTuple SwiftVersion)8645f757f3fSDimitry Andric void convertNamespaceContext(std::optional<ContextID> ParentContextID,
8655f757f3fSDimitry Andric const Namespace &TheNamespace,
8665f757f3fSDimitry Andric VersionTuple SwiftVersion) {
8675f757f3fSDimitry Andric // Write the namespace.
868*0fca6ea1SDimitry Andric ContextInfo CI;
8695f757f3fSDimitry Andric convertCommonEntity(TheNamespace, CI, TheNamespace.Name);
8705f757f3fSDimitry Andric
8715f757f3fSDimitry Andric ContextID CtxID =
872*0fca6ea1SDimitry Andric Writer.addContext(ParentContextID, TheNamespace.Name,
8735f757f3fSDimitry Andric ContextKind::Namespace, CI, SwiftVersion);
8745f757f3fSDimitry Andric
8755f757f3fSDimitry Andric convertTopLevelItems(Context(CtxID, ContextKind::Namespace),
8765f757f3fSDimitry Andric TheNamespace.Items, SwiftVersion);
8775f757f3fSDimitry Andric }
8785f757f3fSDimitry Andric
convertFunction(const Function & Function,FunctionInfo & FI)879*0fca6ea1SDimitry Andric void convertFunction(const Function &Function, FunctionInfo &FI) {
880*0fca6ea1SDimitry Andric convertAvailability(Function.Availability, FI, Function.Name);
881*0fca6ea1SDimitry Andric FI.setSwiftPrivate(Function.SwiftPrivate);
882*0fca6ea1SDimitry Andric FI.SwiftName = std::string(Function.SwiftName);
883*0fca6ea1SDimitry Andric convertParams(Function.Params, FI);
884*0fca6ea1SDimitry Andric convertNullability(Function.Nullability, Function.NullabilityOfRet, FI,
885*0fca6ea1SDimitry Andric Function.Name);
886*0fca6ea1SDimitry Andric FI.ResultType = std::string(Function.ResultType);
887*0fca6ea1SDimitry Andric FI.setRetainCountConvention(Function.RetainCountConvention);
888*0fca6ea1SDimitry Andric }
889*0fca6ea1SDimitry Andric
convertTagContext(std::optional<Context> ParentContext,const Tag & T,VersionTuple SwiftVersion)890*0fca6ea1SDimitry Andric void convertTagContext(std::optional<Context> ParentContext, const Tag &T,
891*0fca6ea1SDimitry Andric VersionTuple SwiftVersion) {
892*0fca6ea1SDimitry Andric TagInfo TI;
893*0fca6ea1SDimitry Andric std::optional<ContextID> ParentContextID =
894*0fca6ea1SDimitry Andric ParentContext ? std::optional<ContextID>(ParentContext->id)
895*0fca6ea1SDimitry Andric : std::nullopt;
896*0fca6ea1SDimitry Andric convertCommonType(T, TI, T.Name);
897*0fca6ea1SDimitry Andric
898*0fca6ea1SDimitry Andric if ((T.SwiftRetainOp || T.SwiftReleaseOp) && !T.SwiftImportAs) {
899*0fca6ea1SDimitry Andric emitError(llvm::Twine("should declare SwiftImportAs to use "
900*0fca6ea1SDimitry Andric "SwiftRetainOp and SwiftReleaseOp (for ") +
901*0fca6ea1SDimitry Andric T.Name + ")");
902*0fca6ea1SDimitry Andric return;
903*0fca6ea1SDimitry Andric }
904*0fca6ea1SDimitry Andric if (T.SwiftReleaseOp.has_value() != T.SwiftRetainOp.has_value()) {
905*0fca6ea1SDimitry Andric emitError(llvm::Twine("should declare both SwiftReleaseOp and "
906*0fca6ea1SDimitry Andric "SwiftRetainOp (for ") +
907*0fca6ea1SDimitry Andric T.Name + ")");
908*0fca6ea1SDimitry Andric return;
909*0fca6ea1SDimitry Andric }
910*0fca6ea1SDimitry Andric
911*0fca6ea1SDimitry Andric if (T.SwiftImportAs)
912*0fca6ea1SDimitry Andric TI.SwiftImportAs = T.SwiftImportAs;
913*0fca6ea1SDimitry Andric if (T.SwiftRetainOp)
914*0fca6ea1SDimitry Andric TI.SwiftRetainOp = T.SwiftRetainOp;
915*0fca6ea1SDimitry Andric if (T.SwiftReleaseOp)
916*0fca6ea1SDimitry Andric TI.SwiftReleaseOp = T.SwiftReleaseOp;
917*0fca6ea1SDimitry Andric
918*0fca6ea1SDimitry Andric if (T.SwiftCopyable)
919*0fca6ea1SDimitry Andric TI.setSwiftCopyable(T.SwiftCopyable);
920*0fca6ea1SDimitry Andric
921*0fca6ea1SDimitry Andric if (T.EnumConvenienceKind) {
922*0fca6ea1SDimitry Andric if (T.EnumExtensibility) {
923*0fca6ea1SDimitry Andric emitError(
924*0fca6ea1SDimitry Andric llvm::Twine("cannot mix EnumKind and EnumExtensibility (for ") +
925*0fca6ea1SDimitry Andric T.Name + ")");
926*0fca6ea1SDimitry Andric return;
927*0fca6ea1SDimitry Andric }
928*0fca6ea1SDimitry Andric if (T.FlagEnum) {
929*0fca6ea1SDimitry Andric emitError(llvm::Twine("cannot mix EnumKind and FlagEnum (for ") +
930*0fca6ea1SDimitry Andric T.Name + ")");
931*0fca6ea1SDimitry Andric return;
932*0fca6ea1SDimitry Andric }
933*0fca6ea1SDimitry Andric switch (*T.EnumConvenienceKind) {
934*0fca6ea1SDimitry Andric case EnumConvenienceAliasKind::None:
935*0fca6ea1SDimitry Andric TI.EnumExtensibility = EnumExtensibilityKind::None;
936*0fca6ea1SDimitry Andric TI.setFlagEnum(false);
937*0fca6ea1SDimitry Andric break;
938*0fca6ea1SDimitry Andric case EnumConvenienceAliasKind::CFEnum:
939*0fca6ea1SDimitry Andric TI.EnumExtensibility = EnumExtensibilityKind::Open;
940*0fca6ea1SDimitry Andric TI.setFlagEnum(false);
941*0fca6ea1SDimitry Andric break;
942*0fca6ea1SDimitry Andric case EnumConvenienceAliasKind::CFOptions:
943*0fca6ea1SDimitry Andric TI.EnumExtensibility = EnumExtensibilityKind::Open;
944*0fca6ea1SDimitry Andric TI.setFlagEnum(true);
945*0fca6ea1SDimitry Andric break;
946*0fca6ea1SDimitry Andric case EnumConvenienceAliasKind::CFClosedEnum:
947*0fca6ea1SDimitry Andric TI.EnumExtensibility = EnumExtensibilityKind::Closed;
948*0fca6ea1SDimitry Andric TI.setFlagEnum(false);
949*0fca6ea1SDimitry Andric break;
950*0fca6ea1SDimitry Andric }
951*0fca6ea1SDimitry Andric } else {
952*0fca6ea1SDimitry Andric TI.EnumExtensibility = T.EnumExtensibility;
953*0fca6ea1SDimitry Andric TI.setFlagEnum(T.FlagEnum);
954*0fca6ea1SDimitry Andric }
955*0fca6ea1SDimitry Andric
956*0fca6ea1SDimitry Andric Writer.addTag(ParentContext, T.Name, TI, SwiftVersion);
957*0fca6ea1SDimitry Andric
958*0fca6ea1SDimitry Andric ContextInfo CI;
959*0fca6ea1SDimitry Andric auto TagCtxID = Writer.addContext(ParentContextID, T.Name, ContextKind::Tag,
960*0fca6ea1SDimitry Andric CI, SwiftVersion);
961*0fca6ea1SDimitry Andric
962*0fca6ea1SDimitry Andric for (const auto &CXXMethod : T.Methods) {
963*0fca6ea1SDimitry Andric CXXMethodInfo MI;
964*0fca6ea1SDimitry Andric convertFunction(CXXMethod, MI);
965*0fca6ea1SDimitry Andric Writer.addCXXMethod(TagCtxID, CXXMethod.Name, MI, SwiftVersion);
966*0fca6ea1SDimitry Andric }
967*0fca6ea1SDimitry Andric }
968*0fca6ea1SDimitry Andric
convertTopLevelItems(std::optional<Context> Ctx,const TopLevelItems & TLItems,VersionTuple SwiftVersion)9695f757f3fSDimitry Andric void convertTopLevelItems(std::optional<Context> Ctx,
9705f757f3fSDimitry Andric const TopLevelItems &TLItems,
9715f757f3fSDimitry Andric VersionTuple SwiftVersion) {
9725f757f3fSDimitry Andric std::optional<ContextID> CtxID =
9735f757f3fSDimitry Andric Ctx ? std::optional(Ctx->id) : std::nullopt;
9745f757f3fSDimitry Andric
9755f757f3fSDimitry Andric // Write all classes.
9765f757f3fSDimitry Andric llvm::StringSet<> KnownClasses;
9775f757f3fSDimitry Andric for (const auto &Class : TLItems.Classes) {
9785f757f3fSDimitry Andric // Check for duplicate class definitions.
9795f757f3fSDimitry Andric if (!KnownClasses.insert(Class.Name).second) {
9805f757f3fSDimitry Andric emitError(llvm::Twine("multiple definitions of class '") + Class.Name +
9815f757f3fSDimitry Andric "'");
9825f757f3fSDimitry Andric continue;
9835f757f3fSDimitry Andric }
9845f757f3fSDimitry Andric
9855f757f3fSDimitry Andric convertContext(CtxID, Class, ContextKind::ObjCClass, SwiftVersion);
9865f757f3fSDimitry Andric }
9875f757f3fSDimitry Andric
9885f757f3fSDimitry Andric // Write all protocols.
9895f757f3fSDimitry Andric llvm::StringSet<> KnownProtocols;
9905f757f3fSDimitry Andric for (const auto &Protocol : TLItems.Protocols) {
9915f757f3fSDimitry Andric // Check for duplicate protocol definitions.
9925f757f3fSDimitry Andric if (!KnownProtocols.insert(Protocol.Name).second) {
9935f757f3fSDimitry Andric emitError(llvm::Twine("multiple definitions of protocol '") +
9945f757f3fSDimitry Andric Protocol.Name + "'");
9955f757f3fSDimitry Andric continue;
9965f757f3fSDimitry Andric }
9975f757f3fSDimitry Andric
9985f757f3fSDimitry Andric convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);
9995f757f3fSDimitry Andric }
10005f757f3fSDimitry Andric
10015f757f3fSDimitry Andric // Write all namespaces.
10025f757f3fSDimitry Andric llvm::StringSet<> KnownNamespaces;
10035f757f3fSDimitry Andric for (const auto &Namespace : TLItems.Namespaces) {
10045f757f3fSDimitry Andric // Check for duplicate namespace definitions.
10055f757f3fSDimitry Andric if (!KnownNamespaces.insert(Namespace.Name).second) {
10065f757f3fSDimitry Andric emitError(llvm::Twine("multiple definitions of namespace '") +
10075f757f3fSDimitry Andric Namespace.Name + "'");
10085f757f3fSDimitry Andric continue;
10095f757f3fSDimitry Andric }
10105f757f3fSDimitry Andric
10115f757f3fSDimitry Andric convertNamespaceContext(CtxID, Namespace, SwiftVersion);
10125f757f3fSDimitry Andric }
10135f757f3fSDimitry Andric
10145f757f3fSDimitry Andric // Write all global variables.
10155f757f3fSDimitry Andric llvm::StringSet<> KnownGlobals;
10165f757f3fSDimitry Andric for (const auto &Global : TLItems.Globals) {
10175f757f3fSDimitry Andric // Check for duplicate global variables.
10185f757f3fSDimitry Andric if (!KnownGlobals.insert(Global.Name).second) {
10195f757f3fSDimitry Andric emitError(llvm::Twine("multiple definitions of global variable '") +
10205f757f3fSDimitry Andric Global.Name + "'");
10215f757f3fSDimitry Andric continue;
10225f757f3fSDimitry Andric }
10235f757f3fSDimitry Andric
10245f757f3fSDimitry Andric GlobalVariableInfo GVI;
10255f757f3fSDimitry Andric convertAvailability(Global.Availability, GVI, Global.Name);
10265f757f3fSDimitry Andric GVI.setSwiftPrivate(Global.SwiftPrivate);
10275f757f3fSDimitry Andric GVI.SwiftName = std::string(Global.SwiftName);
10285f757f3fSDimitry Andric if (Global.Nullability)
10295f757f3fSDimitry Andric GVI.setNullabilityAudited(*Global.Nullability);
10305f757f3fSDimitry Andric GVI.setType(std::string(Global.Type));
10315f757f3fSDimitry Andric Writer.addGlobalVariable(Ctx, Global.Name, GVI, SwiftVersion);
10325f757f3fSDimitry Andric }
10335f757f3fSDimitry Andric
10345f757f3fSDimitry Andric // Write all global functions.
10355f757f3fSDimitry Andric llvm::StringSet<> KnownFunctions;
10365f757f3fSDimitry Andric for (const auto &Function : TLItems.Functions) {
10375f757f3fSDimitry Andric // Check for duplicate global functions.
10385f757f3fSDimitry Andric if (!KnownFunctions.insert(Function.Name).second) {
10395f757f3fSDimitry Andric emitError(llvm::Twine("multiple definitions of global function '") +
10405f757f3fSDimitry Andric Function.Name + "'");
10415f757f3fSDimitry Andric continue;
10425f757f3fSDimitry Andric }
10435f757f3fSDimitry Andric
10445f757f3fSDimitry Andric GlobalFunctionInfo GFI;
1045*0fca6ea1SDimitry Andric convertFunction(Function, GFI);
10465f757f3fSDimitry Andric Writer.addGlobalFunction(Ctx, Function.Name, GFI, SwiftVersion);
10475f757f3fSDimitry Andric }
10485f757f3fSDimitry Andric
10495f757f3fSDimitry Andric // Write all enumerators.
10505f757f3fSDimitry Andric llvm::StringSet<> KnownEnumConstants;
10515f757f3fSDimitry Andric for (const auto &EnumConstant : TLItems.EnumConstants) {
10525f757f3fSDimitry Andric // Check for duplicate enumerators
10535f757f3fSDimitry Andric if (!KnownEnumConstants.insert(EnumConstant.Name).second) {
10545f757f3fSDimitry Andric emitError(llvm::Twine("multiple definitions of enumerator '") +
10555f757f3fSDimitry Andric EnumConstant.Name + "'");
10565f757f3fSDimitry Andric continue;
10575f757f3fSDimitry Andric }
10585f757f3fSDimitry Andric
10595f757f3fSDimitry Andric EnumConstantInfo ECI;
10605f757f3fSDimitry Andric convertAvailability(EnumConstant.Availability, ECI, EnumConstant.Name);
10615f757f3fSDimitry Andric ECI.setSwiftPrivate(EnumConstant.SwiftPrivate);
10625f757f3fSDimitry Andric ECI.SwiftName = std::string(EnumConstant.SwiftName);
10635f757f3fSDimitry Andric Writer.addEnumConstant(EnumConstant.Name, ECI, SwiftVersion);
10645f757f3fSDimitry Andric }
10655f757f3fSDimitry Andric
10665f757f3fSDimitry Andric // Write all tags.
10675f757f3fSDimitry Andric llvm::StringSet<> KnownTags;
10685f757f3fSDimitry Andric for (const auto &Tag : TLItems.Tags) {
10695f757f3fSDimitry Andric // Check for duplicate tag definitions.
10705f757f3fSDimitry Andric if (!KnownTags.insert(Tag.Name).second) {
10715f757f3fSDimitry Andric emitError(llvm::Twine("multiple definitions of tag '") + Tag.Name +
10725f757f3fSDimitry Andric "'");
10735f757f3fSDimitry Andric continue;
10745f757f3fSDimitry Andric }
10755f757f3fSDimitry Andric
1076*0fca6ea1SDimitry Andric convertTagContext(Ctx, Tag, SwiftVersion);
10775f757f3fSDimitry Andric }
10785f757f3fSDimitry Andric
10795f757f3fSDimitry Andric // Write all typedefs.
10805f757f3fSDimitry Andric llvm::StringSet<> KnownTypedefs;
10815f757f3fSDimitry Andric for (const auto &Typedef : TLItems.Typedefs) {
10825f757f3fSDimitry Andric // Check for duplicate typedef definitions.
10835f757f3fSDimitry Andric if (!KnownTypedefs.insert(Typedef.Name).second) {
10845f757f3fSDimitry Andric emitError(llvm::Twine("multiple definitions of typedef '") +
10855f757f3fSDimitry Andric Typedef.Name + "'");
10865f757f3fSDimitry Andric continue;
10875f757f3fSDimitry Andric }
10885f757f3fSDimitry Andric
10895f757f3fSDimitry Andric TypedefInfo TInfo;
10905f757f3fSDimitry Andric convertCommonType(Typedef, TInfo, Typedef.Name);
10915f757f3fSDimitry Andric TInfo.SwiftWrapper = Typedef.SwiftType;
10925f757f3fSDimitry Andric
10935f757f3fSDimitry Andric Writer.addTypedef(Ctx, Typedef.Name, TInfo, SwiftVersion);
10945f757f3fSDimitry Andric }
10955f757f3fSDimitry Andric }
10965f757f3fSDimitry Andric
convertModule()10975f757f3fSDimitry Andric bool convertModule() {
10985f757f3fSDimitry Andric // Write the top-level items.
10995f757f3fSDimitry Andric convertTopLevelItems(/* context */ std::nullopt, M.TopLevel,
11005f757f3fSDimitry Andric VersionTuple());
11015f757f3fSDimitry Andric
11025f757f3fSDimitry Andric // Convert the versioned information.
11035f757f3fSDimitry Andric for (const auto &Versioned : M.SwiftVersions)
11045f757f3fSDimitry Andric convertTopLevelItems(/* context */ std::nullopt, Versioned.Items,
11055f757f3fSDimitry Andric Versioned.Version);
11065f757f3fSDimitry Andric
11075f757f3fSDimitry Andric if (!ErrorOccured)
11085f757f3fSDimitry Andric Writer.writeToStream(OS);
11095f757f3fSDimitry Andric
11105f757f3fSDimitry Andric return ErrorOccured;
11115f757f3fSDimitry Andric }
11125f757f3fSDimitry Andric };
11135f757f3fSDimitry Andric } // namespace
11145f757f3fSDimitry Andric
compile(const Module & M,const FileEntry * SourceFile,llvm::raw_ostream & OS,llvm::SourceMgr::DiagHandlerTy DiagHandler,void * DiagHandlerCtxt)11155f757f3fSDimitry Andric static bool compile(const Module &M, const FileEntry *SourceFile,
11165f757f3fSDimitry Andric llvm::raw_ostream &OS,
11175f757f3fSDimitry Andric llvm::SourceMgr::DiagHandlerTy DiagHandler,
11185f757f3fSDimitry Andric void *DiagHandlerCtxt) {
11195f757f3fSDimitry Andric YAMLConverter C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
11205f757f3fSDimitry Andric return C.convertModule();
11215f757f3fSDimitry Andric }
11225f757f3fSDimitry Andric
11235f757f3fSDimitry Andric /// Simple diagnostic handler that prints diagnostics to standard error.
printDiagnostic(const llvm::SMDiagnostic & Diag,void * Context)11245f757f3fSDimitry Andric static void printDiagnostic(const llvm::SMDiagnostic &Diag, void *Context) {
11255f757f3fSDimitry Andric Diag.print(nullptr, llvm::errs());
11265f757f3fSDimitry Andric }
11275f757f3fSDimitry Andric
compileAPINotes(StringRef YAMLInput,const FileEntry * SourceFile,llvm::raw_ostream & OS,llvm::SourceMgr::DiagHandlerTy DiagHandler,void * DiagHandlerCtxt)11285f757f3fSDimitry Andric bool api_notes::compileAPINotes(StringRef YAMLInput,
11295f757f3fSDimitry Andric const FileEntry *SourceFile,
11305f757f3fSDimitry Andric llvm::raw_ostream &OS,
11315f757f3fSDimitry Andric llvm::SourceMgr::DiagHandlerTy DiagHandler,
11325f757f3fSDimitry Andric void *DiagHandlerCtxt) {
11335f757f3fSDimitry Andric Module TheModule;
11345f757f3fSDimitry Andric
11355f757f3fSDimitry Andric if (!DiagHandler)
11365f757f3fSDimitry Andric DiagHandler = &printDiagnostic;
11375f757f3fSDimitry Andric
11385f757f3fSDimitry Andric if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))
11395f757f3fSDimitry Andric return true;
11405f757f3fSDimitry Andric
11415f757f3fSDimitry Andric return compile(TheModule, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
11425f757f3fSDimitry Andric }
1143