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