Home | History | Annotate | Line # | Download | only in APINotes
      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> {
     41   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> {
     62   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> {
     88   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> {
    106   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> {
    120   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> {
    173   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> {
    181   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> {
    222   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> {
    261   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> {
    302   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> {
    337   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> {
    367   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> {
    396   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> {
    430   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> {
    438   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> {
    474   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> {
    482   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 {
    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> {
    537   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 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
    555   LLVM_DUMP_METHOD void dump() /*const*/;
    556 #endif
    557 };
    558 } // namespace
    559 
    560 namespace llvm {
    561 namespace yaml {
    562 template <> struct MappingTraits<Module> {
    563   static void mapping(IO &IO, Module &M) {
    564     IO.mapRequired("Name", M.Name);
    565     IO.mapOptional("Availability", M.Availability.Mode,
    566                    APIAvailability::Available);
    567     IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
    568     IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember);
    569     mapTopLevelItems(IO, M.TopLevel);
    570     IO.mapOptional("SwiftVersions", M.SwiftVersions);
    571   }
    572 };
    573 } // namespace yaml
    574 } // namespace llvm
    575 
    576 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
    577 LLVM_DUMP_METHOD void Module::dump() {
    578   llvm::yaml::Output OS(llvm::errs());
    579   OS << *this;
    580 }
    581 #endif
    582 
    583 namespace {
    584 bool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag,
    585                    void *DiagContext) {
    586   llvm::yaml::Input IS(YI, nullptr, Diag, DiagContext);
    587   IS >> M;
    588   return static_cast<bool>(IS.error());
    589 }
    590 } // namespace
    591 
    592 bool clang::api_notes::parseAndDumpAPINotes(StringRef YI,
    593                                             llvm::raw_ostream &OS) {
    594   Module M;
    595   if (parseAPINotes(YI, M, nullptr, nullptr))
    596     return true;
    597 
    598   llvm::yaml::Output YOS(OS);
    599   YOS << M;
    600 
    601   return false;
    602 }
    603