21#include "llvm/ADT/StringSet.h"
22#include "llvm/Support/SourceMgr.h"
23#include "llvm/Support/VersionTuple.h"
24#include "llvm/Support/YAMLTraits.h"
29using namespace api_notes;
32enum class APIAvailability {
41template <>
struct ScalarEnumerationTraits<APIAvailability> {
43 IO.enumCase(AA,
"none", APIAvailability::None);
44 IO.enumCase(AA,
"nonswift", APIAvailability::NonSwift);
45 IO.enumCase(AA,
"available", APIAvailability::Available);
52enum class MethodKind {
60template <>
struct ScalarEnumerationTraits<MethodKind> {
62 IO.enumCase(MK,
"Class", MethodKind::Class);
63 IO.enumCase(MK,
"Instance", MethodKind::Instance);
72 std::optional<bool> NoEscape =
false;
74 std::optional<RetainCountConventionKind> RetainCountConvention;
78typedef std::vector<Param> ParamsSeq;
81LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
88 IO.enumCase(NK,
"Nonnull", NullabilityKind::NonNull);
89 IO.enumCase(NK,
"Optional", NullabilityKind::Nullable);
90 IO.enumCase(NK,
"Unspecified", NullabilityKind::Unspecified);
91 IO.enumCase(NK,
"NullableResult", NullabilityKind::NullableResult);
94 IO.enumCase(NK,
"Scalar", NullabilityKind::Unspecified);
97 IO.enumCase(NK,
"N", NullabilityKind::NonNull);
98 IO.enumCase(NK,
"O", NullabilityKind::Nullable);
99 IO.enumCase(NK,
"U", NullabilityKind::Unspecified);
100 IO.enumCase(NK,
"S", NullabilityKind::Unspecified);
106 IO.enumCase(RCCK,
"none", RetainCountConventionKind::None);
107 IO.enumCase(RCCK,
"CFReturnsRetained",
108 RetainCountConventionKind::CFReturnsRetained);
109 IO.enumCase(RCCK,
"CFReturnsNotRetained",
110 RetainCountConventionKind::CFReturnsNotRetained);
111 IO.enumCase(RCCK,
"NSReturnsRetained",
112 RetainCountConventionKind::NSReturnsRetained);
113 IO.enumCase(RCCK,
"NSReturnsNotRetained",
114 RetainCountConventionKind::NSReturnsNotRetained);
118template <>
struct MappingTraits<Param> {
120 IO.mapRequired(
"Position",
P.Position);
121 IO.mapOptional(
"Nullability",
P.Nullability, std::nullopt);
122 IO.mapOptional(
"RetainCountConvention",
P.RetainCountConvention);
123 IO.mapOptional(
"NoEscape",
P.NoEscape);
124 IO.mapOptional(
"Type",
P.Type, StringRef(
""));
131typedef std::vector<NullabilityKind> NullabilitySeq;
133struct AvailabilityItem {
134 APIAvailability Mode = APIAvailability::Available;
139enum class FactoryAsInitKind {
153 std::optional<NullabilityKind> NullabilityOfRet;
154 std::optional<RetainCountConventionKind> RetainCountConvention;
155 AvailabilityItem Availability;
156 std::optional<bool> SwiftPrivate;
158 FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
159 bool DesignatedInit =
false;
161 StringRef ResultType;
164typedef std::vector<Method> MethodsSeq;
167LLVM_YAML_IS_SEQUENCE_VECTOR(Method)
171template <>
struct ScalarEnumerationTraits<FactoryAsInitKind> {
173 IO.enumCase(FIK,
"A", FactoryAsInitKind::Infer);
174 IO.enumCase(FIK,
"C", FactoryAsInitKind::AsClassMethod);
175 IO.enumCase(FIK,
"I", FactoryAsInitKind::AsInitializer);
179template <>
struct MappingTraits<Method> {
181 IO.mapRequired(
"Selector", M.Selector);
182 IO.mapRequired(
"MethodKind", M.Kind);
183 IO.mapOptional(
"Parameters", M.Params);
184 IO.mapOptional(
"Nullability", M.Nullability);
185 IO.mapOptional(
"NullabilityOfRet", M.NullabilityOfRet, std::nullopt);
186 IO.mapOptional(
"RetainCountConvention", M.RetainCountConvention);
187 IO.mapOptional(
"Availability", M.Availability.Mode,
188 APIAvailability::Available);
189 IO.mapOptional(
"AvailabilityMsg", M.Availability.Msg, StringRef(
""));
190 IO.mapOptional(
"SwiftPrivate", M.SwiftPrivate);
191 IO.mapOptional(
"SwiftName", M.SwiftName, StringRef(
""));
192 IO.mapOptional(
"FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);
193 IO.mapOptional(
"DesignatedInit", M.DesignatedInit,
false);
194 IO.mapOptional(
"Required", M.Required,
false);
195 IO.mapOptional(
"ResultType", M.ResultType, StringRef(
""));
204 std::optional<MethodKind>
Kind;
206 AvailabilityItem Availability;
207 std::optional<bool> SwiftPrivate;
209 std::optional<bool> SwiftImportAsAccessors;
213typedef std::vector<Property> PropertiesSeq;
216LLVM_YAML_IS_SEQUENCE_VECTOR(Property)
222 IO.mapRequired(
"Name",
P.Name);
223 IO.mapOptional(
"PropertyKind",
P.Kind);
224 IO.mapOptional(
"Nullability",
P.Nullability, std::nullopt);
225 IO.mapOptional(
"Availability",
P.Availability.Mode,
226 APIAvailability::Available);
227 IO.mapOptional(
"AvailabilityMsg",
P.Availability.Msg, StringRef(
""));
228 IO.mapOptional(
"SwiftPrivate",
P.SwiftPrivate);
229 IO.mapOptional(
"SwiftName",
P.SwiftName, StringRef(
""));
230 IO.mapOptional(
"SwiftImportAsAccessors",
P.SwiftImportAsAccessors);
231 IO.mapOptional(
"Type",
P.Type, StringRef(
""));
240 bool AuditedForNullability =
false;
241 AvailabilityItem Availability;
242 std::optional<bool> SwiftPrivate;
244 std::optional<StringRef> SwiftBridge;
245 std::optional<StringRef> NSErrorDomain;
246 std::optional<bool> SwiftImportAsNonGeneric;
247 std::optional<bool> SwiftObjCMembers;
249 PropertiesSeq Properties;
252typedef std::vector<Class> ClassesSeq;
255LLVM_YAML_IS_SEQUENCE_VECTOR(Class)
259template <>
struct MappingTraits<
Class> {
261 IO.mapRequired(
"Name",
C.Name);
262 IO.mapOptional(
"AuditedForNullability",
C.AuditedForNullability,
false);
263 IO.mapOptional(
"Availability",
C.Availability.Mode,
264 APIAvailability::Available);
265 IO.mapOptional(
"AvailabilityMsg",
C.Availability.Msg, StringRef(
""));
266 IO.mapOptional(
"SwiftPrivate",
C.SwiftPrivate);
267 IO.mapOptional(
"SwiftName",
C.SwiftName, StringRef(
""));
268 IO.mapOptional(
"SwiftBridge",
C.SwiftBridge);
269 IO.mapOptional(
"NSErrorDomain",
C.NSErrorDomain);
270 IO.mapOptional(
"SwiftImportAsNonGeneric",
C.SwiftImportAsNonGeneric);
271 IO.mapOptional(
"SwiftObjCMembers",
C.SwiftObjCMembers);
272 IO.mapOptional(
"Methods",
C.Methods);
273 IO.mapOptional(
"Properties",
C.Properties);
284 std::optional<NullabilityKind> NullabilityOfRet;
285 std::optional<api_notes::RetainCountConventionKind> RetainCountConvention;
286 AvailabilityItem Availability;
287 std::optional<bool> SwiftPrivate;
290 StringRef ResultType;
293typedef std::vector<Function> FunctionsSeq;
296LLVM_YAML_IS_SEQUENCE_VECTOR(Function)
302 IO.mapRequired(
"Name", F.Name);
303 IO.mapOptional(
"Parameters", F.Params);
304 IO.mapOptional(
"Nullability", F.Nullability);
305 IO.mapOptional(
"NullabilityOfRet", F.NullabilityOfRet, std::nullopt);
306 IO.mapOptional(
"RetainCountConvention", F.RetainCountConvention);
307 IO.mapOptional(
"Availability", F.Availability.Mode,
308 APIAvailability::Available);
309 IO.mapOptional(
"AvailabilityMsg", F.Availability.Msg, StringRef(
""));
310 IO.mapOptional(
"SwiftPrivate", F.SwiftPrivate);
311 IO.mapOptional(
"SwiftName", F.SwiftName, StringRef(
""));
312 IO.mapOptional(
"ResultType", F.ResultType, StringRef(
""));
319struct GlobalVariable {
322 AvailabilityItem Availability;
323 std::optional<bool> SwiftPrivate;
328typedef std::vector<GlobalVariable> GlobalVariablesSeq;
331LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
335template <>
struct MappingTraits<GlobalVariable> {
336 static void mapping(IO &IO, GlobalVariable &GV) {
337 IO.mapRequired(
"Name", GV.Name);
338 IO.mapOptional(
"Nullability", GV.Nullability, std::nullopt);
339 IO.mapOptional(
"Availability", GV.Availability.Mode,
340 APIAvailability::Available);
341 IO.mapOptional(
"AvailabilityMsg", GV.Availability.Msg, StringRef(
""));
342 IO.mapOptional(
"SwiftPrivate", GV.SwiftPrivate);
343 IO.mapOptional(
"SwiftName", GV.SwiftName, StringRef(
""));
344 IO.mapOptional(
"Type", GV.Type, StringRef(
""));
353 AvailabilityItem Availability;
354 std::optional<bool> SwiftPrivate;
358typedef std::vector<EnumConstant> EnumConstantsSeq;
361LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
365template <>
struct MappingTraits<EnumConstant> {
366 static void mapping(IO &IO, EnumConstant &EC) {
367 IO.mapRequired(
"Name", EC.Name);
368 IO.mapOptional(
"Availability", EC.Availability.Mode,
369 APIAvailability::Available);
370 IO.mapOptional(
"AvailabilityMsg", EC.Availability.Msg, StringRef(
""));
371 IO.mapOptional(
"SwiftPrivate", EC.SwiftPrivate);
372 IO.mapOptional(
"SwiftName", EC.SwiftName, StringRef(
""));
380enum class EnumConvenienceAliasKind {
394template <>
struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
396 IO.enumCase(ECAK,
"none", EnumConvenienceAliasKind::None);
397 IO.enumCase(ECAK,
"CFEnum", EnumConvenienceAliasKind::CFEnum);
398 IO.enumCase(ECAK,
"NSEnum", EnumConvenienceAliasKind::CFEnum);
399 IO.enumCase(ECAK,
"CFOptions", EnumConvenienceAliasKind::CFOptions);
400 IO.enumCase(ECAK,
"NSOptions", EnumConvenienceAliasKind::CFOptions);
401 IO.enumCase(ECAK,
"CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
402 IO.enumCase(ECAK,
"NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
411 AvailabilityItem Availability;
413 std::optional<bool> SwiftPrivate;
414 std::optional<StringRef> SwiftBridge;
415 std::optional<StringRef> NSErrorDomain;
416 std::optional<std::string> SwiftImportAs;
417 std::optional<std::string> SwiftRetainOp;
418 std::optional<std::string> SwiftReleaseOp;
419 std::optional<EnumExtensibilityKind> EnumExtensibility;
420 std::optional<bool> FlagEnum;
421 std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
424typedef std::vector<Tag> TagsSeq;
427LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
433 IO.enumCase(EEK,
"none", EnumExtensibilityKind::None);
434 IO.enumCase(EEK,
"open", EnumExtensibilityKind::Open);
435 IO.enumCase(EEK,
"closed", EnumExtensibilityKind::Closed);
439template <>
struct MappingTraits<Tag> {
441 IO.mapRequired(
"Name", T.Name);
442 IO.mapOptional(
"Availability", T.Availability.Mode,
443 APIAvailability::Available);
444 IO.mapOptional(
"AvailabilityMsg", T.Availability.Msg, StringRef(
""));
445 IO.mapOptional(
"SwiftPrivate", T.SwiftPrivate);
446 IO.mapOptional(
"SwiftName", T.SwiftName, StringRef(
""));
447 IO.mapOptional(
"SwiftBridge", T.SwiftBridge);
448 IO.mapOptional(
"NSErrorDomain", T.NSErrorDomain);
449 IO.mapOptional(
"SwiftImportAs", T.SwiftImportAs);
450 IO.mapOptional(
"SwiftReleaseOp", T.SwiftReleaseOp);
451 IO.mapOptional(
"SwiftRetainOp", T.SwiftRetainOp);
452 IO.mapOptional(
"EnumExtensibility", T.EnumExtensibility);
453 IO.mapOptional(
"FlagEnum", T.FlagEnum);
454 IO.mapOptional(
"EnumKind", T.EnumConvenienceKind);
463 AvailabilityItem Availability;
465 std::optional<bool> SwiftPrivate;
466 std::optional<StringRef> SwiftBridge;
467 std::optional<StringRef> NSErrorDomain;
468 std::optional<SwiftNewTypeKind> SwiftType;
471typedef std::vector<Typedef> TypedefsSeq;
474LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
480 IO.enumCase(SWK,
"none", SwiftNewTypeKind::None);
481 IO.enumCase(SWK,
"struct", SwiftNewTypeKind::Struct);
482 IO.enumCase(SWK,
"enum", SwiftNewTypeKind::Enum);
486template <>
struct MappingTraits<Typedef> {
488 IO.mapRequired(
"Name", T.Name);
489 IO.mapOptional(
"Availability", T.Availability.Mode,
490 APIAvailability::Available);
491 IO.mapOptional(
"AvailabilityMsg", T.Availability.Msg, StringRef(
""));
492 IO.mapOptional(
"SwiftPrivate", T.SwiftPrivate);
493 IO.mapOptional(
"SwiftName", T.SwiftName, StringRef(
""));
494 IO.mapOptional(
"SwiftBridge", T.SwiftBridge);
495 IO.mapOptional(
"NSErrorDomain", T.NSErrorDomain);
496 IO.mapOptional(
"SwiftWrapper", T.SwiftType);
504typedef std::vector<Namespace> NamespacesSeq;
506struct TopLevelItems {
508 ClassesSeq Protocols;
509 FunctionsSeq Functions;
510 GlobalVariablesSeq Globals;
511 EnumConstantsSeq EnumConstants;
513 TypedefsSeq Typedefs;
514 NamespacesSeq Namespaces;
521 IO.mapOptional(
"Classes", TLI.Classes);
522 IO.mapOptional(
"Protocols", TLI.Protocols);
523 IO.mapOptional(
"Functions", TLI.Functions);
524 IO.mapOptional(
"Globals", TLI.Globals);
525 IO.mapOptional(
"Enumerators", TLI.EnumConstants);
526 IO.mapOptional(
"Tags", TLI.Tags);
527 IO.mapOptional(
"Typedefs", TLI.Typedefs);
528 IO.mapOptional(
"Namespaces", TLI.Namespaces);
536 AvailabilityItem Availability;
538 std::optional<bool> SwiftPrivate;
543LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)
549 IO.mapRequired(
"Name", T.Name);
550 IO.mapOptional(
"Availability", T.Availability.Mode,
551 APIAvailability::Available);
552 IO.mapOptional(
"AvailabilityMsg", T.Availability.Msg, StringRef(
""));
553 IO.mapOptional(
"SwiftPrivate", T.SwiftPrivate);
554 IO.mapOptional(
"SwiftName", T.SwiftName, StringRef(
""));
563 VersionTuple Version;
567typedef std::vector<Versioned> VersionedSeq;
570LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
574template <>
struct MappingTraits<Versioned> {
576 IO.mapRequired(
"Version",
V.Version);
586 AvailabilityItem Availability;
587 TopLevelItems TopLevel;
588 VersionedSeq SwiftVersions;
590 std::optional<bool> SwiftInferImportAsMember;
592#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
593 LLVM_DUMP_METHOD
void dump() ;
600template <>
struct MappingTraits<
Module> {
602 IO.mapRequired(
"Name", M.
Name);
603 IO.mapOptional(
"Availability", M.Availability.Mode,
604 APIAvailability::Available);
605 IO.mapOptional(
"AvailabilityMsg", M.Availability.Msg, StringRef(
""));
606 IO.mapOptional(
"SwiftInferImportAsMember", M.SwiftInferImportAsMember);
608 IO.mapOptional(
"SwiftVersions", M.SwiftVersions);
614#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
615LLVM_DUMP_METHOD
void Module::dump() {
616 llvm::yaml::Output OS(llvm::errs());
622bool parseAPINotes(StringRef YI,
Module &M, llvm::SourceMgr::DiagHandlerTy
Diag,
624 llvm::yaml::Input IS(YI,
nullptr,
Diag, DiagContext);
626 return static_cast<bool>(IS.error());
631 llvm::raw_ostream &OS) {
633 if (parseAPINotes(YI, M,
nullptr,
nullptr))
636 llvm::yaml::Output YOS(OS);
643using namespace api_notes;
648 llvm::raw_ostream &OS;
649 llvm::SourceMgr::DiagHandlerTy DiagHandler;
650 void *DiagHandlerCtxt;
654 bool emitError(llvm::Twine Message) {
656 llvm::SMDiagnostic(
"", llvm::SourceMgr::DK_Error, Message.str()),
664 llvm::raw_ostream &OS,
665 llvm::SourceMgr::DiagHandlerTy DiagHandler,
666 void *DiagHandlerCtxt)
667 : M(TheModule), Writer(TheModule.Name, SourceFile), OS(OS),
668 DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),
669 ErrorOccured(
false) {}
671 void convertAvailability(
const AvailabilityItem &Availability,
674 CEI.
Unavailable = (Availability.Mode == APIAvailability::None);
679 if (!Availability.Msg.empty())
680 emitError(llvm::Twine(
"availability message for available API '") +
681 APIName +
"' will not be used");
685 void convertParams(
const ParamsSeq &Params,
FunctionInfo &OutInfo) {
686 for (
const auto &
P : Params) {
693 if (OutInfo.
Params.size() <=
P.Position)
694 OutInfo.
Params.resize(
P.Position + 1);
695 OutInfo.
Params[
P.Position] |= PI;
699 void convertNullability(
const NullabilitySeq &Nullability,
700 std::optional<NullabilityKind> ReturnNullability,
703 emitError(llvm::Twine(
"nullability info for '") + APIName +
708 bool audited =
false;
709 unsigned int idx = 1;
710 for (
const auto &N : Nullability)
712 audited =
Nullability.size() > 0 || ReturnNullability;
714 OutInfo.
addTypeInfo(0, ReturnNullability ? *ReturnNullability
715 : NullabilityKind::NonNull);
723 template <
typename T>
726 convertAvailability(Common.Availability, Info, APIName);
728 Info.
SwiftName = std::string(Common.SwiftName);
732 template <
typename T>
735 convertCommonEntity(Common, Info, APIName);
736 if (Common.SwiftBridge)
742 void convertMethod(
const Method &M,
ContextID ClassID, StringRef ClassName,
743 VersionTuple SwiftVersion) {
745 convertCommonEntity(M, MI, M.Selector);
748 bool takesArguments = M.Selector.ends_with(
":");
752 M.Selector.split(Args,
":", -1,
false);
753 if (!takesArguments && Args.size() > 1) {
754 emitError(
"selector '" + M.Selector +
"' is missing a ':' at the end");
760 Selector.NumArgs = !takesArguments ? 0 : Args.size();
766 if (M.FactoryAsInit != FactoryAsInitKind::Infer)
767 emitError(
"'FactoryAsInit' is no longer valid; use 'SwiftName' instead");
772 convertParams(M.Params, MI);
775 convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);
784 void convertContext(std::optional<ContextID> ParentContextID,
const Class &
C,
788 convertCommonType(
C, CI,
C.Name);
790 if (
C.AuditedForNullability)
792 if (
C.SwiftImportAsNonGeneric)
794 if (
C.SwiftObjCMembers)
798 Writer.
addObjCContext(ParentContextID,
C.Name, Kind, CI, SwiftVersion);
801 llvm::StringMap<std::pair<bool, bool>> KnownMethods;
802 for (
const auto &method :
C.Methods) {
806 : KnownMethods[method.Selector].second;
808 emitError(llvm::Twine(
"duplicate definition of method '") +
809 (IsInstanceMethod ?
"-" :
"+") +
"[" +
C.Name +
" " +
810 method.Selector +
"]'");
815 convertMethod(method, CtxID,
C.Name, SwiftVersion);
819 llvm::StringSet<> KnownInstanceProperties;
820 llvm::StringSet<> KnownClassProperties;
821 for (
const auto &Property :
C.Properties) {
824 !KnownInstanceProperties.insert(
Property.Name).second) {
825 emitError(llvm::Twine(
"duplicate definition of instance property '") +
831 !KnownClassProperties.insert(
Property.Name).second) {
832 emitError(llvm::Twine(
"duplicate definition of class property '") +
844 if (
Property.SwiftImportAsAccessors)
851 *
Property.Kind == MethodKind::Instance, PI,
860 void convertNamespaceContext(std::optional<ContextID> ParentContextID,
861 const Namespace &TheNamespace,
862 VersionTuple SwiftVersion) {
865 convertCommonEntity(TheNamespace, CI, TheNamespace.Name);
869 ContextKind::Namespace, CI, SwiftVersion);
871 convertTopLevelItems(
Context(CtxID, ContextKind::Namespace),
872 TheNamespace.Items, SwiftVersion);
875 void convertTopLevelItems(std::optional<Context> Ctx,
876 const TopLevelItems &TLItems,
877 VersionTuple SwiftVersion) {
878 std::optional<ContextID> CtxID =
879 Ctx ? std::optional(Ctx->id) :
std::nullopt;
882 llvm::StringSet<> KnownClasses;
883 for (
const auto &Class : TLItems.Classes) {
885 if (!KnownClasses.insert(
Class.Name).second) {
886 emitError(llvm::Twine(
"multiple definitions of class '") +
Class.Name +
891 convertContext(CtxID, Class, ContextKind::ObjCClass, SwiftVersion);
895 llvm::StringSet<> KnownProtocols;
896 for (
const auto &Protocol : TLItems.Protocols) {
898 if (!KnownProtocols.insert(
Protocol.Name).second) {
899 emitError(llvm::Twine(
"multiple definitions of protocol '") +
904 convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);
908 llvm::StringSet<> KnownNamespaces;
909 for (
const auto &Namespace : TLItems.Namespaces) {
911 if (!KnownNamespaces.insert(
Namespace.Name).second) {
912 emitError(llvm::Twine(
"multiple definitions of namespace '") +
917 convertNamespaceContext(CtxID, Namespace, SwiftVersion);
921 llvm::StringSet<> KnownGlobals;
922 for (
const auto &Global : TLItems.Globals) {
924 if (!KnownGlobals.insert(Global.Name).second) {
925 emitError(llvm::Twine(
"multiple definitions of global variable '") +
931 convertAvailability(Global.Availability, GVI, Global.Name);
933 GVI.
SwiftName = std::string(Global.SwiftName);
934 if (Global.Nullability)
936 GVI.
setType(std::string(Global.Type));
941 llvm::StringSet<> KnownFunctions;
942 for (
const auto &Function : TLItems.Functions) {
944 if (!KnownFunctions.insert(
Function.Name).second) {
945 emitError(llvm::Twine(
"multiple definitions of global function '") +
954 convertParams(
Function.Params, GFI);
963 llvm::StringSet<> KnownEnumConstants;
964 for (
const auto &EnumConstant : TLItems.EnumConstants) {
966 if (!KnownEnumConstants.insert(
EnumConstant.Name).second) {
967 emitError(llvm::Twine(
"multiple definitions of enumerator '") +
980 llvm::StringSet<> KnownTags;
981 for (
const auto &Tag : TLItems.Tags) {
983 if (!KnownTags.insert(Tag.Name).second) {
984 emitError(llvm::Twine(
"multiple definitions of tag '") + Tag.Name +
990 convertCommonType(Tag, TI, Tag.Name);
992 if ((Tag.SwiftRetainOp || Tag.SwiftReleaseOp) && !Tag.SwiftImportAs) {
993 emitError(llvm::Twine(
"should declare SwiftImportAs to use "
994 "SwiftRetainOp and SwiftReleaseOp (for ") +
998 if (Tag.SwiftReleaseOp.has_value() != Tag.SwiftRetainOp.has_value()) {
999 emitError(llvm::Twine(
"should declare both SwiftReleaseOp and "
1000 "SwiftRetainOp (for ") +
1005 if (Tag.SwiftImportAs)
1007 if (Tag.SwiftRetainOp)
1009 if (Tag.SwiftReleaseOp)
1012 if (Tag.EnumConvenienceKind) {
1013 if (Tag.EnumExtensibility) {
1015 llvm::Twine(
"cannot mix EnumKind and EnumExtensibility (for ") +
1020 emitError(llvm::Twine(
"cannot mix EnumKind and FlagEnum (for ") +
1024 switch (*Tag.EnumConvenienceKind) {
1025 case EnumConvenienceAliasKind::None:
1029 case EnumConvenienceAliasKind::CFEnum:
1033 case EnumConvenienceAliasKind::CFOptions:
1037 case EnumConvenienceAliasKind::CFClosedEnum:
1047 Writer.
addTag(Ctx, Tag.Name, TI, SwiftVersion);
1051 llvm::StringSet<> KnownTypedefs;
1052 for (
const auto &Typedef : TLItems.Typedefs) {
1054 if (!KnownTypedefs.insert(Typedef.Name).second) {
1055 emitError(llvm::Twine(
"multiple definitions of typedef '") +
1056 Typedef.Name +
"'");
1061 convertCommonType(Typedef, TInfo, Typedef.Name);
1064 Writer.
addTypedef(Ctx, Typedef.Name, TInfo, SwiftVersion);
1068 bool convertModule() {
1070 convertTopLevelItems( std::nullopt, M.TopLevel,
1074 for (
const auto &Versioned : M.SwiftVersions)
1075 convertTopLevelItems( std::nullopt, Versioned.Items,
1081 return ErrorOccured;
1087 llvm::raw_ostream &OS,
1088 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1089 void *DiagHandlerCtxt) {
1090 YAMLConverter
C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
1091 return C.convertModule();
1096 Diag.print(
nullptr, llvm::errs());
1101 llvm::raw_ostream &OS,
1102 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1103 void *DiagHandlerCtxt) {
1109 if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))
1112 return compile(TheModule, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
static void printDiagnostic(const llvm::SMDiagnostic &Diag, void *Context)
Simple diagnostic handler that prints diagnostics to standard error.
static bool compile(const Module &M, const FileEntry *SourceFile, llvm::raw_ostream &OS, llvm::SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines various enumerations that describe declaration and type specifiers.
Cached information about one file (either on disk or in the virtual file system).
Describes a module or submodule.
std::string Name
The name of this module.
void dump() const
Dump the contents of this module to the given output stream.
Smart pointer class that efficiently represents Objective-C method names.
The base class of the type hierarchy.
A class that writes API notes data to a binary representation that can be read by the APINotesReader.
void addObjCMethod(ContextID CtxID, ObjCSelectorRef Selector, bool IsInstanceMethod, const ObjCMethodInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific Objective-C method.
void addEnumConstant(llvm::StringRef Name, const EnumConstantInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about an enumerator.
void addGlobalFunction(std::optional< Context > Ctx, llvm::StringRef Name, const GlobalFunctionInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a global function.
void addObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstanceProperty, const ObjCPropertyInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific Objective-C property.
void addGlobalVariable(std::optional< Context > Ctx, llvm::StringRef Name, const GlobalVariableInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a global variable.
void addTypedef(std::optional< Context > Ctx, llvm::StringRef Name, const TypedefInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a typedef.
void writeToStream(llvm::raw_ostream &OS)
ContextID addObjCContext(std::optional< ContextID > ParentCtxID, llvm::StringRef Name, ContextKind Kind, const ObjCContextInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific Objective-C class or protocol or a C++ namespace.
void addTag(std::optional< Context > Ctx, llvm::StringRef Name, const TagInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a tag (struct/union/enum/C++ class).
Describes API notes data for any entity.
unsigned UnavailableInSwift
Whether this entity is marked unavailable in Swift.
unsigned Unavailable
Whether this entity is marked unavailable.
std::string SwiftName
Swift name of this entity.
void setSwiftPrivate(std::optional< bool > Private)
std::string UnavailableMsg
Message to use when this entity is unavailable.
Describes API notes for types.
void setNSErrorDomain(const std::optional< std::string > &Domain)
void setSwiftBridge(std::optional< std::string > SwiftType)
Opaque context ID used to refer to an Objective-C class or protocol or a C++ namespace.
Describes API notes data for an enumerator.
API notes for a function or method.
void addTypeInfo(unsigned index, NullabilityKind kind)
void setRetainCountConvention(std::optional< RetainCountConventionKind > Value)
std::vector< ParamInfo > Params
The function parameters.
unsigned NumAdjustedNullable
Number of types whose nullability is encoded with the NullabilityPayload.
std::string ResultType
The result type of this function, as a C type.
static unsigned getMaxNullabilityIndex()
unsigned NullabilityAudited
Whether the signature has been audited with respect to nullability.
Describes API notes data for a global function.
Describes API notes data for a global variable.
Describes API notes data for an Objective-C class or protocol.
void setSwiftObjCMembers(std::optional< bool > Value)
void setSwiftImportAsNonGeneric(std::optional< bool > Value)
void setDefaultNullability(NullabilityKind Kind)
Set the default nullability for properties and methods of this class.
Describes API notes data for an Objective-C method.
unsigned DesignatedInit
Whether this is a designated initializer of its class.
unsigned RequiredInit
Whether this is a required initializer.
Describes API notes data for an Objective-C property.
void setSwiftImportAsAccessors(std::optional< bool > Value)
Describes a function or method parameter.
void setNoEscape(std::optional< bool > Value)
void setRetainCountConvention(std::optional< RetainCountConventionKind > Value)
Describes API notes data for a tag.
std::optional< std::string > SwiftReleaseOp
std::optional< std::string > SwiftRetainOp
std::optional< std::string > SwiftImportAs
std::optional< EnumExtensibilityKind > EnumExtensibility
void setFlagEnum(std::optional< bool > Value)
Describes API notes data for a typedef.
std::optional< SwiftNewTypeKind > SwiftWrapper
void setNullabilityAudited(NullabilityKind kind)
void setType(const std::string &type)
RetainCountConventionKind
bool compileAPINotes(llvm::StringRef YAMLInput, const FileEntry *SourceFile, llvm::raw_ostream &OS, llvm::SourceMgr::DiagHandlerTy DiagHandler=nullptr, void *DiagHandlerCtxt=nullptr)
Converts API notes from YAML format to binary format.
SwiftNewTypeKind
The kind of a swift_wrapper/swift_newtype.
EnumExtensibilityKind
The payload for an enum_extensibility attribute.
bool parseAndDumpAPINotes(llvm::StringRef YI, llvm::raw_ostream &OS)
Parses the APINotes YAML content and writes the representation back to the specified stream.
The JSON file list parser is used to communicate input to InstallAPI.
NullabilityKind
Describes the nullability of a particular type.
@ Property
The type of a property.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
static void mapTopLevelItems(IO &IO, TopLevelItems &TLI)
YAML serialization mapping.
A temporary reference to an Objective-C selector, suitable for referencing selector data on the stack...
static void mapping(IO &IO, Class &C)
static void mapping(IO &IO, EnumConstant &EC)
static void mapping(IO &IO, Function &F)
static void mapping(IO &IO, GlobalVariable &GV)
static void mapping(IO &IO, Method &M)
static void mapping(IO &IO, Module &M)
static void mapping(IO &IO, Namespace &T)
static void mapping(IO &IO, Param &P)
static void mapping(IO &IO, Property &P)
static void mapping(IO &IO, Tag &T)
static void mapping(IO &IO, Typedef &T)
static void mapping(IO &IO, Versioned &V)
static void enumeration(IO &IO, APIAvailability &AA)
static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK)
static void enumeration(IO &IO, EnumExtensibilityKind &EEK)
static void enumeration(IO &IO, FactoryAsInitKind &FIK)
static void enumeration(IO &IO, MethodKind &MK)
static void enumeration(IO &IO, NullabilityKind &NK)
static void enumeration(IO &IO, RetainCountConventionKind &RCCK)
static void enumeration(IO &IO, SwiftNewTypeKind &SWK)