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