xref: /freebsd/contrib/llvm-project/clang/lib/APINotes/APINotesYAMLCompiler.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
1*e8d8bef9SDimitry Andric //===-- APINotesYAMLCompiler.cpp - API Notes YAML Format Reader -*- C++ -*-===//
2*e8d8bef9SDimitry Andric //
3*e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e8d8bef9SDimitry Andric //
7*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8*e8d8bef9SDimitry Andric //
9*e8d8bef9SDimitry Andric // The types defined locally are designed to represent the YAML state, which
10*e8d8bef9SDimitry Andric // adds an additional bit of state: e.g. a tri-state boolean attribute (yes, no,
11*e8d8bef9SDimitry Andric // not applied) becomes a tri-state boolean + present.  As a result, while these
12*e8d8bef9SDimitry Andric // enumerations appear to be redefining constants from the attributes table
13*e8d8bef9SDimitry Andric // data, they are distinct.
14*e8d8bef9SDimitry Andric //
15*e8d8bef9SDimitry Andric 
16*e8d8bef9SDimitry Andric #include "clang/APINotes/APINotesYAMLCompiler.h"
17*e8d8bef9SDimitry Andric #include "clang/APINotes/Types.h"
18*e8d8bef9SDimitry Andric #include "clang/Basic/LLVM.h"
19*e8d8bef9SDimitry Andric #include "clang/Basic/Specifiers.h"
20*e8d8bef9SDimitry Andric #include "llvm/ADT/Optional.h"
21*e8d8bef9SDimitry Andric #include "llvm/Support/VersionTuple.h"
22*e8d8bef9SDimitry Andric #include "llvm/Support/YAMLParser.h"
23*e8d8bef9SDimitry Andric #include "llvm/Support/YAMLTraits.h"
24*e8d8bef9SDimitry Andric #include <vector>
25*e8d8bef9SDimitry Andric using namespace clang;
26*e8d8bef9SDimitry Andric using namespace api_notes;
27*e8d8bef9SDimitry Andric 
28*e8d8bef9SDimitry Andric namespace {
29*e8d8bef9SDimitry Andric enum class APIAvailability {
30*e8d8bef9SDimitry Andric   Available = 0,
31*e8d8bef9SDimitry Andric   OSX,
32*e8d8bef9SDimitry Andric   IOS,
33*e8d8bef9SDimitry Andric   None,
34*e8d8bef9SDimitry Andric   NonSwift,
35*e8d8bef9SDimitry Andric };
36*e8d8bef9SDimitry Andric } // namespace
37*e8d8bef9SDimitry Andric 
38*e8d8bef9SDimitry Andric namespace llvm {
39*e8d8bef9SDimitry Andric namespace yaml {
40*e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<APIAvailability> {
41*e8d8bef9SDimitry Andric   static void enumeration(IO &IO, APIAvailability &AA) {
42*e8d8bef9SDimitry Andric     IO.enumCase(AA, "OSX", APIAvailability::OSX);
43*e8d8bef9SDimitry Andric     IO.enumCase(AA, "iOS", APIAvailability::IOS);
44*e8d8bef9SDimitry Andric     IO.enumCase(AA, "none", APIAvailability::None);
45*e8d8bef9SDimitry Andric     IO.enumCase(AA, "nonswift", APIAvailability::NonSwift);
46*e8d8bef9SDimitry Andric     IO.enumCase(AA, "available", APIAvailability::Available);
47*e8d8bef9SDimitry Andric   }
48*e8d8bef9SDimitry Andric };
49*e8d8bef9SDimitry Andric } // namespace yaml
50*e8d8bef9SDimitry Andric } // namespace llvm
51*e8d8bef9SDimitry Andric 
52*e8d8bef9SDimitry Andric namespace {
53*e8d8bef9SDimitry Andric enum class MethodKind {
54*e8d8bef9SDimitry Andric   Class,
55*e8d8bef9SDimitry Andric   Instance,
56*e8d8bef9SDimitry Andric };
57*e8d8bef9SDimitry Andric } // namespace
58*e8d8bef9SDimitry Andric 
59*e8d8bef9SDimitry Andric namespace llvm {
60*e8d8bef9SDimitry Andric namespace yaml {
61*e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<MethodKind> {
62*e8d8bef9SDimitry Andric   static void enumeration(IO &IO, MethodKind &MK) {
63*e8d8bef9SDimitry Andric     IO.enumCase(MK, "Class", MethodKind::Class);
64*e8d8bef9SDimitry Andric     IO.enumCase(MK, "Instance", MethodKind::Instance);
65*e8d8bef9SDimitry Andric   }
66*e8d8bef9SDimitry Andric };
67*e8d8bef9SDimitry Andric } // namespace yaml
68*e8d8bef9SDimitry Andric } // namespace llvm
69*e8d8bef9SDimitry Andric 
70*e8d8bef9SDimitry Andric namespace {
71*e8d8bef9SDimitry Andric struct Param {
72*e8d8bef9SDimitry Andric   unsigned Position;
73*e8d8bef9SDimitry Andric   Optional<bool> NoEscape = false;
74*e8d8bef9SDimitry Andric   Optional<NullabilityKind> Nullability;
75*e8d8bef9SDimitry Andric   Optional<RetainCountConventionKind> RetainCountConvention;
76*e8d8bef9SDimitry Andric   StringRef Type;
77*e8d8bef9SDimitry Andric };
78*e8d8bef9SDimitry Andric 
79*e8d8bef9SDimitry Andric typedef std::vector<Param> ParamsSeq;
80*e8d8bef9SDimitry Andric } // namespace
81*e8d8bef9SDimitry Andric 
82*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
83*e8d8bef9SDimitry Andric LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(NullabilityKind)
84*e8d8bef9SDimitry Andric 
85*e8d8bef9SDimitry Andric namespace llvm {
86*e8d8bef9SDimitry Andric namespace yaml {
87*e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<NullabilityKind> {
88*e8d8bef9SDimitry Andric   static void enumeration(IO &IO, NullabilityKind &NK) {
89*e8d8bef9SDimitry Andric     IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull);
90*e8d8bef9SDimitry Andric     IO.enumCase(NK, "Optional", NullabilityKind::Nullable);
91*e8d8bef9SDimitry Andric     IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified);
92*e8d8bef9SDimitry Andric     IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult);
93*e8d8bef9SDimitry Andric     // TODO: Mapping this to it's own value would allow for better cross
94*e8d8bef9SDimitry Andric     // checking. Also the default should be Unknown.
95*e8d8bef9SDimitry Andric     IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified);
96*e8d8bef9SDimitry Andric 
97*e8d8bef9SDimitry Andric     // Aliases for compatibility with existing APINotes.
98*e8d8bef9SDimitry Andric     IO.enumCase(NK, "N", NullabilityKind::NonNull);
99*e8d8bef9SDimitry Andric     IO.enumCase(NK, "O", NullabilityKind::Nullable);
100*e8d8bef9SDimitry Andric     IO.enumCase(NK, "U", NullabilityKind::Unspecified);
101*e8d8bef9SDimitry Andric     IO.enumCase(NK, "S", NullabilityKind::Unspecified);
102*e8d8bef9SDimitry Andric   }
103*e8d8bef9SDimitry Andric };
104*e8d8bef9SDimitry Andric 
105*e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<RetainCountConventionKind> {
106*e8d8bef9SDimitry Andric   static void enumeration(IO &IO, RetainCountConventionKind &RCCK) {
107*e8d8bef9SDimitry Andric     IO.enumCase(RCCK, "none", RetainCountConventionKind::None);
108*e8d8bef9SDimitry Andric     IO.enumCase(RCCK, "CFReturnsRetained",
109*e8d8bef9SDimitry Andric                 RetainCountConventionKind::CFReturnsRetained);
110*e8d8bef9SDimitry Andric     IO.enumCase(RCCK, "CFReturnsNotRetained",
111*e8d8bef9SDimitry Andric                 RetainCountConventionKind::CFReturnsNotRetained);
112*e8d8bef9SDimitry Andric     IO.enumCase(RCCK, "NSReturnsRetained",
113*e8d8bef9SDimitry Andric                 RetainCountConventionKind::NSReturnsRetained);
114*e8d8bef9SDimitry Andric     IO.enumCase(RCCK, "NSReturnsNotRetained",
115*e8d8bef9SDimitry Andric                 RetainCountConventionKind::NSReturnsNotRetained);
116*e8d8bef9SDimitry Andric   }
117*e8d8bef9SDimitry Andric };
118*e8d8bef9SDimitry Andric 
119*e8d8bef9SDimitry Andric template <> struct MappingTraits<Param> {
120*e8d8bef9SDimitry Andric   static void mapping(IO &IO, Param &P) {
121*e8d8bef9SDimitry Andric     IO.mapRequired("Position", P.Position);
122*e8d8bef9SDimitry Andric     IO.mapOptional("Nullability", P.Nullability, llvm::None);
123*e8d8bef9SDimitry Andric     IO.mapOptional("RetainCountConvention", P.RetainCountConvention);
124*e8d8bef9SDimitry Andric     IO.mapOptional("NoEscape", P.NoEscape);
125*e8d8bef9SDimitry Andric     IO.mapOptional("Type", P.Type, StringRef(""));
126*e8d8bef9SDimitry Andric   }
127*e8d8bef9SDimitry Andric };
128*e8d8bef9SDimitry Andric } // namespace yaml
129*e8d8bef9SDimitry Andric } // namespace llvm
130*e8d8bef9SDimitry Andric 
131*e8d8bef9SDimitry Andric namespace {
132*e8d8bef9SDimitry Andric typedef std::vector<NullabilityKind> NullabilitySeq;
133*e8d8bef9SDimitry Andric 
134*e8d8bef9SDimitry Andric struct AvailabilityItem {
135*e8d8bef9SDimitry Andric   APIAvailability Mode = APIAvailability::Available;
136*e8d8bef9SDimitry Andric   StringRef Msg;
137*e8d8bef9SDimitry Andric };
138*e8d8bef9SDimitry Andric 
139*e8d8bef9SDimitry Andric /// Old attribute deprecated in favor of SwiftName.
140*e8d8bef9SDimitry Andric enum class FactoryAsInitKind {
141*e8d8bef9SDimitry Andric   /// Infer based on name and type (the default).
142*e8d8bef9SDimitry Andric   Infer,
143*e8d8bef9SDimitry Andric   /// Treat as a class method.
144*e8d8bef9SDimitry Andric   AsClassMethod,
145*e8d8bef9SDimitry Andric   /// Treat as an initializer.
146*e8d8bef9SDimitry Andric   AsInitializer,
147*e8d8bef9SDimitry Andric };
148*e8d8bef9SDimitry Andric 
149*e8d8bef9SDimitry Andric struct Method {
150*e8d8bef9SDimitry Andric   StringRef Selector;
151*e8d8bef9SDimitry Andric   MethodKind Kind;
152*e8d8bef9SDimitry Andric   ParamsSeq Params;
153*e8d8bef9SDimitry Andric   NullabilitySeq Nullability;
154*e8d8bef9SDimitry Andric   Optional<NullabilityKind> NullabilityOfRet;
155*e8d8bef9SDimitry Andric   Optional<RetainCountConventionKind> RetainCountConvention;
156*e8d8bef9SDimitry Andric   AvailabilityItem Availability;
157*e8d8bef9SDimitry Andric   Optional<bool> SwiftPrivate;
158*e8d8bef9SDimitry Andric   StringRef SwiftName;
159*e8d8bef9SDimitry Andric   FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
160*e8d8bef9SDimitry Andric   bool DesignatedInit = false;
161*e8d8bef9SDimitry Andric   bool Required = false;
162*e8d8bef9SDimitry Andric   StringRef ResultType;
163*e8d8bef9SDimitry Andric };
164*e8d8bef9SDimitry Andric 
165*e8d8bef9SDimitry Andric typedef std::vector<Method> MethodsSeq;
166*e8d8bef9SDimitry Andric } // namespace
167*e8d8bef9SDimitry Andric 
168*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Method)
169*e8d8bef9SDimitry Andric 
170*e8d8bef9SDimitry Andric namespace llvm {
171*e8d8bef9SDimitry Andric namespace yaml {
172*e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<FactoryAsInitKind> {
173*e8d8bef9SDimitry Andric   static void enumeration(IO &IO, FactoryAsInitKind &FIK) {
174*e8d8bef9SDimitry Andric     IO.enumCase(FIK, "A", FactoryAsInitKind::Infer);
175*e8d8bef9SDimitry Andric     IO.enumCase(FIK, "C", FactoryAsInitKind::AsClassMethod);
176*e8d8bef9SDimitry Andric     IO.enumCase(FIK, "I", FactoryAsInitKind::AsInitializer);
177*e8d8bef9SDimitry Andric   }
178*e8d8bef9SDimitry Andric };
179*e8d8bef9SDimitry Andric 
180*e8d8bef9SDimitry Andric template <> struct MappingTraits<Method> {
181*e8d8bef9SDimitry Andric   static void mapping(IO &IO, Method &M) {
182*e8d8bef9SDimitry Andric     IO.mapRequired("Selector", M.Selector);
183*e8d8bef9SDimitry Andric     IO.mapRequired("MethodKind", M.Kind);
184*e8d8bef9SDimitry Andric     IO.mapOptional("Parameters", M.Params);
185*e8d8bef9SDimitry Andric     IO.mapOptional("Nullability", M.Nullability);
186*e8d8bef9SDimitry Andric     IO.mapOptional("NullabilityOfRet", M.NullabilityOfRet, llvm::None);
187*e8d8bef9SDimitry Andric     IO.mapOptional("RetainCountConvention", M.RetainCountConvention);
188*e8d8bef9SDimitry Andric     IO.mapOptional("Availability", M.Availability.Mode,
189*e8d8bef9SDimitry Andric                    APIAvailability::Available);
190*e8d8bef9SDimitry Andric     IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
191*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftPrivate", M.SwiftPrivate);
192*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftName", M.SwiftName, StringRef(""));
193*e8d8bef9SDimitry Andric     IO.mapOptional("FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);
194*e8d8bef9SDimitry Andric     IO.mapOptional("DesignatedInit", M.DesignatedInit, false);
195*e8d8bef9SDimitry Andric     IO.mapOptional("Required", M.Required, false);
196*e8d8bef9SDimitry Andric     IO.mapOptional("ResultType", M.ResultType, StringRef(""));
197*e8d8bef9SDimitry Andric   }
198*e8d8bef9SDimitry Andric };
199*e8d8bef9SDimitry Andric } // namespace yaml
200*e8d8bef9SDimitry Andric } // namespace llvm
201*e8d8bef9SDimitry Andric 
202*e8d8bef9SDimitry Andric namespace {
203*e8d8bef9SDimitry Andric struct Property {
204*e8d8bef9SDimitry Andric   StringRef Name;
205*e8d8bef9SDimitry Andric   llvm::Optional<MethodKind> Kind;
206*e8d8bef9SDimitry Andric   llvm::Optional<NullabilityKind> Nullability;
207*e8d8bef9SDimitry Andric   AvailabilityItem Availability;
208*e8d8bef9SDimitry Andric   Optional<bool> SwiftPrivate;
209*e8d8bef9SDimitry Andric   StringRef SwiftName;
210*e8d8bef9SDimitry Andric   Optional<bool> SwiftImportAsAccessors;
211*e8d8bef9SDimitry Andric   StringRef Type;
212*e8d8bef9SDimitry Andric };
213*e8d8bef9SDimitry Andric 
214*e8d8bef9SDimitry Andric typedef std::vector<Property> PropertiesSeq;
215*e8d8bef9SDimitry Andric } // namespace
216*e8d8bef9SDimitry Andric 
217*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Property)
218*e8d8bef9SDimitry Andric 
219*e8d8bef9SDimitry Andric namespace llvm {
220*e8d8bef9SDimitry Andric namespace yaml {
221*e8d8bef9SDimitry Andric template <> struct MappingTraits<Property> {
222*e8d8bef9SDimitry Andric   static void mapping(IO &IO, Property &P) {
223*e8d8bef9SDimitry Andric     IO.mapRequired("Name", P.Name);
224*e8d8bef9SDimitry Andric     IO.mapOptional("PropertyKind", P.Kind);
225*e8d8bef9SDimitry Andric     IO.mapOptional("Nullability", P.Nullability, llvm::None);
226*e8d8bef9SDimitry Andric     IO.mapOptional("Availability", P.Availability.Mode,
227*e8d8bef9SDimitry Andric                    APIAvailability::Available);
228*e8d8bef9SDimitry Andric     IO.mapOptional("AvailabilityMsg", P.Availability.Msg, StringRef(""));
229*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftPrivate", P.SwiftPrivate);
230*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftName", P.SwiftName, StringRef(""));
231*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors);
232*e8d8bef9SDimitry Andric     IO.mapOptional("Type", P.Type, StringRef(""));
233*e8d8bef9SDimitry Andric   }
234*e8d8bef9SDimitry Andric };
235*e8d8bef9SDimitry Andric } // namespace yaml
236*e8d8bef9SDimitry Andric } // namespace llvm
237*e8d8bef9SDimitry Andric 
238*e8d8bef9SDimitry Andric namespace {
239*e8d8bef9SDimitry Andric struct Class {
240*e8d8bef9SDimitry Andric   StringRef Name;
241*e8d8bef9SDimitry Andric   bool AuditedForNullability = false;
242*e8d8bef9SDimitry Andric   AvailabilityItem Availability;
243*e8d8bef9SDimitry Andric   Optional<bool> SwiftPrivate;
244*e8d8bef9SDimitry Andric   StringRef SwiftName;
245*e8d8bef9SDimitry Andric   Optional<StringRef> SwiftBridge;
246*e8d8bef9SDimitry Andric   Optional<StringRef> NSErrorDomain;
247*e8d8bef9SDimitry Andric   Optional<bool> SwiftImportAsNonGeneric;
248*e8d8bef9SDimitry Andric   Optional<bool> SwiftObjCMembers;
249*e8d8bef9SDimitry Andric   MethodsSeq Methods;
250*e8d8bef9SDimitry Andric   PropertiesSeq Properties;
251*e8d8bef9SDimitry Andric };
252*e8d8bef9SDimitry Andric 
253*e8d8bef9SDimitry Andric typedef std::vector<Class> ClassesSeq;
254*e8d8bef9SDimitry Andric } // namespace
255*e8d8bef9SDimitry Andric 
256*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Class)
257*e8d8bef9SDimitry Andric 
258*e8d8bef9SDimitry Andric namespace llvm {
259*e8d8bef9SDimitry Andric namespace yaml {
260*e8d8bef9SDimitry Andric template <> struct MappingTraits<Class> {
261*e8d8bef9SDimitry Andric   static void mapping(IO &IO, Class &C) {
262*e8d8bef9SDimitry Andric     IO.mapRequired("Name", C.Name);
263*e8d8bef9SDimitry Andric     IO.mapOptional("AuditedForNullability", C.AuditedForNullability, false);
264*e8d8bef9SDimitry Andric     IO.mapOptional("Availability", C.Availability.Mode,
265*e8d8bef9SDimitry Andric                    APIAvailability::Available);
266*e8d8bef9SDimitry Andric     IO.mapOptional("AvailabilityMsg", C.Availability.Msg, StringRef(""));
267*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftPrivate", C.SwiftPrivate);
268*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftName", C.SwiftName, StringRef(""));
269*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftBridge", C.SwiftBridge);
270*e8d8bef9SDimitry Andric     IO.mapOptional("NSErrorDomain", C.NSErrorDomain);
271*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric);
272*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers);
273*e8d8bef9SDimitry Andric     IO.mapOptional("Methods", C.Methods);
274*e8d8bef9SDimitry Andric     IO.mapOptional("Properties", C.Properties);
275*e8d8bef9SDimitry Andric   }
276*e8d8bef9SDimitry Andric };
277*e8d8bef9SDimitry Andric } // namespace yaml
278*e8d8bef9SDimitry Andric } // namespace llvm
279*e8d8bef9SDimitry Andric 
280*e8d8bef9SDimitry Andric namespace {
281*e8d8bef9SDimitry Andric struct Function {
282*e8d8bef9SDimitry Andric   StringRef Name;
283*e8d8bef9SDimitry Andric   ParamsSeq Params;
284*e8d8bef9SDimitry Andric   NullabilitySeq Nullability;
285*e8d8bef9SDimitry Andric   Optional<NullabilityKind> NullabilityOfRet;
286*e8d8bef9SDimitry Andric   Optional<api_notes::RetainCountConventionKind> RetainCountConvention;
287*e8d8bef9SDimitry Andric   AvailabilityItem Availability;
288*e8d8bef9SDimitry Andric   Optional<bool> SwiftPrivate;
289*e8d8bef9SDimitry Andric   StringRef SwiftName;
290*e8d8bef9SDimitry Andric   StringRef Type;
291*e8d8bef9SDimitry Andric   StringRef ResultType;
292*e8d8bef9SDimitry Andric };
293*e8d8bef9SDimitry Andric 
294*e8d8bef9SDimitry Andric typedef std::vector<Function> FunctionsSeq;
295*e8d8bef9SDimitry Andric } // namespace
296*e8d8bef9SDimitry Andric 
297*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Function)
298*e8d8bef9SDimitry Andric 
299*e8d8bef9SDimitry Andric namespace llvm {
300*e8d8bef9SDimitry Andric namespace yaml {
301*e8d8bef9SDimitry Andric template <> struct MappingTraits<Function> {
302*e8d8bef9SDimitry Andric   static void mapping(IO &IO, Function &F) {
303*e8d8bef9SDimitry Andric     IO.mapRequired("Name", F.Name);
304*e8d8bef9SDimitry Andric     IO.mapOptional("Parameters", F.Params);
305*e8d8bef9SDimitry Andric     IO.mapOptional("Nullability", F.Nullability);
306*e8d8bef9SDimitry Andric     IO.mapOptional("NullabilityOfRet", F.NullabilityOfRet, llvm::None);
307*e8d8bef9SDimitry Andric     IO.mapOptional("RetainCountConvention", F.RetainCountConvention);
308*e8d8bef9SDimitry Andric     IO.mapOptional("Availability", F.Availability.Mode,
309*e8d8bef9SDimitry Andric                    APIAvailability::Available);
310*e8d8bef9SDimitry Andric     IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));
311*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftPrivate", F.SwiftPrivate);
312*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
313*e8d8bef9SDimitry Andric     IO.mapOptional("ResultType", F.ResultType, StringRef(""));
314*e8d8bef9SDimitry Andric   }
315*e8d8bef9SDimitry Andric };
316*e8d8bef9SDimitry Andric } // namespace yaml
317*e8d8bef9SDimitry Andric } // namespace llvm
318*e8d8bef9SDimitry Andric 
319*e8d8bef9SDimitry Andric namespace {
320*e8d8bef9SDimitry Andric struct GlobalVariable {
321*e8d8bef9SDimitry Andric   StringRef Name;
322*e8d8bef9SDimitry Andric   llvm::Optional<NullabilityKind> Nullability;
323*e8d8bef9SDimitry Andric   AvailabilityItem Availability;
324*e8d8bef9SDimitry Andric   Optional<bool> SwiftPrivate;
325*e8d8bef9SDimitry Andric   StringRef SwiftName;
326*e8d8bef9SDimitry Andric   StringRef Type;
327*e8d8bef9SDimitry Andric };
328*e8d8bef9SDimitry Andric 
329*e8d8bef9SDimitry Andric typedef std::vector<GlobalVariable> GlobalVariablesSeq;
330*e8d8bef9SDimitry Andric } // namespace
331*e8d8bef9SDimitry Andric 
332*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
333*e8d8bef9SDimitry Andric 
334*e8d8bef9SDimitry Andric namespace llvm {
335*e8d8bef9SDimitry Andric namespace yaml {
336*e8d8bef9SDimitry Andric template <> struct MappingTraits<GlobalVariable> {
337*e8d8bef9SDimitry Andric   static void mapping(IO &IO, GlobalVariable &GV) {
338*e8d8bef9SDimitry Andric     IO.mapRequired("Name", GV.Name);
339*e8d8bef9SDimitry Andric     IO.mapOptional("Nullability", GV.Nullability, llvm::None);
340*e8d8bef9SDimitry Andric     IO.mapOptional("Availability", GV.Availability.Mode,
341*e8d8bef9SDimitry Andric                    APIAvailability::Available);
342*e8d8bef9SDimitry Andric     IO.mapOptional("AvailabilityMsg", GV.Availability.Msg, StringRef(""));
343*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftPrivate", GV.SwiftPrivate);
344*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftName", GV.SwiftName, StringRef(""));
345*e8d8bef9SDimitry Andric     IO.mapOptional("Type", GV.Type, StringRef(""));
346*e8d8bef9SDimitry Andric   }
347*e8d8bef9SDimitry Andric };
348*e8d8bef9SDimitry Andric } // namespace yaml
349*e8d8bef9SDimitry Andric } // namespace llvm
350*e8d8bef9SDimitry Andric 
351*e8d8bef9SDimitry Andric namespace {
352*e8d8bef9SDimitry Andric struct EnumConstant {
353*e8d8bef9SDimitry Andric   StringRef Name;
354*e8d8bef9SDimitry Andric   AvailabilityItem Availability;
355*e8d8bef9SDimitry Andric   Optional<bool> SwiftPrivate;
356*e8d8bef9SDimitry Andric   StringRef SwiftName;
357*e8d8bef9SDimitry Andric };
358*e8d8bef9SDimitry Andric 
359*e8d8bef9SDimitry Andric typedef std::vector<EnumConstant> EnumConstantsSeq;
360*e8d8bef9SDimitry Andric } // namespace
361*e8d8bef9SDimitry Andric 
362*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
363*e8d8bef9SDimitry Andric 
364*e8d8bef9SDimitry Andric namespace llvm {
365*e8d8bef9SDimitry Andric namespace yaml {
366*e8d8bef9SDimitry Andric template <> struct MappingTraits<EnumConstant> {
367*e8d8bef9SDimitry Andric   static void mapping(IO &IO, EnumConstant &EC) {
368*e8d8bef9SDimitry Andric     IO.mapRequired("Name", EC.Name);
369*e8d8bef9SDimitry Andric     IO.mapOptional("Availability", EC.Availability.Mode,
370*e8d8bef9SDimitry Andric                    APIAvailability::Available);
371*e8d8bef9SDimitry Andric     IO.mapOptional("AvailabilityMsg", EC.Availability.Msg, StringRef(""));
372*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftPrivate", EC.SwiftPrivate);
373*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftName", EC.SwiftName, StringRef(""));
374*e8d8bef9SDimitry Andric   }
375*e8d8bef9SDimitry Andric };
376*e8d8bef9SDimitry Andric } // namespace yaml
377*e8d8bef9SDimitry Andric } // namespace llvm
378*e8d8bef9SDimitry Andric 
379*e8d8bef9SDimitry Andric namespace {
380*e8d8bef9SDimitry Andric /// Syntactic sugar for EnumExtensibility and FlagEnum
381*e8d8bef9SDimitry Andric enum class EnumConvenienceAliasKind {
382*e8d8bef9SDimitry Andric   /// EnumExtensibility: none, FlagEnum: false
383*e8d8bef9SDimitry Andric   None,
384*e8d8bef9SDimitry Andric   /// EnumExtensibility: open, FlagEnum: false
385*e8d8bef9SDimitry Andric   CFEnum,
386*e8d8bef9SDimitry Andric   /// EnumExtensibility: open, FlagEnum: true
387*e8d8bef9SDimitry Andric   CFOptions,
388*e8d8bef9SDimitry Andric   /// EnumExtensibility: closed, FlagEnum: false
389*e8d8bef9SDimitry Andric   CFClosedEnum
390*e8d8bef9SDimitry Andric };
391*e8d8bef9SDimitry Andric } // namespace
392*e8d8bef9SDimitry Andric 
393*e8d8bef9SDimitry Andric namespace llvm {
394*e8d8bef9SDimitry Andric namespace yaml {
395*e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
396*e8d8bef9SDimitry Andric   static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK) {
397*e8d8bef9SDimitry Andric     IO.enumCase(ECAK, "none", EnumConvenienceAliasKind::None);
398*e8d8bef9SDimitry Andric     IO.enumCase(ECAK, "CFEnum", EnumConvenienceAliasKind::CFEnum);
399*e8d8bef9SDimitry Andric     IO.enumCase(ECAK, "NSEnum", EnumConvenienceAliasKind::CFEnum);
400*e8d8bef9SDimitry Andric     IO.enumCase(ECAK, "CFOptions", EnumConvenienceAliasKind::CFOptions);
401*e8d8bef9SDimitry Andric     IO.enumCase(ECAK, "NSOptions", EnumConvenienceAliasKind::CFOptions);
402*e8d8bef9SDimitry Andric     IO.enumCase(ECAK, "CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
403*e8d8bef9SDimitry Andric     IO.enumCase(ECAK, "NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
404*e8d8bef9SDimitry Andric   }
405*e8d8bef9SDimitry Andric };
406*e8d8bef9SDimitry Andric } // namespace yaml
407*e8d8bef9SDimitry Andric } // namespace llvm
408*e8d8bef9SDimitry Andric 
409*e8d8bef9SDimitry Andric namespace {
410*e8d8bef9SDimitry Andric struct Tag {
411*e8d8bef9SDimitry Andric   StringRef Name;
412*e8d8bef9SDimitry Andric   AvailabilityItem Availability;
413*e8d8bef9SDimitry Andric   StringRef SwiftName;
414*e8d8bef9SDimitry Andric   Optional<bool> SwiftPrivate;
415*e8d8bef9SDimitry Andric   Optional<StringRef> SwiftBridge;
416*e8d8bef9SDimitry Andric   Optional<StringRef> NSErrorDomain;
417*e8d8bef9SDimitry Andric   Optional<EnumExtensibilityKind> EnumExtensibility;
418*e8d8bef9SDimitry Andric   Optional<bool> FlagEnum;
419*e8d8bef9SDimitry Andric   Optional<EnumConvenienceAliasKind> EnumConvenienceKind;
420*e8d8bef9SDimitry Andric };
421*e8d8bef9SDimitry Andric 
422*e8d8bef9SDimitry Andric typedef std::vector<Tag> TagsSeq;
423*e8d8bef9SDimitry Andric } // namespace
424*e8d8bef9SDimitry Andric 
425*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
426*e8d8bef9SDimitry Andric 
427*e8d8bef9SDimitry Andric namespace llvm {
428*e8d8bef9SDimitry Andric namespace yaml {
429*e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<EnumExtensibilityKind> {
430*e8d8bef9SDimitry Andric   static void enumeration(IO &IO, EnumExtensibilityKind &EEK) {
431*e8d8bef9SDimitry Andric     IO.enumCase(EEK, "none", EnumExtensibilityKind::None);
432*e8d8bef9SDimitry Andric     IO.enumCase(EEK, "open", EnumExtensibilityKind::Open);
433*e8d8bef9SDimitry Andric     IO.enumCase(EEK, "closed", EnumExtensibilityKind::Closed);
434*e8d8bef9SDimitry Andric   }
435*e8d8bef9SDimitry Andric };
436*e8d8bef9SDimitry Andric 
437*e8d8bef9SDimitry Andric template <> struct MappingTraits<Tag> {
438*e8d8bef9SDimitry Andric   static void mapping(IO &IO, Tag &T) {
439*e8d8bef9SDimitry Andric     IO.mapRequired("Name", T.Name);
440*e8d8bef9SDimitry Andric     IO.mapOptional("Availability", T.Availability.Mode,
441*e8d8bef9SDimitry Andric                    APIAvailability::Available);
442*e8d8bef9SDimitry Andric     IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
443*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
444*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
445*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftBridge", T.SwiftBridge);
446*e8d8bef9SDimitry Andric     IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
447*e8d8bef9SDimitry Andric     IO.mapOptional("EnumExtensibility", T.EnumExtensibility);
448*e8d8bef9SDimitry Andric     IO.mapOptional("FlagEnum", T.FlagEnum);
449*e8d8bef9SDimitry Andric     IO.mapOptional("EnumKind", T.EnumConvenienceKind);
450*e8d8bef9SDimitry Andric   }
451*e8d8bef9SDimitry Andric };
452*e8d8bef9SDimitry Andric } // namespace yaml
453*e8d8bef9SDimitry Andric } // namespace llvm
454*e8d8bef9SDimitry Andric 
455*e8d8bef9SDimitry Andric namespace {
456*e8d8bef9SDimitry Andric struct Typedef {
457*e8d8bef9SDimitry Andric   StringRef Name;
458*e8d8bef9SDimitry Andric   AvailabilityItem Availability;
459*e8d8bef9SDimitry Andric   StringRef SwiftName;
460*e8d8bef9SDimitry Andric   Optional<bool> SwiftPrivate;
461*e8d8bef9SDimitry Andric   Optional<StringRef> SwiftBridge;
462*e8d8bef9SDimitry Andric   Optional<StringRef> NSErrorDomain;
463*e8d8bef9SDimitry Andric   Optional<SwiftNewTypeKind> SwiftType;
464*e8d8bef9SDimitry Andric };
465*e8d8bef9SDimitry Andric 
466*e8d8bef9SDimitry Andric typedef std::vector<Typedef> TypedefsSeq;
467*e8d8bef9SDimitry Andric } // namespace
468*e8d8bef9SDimitry Andric 
469*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
470*e8d8bef9SDimitry Andric 
471*e8d8bef9SDimitry Andric namespace llvm {
472*e8d8bef9SDimitry Andric namespace yaml {
473*e8d8bef9SDimitry Andric template <> struct ScalarEnumerationTraits<SwiftNewTypeKind> {
474*e8d8bef9SDimitry Andric   static void enumeration(IO &IO, SwiftNewTypeKind &SWK) {
475*e8d8bef9SDimitry Andric     IO.enumCase(SWK, "none", SwiftNewTypeKind::None);
476*e8d8bef9SDimitry Andric     IO.enumCase(SWK, "struct", SwiftNewTypeKind::Struct);
477*e8d8bef9SDimitry Andric     IO.enumCase(SWK, "enum", SwiftNewTypeKind::Enum);
478*e8d8bef9SDimitry Andric   }
479*e8d8bef9SDimitry Andric };
480*e8d8bef9SDimitry Andric 
481*e8d8bef9SDimitry Andric template <> struct MappingTraits<Typedef> {
482*e8d8bef9SDimitry Andric   static void mapping(IO &IO, Typedef &T) {
483*e8d8bef9SDimitry Andric     IO.mapRequired("Name", T.Name);
484*e8d8bef9SDimitry Andric     IO.mapOptional("Availability", T.Availability.Mode,
485*e8d8bef9SDimitry Andric                    APIAvailability::Available);
486*e8d8bef9SDimitry Andric     IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
487*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
488*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
489*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftBridge", T.SwiftBridge);
490*e8d8bef9SDimitry Andric     IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
491*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftWrapper", T.SwiftType);
492*e8d8bef9SDimitry Andric   }
493*e8d8bef9SDimitry Andric };
494*e8d8bef9SDimitry Andric } // namespace yaml
495*e8d8bef9SDimitry Andric } // namespace llvm
496*e8d8bef9SDimitry Andric 
497*e8d8bef9SDimitry Andric namespace {
498*e8d8bef9SDimitry Andric struct TopLevelItems {
499*e8d8bef9SDimitry Andric   ClassesSeq Classes;
500*e8d8bef9SDimitry Andric   ClassesSeq Protocols;
501*e8d8bef9SDimitry Andric   FunctionsSeq Functions;
502*e8d8bef9SDimitry Andric   GlobalVariablesSeq Globals;
503*e8d8bef9SDimitry Andric   EnumConstantsSeq EnumConstants;
504*e8d8bef9SDimitry Andric   TagsSeq Tags;
505*e8d8bef9SDimitry Andric   TypedefsSeq Typedefs;
506*e8d8bef9SDimitry Andric };
507*e8d8bef9SDimitry Andric } // namespace
508*e8d8bef9SDimitry Andric 
509*e8d8bef9SDimitry Andric namespace llvm {
510*e8d8bef9SDimitry Andric namespace yaml {
511*e8d8bef9SDimitry Andric static void mapTopLevelItems(IO &IO, TopLevelItems &TLI) {
512*e8d8bef9SDimitry Andric   IO.mapOptional("Classes", TLI.Classes);
513*e8d8bef9SDimitry Andric   IO.mapOptional("Protocols", TLI.Protocols);
514*e8d8bef9SDimitry Andric   IO.mapOptional("Functions", TLI.Functions);
515*e8d8bef9SDimitry Andric   IO.mapOptional("Globals", TLI.Globals);
516*e8d8bef9SDimitry Andric   IO.mapOptional("Enumerators", TLI.EnumConstants);
517*e8d8bef9SDimitry Andric   IO.mapOptional("Tags", TLI.Tags);
518*e8d8bef9SDimitry Andric   IO.mapOptional("Typedefs", TLI.Typedefs);
519*e8d8bef9SDimitry Andric }
520*e8d8bef9SDimitry Andric } // namespace yaml
521*e8d8bef9SDimitry Andric } // namespace llvm
522*e8d8bef9SDimitry Andric 
523*e8d8bef9SDimitry Andric namespace {
524*e8d8bef9SDimitry Andric struct Versioned {
525*e8d8bef9SDimitry Andric   VersionTuple Version;
526*e8d8bef9SDimitry Andric   TopLevelItems Items;
527*e8d8bef9SDimitry Andric };
528*e8d8bef9SDimitry Andric 
529*e8d8bef9SDimitry Andric typedef std::vector<Versioned> VersionedSeq;
530*e8d8bef9SDimitry Andric } // namespace
531*e8d8bef9SDimitry Andric 
532*e8d8bef9SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
533*e8d8bef9SDimitry Andric 
534*e8d8bef9SDimitry Andric namespace llvm {
535*e8d8bef9SDimitry Andric namespace yaml {
536*e8d8bef9SDimitry Andric template <> struct MappingTraits<Versioned> {
537*e8d8bef9SDimitry Andric   static void mapping(IO &IO, Versioned &V) {
538*e8d8bef9SDimitry Andric     IO.mapRequired("Version", V.Version);
539*e8d8bef9SDimitry Andric     mapTopLevelItems(IO, V.Items);
540*e8d8bef9SDimitry Andric   }
541*e8d8bef9SDimitry Andric };
542*e8d8bef9SDimitry Andric } // namespace yaml
543*e8d8bef9SDimitry Andric } // namespace llvm
544*e8d8bef9SDimitry Andric 
545*e8d8bef9SDimitry Andric namespace {
546*e8d8bef9SDimitry Andric struct Module {
547*e8d8bef9SDimitry Andric   StringRef Name;
548*e8d8bef9SDimitry Andric   AvailabilityItem Availability;
549*e8d8bef9SDimitry Andric   TopLevelItems TopLevel;
550*e8d8bef9SDimitry Andric   VersionedSeq SwiftVersions;
551*e8d8bef9SDimitry Andric 
552*e8d8bef9SDimitry Andric   llvm::Optional<bool> SwiftInferImportAsMember = {llvm::None};
553*e8d8bef9SDimitry Andric 
554*e8d8bef9SDimitry Andric   LLVM_DUMP_METHOD void dump() /*const*/;
555*e8d8bef9SDimitry Andric };
556*e8d8bef9SDimitry Andric } // namespace
557*e8d8bef9SDimitry Andric 
558*e8d8bef9SDimitry Andric namespace llvm {
559*e8d8bef9SDimitry Andric namespace yaml {
560*e8d8bef9SDimitry Andric template <> struct MappingTraits<Module> {
561*e8d8bef9SDimitry Andric   static void mapping(IO &IO, Module &M) {
562*e8d8bef9SDimitry Andric     IO.mapRequired("Name", M.Name);
563*e8d8bef9SDimitry Andric     IO.mapOptional("Availability", M.Availability.Mode,
564*e8d8bef9SDimitry Andric                    APIAvailability::Available);
565*e8d8bef9SDimitry Andric     IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
566*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember);
567*e8d8bef9SDimitry Andric     mapTopLevelItems(IO, M.TopLevel);
568*e8d8bef9SDimitry Andric     IO.mapOptional("SwiftVersions", M.SwiftVersions);
569*e8d8bef9SDimitry Andric   }
570*e8d8bef9SDimitry Andric };
571*e8d8bef9SDimitry Andric } // namespace yaml
572*e8d8bef9SDimitry Andric } // namespace llvm
573*e8d8bef9SDimitry Andric 
574*e8d8bef9SDimitry Andric void Module::dump() {
575*e8d8bef9SDimitry Andric   llvm::yaml::Output OS(llvm::errs());
576*e8d8bef9SDimitry Andric   OS << *this;
577*e8d8bef9SDimitry Andric }
578*e8d8bef9SDimitry Andric 
579*e8d8bef9SDimitry Andric namespace {
580*e8d8bef9SDimitry Andric bool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag,
581*e8d8bef9SDimitry Andric                    void *DiagContext) {
582*e8d8bef9SDimitry Andric   llvm::yaml::Input IS(YI, nullptr, Diag, DiagContext);
583*e8d8bef9SDimitry Andric   IS >> M;
584*e8d8bef9SDimitry Andric   return static_cast<bool>(IS.error());
585*e8d8bef9SDimitry Andric }
586*e8d8bef9SDimitry Andric } // namespace
587*e8d8bef9SDimitry Andric 
588*e8d8bef9SDimitry Andric bool clang::api_notes::parseAndDumpAPINotes(StringRef YI,
589*e8d8bef9SDimitry Andric                                             llvm::raw_ostream &OS) {
590*e8d8bef9SDimitry Andric   Module M;
591*e8d8bef9SDimitry Andric   if (parseAPINotes(YI, M, nullptr, nullptr))
592*e8d8bef9SDimitry Andric     return true;
593*e8d8bef9SDimitry Andric 
594*e8d8bef9SDimitry Andric   llvm::yaml::Output YOS(OS);
595*e8d8bef9SDimitry Andric   YOS << M;
596*e8d8bef9SDimitry Andric 
597*e8d8bef9SDimitry Andric   return false;
598*e8d8bef9SDimitry Andric }
599