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