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