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