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