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.endswith(
":");
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.
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.
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)