brintos

brintos / llvm-project-archived public Read only

0
0
Text · 42.1 KiB · 8e91d48 Raw
1273 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// The types defined locally are designed to represent the YAML state, which10// 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 these12// enumerations appear to be redefining constants from the attributes table13// data, they are distinct.14//15 16#include "clang/APINotes/APINotesYAMLCompiler.h"17#include "clang/APINotes/APINotesWriter.h"18#include "clang/APINotes/Types.h"19#include "clang/Basic/LLVM.h"20#include "clang/Basic/Specifiers.h"21#include "llvm/ADT/StringSet.h"22#include "llvm/Support/SourceMgr.h"23#include "llvm/Support/VersionTuple.h"24#include "llvm/Support/YAMLTraits.h"25#include <optional>26#include <type_traits>27#include <vector>28 29using namespace clang;30using namespace api_notes;31 32namespace llvm {33namespace yaml {34template <> struct ScalarEnumerationTraits<SwiftSafetyKind> {35  static void enumeration(IO &IO, SwiftSafetyKind &SK) {36    IO.enumCase(SK, "unspecified", SwiftSafetyKind::Unspecified);37    IO.enumCase(SK, "safe", SwiftSafetyKind::Safe);38    IO.enumCase(SK, "unsafe", SwiftSafetyKind::Unsafe);39  }40};41} // namespace yaml42} // namespace llvm43 44namespace {45enum class APIAvailability {46  Available = 0,47  None,48  NonSwift,49};50} // namespace51 52namespace llvm {53namespace yaml {54template <> struct ScalarEnumerationTraits<APIAvailability> {55  static void enumeration(IO &IO, APIAvailability &AA) {56    IO.enumCase(AA, "none", APIAvailability::None);57    IO.enumCase(AA, "nonswift", APIAvailability::NonSwift);58    IO.enumCase(AA, "available", APIAvailability::Available);59  }60};61} // namespace yaml62} // namespace llvm63 64namespace {65enum class MethodKind {66  Class,67  Instance,68};69} // namespace70 71namespace llvm {72namespace yaml {73template <> struct ScalarEnumerationTraits<MethodKind> {74  static void enumeration(IO &IO, MethodKind &MK) {75    IO.enumCase(MK, "Class", MethodKind::Class);76    IO.enumCase(MK, "Instance", MethodKind::Instance);77  }78};79} // namespace yaml80} // namespace llvm81 82namespace {83struct Param {84  int Position;85  std::optional<bool> NoEscape = false;86  std::optional<bool> Lifetimebound = false;87  std::optional<NullabilityKind> Nullability;88  std::optional<RetainCountConventionKind> RetainCountConvention;89  StringRef Type;90};91 92typedef std::vector<Param> ParamsSeq;93} // namespace94 95LLVM_YAML_IS_SEQUENCE_VECTOR(Param)96LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(NullabilityKind)97 98namespace llvm {99namespace yaml {100template <> struct ScalarEnumerationTraits<NullabilityKind> {101  static void enumeration(IO &IO, NullabilityKind &NK) {102    IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull);103    IO.enumCase(NK, "Optional", NullabilityKind::Nullable);104    IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified);105    IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult);106    // TODO: Mapping this to it's own value would allow for better cross107    // checking. Also the default should be Unknown.108    IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified);109 110    // Aliases for compatibility with existing APINotes.111    IO.enumCase(NK, "N", NullabilityKind::NonNull);112    IO.enumCase(NK, "O", NullabilityKind::Nullable);113    IO.enumCase(NK, "U", NullabilityKind::Unspecified);114    IO.enumCase(NK, "S", NullabilityKind::Unspecified);115  }116};117 118template <> struct ScalarEnumerationTraits<RetainCountConventionKind> {119  static void enumeration(IO &IO, RetainCountConventionKind &RCCK) {120    IO.enumCase(RCCK, "none", RetainCountConventionKind::None);121    IO.enumCase(RCCK, "CFReturnsRetained",122                RetainCountConventionKind::CFReturnsRetained);123    IO.enumCase(RCCK, "CFReturnsNotRetained",124                RetainCountConventionKind::CFReturnsNotRetained);125    IO.enumCase(RCCK, "NSReturnsRetained",126                RetainCountConventionKind::NSReturnsRetained);127    IO.enumCase(RCCK, "NSReturnsNotRetained",128                RetainCountConventionKind::NSReturnsNotRetained);129  }130};131 132template <> struct MappingTraits<Param> {133  static void mapping(IO &IO, Param &P) {134    IO.mapRequired("Position", P.Position);135    IO.mapOptional("Nullability", P.Nullability, std::nullopt);136    IO.mapOptional("RetainCountConvention", P.RetainCountConvention);137    IO.mapOptional("NoEscape", P.NoEscape);138    IO.mapOptional("Lifetimebound", P.Lifetimebound);139    IO.mapOptional("Type", P.Type, StringRef(""));140  }141};142} // namespace yaml143} // namespace llvm144 145namespace {146typedef std::vector<NullabilityKind> NullabilitySeq;147 148struct AvailabilityItem {149  APIAvailability Mode = APIAvailability::Available;150  StringRef Msg;151};152 153/// Old attribute deprecated in favor of SwiftName.154enum class FactoryAsInitKind {155  /// Infer based on name and type (the default).156  Infer,157  /// Treat as a class method.158  AsClassMethod,159  /// Treat as an initializer.160  AsInitializer,161};162 163struct Method {164  StringRef Selector;165  MethodKind Kind;166  ParamsSeq Params;167  NullabilitySeq Nullability;168  std::optional<NullabilityKind> NullabilityOfRet;169  std::optional<RetainCountConventionKind> RetainCountConvention;170  AvailabilityItem Availability;171  std::optional<bool> SwiftPrivate;172  StringRef SwiftName;173  FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;174  bool DesignatedInit = false;175  bool Required = false;176  StringRef ResultType;177  StringRef SwiftReturnOwnership;178  SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;179};180 181typedef std::vector<Method> MethodsSeq;182} // namespace183 184LLVM_YAML_IS_SEQUENCE_VECTOR(Method)185 186namespace llvm {187namespace yaml {188template <> struct ScalarEnumerationTraits<FactoryAsInitKind> {189  static void enumeration(IO &IO, FactoryAsInitKind &FIK) {190    IO.enumCase(FIK, "A", FactoryAsInitKind::Infer);191    IO.enumCase(FIK, "C", FactoryAsInitKind::AsClassMethod);192    IO.enumCase(FIK, "I", FactoryAsInitKind::AsInitializer);193  }194};195 196template <> struct MappingTraits<Method> {197  static void mapping(IO &IO, Method &M) {198    IO.mapRequired("Selector", M.Selector);199    IO.mapRequired("MethodKind", M.Kind);200    IO.mapOptional("Parameters", M.Params);201    IO.mapOptional("Nullability", M.Nullability);202    IO.mapOptional("NullabilityOfRet", M.NullabilityOfRet, std::nullopt);203    IO.mapOptional("RetainCountConvention", M.RetainCountConvention);204    IO.mapOptional("Availability", M.Availability.Mode,205                   APIAvailability::Available);206    IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));207    IO.mapOptional("SwiftPrivate", M.SwiftPrivate);208    IO.mapOptional("SwiftName", M.SwiftName, StringRef(""));209    IO.mapOptional("FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);210    IO.mapOptional("DesignatedInit", M.DesignatedInit, false);211    IO.mapOptional("Required", M.Required, false);212    IO.mapOptional("ResultType", M.ResultType, StringRef(""));213    IO.mapOptional("SwiftReturnOwnership", M.SwiftReturnOwnership,214                   StringRef(""));215    IO.mapOptional("SwiftSafety", M.SafetyKind, SwiftSafetyKind::None);216  }217};218} // namespace yaml219} // namespace llvm220 221namespace {222struct Property {223  StringRef Name;224  std::optional<MethodKind> Kind;225  std::optional<NullabilityKind> Nullability;226  AvailabilityItem Availability;227  std::optional<bool> SwiftPrivate;228  StringRef SwiftName;229  std::optional<bool> SwiftImportAsAccessors;230  StringRef Type;231  SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;232};233 234typedef std::vector<Property> PropertiesSeq;235} // namespace236 237LLVM_YAML_IS_SEQUENCE_VECTOR(Property)238 239namespace llvm {240namespace yaml {241template <> struct MappingTraits<Property> {242  static void mapping(IO &IO, Property &P) {243    IO.mapRequired("Name", P.Name);244    IO.mapOptional("PropertyKind", P.Kind);245    IO.mapOptional("Nullability", P.Nullability, std::nullopt);246    IO.mapOptional("Availability", P.Availability.Mode,247                   APIAvailability::Available);248    IO.mapOptional("AvailabilityMsg", P.Availability.Msg, StringRef(""));249    IO.mapOptional("SwiftPrivate", P.SwiftPrivate);250    IO.mapOptional("SwiftName", P.SwiftName, StringRef(""));251    IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors);252    IO.mapOptional("Type", P.Type, StringRef(""));253    IO.mapOptional("SwiftSafety", P.SafetyKind, SwiftSafetyKind::None);254  }255};256} // namespace yaml257} // namespace llvm258 259namespace {260struct Class {261  StringRef Name;262  bool AuditedForNullability = false;263  AvailabilityItem Availability;264  std::optional<bool> SwiftPrivate;265  StringRef SwiftName;266  std::optional<StringRef> SwiftBridge;267  std::optional<StringRef> NSErrorDomain;268  std::optional<bool> SwiftImportAsNonGeneric;269  std::optional<bool> SwiftObjCMembers;270  std::optional<std::string> SwiftConformance;271  MethodsSeq Methods;272  PropertiesSeq Properties;273  SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;274};275 276typedef std::vector<Class> ClassesSeq;277} // namespace278 279LLVM_YAML_IS_SEQUENCE_VECTOR(Class)280 281namespace llvm {282namespace yaml {283template <> struct MappingTraits<Class> {284  static void mapping(IO &IO, Class &C) {285    IO.mapRequired("Name", C.Name);286    IO.mapOptional("AuditedForNullability", C.AuditedForNullability, false);287    IO.mapOptional("Availability", C.Availability.Mode,288                   APIAvailability::Available);289    IO.mapOptional("AvailabilityMsg", C.Availability.Msg, StringRef(""));290    IO.mapOptional("SwiftPrivate", C.SwiftPrivate);291    IO.mapOptional("SwiftName", C.SwiftName, StringRef(""));292    IO.mapOptional("SwiftBridge", C.SwiftBridge);293    IO.mapOptional("NSErrorDomain", C.NSErrorDomain);294    IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric);295    IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers);296    IO.mapOptional("SwiftConformsTo", C.SwiftConformance);297    IO.mapOptional("Methods", C.Methods);298    IO.mapOptional("Properties", C.Properties);299    IO.mapOptional("SwiftSafety", C.SafetyKind, SwiftSafetyKind::None);300  }301};302} // namespace yaml303} // namespace llvm304 305namespace {306struct Function {307  StringRef Name;308  ParamsSeq Params;309  NullabilitySeq Nullability;310  std::optional<NullabilityKind> NullabilityOfRet;311  std::optional<api_notes::RetainCountConventionKind> RetainCountConvention;312  AvailabilityItem Availability;313  std::optional<bool> SwiftPrivate;314  StringRef SwiftName;315  StringRef Type;316  StringRef ResultType;317  StringRef SwiftReturnOwnership;318  SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;319};320 321typedef std::vector<Function> FunctionsSeq;322} // namespace323 324LLVM_YAML_IS_SEQUENCE_VECTOR(Function)325 326namespace llvm {327namespace yaml {328template <> struct MappingTraits<Function> {329  static void mapping(IO &IO, Function &F) {330    IO.mapRequired("Name", F.Name);331    IO.mapOptional("Parameters", F.Params);332    IO.mapOptional("Nullability", F.Nullability);333    IO.mapOptional("NullabilityOfRet", F.NullabilityOfRet, std::nullopt);334    IO.mapOptional("RetainCountConvention", F.RetainCountConvention);335    IO.mapOptional("Availability", F.Availability.Mode,336                   APIAvailability::Available);337    IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));338    IO.mapOptional("SwiftPrivate", F.SwiftPrivate);339    IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));340    IO.mapOptional("ResultType", F.ResultType, StringRef(""));341    IO.mapOptional("SwiftReturnOwnership", F.SwiftReturnOwnership,342                   StringRef(""));343    IO.mapOptional("SwiftSafety", F.SafetyKind, SwiftSafetyKind::None);344  }345};346} // namespace yaml347} // namespace llvm348 349namespace {350struct GlobalVariable {351  StringRef Name;352  std::optional<NullabilityKind> Nullability;353  AvailabilityItem Availability;354  std::optional<bool> SwiftPrivate;355  StringRef SwiftName;356  StringRef Type;357  SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;358};359 360typedef std::vector<GlobalVariable> GlobalVariablesSeq;361} // namespace362 363LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)364 365namespace llvm {366namespace yaml {367template <> struct MappingTraits<GlobalVariable> {368  static void mapping(IO &IO, GlobalVariable &GV) {369    IO.mapRequired("Name", GV.Name);370    IO.mapOptional("Nullability", GV.Nullability, std::nullopt);371    IO.mapOptional("Availability", GV.Availability.Mode,372                   APIAvailability::Available);373    IO.mapOptional("AvailabilityMsg", GV.Availability.Msg, StringRef(""));374    IO.mapOptional("SwiftPrivate", GV.SwiftPrivate);375    IO.mapOptional("SwiftName", GV.SwiftName, StringRef(""));376    IO.mapOptional("Type", GV.Type, StringRef(""));377    IO.mapOptional("SwiftSafety", GV.SafetyKind, SwiftSafetyKind::None);378  }379};380} // namespace yaml381} // namespace llvm382 383namespace {384struct EnumConstant {385  StringRef Name;386  AvailabilityItem Availability;387  std::optional<bool> SwiftPrivate;388  StringRef SwiftName;389  SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;390};391 392typedef std::vector<EnumConstant> EnumConstantsSeq;393} // namespace394 395LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)396 397namespace llvm {398namespace yaml {399template <> struct MappingTraits<EnumConstant> {400  static void mapping(IO &IO, EnumConstant &EC) {401    IO.mapRequired("Name", EC.Name);402    IO.mapOptional("Availability", EC.Availability.Mode,403                   APIAvailability::Available);404    IO.mapOptional("AvailabilityMsg", EC.Availability.Msg, StringRef(""));405    IO.mapOptional("SwiftPrivate", EC.SwiftPrivate);406    IO.mapOptional("SwiftName", EC.SwiftName, StringRef(""));407    IO.mapOptional("SwiftSafety", EC.SafetyKind, SwiftSafetyKind::None);408  }409};410} // namespace yaml411} // namespace llvm412 413namespace {414/// Syntactic sugar for EnumExtensibility and FlagEnum415enum class EnumConvenienceAliasKind {416  /// EnumExtensibility: none, FlagEnum: false417  None,418  /// EnumExtensibility: open, FlagEnum: false419  CFEnum,420  /// EnumExtensibility: open, FlagEnum: true421  CFOptions,422  /// EnumExtensibility: closed, FlagEnum: false423  CFClosedEnum424};425} // namespace426 427namespace llvm {428namespace yaml {429template <> struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {430  static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK) {431    IO.enumCase(ECAK, "none", EnumConvenienceAliasKind::None);432    IO.enumCase(ECAK, "CFEnum", EnumConvenienceAliasKind::CFEnum);433    IO.enumCase(ECAK, "NSEnum", EnumConvenienceAliasKind::CFEnum);434    IO.enumCase(ECAK, "CFOptions", EnumConvenienceAliasKind::CFOptions);435    IO.enumCase(ECAK, "NSOptions", EnumConvenienceAliasKind::CFOptions);436    IO.enumCase(ECAK, "CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);437    IO.enumCase(ECAK, "NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);438  }439};440} // namespace yaml441} // namespace llvm442 443namespace {444struct Field {445  StringRef Name;446  std::optional<NullabilityKind> Nullability;447  AvailabilityItem Availability;448  std::optional<bool> SwiftPrivate;449  StringRef SwiftName;450  StringRef Type;451  SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;452};453 454typedef std::vector<Field> FieldsSeq;455} // namespace456 457LLVM_YAML_IS_SEQUENCE_VECTOR(Field)458 459namespace llvm {460namespace yaml {461template <> struct MappingTraits<Field> {462  static void mapping(IO &IO, Field &F) {463    IO.mapRequired("Name", F.Name);464    IO.mapOptional("Nullability", F.Nullability, std::nullopt);465    IO.mapOptional("Availability", F.Availability.Mode,466                   APIAvailability::Available);467    IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));468    IO.mapOptional("SwiftPrivate", F.SwiftPrivate);469    IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));470    IO.mapOptional("Type", F.Type, StringRef(""));471    IO.mapOptional("SwiftSafety", F.SafetyKind, SwiftSafetyKind::None);472  }473};474} // namespace yaml475} // namespace llvm476 477namespace {478struct Tag;479typedef std::vector<Tag> TagsSeq;480 481struct Tag {482  StringRef Name;483  AvailabilityItem Availability;484  StringRef SwiftName;485  std::optional<bool> SwiftPrivate;486  std::optional<StringRef> SwiftBridge;487  std::optional<StringRef> NSErrorDomain;488  std::optional<std::string> SwiftImportAs;489  std::optional<std::string> SwiftRetainOp;490  std::optional<std::string> SwiftReleaseOp;491  std::optional<std::string> SwiftDestroyOp;492  std::optional<std::string> SwiftDefaultOwnership;493  std::optional<std::string> SwiftConformance;494  std::optional<EnumExtensibilityKind> EnumExtensibility;495  std::optional<bool> FlagEnum;496  std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;497  std::optional<bool> SwiftCopyable;498  std::optional<bool> SwiftEscapable;499  SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;500  FunctionsSeq Methods;501  FieldsSeq Fields;502 503  /// Tags that are declared within the current tag. Only the tags that have504  /// corresponding API Notes will be listed.505  TagsSeq Tags;506};507} // namespace508 509LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)510 511namespace llvm {512namespace yaml {513template <> struct ScalarEnumerationTraits<EnumExtensibilityKind> {514  static void enumeration(IO &IO, EnumExtensibilityKind &EEK) {515    IO.enumCase(EEK, "none", EnumExtensibilityKind::None);516    IO.enumCase(EEK, "open", EnumExtensibilityKind::Open);517    IO.enumCase(EEK, "closed", EnumExtensibilityKind::Closed);518  }519};520 521template <> struct MappingTraits<Tag> {522  static void mapping(IO &IO, Tag &T) {523    IO.mapRequired("Name", T.Name);524    IO.mapOptional("Availability", T.Availability.Mode,525                   APIAvailability::Available);526    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));527    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);528    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));529    IO.mapOptional("SwiftBridge", T.SwiftBridge);530    IO.mapOptional("NSErrorDomain", T.NSErrorDomain);531    IO.mapOptional("SwiftImportAs", T.SwiftImportAs);532    IO.mapOptional("SwiftReleaseOp", T.SwiftReleaseOp);533    IO.mapOptional("SwiftRetainOp", T.SwiftRetainOp);534    IO.mapOptional("SwiftDestroyOp", T.SwiftDestroyOp);535    IO.mapOptional("SwiftDefaultOwnership", T.SwiftDefaultOwnership);536    IO.mapOptional("SwiftConformsTo", T.SwiftConformance);537    IO.mapOptional("EnumExtensibility", T.EnumExtensibility);538    IO.mapOptional("FlagEnum", T.FlagEnum);539    IO.mapOptional("EnumKind", T.EnumConvenienceKind);540    IO.mapOptional("SwiftCopyable", T.SwiftCopyable);541    IO.mapOptional("SwiftEscapable", T.SwiftEscapable);542    IO.mapOptional("Methods", T.Methods);543    IO.mapOptional("Fields", T.Fields);544    IO.mapOptional("Tags", T.Tags);545    IO.mapOptional("SwiftSafety", T.SafetyKind, SwiftSafetyKind::None);546  }547};548} // namespace yaml549} // namespace llvm550 551namespace {552struct Typedef {553  StringRef Name;554  AvailabilityItem Availability;555  StringRef SwiftName;556  std::optional<bool> SwiftPrivate;557  std::optional<StringRef> SwiftBridge;558  std::optional<StringRef> NSErrorDomain;559  std::optional<SwiftNewTypeKind> SwiftType;560  std::optional<std::string> SwiftConformance;561  const SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;562};563 564typedef std::vector<Typedef> TypedefsSeq;565} // namespace566 567LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)568 569namespace llvm {570namespace yaml {571template <> struct ScalarEnumerationTraits<SwiftNewTypeKind> {572  static void enumeration(IO &IO, SwiftNewTypeKind &SWK) {573    IO.enumCase(SWK, "none", SwiftNewTypeKind::None);574    IO.enumCase(SWK, "struct", SwiftNewTypeKind::Struct);575    IO.enumCase(SWK, "enum", SwiftNewTypeKind::Enum);576  }577};578 579template <> struct MappingTraits<Typedef> {580  static void mapping(IO &IO, Typedef &T) {581    IO.mapRequired("Name", T.Name);582    IO.mapOptional("Availability", T.Availability.Mode,583                   APIAvailability::Available);584    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));585    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);586    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));587    IO.mapOptional("SwiftBridge", T.SwiftBridge);588    IO.mapOptional("NSErrorDomain", T.NSErrorDomain);589    IO.mapOptional("SwiftWrapper", T.SwiftType);590    IO.mapOptional("SwiftConformsTo", T.SwiftConformance);591  }592};593} // namespace yaml594} // namespace llvm595 596namespace {597struct Namespace;598typedef std::vector<Namespace> NamespacesSeq;599 600struct TopLevelItems {601  ClassesSeq Classes;602  ClassesSeq Protocols;603  FunctionsSeq Functions;604  GlobalVariablesSeq Globals;605  EnumConstantsSeq EnumConstants;606  TagsSeq Tags;607  TypedefsSeq Typedefs;608  NamespacesSeq Namespaces;609};610} // namespace611 612namespace llvm {613namespace yaml {614static void mapTopLevelItems(IO &IO, TopLevelItems &TLI) {615  IO.mapOptional("Classes", TLI.Classes);616  IO.mapOptional("Protocols", TLI.Protocols);617  IO.mapOptional("Functions", TLI.Functions);618  IO.mapOptional("Globals", TLI.Globals);619  IO.mapOptional("Enumerators", TLI.EnumConstants);620  IO.mapOptional("Tags", TLI.Tags);621  IO.mapOptional("Typedefs", TLI.Typedefs);622  IO.mapOptional("Namespaces", TLI.Namespaces);623}624} // namespace yaml625} // namespace llvm626 627namespace {628struct Namespace {629  StringRef Name;630  AvailabilityItem Availability;631  StringRef SwiftName;632  std::optional<bool> SwiftPrivate;633  TopLevelItems Items;634  const SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;635};636} // namespace637 638LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)639 640namespace llvm {641namespace yaml {642template <> struct MappingTraits<Namespace> {643  static void mapping(IO &IO, Namespace &T) {644    IO.mapRequired("Name", T.Name);645    IO.mapOptional("Availability", T.Availability.Mode,646                   APIAvailability::Available);647    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));648    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);649    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));650    mapTopLevelItems(IO, T.Items);651  }652};653} // namespace yaml654} // namespace llvm655 656namespace {657struct Versioned {658  VersionTuple Version;659  TopLevelItems Items;660};661 662typedef std::vector<Versioned> VersionedSeq;663} // namespace664 665LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)666 667namespace llvm {668namespace yaml {669template <> struct MappingTraits<Versioned> {670  static void mapping(IO &IO, Versioned &V) {671    IO.mapRequired("Version", V.Version);672    mapTopLevelItems(IO, V.Items);673  }674};675} // namespace yaml676} // namespace llvm677 678namespace {679struct Module {680  StringRef Name;681  AvailabilityItem Availability;682  TopLevelItems TopLevel;683  VersionedSeq SwiftVersions;684 685  std::optional<bool> SwiftInferImportAsMember;686 687#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)688  LLVM_DUMP_METHOD void dump() /*const*/;689#endif690};691} // namespace692 693namespace llvm {694namespace yaml {695template <> struct MappingTraits<Module> {696  static void mapping(IO &IO, Module &M) {697    IO.mapRequired("Name", M.Name);698    IO.mapOptional("Availability", M.Availability.Mode,699                   APIAvailability::Available);700    IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));701    IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember);702    mapTopLevelItems(IO, M.TopLevel);703    IO.mapOptional("SwiftVersions", M.SwiftVersions);704  }705};706} // namespace yaml707} // namespace llvm708 709#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)710LLVM_DUMP_METHOD void Module::dump() {711  llvm::yaml::Output OS(llvm::errs());712  OS << *this;713}714#endif715 716namespace {717bool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag,718                   void *DiagContext) {719  llvm::yaml::Input IS(YI, nullptr, Diag, DiagContext);720  IS >> M;721  return static_cast<bool>(IS.error());722}723} // namespace724 725bool clang::api_notes::parseAndDumpAPINotes(StringRef YI,726                                            llvm::raw_ostream &OS) {727  Module M;728  if (parseAPINotes(YI, M, nullptr, nullptr))729    return true;730 731  llvm::yaml::Output YOS(OS);732  YOS << M;733 734  return false;735}736 737namespace {738using namespace api_notes;739 740class YAMLConverter {741  const Module &M;742  APINotesWriter Writer;743  llvm::raw_ostream &OS;744  llvm::SourceMgr::DiagHandlerTy DiagHandler;745  void *DiagHandlerCtxt;746  bool ErrorOccured;747 748  /// Emit a diagnostic749  bool emitError(llvm::Twine Message) {750    DiagHandler(751        llvm::SMDiagnostic("", llvm::SourceMgr::DK_Error, Message.str()),752        DiagHandlerCtxt);753    ErrorOccured = true;754    return true;755  }756 757public:758  YAMLConverter(const Module &TheModule, const FileEntry *SourceFile,759                llvm::raw_ostream &OS,760                llvm::SourceMgr::DiagHandlerTy DiagHandler,761                void *DiagHandlerCtxt)762      : M(TheModule), Writer(TheModule.Name, SourceFile), OS(OS),763        DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),764        ErrorOccured(false) {}765 766  void convertAvailability(const AvailabilityItem &Availability,767                           CommonEntityInfo &CEI, llvm::StringRef APIName) {768    // Populate the unavailability information.769    CEI.Unavailable = (Availability.Mode == APIAvailability::None);770    CEI.UnavailableInSwift = (Availability.Mode == APIAvailability::NonSwift);771    if (CEI.Unavailable || CEI.UnavailableInSwift) {772      CEI.UnavailableMsg = std::string(Availability.Msg);773    } else {774      if (!Availability.Msg.empty())775        emitError(llvm::Twine("availability message for available API '") +776                  APIName + "' will not be used");777    }778  }779 780  void convertParams(const ParamsSeq &Params, FunctionInfo &OutInfo,781                     std::optional<ParamInfo> &thisOrSelf) {782    for (const auto &P : Params) {783      ParamInfo PI;784      if (P.Nullability)785        PI.setNullabilityAudited(*P.Nullability);786      PI.setNoEscape(P.NoEscape);787      PI.setLifetimebound(P.Lifetimebound);788      PI.setType(std::string(P.Type));789      PI.setRetainCountConvention(P.RetainCountConvention);790      if (static_cast<int>(OutInfo.Params.size()) <= P.Position)791        OutInfo.Params.resize(P.Position + 1);792      if (P.Position == -1)793        thisOrSelf = PI;794      else if (P.Position >= 0)795        OutInfo.Params[P.Position] |= PI;796      else797        emitError("invalid parameter position " + llvm::itostr(P.Position));798    }799  }800 801  void convertNullability(const NullabilitySeq &Nullability,802                          std::optional<NullabilityKind> ReturnNullability,803                          FunctionInfo &OutInfo, llvm::StringRef APIName) {804    if (Nullability.size() > FunctionInfo::getMaxNullabilityIndex()) {805      emitError(llvm::Twine("nullability info for '") + APIName +806                "' does not fit");807      return;808    }809 810    bool audited = false;811    unsigned int idx = 1;812    for (const auto &N : Nullability)813      OutInfo.addTypeInfo(idx++, N);814    audited = Nullability.size() > 0 || ReturnNullability;815    if (audited)816      OutInfo.addTypeInfo(0,817                          ReturnNullability.value_or(NullabilityKind::NonNull));818    if (!audited)819      return;820    OutInfo.NullabilityAudited = audited;821    OutInfo.NumAdjustedNullable = idx;822  }823 824  /// Convert the common parts of an entity from YAML.825  template <typename T>826  void convertCommonEntity(const T &Common, CommonEntityInfo &Info,827                           StringRef APIName) {828    convertAvailability(Common.Availability, Info, APIName);829    Info.setSwiftPrivate(Common.SwiftPrivate);830    if (Common.SafetyKind != SwiftSafetyKind::None)831      Info.setSwiftSafety(Common.SafetyKind);832    Info.SwiftName = std::string(Common.SwiftName);833  }834 835  /// Convert the common parts of a type entity from YAML.836  template <typename T>837  void convertCommonType(const T &Common, CommonTypeInfo &Info,838                         StringRef APIName) {839    convertCommonEntity(Common, Info, APIName);840    if (Common.SwiftBridge)841      Info.setSwiftBridge(std::string(*Common.SwiftBridge));842    Info.setNSErrorDomain(Common.NSErrorDomain);843    if (auto conformance = Common.SwiftConformance)844      Info.setSwiftConformance(conformance);845  }846 847  // Translate from Method into ObjCMethodInfo and write it out.848  void convertMethod(const Method &M, ContextID ClassID, StringRef ClassName,849                     VersionTuple SwiftVersion) {850    ObjCMethodInfo MI;851    convertCommonEntity(M, MI, M.Selector);852 853    // Check if the selector ends with ':' to determine if it takes arguments.854    bool takesArguments = M.Selector.ends_with(":");855 856    // Split the selector into pieces.857    llvm::SmallVector<StringRef, 4> Args;858    M.Selector.split(Args, ":", /*MaxSplit*/ -1, /*KeepEmpty*/ false);859    if (!takesArguments && Args.size() > 1) {860      emitError("selector '" + M.Selector + "' is missing a ':' at the end");861      return;862    }863 864    // Construct ObjCSelectorRef.865    api_notes::ObjCSelectorRef Selector;866    Selector.NumArgs = !takesArguments ? 0 : Args.size();867    Selector.Identifiers = Args;868 869    // Translate the initializer info.870    MI.DesignatedInit = M.DesignatedInit;871    MI.RequiredInit = M.Required;872    if (M.FactoryAsInit != FactoryAsInitKind::Infer)873      emitError("'FactoryAsInit' is no longer valid; use 'SwiftName' instead");874 875    MI.ResultType = std::string(M.ResultType);876    MI.SwiftReturnOwnership = std::string(M.SwiftReturnOwnership);877 878    // Translate parameter information.879    convertParams(M.Params, MI, MI.Self);880 881    // Translate nullability info.882    convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);883 884    MI.setRetainCountConvention(M.RetainCountConvention);885 886    // Write it.887    Writer.addObjCMethod(ClassID, Selector, M.Kind == MethodKind::Instance, MI,888                         SwiftVersion);889  }890 891  template <typename T>892  void convertVariable(const T &Entity, VariableInfo &VI) {893    convertAvailability(Entity.Availability, VI, Entity.Name);894    VI.setSwiftPrivate(Entity.SwiftPrivate);895    VI.SwiftName = std::string(Entity.SwiftName);896    if (Entity.Nullability)897      VI.setNullabilityAudited(*Entity.Nullability);898    VI.setType(std::string(Entity.Type));899  }900 901  void convertContext(std::optional<ContextID> ParentContextID, const Class &C,902                      ContextKind Kind, VersionTuple SwiftVersion) {903    // Write the class.904    ContextInfo CI;905    convertCommonType(C, CI, C.Name);906 907    if (C.AuditedForNullability)908      CI.setDefaultNullability(NullabilityKind::NonNull);909    if (C.SwiftImportAsNonGeneric)910      CI.setSwiftImportAsNonGeneric(*C.SwiftImportAsNonGeneric);911    if (C.SwiftObjCMembers)912      CI.setSwiftObjCMembers(*C.SwiftObjCMembers);913 914    ContextID CtxID =915        Writer.addContext(ParentContextID, C.Name, Kind, CI, SwiftVersion);916 917    // Write all methods.918    llvm::StringMap<std::pair<bool, bool>> KnownMethods;919    for (const auto &method : C.Methods) {920      // Check for duplicate method definitions.921      bool IsInstanceMethod = method.Kind == MethodKind::Instance;922      bool &Known = IsInstanceMethod ? KnownMethods[method.Selector].first923                                     : KnownMethods[method.Selector].second;924      if (Known) {925        emitError(llvm::Twine("duplicate definition of method '") +926                  (IsInstanceMethod ? "-" : "+") + "[" + C.Name + " " +927                  method.Selector + "]'");928        continue;929      }930      Known = true;931 932      convertMethod(method, CtxID, C.Name, SwiftVersion);933    }934 935    // Write all properties.936    llvm::StringSet<> KnownInstanceProperties;937    llvm::StringSet<> KnownClassProperties;938    for (const auto &Property : C.Properties) {939      // Check for duplicate property definitions.940      if ((!Property.Kind || *Property.Kind == MethodKind::Instance) &&941          !KnownInstanceProperties.insert(Property.Name).second) {942        emitError(llvm::Twine("duplicate definition of instance property '") +943                  C.Name + "." + Property.Name + "'");944        continue;945      }946 947      if ((!Property.Kind || *Property.Kind == MethodKind::Class) &&948          !KnownClassProperties.insert(Property.Name).second) {949        emitError(llvm::Twine("duplicate definition of class property '") +950                  C.Name + "." + Property.Name + "'");951        continue;952      }953 954      // Translate from Property into ObjCPropertyInfo.955      ObjCPropertyInfo PI;956      convertVariable(Property, PI);957      if (Property.SwiftImportAsAccessors)958        PI.setSwiftImportAsAccessors(*Property.SwiftImportAsAccessors);959 960      // Add both instance and class properties with this name.961      if (Property.Kind) {962        Writer.addObjCProperty(CtxID, Property.Name,963                               *Property.Kind == MethodKind::Instance, PI,964                               SwiftVersion);965      } else {966        Writer.addObjCProperty(CtxID, Property.Name, true, PI, SwiftVersion);967        Writer.addObjCProperty(CtxID, Property.Name, false, PI, SwiftVersion);968      }969    }970  }971 972  void convertNamespaceContext(std::optional<ContextID> ParentContextID,973                               const Namespace &TheNamespace,974                               VersionTuple SwiftVersion) {975    // Write the namespace.976    ContextInfo CI;977    convertCommonEntity(TheNamespace, CI, TheNamespace.Name);978 979    ContextID CtxID =980        Writer.addContext(ParentContextID, TheNamespace.Name,981                          ContextKind::Namespace, CI, SwiftVersion);982 983    convertTopLevelItems(Context(CtxID, ContextKind::Namespace),984                         TheNamespace.Items, SwiftVersion);985  }986 987  template <typename FuncOrMethodInfo>988  void convertFunction(const Function &Function, FuncOrMethodInfo &FI) {989    convertAvailability(Function.Availability, FI, Function.Name);990    FI.setSwiftPrivate(Function.SwiftPrivate);991    if (Function.SafetyKind != SwiftSafetyKind::None)992      FI.setSwiftSafety(Function.SafetyKind);993    FI.SwiftName = std::string(Function.SwiftName);994    std::optional<ParamInfo> This;995    convertParams(Function.Params, FI, This);996    if constexpr (std::is_same_v<FuncOrMethodInfo, CXXMethodInfo>)997      FI.This = This;998    else if (This)999      emitError("implicit instance parameter is only permitted on C++ and "1000                "Objective-C methods");1001    convertNullability(Function.Nullability, Function.NullabilityOfRet, FI,1002                       Function.Name);1003    FI.ResultType = std::string(Function.ResultType);1004    FI.SwiftReturnOwnership = std::string(Function.SwiftReturnOwnership);1005    FI.setRetainCountConvention(Function.RetainCountConvention);1006  }1007 1008  void convertTagContext(std::optional<Context> ParentContext, const Tag &T,1009                         VersionTuple SwiftVersion) {1010    TagInfo TI;1011    std::optional<ContextID> ParentContextID =1012        ParentContext ? std::optional<ContextID>(ParentContext->id)1013                      : std::nullopt;1014    convertCommonType(T, TI, T.Name);1015 1016    if ((T.SwiftRetainOp || T.SwiftReleaseOp) && !T.SwiftImportAs) {1017      emitError(llvm::Twine("should declare SwiftImportAs to use "1018                            "SwiftRetainOp and SwiftReleaseOp (for ") +1019                T.Name + ")");1020      return;1021    }1022    if (T.SwiftReleaseOp.has_value() != T.SwiftRetainOp.has_value()) {1023      emitError(llvm::Twine("should declare both SwiftReleaseOp and "1024                            "SwiftRetainOp (for ") +1025                T.Name + ")");1026      return;1027    }1028 1029    if (T.SwiftImportAs)1030      TI.SwiftImportAs = T.SwiftImportAs;1031    if (T.SwiftRetainOp)1032      TI.SwiftRetainOp = T.SwiftRetainOp;1033    if (T.SwiftReleaseOp)1034      TI.SwiftReleaseOp = T.SwiftReleaseOp;1035    if (T.SwiftDestroyOp)1036      TI.SwiftDestroyOp = T.SwiftDestroyOp;1037    if (T.SwiftDefaultOwnership)1038      TI.SwiftDefaultOwnership = T.SwiftDefaultOwnership;1039 1040    if (T.SwiftCopyable)1041      TI.setSwiftCopyable(T.SwiftCopyable);1042    if (T.SwiftEscapable)1043      TI.setSwiftEscapable(T.SwiftEscapable);1044 1045    if (T.EnumConvenienceKind) {1046      if (T.EnumExtensibility) {1047        emitError(1048            llvm::Twine("cannot mix EnumKind and EnumExtensibility (for ") +1049            T.Name + ")");1050        return;1051      }1052      if (T.FlagEnum) {1053        emitError(llvm::Twine("cannot mix EnumKind and FlagEnum (for ") +1054                  T.Name + ")");1055        return;1056      }1057      switch (*T.EnumConvenienceKind) {1058      case EnumConvenienceAliasKind::None:1059        TI.EnumExtensibility = EnumExtensibilityKind::None;1060        TI.setFlagEnum(false);1061        break;1062      case EnumConvenienceAliasKind::CFEnum:1063        TI.EnumExtensibility = EnumExtensibilityKind::Open;1064        TI.setFlagEnum(false);1065        break;1066      case EnumConvenienceAliasKind::CFOptions:1067        TI.EnumExtensibility = EnumExtensibilityKind::Open;1068        TI.setFlagEnum(true);1069        break;1070      case EnumConvenienceAliasKind::CFClosedEnum:1071        TI.EnumExtensibility = EnumExtensibilityKind::Closed;1072        TI.setFlagEnum(false);1073        break;1074      }1075    } else {1076      TI.EnumExtensibility = T.EnumExtensibility;1077      TI.setFlagEnum(T.FlagEnum);1078    }1079 1080    Writer.addTag(ParentContext, T.Name, TI, SwiftVersion);1081 1082    ContextInfo CI;1083    auto TagCtxID = Writer.addContext(ParentContextID, T.Name, ContextKind::Tag,1084                                      CI, SwiftVersion);1085    Context TagCtx(TagCtxID, ContextKind::Tag);1086 1087    for (const auto &Field : T.Fields) {1088      FieldInfo FI;1089      convertVariable(Field, FI);1090      Writer.addField(TagCtxID, Field.Name, FI, SwiftVersion);1091    }1092 1093    for (const auto &CXXMethod : T.Methods) {1094      CXXMethodInfo MI;1095      convertFunction(CXXMethod, MI);1096      Writer.addCXXMethod(TagCtxID, CXXMethod.Name, MI, SwiftVersion);1097    }1098 1099    // Convert nested tags.1100    for (const auto &Tag : T.Tags)1101      convertTagContext(TagCtx, Tag, SwiftVersion);1102  }1103 1104  void convertTopLevelItems(std::optional<Context> Ctx,1105                            const TopLevelItems &TLItems,1106                            VersionTuple SwiftVersion) {1107    std::optional<ContextID> CtxID =1108        Ctx ? std::optional(Ctx->id) : std::nullopt;1109 1110    // Write all classes.1111    llvm::StringSet<> KnownClasses;1112    for (const auto &Class : TLItems.Classes) {1113      // Check for duplicate class definitions.1114      if (!KnownClasses.insert(Class.Name).second) {1115        emitError(llvm::Twine("multiple definitions of class '") + Class.Name +1116                  "'");1117        continue;1118      }1119 1120      convertContext(CtxID, Class, ContextKind::ObjCClass, SwiftVersion);1121    }1122 1123    // Write all protocols.1124    llvm::StringSet<> KnownProtocols;1125    for (const auto &Protocol : TLItems.Protocols) {1126      // Check for duplicate protocol definitions.1127      if (!KnownProtocols.insert(Protocol.Name).second) {1128        emitError(llvm::Twine("multiple definitions of protocol '") +1129                  Protocol.Name + "'");1130        continue;1131      }1132 1133      convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);1134    }1135 1136    // Write all namespaces.1137    llvm::StringSet<> KnownNamespaces;1138    for (const auto &Namespace : TLItems.Namespaces) {1139      // Check for duplicate namespace definitions.1140      if (!KnownNamespaces.insert(Namespace.Name).second) {1141        emitError(llvm::Twine("multiple definitions of namespace '") +1142                  Namespace.Name + "'");1143        continue;1144      }1145 1146      convertNamespaceContext(CtxID, Namespace, SwiftVersion);1147    }1148 1149    // Write all global variables.1150    llvm::StringSet<> KnownGlobals;1151    for (const auto &Global : TLItems.Globals) {1152      // Check for duplicate global variables.1153      if (!KnownGlobals.insert(Global.Name).second) {1154        emitError(llvm::Twine("multiple definitions of global variable '") +1155                  Global.Name + "'");1156        continue;1157      }1158 1159      GlobalVariableInfo GVI;1160      convertVariable(Global, GVI);1161      Writer.addGlobalVariable(Ctx, Global.Name, GVI, SwiftVersion);1162    }1163 1164    // Write all global functions.1165    llvm::StringSet<> KnownFunctions;1166    for (const auto &Function : TLItems.Functions) {1167      // Check for duplicate global functions.1168      if (!KnownFunctions.insert(Function.Name).second) {1169        emitError(llvm::Twine("multiple definitions of global function '") +1170                  Function.Name + "'");1171        continue;1172      }1173 1174      GlobalFunctionInfo GFI;1175      convertFunction(Function, GFI);1176      Writer.addGlobalFunction(Ctx, Function.Name, GFI, SwiftVersion);1177    }1178 1179    // Write all enumerators.1180    llvm::StringSet<> KnownEnumConstants;1181    for (const auto &EnumConstant : TLItems.EnumConstants) {1182      // Check for duplicate enumerators1183      if (!KnownEnumConstants.insert(EnumConstant.Name).second) {1184        emitError(llvm::Twine("multiple definitions of enumerator '") +1185                  EnumConstant.Name + "'");1186        continue;1187      }1188 1189      EnumConstantInfo ECI;1190      convertAvailability(EnumConstant.Availability, ECI, EnumConstant.Name);1191      ECI.setSwiftPrivate(EnumConstant.SwiftPrivate);1192      ECI.SwiftName = std::string(EnumConstant.SwiftName);1193      Writer.addEnumConstant(EnumConstant.Name, ECI, SwiftVersion);1194    }1195 1196    // Write all tags.1197    llvm::StringSet<> KnownTags;1198    for (const auto &Tag : TLItems.Tags) {1199      // Check for duplicate tag definitions.1200      if (!KnownTags.insert(Tag.Name).second) {1201        emitError(llvm::Twine("multiple definitions of tag '") + Tag.Name +1202                  "'");1203        continue;1204      }1205 1206      convertTagContext(Ctx, Tag, SwiftVersion);1207    }1208 1209    // Write all typedefs.1210    llvm::StringSet<> KnownTypedefs;1211    for (const auto &Typedef : TLItems.Typedefs) {1212      // Check for duplicate typedef definitions.1213      if (!KnownTypedefs.insert(Typedef.Name).second) {1214        emitError(llvm::Twine("multiple definitions of typedef '") +1215                  Typedef.Name + "'");1216        continue;1217      }1218 1219      TypedefInfo TInfo;1220      convertCommonType(Typedef, TInfo, Typedef.Name);1221      TInfo.SwiftWrapper = Typedef.SwiftType;1222 1223      Writer.addTypedef(Ctx, Typedef.Name, TInfo, SwiftVersion);1224    }1225  }1226 1227  bool convertModule() {1228    // Write the top-level items.1229    convertTopLevelItems(/* context */ std::nullopt, M.TopLevel,1230                         VersionTuple());1231 1232    // Convert the versioned information.1233    for (const auto &Versioned : M.SwiftVersions)1234      convertTopLevelItems(/* context */ std::nullopt, Versioned.Items,1235                           Versioned.Version);1236 1237    if (!ErrorOccured)1238      Writer.writeToStream(OS);1239 1240    return ErrorOccured;1241  }1242};1243} // namespace1244 1245static bool compile(const Module &M, const FileEntry *SourceFile,1246                    llvm::raw_ostream &OS,1247                    llvm::SourceMgr::DiagHandlerTy DiagHandler,1248                    void *DiagHandlerCtxt) {1249  YAMLConverter C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);1250  return C.convertModule();1251}1252 1253/// Simple diagnostic handler that prints diagnostics to standard error.1254static void printDiagnostic(const llvm::SMDiagnostic &Diag, void *Context) {1255  Diag.print(nullptr, llvm::errs());1256}1257 1258bool api_notes::compileAPINotes(StringRef YAMLInput,1259                                const FileEntry *SourceFile,1260                                llvm::raw_ostream &OS,1261                                llvm::SourceMgr::DiagHandlerTy DiagHandler,1262                                void *DiagHandlerCtxt) {1263  Module TheModule;1264 1265  if (!DiagHandler)1266    DiagHandler = &printDiagnostic;1267 1268  if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))1269    return true;1270 1271  return compile(TheModule, SourceFile, OS, DiagHandler, DiagHandlerCtxt);1272}1273