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