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;
422 std::optional<bool> SwiftCopyable;
425typedef std::vector<Tag> TagsSeq;
428LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
434 IO.enumCase(EEK,
"none", EnumExtensibilityKind::None);
435 IO.enumCase(EEK,
"open", EnumExtensibilityKind::Open);
436 IO.enumCase(EEK,
"closed", EnumExtensibilityKind::Closed);
440template <>
struct MappingTraits<Tag> {
442 IO.mapRequired(
"Name",
T.Name);
443 IO.mapOptional(
"Availability",
T.Availability.Mode,
444 APIAvailability::Available);
445 IO.mapOptional(
"AvailabilityMsg",
T.Availability.Msg, StringRef(
""));
446 IO.mapOptional(
"SwiftPrivate",
T.SwiftPrivate);
447 IO.mapOptional(
"SwiftName",
T.SwiftName, StringRef(
""));
448 IO.mapOptional(
"SwiftBridge",
T.SwiftBridge);
449 IO.mapOptional(
"NSErrorDomain",
T.NSErrorDomain);
450 IO.mapOptional(
"SwiftImportAs",
T.SwiftImportAs);
451 IO.mapOptional(
"SwiftReleaseOp",
T.SwiftReleaseOp);
452 IO.mapOptional(
"SwiftRetainOp",
T.SwiftRetainOp);
453 IO.mapOptional(
"EnumExtensibility",
T.EnumExtensibility);
454 IO.mapOptional(
"FlagEnum",
T.FlagEnum);
455 IO.mapOptional(
"EnumKind",
T.EnumConvenienceKind);
456 IO.mapOptional(
"SwiftCopyable",
T.SwiftCopyable);
465 AvailabilityItem Availability;
467 std::optional<bool> SwiftPrivate;
468 std::optional<StringRef> SwiftBridge;
469 std::optional<StringRef> NSErrorDomain;
470 std::optional<SwiftNewTypeKind> SwiftType;
473typedef std::vector<Typedef> TypedefsSeq;
476LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
482 IO.enumCase(SWK,
"none", SwiftNewTypeKind::None);
483 IO.enumCase(SWK,
"struct", SwiftNewTypeKind::Struct);
484 IO.enumCase(SWK,
"enum", SwiftNewTypeKind::Enum);
488template <>
struct MappingTraits<Typedef> {
490 IO.mapRequired(
"Name",
T.Name);
491 IO.mapOptional(
"Availability",
T.Availability.Mode,
492 APIAvailability::Available);
493 IO.mapOptional(
"AvailabilityMsg",
T.Availability.Msg, StringRef(
""));
494 IO.mapOptional(
"SwiftPrivate",
T.SwiftPrivate);
495 IO.mapOptional(
"SwiftName",
T.SwiftName, StringRef(
""));
496 IO.mapOptional(
"SwiftBridge",
T.SwiftBridge);
497 IO.mapOptional(
"NSErrorDomain",
T.NSErrorDomain);
498 IO.mapOptional(
"SwiftWrapper",
T.SwiftType);
506typedef std::vector<Namespace> NamespacesSeq;
508struct TopLevelItems {
510 ClassesSeq Protocols;
511 FunctionsSeq Functions;
512 GlobalVariablesSeq Globals;
513 EnumConstantsSeq EnumConstants;
515 TypedefsSeq Typedefs;
516 NamespacesSeq Namespaces;
523 IO.mapOptional(
"Classes", TLI.Classes);
524 IO.mapOptional(
"Protocols", TLI.Protocols);
525 IO.mapOptional(
"Functions", TLI.Functions);
526 IO.mapOptional(
"Globals", TLI.Globals);
527 IO.mapOptional(
"Enumerators", TLI.EnumConstants);
528 IO.mapOptional(
"Tags", TLI.Tags);
529 IO.mapOptional(
"Typedefs", TLI.Typedefs);
530 IO.mapOptional(
"Namespaces", TLI.Namespaces);
538 AvailabilityItem Availability;
540 std::optional<bool> SwiftPrivate;
545LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)
551 IO.mapRequired(
"Name",
T.Name);
552 IO.mapOptional(
"Availability",
T.Availability.Mode,
553 APIAvailability::Available);
554 IO.mapOptional(
"AvailabilityMsg",
T.Availability.Msg, StringRef(
""));
555 IO.mapOptional(
"SwiftPrivate",
T.SwiftPrivate);
556 IO.mapOptional(
"SwiftName",
T.SwiftName, StringRef(
""));
565 VersionTuple Version;
569typedef std::vector<Versioned> VersionedSeq;
572LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
576template <>
struct MappingTraits<Versioned> {
578 IO.mapRequired(
"Version",
V.Version);
588 AvailabilityItem Availability;
589 TopLevelItems TopLevel;
590 VersionedSeq SwiftVersions;
592 std::optional<bool> SwiftInferImportAsMember;
594#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
595 LLVM_DUMP_METHOD
void dump() ;
602template <>
struct MappingTraits<
Module> {
604 IO.mapRequired(
"Name", M.
Name);
605 IO.mapOptional(
"Availability", M.Availability.Mode,
606 APIAvailability::Available);
607 IO.mapOptional(
"AvailabilityMsg", M.Availability.Msg, StringRef(
""));
608 IO.mapOptional(
"SwiftInferImportAsMember", M.SwiftInferImportAsMember);
610 IO.mapOptional(
"SwiftVersions", M.SwiftVersions);
616#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
617LLVM_DUMP_METHOD
void Module::dump() {
618 llvm::yaml::Output OS(llvm::errs());
624bool parseAPINotes(StringRef YI,
Module &M, llvm::SourceMgr::DiagHandlerTy
Diag,
626 llvm::yaml::Input IS(YI,
nullptr,
Diag, DiagContext);
628 return static_cast<bool>(IS.error());
633 llvm::raw_ostream &OS) {
635 if (parseAPINotes(YI, M,
nullptr,
nullptr))
638 llvm::yaml::Output YOS(OS);
645using namespace api_notes;
650 llvm::raw_ostream &OS;
651 llvm::SourceMgr::DiagHandlerTy DiagHandler;
652 void *DiagHandlerCtxt;
656 bool emitError(llvm::Twine Message) {
658 llvm::SMDiagnostic(
"", llvm::SourceMgr::DK_Error, Message.str()),
666 llvm::raw_ostream &OS,
667 llvm::SourceMgr::DiagHandlerTy DiagHandler,
668 void *DiagHandlerCtxt)
669 : M(TheModule), Writer(TheModule.Name, SourceFile), OS(OS),
670 DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),
671 ErrorOccured(
false) {}
673 void convertAvailability(
const AvailabilityItem &Availability,
676 CEI.
Unavailable = (Availability.Mode == APIAvailability::None);
681 if (!Availability.Msg.empty())
682 emitError(llvm::Twine(
"availability message for available API '") +
683 APIName +
"' will not be used");
687 void convertParams(
const ParamsSeq &Params,
FunctionInfo &OutInfo) {
688 for (
const auto &
P : Params) {
695 if (OutInfo.
Params.size() <=
P.Position)
696 OutInfo.
Params.resize(
P.Position + 1);
697 OutInfo.
Params[
P.Position] |= PI;
701 void convertNullability(
const NullabilitySeq &Nullability,
702 std::optional<NullabilityKind> ReturnNullability,
705 emitError(llvm::Twine(
"nullability info for '") + APIName +
710 bool audited =
false;
711 unsigned int idx = 1;
712 for (
const auto &N : Nullability)
714 audited =
Nullability.size() > 0 || ReturnNullability;
716 OutInfo.
addTypeInfo(0, ReturnNullability ? *ReturnNullability
717 : NullabilityKind::NonNull);
725 template <
typename T>
728 convertAvailability(Common.Availability, Info, APIName);
730 Info.
SwiftName = std::string(Common.SwiftName);
734 template <
typename T>
737 convertCommonEntity(Common, Info, APIName);
738 if (Common.SwiftBridge)
744 void convertMethod(
const Method &M,
ContextID ClassID, StringRef ClassName,
745 VersionTuple SwiftVersion) {
747 convertCommonEntity(M, MI, M.Selector);
750 bool takesArguments = M.Selector.ends_with(
":");
754 M.Selector.split(Args,
":", -1,
false);
755 if (!takesArguments && Args.size() > 1) {
756 emitError(
"selector '" + M.Selector +
"' is missing a ':' at the end");
762 Selector.NumArgs = !takesArguments ? 0 : Args.size();
768 if (M.FactoryAsInit != FactoryAsInitKind::Infer)
769 emitError(
"'FactoryAsInit' is no longer valid; use 'SwiftName' instead");
774 convertParams(M.Params, MI);
777 convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);
786 void convertContext(std::optional<ContextID> ParentContextID,
const Class &
C,
790 convertCommonType(
C, CI,
C.Name);
792 if (
C.AuditedForNullability)
794 if (
C.SwiftImportAsNonGeneric)
796 if (
C.SwiftObjCMembers)
800 Writer.
addObjCContext(ParentContextID,
C.Name, Kind, CI, SwiftVersion);
803 llvm::StringMap<std::pair<bool, bool>> KnownMethods;
804 for (
const auto &method :
C.Methods) {
808 : KnownMethods[method.Selector].second;
810 emitError(llvm::Twine(
"duplicate definition of method '") +
811 (IsInstanceMethod ?
"-" :
"+") +
"[" +
C.Name +
" " +
812 method.Selector +
"]'");
817 convertMethod(method, CtxID,
C.Name, SwiftVersion);
821 llvm::StringSet<> KnownInstanceProperties;
822 llvm::StringSet<> KnownClassProperties;
823 for (
const auto &Property :
C.Properties) {
826 !KnownInstanceProperties.insert(
Property.Name).second) {
827 emitError(llvm::Twine(
"duplicate definition of instance property '") +
833 !KnownClassProperties.insert(
Property.Name).second) {
834 emitError(llvm::Twine(
"duplicate definition of class property '") +
846 if (
Property.SwiftImportAsAccessors)
853 *
Property.Kind == MethodKind::Instance, PI,
862 void convertNamespaceContext(std::optional<ContextID> ParentContextID,
863 const Namespace &TheNamespace,
864 VersionTuple SwiftVersion) {
867 convertCommonEntity(TheNamespace, CI, TheNamespace.Name);
871 ContextKind::Namespace, CI, SwiftVersion);
873 convertTopLevelItems(
Context(CtxID, ContextKind::Namespace),
874 TheNamespace.Items, SwiftVersion);
877 void convertTopLevelItems(std::optional<Context> Ctx,
878 const TopLevelItems &TLItems,
879 VersionTuple SwiftVersion) {
880 std::optional<ContextID> CtxID =
881 Ctx ? std::optional(Ctx->id) :
std::nullopt;
884 llvm::StringSet<> KnownClasses;
885 for (
const auto &Class : TLItems.Classes) {
887 if (!KnownClasses.insert(
Class.Name).second) {
888 emitError(llvm::Twine(
"multiple definitions of class '") +
Class.Name +
893 convertContext(CtxID, Class, ContextKind::ObjCClass, SwiftVersion);
897 llvm::StringSet<> KnownProtocols;
898 for (
const auto &Protocol : TLItems.Protocols) {
900 if (!KnownProtocols.insert(
Protocol.Name).second) {
901 emitError(llvm::Twine(
"multiple definitions of protocol '") +
906 convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);
910 llvm::StringSet<> KnownNamespaces;
911 for (
const auto &Namespace : TLItems.Namespaces) {
913 if (!KnownNamespaces.insert(
Namespace.Name).second) {
914 emitError(llvm::Twine(
"multiple definitions of namespace '") +
919 convertNamespaceContext(CtxID, Namespace, SwiftVersion);
923 llvm::StringSet<> KnownGlobals;
924 for (
const auto &
Global : TLItems.Globals) {
926 if (!KnownGlobals.insert(
Global.Name).second) {
927 emitError(llvm::Twine(
"multiple definitions of global variable '") +
933 convertAvailability(
Global.Availability, GVI,
Global.Name);
943 llvm::StringSet<> KnownFunctions;
944 for (
const auto &Function : TLItems.Functions) {
946 if (!KnownFunctions.insert(
Function.Name).second) {
947 emitError(llvm::Twine(
"multiple definitions of global function '") +
956 convertParams(
Function.Params, GFI);
965 llvm::StringSet<> KnownEnumConstants;
966 for (
const auto &EnumConstant : TLItems.EnumConstants) {
968 if (!KnownEnumConstants.insert(
EnumConstant.Name).second) {
969 emitError(llvm::Twine(
"multiple definitions of enumerator '") +
982 llvm::StringSet<> KnownTags;
983 for (
const auto &Tag : TLItems.Tags) {
985 if (!KnownTags.insert(Tag.Name).second) {
986 emitError(llvm::Twine(
"multiple definitions of tag '") + Tag.Name +
992 convertCommonType(Tag, TI, Tag.Name);
994 if ((Tag.SwiftRetainOp || Tag.SwiftReleaseOp) && !Tag.SwiftImportAs) {
995 emitError(llvm::Twine(
"should declare SwiftImportAs to use "
996 "SwiftRetainOp and SwiftReleaseOp (for ") +
1000 if (Tag.SwiftReleaseOp.has_value() != Tag.SwiftRetainOp.has_value()) {
1001 emitError(llvm::Twine(
"should declare both SwiftReleaseOp and "
1002 "SwiftRetainOp (for ") +
1007 if (Tag.SwiftImportAs)
1009 if (Tag.SwiftRetainOp)
1011 if (Tag.SwiftReleaseOp)
1014 if (Tag.SwiftCopyable)
1017 if (Tag.EnumConvenienceKind) {
1018 if (Tag.EnumExtensibility) {
1020 llvm::Twine(
"cannot mix EnumKind and EnumExtensibility (for ") +
1025 emitError(llvm::Twine(
"cannot mix EnumKind and FlagEnum (for ") +
1029 switch (*Tag.EnumConvenienceKind) {
1030 case EnumConvenienceAliasKind::None:
1034 case EnumConvenienceAliasKind::CFEnum:
1038 case EnumConvenienceAliasKind::CFOptions:
1042 case EnumConvenienceAliasKind::CFClosedEnum:
1052 Writer.
addTag(Ctx, Tag.Name, TI, SwiftVersion);
1056 llvm::StringSet<> KnownTypedefs;
1057 for (
const auto &Typedef : TLItems.Typedefs) {
1059 if (!KnownTypedefs.insert(Typedef.Name).second) {
1060 emitError(llvm::Twine(
"multiple definitions of typedef '") +
1061 Typedef.Name +
"'");
1066 convertCommonType(Typedef, TInfo, Typedef.Name);
1069 Writer.
addTypedef(Ctx, Typedef.Name, TInfo, SwiftVersion);
1073 bool convertModule() {
1075 convertTopLevelItems( std::nullopt, M.TopLevel,
1079 for (
const auto &Versioned : M.SwiftVersions)
1080 convertTopLevelItems( std::nullopt, Versioned.Items,
1086 return ErrorOccured;
1092 llvm::raw_ostream &OS,
1093 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1094 void *DiagHandlerCtxt) {
1095 YAMLConverter
C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
1096 return C.convertModule();
1101 Diag.print(
nullptr, llvm::errs());
1106 llvm::raw_ostream &OS,
1107 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1108 void *DiagHandlerCtxt) {
1114 if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))
1117 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 setSwiftCopyable(std::optional< bool > Value)
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.
const FunctionProtoType * T
@ Class
The "class" keyword introduces the elaborated-type-specifier.
static void mapTopLevelItems(IO &IO, TopLevelItems &TLI)
Diagnostic wrappers for TextAPI types for error reporting.
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)