21#include "llvm/ADT/StringSet.h"
22#include "llvm/Support/SourceMgr.h"
23#include "llvm/Support/VersionTuple.h"
24#include "llvm/Support/YAMLTraits.h"
30using namespace api_notes;
33enum class APIAvailability {
42template <>
struct ScalarEnumerationTraits<APIAvailability> {
44 IO.enumCase(AA,
"none", APIAvailability::None);
45 IO.enumCase(AA,
"nonswift", APIAvailability::NonSwift);
46 IO.enumCase(AA,
"available", APIAvailability::Available);
53enum class MethodKind {
61template <>
struct ScalarEnumerationTraits<MethodKind> {
63 IO.enumCase(MK,
"Class", MethodKind::Class);
64 IO.enumCase(MK,
"Instance", MethodKind::Instance);
73 std::optional<bool> NoEscape =
false;
74 std::optional<bool> Lifetimebound =
false;
76 std::optional<RetainCountConventionKind> RetainCountConvention;
80typedef std::vector<Param> ParamsSeq;
83LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
90 IO.enumCase(NK,
"Nonnull", NullabilityKind::NonNull);
91 IO.enumCase(NK,
"Optional", NullabilityKind::Nullable);
92 IO.enumCase(NK,
"Unspecified", NullabilityKind::Unspecified);
93 IO.enumCase(NK,
"NullableResult", NullabilityKind::NullableResult);
96 IO.enumCase(NK,
"Scalar", NullabilityKind::Unspecified);
99 IO.enumCase(NK,
"N", NullabilityKind::NonNull);
100 IO.enumCase(NK,
"O", NullabilityKind::Nullable);
101 IO.enumCase(NK,
"U", NullabilityKind::Unspecified);
102 IO.enumCase(NK,
"S", NullabilityKind::Unspecified);
108 IO.enumCase(RCCK,
"none", RetainCountConventionKind::None);
109 IO.enumCase(RCCK,
"CFReturnsRetained",
110 RetainCountConventionKind::CFReturnsRetained);
111 IO.enumCase(RCCK,
"CFReturnsNotRetained",
112 RetainCountConventionKind::CFReturnsNotRetained);
113 IO.enumCase(RCCK,
"NSReturnsRetained",
114 RetainCountConventionKind::NSReturnsRetained);
115 IO.enumCase(RCCK,
"NSReturnsNotRetained",
116 RetainCountConventionKind::NSReturnsNotRetained);
120template <>
struct MappingTraits<Param> {
122 IO.mapRequired(
"Position",
P.Position);
123 IO.mapOptional(
"Nullability",
P.Nullability, std::nullopt);
124 IO.mapOptional(
"RetainCountConvention",
P.RetainCountConvention);
125 IO.mapOptional(
"NoEscape",
P.NoEscape);
126 IO.mapOptional(
"Lifetimebound",
P.Lifetimebound);
127 IO.mapOptional(
"Type",
P.Type, StringRef(
""));
134typedef std::vector<NullabilityKind> NullabilitySeq;
136struct AvailabilityItem {
137 APIAvailability Mode = APIAvailability::Available;
142enum class FactoryAsInitKind {
156 std::optional<NullabilityKind> NullabilityOfRet;
157 std::optional<RetainCountConventionKind> RetainCountConvention;
158 AvailabilityItem Availability;
159 std::optional<bool> SwiftPrivate;
161 FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
162 bool DesignatedInit =
false;
164 StringRef ResultType;
165 StringRef SwiftReturnOwnership;
168typedef std::vector<Method> MethodsSeq;
171LLVM_YAML_IS_SEQUENCE_VECTOR(Method)
175template <>
struct ScalarEnumerationTraits<FactoryAsInitKind> {
177 IO.enumCase(FIK,
"A", FactoryAsInitKind::Infer);
178 IO.enumCase(FIK,
"C", FactoryAsInitKind::AsClassMethod);
179 IO.enumCase(FIK,
"I", FactoryAsInitKind::AsInitializer);
183template <>
struct MappingTraits<
Method> {
185 IO.mapRequired(
"Selector", M.Selector);
186 IO.mapRequired(
"MethodKind", M.Kind);
187 IO.mapOptional(
"Parameters", M.Params);
188 IO.mapOptional(
"Nullability", M.Nullability);
189 IO.mapOptional(
"NullabilityOfRet", M.NullabilityOfRet, std::nullopt);
190 IO.mapOptional(
"RetainCountConvention", M.RetainCountConvention);
191 IO.mapOptional(
"Availability", M.Availability.Mode,
192 APIAvailability::Available);
193 IO.mapOptional(
"AvailabilityMsg", M.Availability.Msg, StringRef(
""));
194 IO.mapOptional(
"SwiftPrivate", M.SwiftPrivate);
195 IO.mapOptional(
"SwiftName", M.SwiftName, StringRef(
""));
196 IO.mapOptional(
"FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);
197 IO.mapOptional(
"DesignatedInit", M.DesignatedInit,
false);
198 IO.mapOptional(
"Required", M.Required,
false);
199 IO.mapOptional(
"ResultType", M.ResultType, StringRef(
""));
200 IO.mapOptional(
"SwiftReturnOwnership", M.SwiftReturnOwnership,
210 std::optional<MethodKind>
Kind;
212 AvailabilityItem Availability;
213 std::optional<bool> SwiftPrivate;
215 std::optional<bool> SwiftImportAsAccessors;
219typedef std::vector<Property> PropertiesSeq;
222LLVM_YAML_IS_SEQUENCE_VECTOR(Property)
228 IO.mapRequired(
"Name",
P.Name);
229 IO.mapOptional(
"PropertyKind",
P.Kind);
230 IO.mapOptional(
"Nullability",
P.Nullability, std::nullopt);
231 IO.mapOptional(
"Availability",
P.Availability.Mode,
232 APIAvailability::Available);
233 IO.mapOptional(
"AvailabilityMsg",
P.Availability.Msg, StringRef(
""));
234 IO.mapOptional(
"SwiftPrivate",
P.SwiftPrivate);
235 IO.mapOptional(
"SwiftName",
P.SwiftName, StringRef(
""));
236 IO.mapOptional(
"SwiftImportAsAccessors",
P.SwiftImportAsAccessors);
237 IO.mapOptional(
"Type",
P.Type, StringRef(
""));
246 bool AuditedForNullability =
false;
247 AvailabilityItem Availability;
248 std::optional<bool> SwiftPrivate;
250 std::optional<StringRef> SwiftBridge;
251 std::optional<StringRef> NSErrorDomain;
252 std::optional<bool> SwiftImportAsNonGeneric;
253 std::optional<bool> SwiftObjCMembers;
254 std::optional<std::string> SwiftConformance;
256 PropertiesSeq Properties;
259typedef std::vector<Class> ClassesSeq;
262LLVM_YAML_IS_SEQUENCE_VECTOR(Class)
266template <>
struct MappingTraits<
Class> {
268 IO.mapRequired(
"Name",
C.Name);
269 IO.mapOptional(
"AuditedForNullability",
C.AuditedForNullability,
false);
270 IO.mapOptional(
"Availability",
C.Availability.Mode,
271 APIAvailability::Available);
272 IO.mapOptional(
"AvailabilityMsg",
C.Availability.Msg, StringRef(
""));
273 IO.mapOptional(
"SwiftPrivate",
C.SwiftPrivate);
274 IO.mapOptional(
"SwiftName",
C.SwiftName, StringRef(
""));
275 IO.mapOptional(
"SwiftBridge",
C.SwiftBridge);
276 IO.mapOptional(
"NSErrorDomain",
C.NSErrorDomain);
277 IO.mapOptional(
"SwiftImportAsNonGeneric",
C.SwiftImportAsNonGeneric);
278 IO.mapOptional(
"SwiftObjCMembers",
C.SwiftObjCMembers);
279 IO.mapOptional(
"SwiftConformsTo",
C.SwiftConformance);
280 IO.mapOptional(
"Methods",
C.Methods);
281 IO.mapOptional(
"Properties",
C.Properties);
292 std::optional<NullabilityKind> NullabilityOfRet;
293 std::optional<api_notes::RetainCountConventionKind> RetainCountConvention;
294 AvailabilityItem Availability;
295 std::optional<bool> SwiftPrivate;
298 StringRef ResultType;
299 StringRef SwiftReturnOwnership;
302typedef std::vector<Function> FunctionsSeq;
305LLVM_YAML_IS_SEQUENCE_VECTOR(Function)
311 IO.mapRequired(
"Name", F.Name);
312 IO.mapOptional(
"Parameters", F.Params);
313 IO.mapOptional(
"Nullability", F.Nullability);
314 IO.mapOptional(
"NullabilityOfRet", F.NullabilityOfRet, std::nullopt);
315 IO.mapOptional(
"RetainCountConvention", F.RetainCountConvention);
316 IO.mapOptional(
"Availability", F.Availability.Mode,
317 APIAvailability::Available);
318 IO.mapOptional(
"AvailabilityMsg", F.Availability.Msg, StringRef(
""));
319 IO.mapOptional(
"SwiftPrivate", F.SwiftPrivate);
320 IO.mapOptional(
"SwiftName", F.SwiftName, StringRef(
""));
321 IO.mapOptional(
"ResultType", F.ResultType, StringRef(
""));
322 IO.mapOptional(
"SwiftReturnOwnership", F.SwiftReturnOwnership,
330struct GlobalVariable {
333 AvailabilityItem Availability;
334 std::optional<bool> SwiftPrivate;
339typedef std::vector<GlobalVariable> GlobalVariablesSeq;
342LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
346template <>
struct MappingTraits<GlobalVariable> {
347 static void mapping(IO &IO, GlobalVariable &GV) {
348 IO.mapRequired(
"Name", GV.Name);
349 IO.mapOptional(
"Nullability", GV.Nullability, std::nullopt);
350 IO.mapOptional(
"Availability", GV.Availability.Mode,
351 APIAvailability::Available);
352 IO.mapOptional(
"AvailabilityMsg", GV.Availability.Msg, StringRef(
""));
353 IO.mapOptional(
"SwiftPrivate", GV.SwiftPrivate);
354 IO.mapOptional(
"SwiftName", GV.SwiftName, StringRef(
""));
355 IO.mapOptional(
"Type", GV.Type, StringRef(
""));
364 AvailabilityItem Availability;
365 std::optional<bool> SwiftPrivate;
369typedef std::vector<EnumConstant> EnumConstantsSeq;
372LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
376template <>
struct MappingTraits<EnumConstant> {
377 static void mapping(IO &IO, EnumConstant &EC) {
378 IO.mapRequired(
"Name", EC.Name);
379 IO.mapOptional(
"Availability", EC.Availability.Mode,
380 APIAvailability::Available);
381 IO.mapOptional(
"AvailabilityMsg", EC.Availability.Msg, StringRef(
""));
382 IO.mapOptional(
"SwiftPrivate", EC.SwiftPrivate);
383 IO.mapOptional(
"SwiftName", EC.SwiftName, StringRef(
""));
391enum class EnumConvenienceAliasKind {
405template <>
struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
407 IO.enumCase(ECAK,
"none", EnumConvenienceAliasKind::None);
408 IO.enumCase(ECAK,
"CFEnum", EnumConvenienceAliasKind::CFEnum);
409 IO.enumCase(ECAK,
"NSEnum", EnumConvenienceAliasKind::CFEnum);
410 IO.enumCase(ECAK,
"CFOptions", EnumConvenienceAliasKind::CFOptions);
411 IO.enumCase(ECAK,
"NSOptions", EnumConvenienceAliasKind::CFOptions);
412 IO.enumCase(ECAK,
"CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
413 IO.enumCase(ECAK,
"NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
423 AvailabilityItem Availability;
424 std::optional<bool> SwiftPrivate;
429typedef std::vector<Field> FieldsSeq;
432LLVM_YAML_IS_SEQUENCE_VECTOR(Field)
436template <>
struct MappingTraits<Field> {
438 IO.mapRequired(
"Name", F.Name);
439 IO.mapOptional(
"Nullability", F.Nullability, std::nullopt);
440 IO.mapOptional(
"Availability", F.Availability.Mode,
441 APIAvailability::Available);
442 IO.mapOptional(
"AvailabilityMsg", F.Availability.Msg, StringRef(
""));
443 IO.mapOptional(
"SwiftPrivate", F.SwiftPrivate);
444 IO.mapOptional(
"SwiftName", F.SwiftName, StringRef(
""));
445 IO.mapOptional(
"Type", F.Type, StringRef(
""));
453typedef std::vector<Tag> TagsSeq;
457 AvailabilityItem Availability;
459 std::optional<bool> SwiftPrivate;
460 std::optional<StringRef> SwiftBridge;
461 std::optional<StringRef> NSErrorDomain;
462 std::optional<std::string> SwiftImportAs;
463 std::optional<std::string> SwiftRetainOp;
464 std::optional<std::string> SwiftReleaseOp;
465 std::optional<std::string> SwiftDestroyOp;
466 std::optional<std::string> SwiftDefaultOwnership;
467 std::optional<std::string> SwiftConformance;
468 std::optional<EnumExtensibilityKind> EnumExtensibility;
469 std::optional<bool> FlagEnum;
470 std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
471 std::optional<bool> SwiftCopyable;
472 std::optional<bool> SwiftEscapable;
473 FunctionsSeq Methods;
482LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
488 IO.enumCase(EEK,
"none", EnumExtensibilityKind::None);
489 IO.enumCase(EEK,
"open", EnumExtensibilityKind::Open);
490 IO.enumCase(EEK,
"closed", EnumExtensibilityKind::Closed);
494template <>
struct MappingTraits<
Tag> {
496 IO.mapRequired(
"Name",
T.Name);
497 IO.mapOptional(
"Availability",
T.Availability.Mode,
498 APIAvailability::Available);
499 IO.mapOptional(
"AvailabilityMsg",
T.Availability.Msg, StringRef(
""));
500 IO.mapOptional(
"SwiftPrivate",
T.SwiftPrivate);
501 IO.mapOptional(
"SwiftName",
T.SwiftName, StringRef(
""));
502 IO.mapOptional(
"SwiftBridge",
T.SwiftBridge);
503 IO.mapOptional(
"NSErrorDomain",
T.NSErrorDomain);
504 IO.mapOptional(
"SwiftImportAs",
T.SwiftImportAs);
505 IO.mapOptional(
"SwiftReleaseOp",
T.SwiftReleaseOp);
506 IO.mapOptional(
"SwiftRetainOp",
T.SwiftRetainOp);
507 IO.mapOptional(
"SwiftDestroyOp",
T.SwiftDestroyOp);
508 IO.mapOptional(
"SwiftDefaultOwnership",
T.SwiftDefaultOwnership);
509 IO.mapOptional(
"SwiftConformsTo",
T.SwiftConformance);
510 IO.mapOptional(
"EnumExtensibility",
T.EnumExtensibility);
511 IO.mapOptional(
"FlagEnum",
T.FlagEnum);
512 IO.mapOptional(
"EnumKind",
T.EnumConvenienceKind);
513 IO.mapOptional(
"SwiftCopyable",
T.SwiftCopyable);
514 IO.mapOptional(
"SwiftEscapable",
T.SwiftEscapable);
515 IO.mapOptional(
"Methods",
T.Methods);
516 IO.mapOptional(
"Fields",
T.Fields);
517 IO.mapOptional(
"Tags",
T.Tags);
526 AvailabilityItem Availability;
528 std::optional<bool> SwiftPrivate;
529 std::optional<StringRef> SwiftBridge;
530 std::optional<StringRef> NSErrorDomain;
531 std::optional<SwiftNewTypeKind> SwiftType;
532 std::optional<std::string> SwiftConformance;
535typedef std::vector<Typedef> TypedefsSeq;
538LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
544 IO.enumCase(SWK,
"none", SwiftNewTypeKind::None);
545 IO.enumCase(SWK,
"struct", SwiftNewTypeKind::Struct);
546 IO.enumCase(SWK,
"enum", SwiftNewTypeKind::Enum);
552 IO.mapRequired(
"Name",
T.Name);
553 IO.mapOptional(
"Availability",
T.Availability.Mode,
554 APIAvailability::Available);
555 IO.mapOptional(
"AvailabilityMsg",
T.Availability.Msg, StringRef(
""));
556 IO.mapOptional(
"SwiftPrivate",
T.SwiftPrivate);
557 IO.mapOptional(
"SwiftName",
T.SwiftName, StringRef(
""));
558 IO.mapOptional(
"SwiftBridge",
T.SwiftBridge);
559 IO.mapOptional(
"NSErrorDomain",
T.NSErrorDomain);
560 IO.mapOptional(
"SwiftWrapper",
T.SwiftType);
561 IO.mapOptional(
"SwiftConformsTo",
T.SwiftConformance);
569typedef std::vector<Namespace> NamespacesSeq;
571struct TopLevelItems {
573 ClassesSeq Protocols;
574 FunctionsSeq Functions;
575 GlobalVariablesSeq Globals;
576 EnumConstantsSeq EnumConstants;
578 TypedefsSeq Typedefs;
579 NamespacesSeq Namespaces;
586 IO.mapOptional(
"Classes", TLI.Classes);
587 IO.mapOptional(
"Protocols", TLI.Protocols);
588 IO.mapOptional(
"Functions", TLI.Functions);
589 IO.mapOptional(
"Globals", TLI.Globals);
590 IO.mapOptional(
"Enumerators", TLI.EnumConstants);
591 IO.mapOptional(
"Tags", TLI.Tags);
592 IO.mapOptional(
"Typedefs", TLI.Typedefs);
593 IO.mapOptional(
"Namespaces", TLI.Namespaces);
601 AvailabilityItem Availability;
603 std::optional<bool> SwiftPrivate;
608LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)
614 IO.mapRequired(
"Name",
T.Name);
615 IO.mapOptional(
"Availability",
T.Availability.Mode,
616 APIAvailability::Available);
617 IO.mapOptional(
"AvailabilityMsg",
T.Availability.Msg, StringRef(
""));
618 IO.mapOptional(
"SwiftPrivate",
T.SwiftPrivate);
619 IO.mapOptional(
"SwiftName",
T.SwiftName, StringRef(
""));
628 VersionTuple Version;
632typedef std::vector<Versioned> VersionedSeq;
635LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
639template <>
struct MappingTraits<Versioned> {
641 IO.mapRequired(
"Version",
V.Version);
651 AvailabilityItem Availability;
652 TopLevelItems TopLevel;
653 VersionedSeq SwiftVersions;
655 std::optional<bool> SwiftInferImportAsMember;
657#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
658 LLVM_DUMP_METHOD
void dump() ;
665template <>
struct MappingTraits<
Module> {
667 IO.mapRequired(
"Name", M.
Name);
668 IO.mapOptional(
"Availability", M.Availability.Mode,
669 APIAvailability::Available);
670 IO.mapOptional(
"AvailabilityMsg", M.Availability.Msg, StringRef(
""));
671 IO.mapOptional(
"SwiftInferImportAsMember", M.SwiftInferImportAsMember);
673 IO.mapOptional(
"SwiftVersions", M.SwiftVersions);
679#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
680LLVM_DUMP_METHOD
void Module::dump() {
681 llvm::yaml::Output OS(llvm::errs());
687bool parseAPINotes(StringRef YI,
Module &M, llvm::SourceMgr::DiagHandlerTy
Diag,
689 llvm::yaml::Input IS(YI,
nullptr,
Diag, DiagContext);
691 return static_cast<bool>(IS.error());
696 llvm::raw_ostream &OS) {
698 if (parseAPINotes(YI, M,
nullptr,
nullptr))
701 llvm::yaml::Output YOS(OS);
708using namespace api_notes;
713 llvm::raw_ostream &OS;
714 llvm::SourceMgr::DiagHandlerTy DiagHandler;
715 void *DiagHandlerCtxt;
719 bool emitError(llvm::Twine Message) {
721 llvm::SMDiagnostic(
"", llvm::SourceMgr::DK_Error, Message.str()),
729 llvm::raw_ostream &OS,
730 llvm::SourceMgr::DiagHandlerTy DiagHandler,
731 void *DiagHandlerCtxt)
732 : M(TheModule), Writer(TheModule.Name, SourceFile), OS(OS),
733 DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),
734 ErrorOccured(
false) {}
736 void convertAvailability(
const AvailabilityItem &Availability,
739 CEI.
Unavailable = (Availability.Mode == APIAvailability::None);
744 if (!Availability.Msg.empty())
745 emitError(llvm::Twine(
"availability message for available API '") +
746 APIName +
"' will not be used");
750 void convertParams(
const ParamsSeq &Params,
FunctionInfo &OutInfo,
751 std::optional<ParamInfo> &thisOrSelf) {
752 for (
const auto &
P : Params) {
760 if (
static_cast<int>(OutInfo.
Params.size()) <=
P.Position)
761 OutInfo.
Params.resize(
P.Position + 1);
762 if (
P.Position == -1)
764 else if (
P.Position >= 0)
765 OutInfo.
Params[
P.Position] |= PI;
767 emitError(
"invalid parameter position " + llvm::itostr(
P.Position));
771 void convertNullability(
const NullabilitySeq &Nullability,
772 std::optional<NullabilityKind> ReturnNullability,
775 emitError(llvm::Twine(
"nullability info for '") + APIName +
780 bool audited =
false;
781 unsigned int idx = 1;
782 for (
const auto &N : Nullability)
784 audited =
Nullability.size() > 0 || ReturnNullability;
787 ReturnNullability.value_or(NullabilityKind::NonNull));
795 template <
typename T>
798 convertAvailability(Common.Availability, Info, APIName);
800 Info.
SwiftName = std::string(Common.SwiftName);
804 template <
typename T>
807 convertCommonEntity(Common, Info, APIName);
808 if (Common.SwiftBridge)
811 if (
auto conformance = Common.SwiftConformance)
816 void convertMethod(
const Method &M,
ContextID ClassID, StringRef ClassName,
817 VersionTuple SwiftVersion) {
819 convertCommonEntity(M, MI, M.Selector);
822 bool takesArguments = M.Selector.ends_with(
":");
826 M.Selector.split(Args,
":", -1,
false);
827 if (!takesArguments && Args.size() > 1) {
828 emitError(
"selector '" + M.Selector +
"' is missing a ':' at the end");
834 Selector.NumArgs = !takesArguments ? 0 : Args.size();
840 if (M.FactoryAsInit != FactoryAsInitKind::Infer)
841 emitError(
"'FactoryAsInit' is no longer valid; use 'SwiftName' instead");
847 convertParams(M.Params, MI, MI.
Self);
850 convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);
859 template <
typename T>
861 convertAvailability(Entity.Availability, VI, Entity.Name);
863 VI.
SwiftName = std::string(Entity.SwiftName);
864 if (Entity.Nullability)
866 VI.
setType(std::string(Entity.Type));
869 void convertContext(std::optional<ContextID> ParentContextID,
const Class &
C,
873 convertCommonType(
C, CI,
C.Name);
875 if (
C.AuditedForNullability)
877 if (
C.SwiftImportAsNonGeneric)
879 if (
C.SwiftObjCMembers)
886 llvm::StringMap<std::pair<bool, bool>> KnownMethods;
887 for (
const auto &method :
C.Methods) {
891 : KnownMethods[method.Selector].second;
893 emitError(llvm::Twine(
"duplicate definition of method '") +
894 (IsInstanceMethod ?
"-" :
"+") +
"[" +
C.Name +
" " +
895 method.Selector +
"]'");
900 convertMethod(method, CtxID,
C.Name, SwiftVersion);
904 llvm::StringSet<> KnownInstanceProperties;
905 llvm::StringSet<> KnownClassProperties;
906 for (
const auto &Property :
C.Properties) {
909 !KnownInstanceProperties.insert(
Property.Name).second) {
910 emitError(llvm::Twine(
"duplicate definition of instance property '") +
916 !KnownClassProperties.insert(
Property.Name).second) {
917 emitError(llvm::Twine(
"duplicate definition of class property '") +
924 convertVariable(Property, PI);
925 if (
Property.SwiftImportAsAccessors)
931 *
Property.Kind == MethodKind::Instance, PI,
940 void convertNamespaceContext(std::optional<ContextID> ParentContextID,
941 const Namespace &TheNamespace,
942 VersionTuple SwiftVersion) {
945 convertCommonEntity(TheNamespace, CI, TheNamespace.Name);
948 Writer.
addContext(ParentContextID, TheNamespace.Name,
949 ContextKind::Namespace, CI, SwiftVersion);
951 convertTopLevelItems(
Context(CtxID, ContextKind::Namespace),
952 TheNamespace.Items, SwiftVersion);
955 template <
typename FuncOrMethodInfo>
956 void convertFunction(
const Function &Function, FuncOrMethodInfo &FI) {
958 FI.setSwiftPrivate(
Function.SwiftPrivate);
959 FI.SwiftName = std::string(
Function.SwiftName);
960 std::optional<ParamInfo>
This;
962 if constexpr (std::is_same_v<FuncOrMethodInfo, CXXMethodInfo>)
965 emitError(
"implicit instance parameter is only permitted on C++ and "
966 "Objective-C methods");
969 FI.ResultType = std::string(
Function.ResultType);
970 FI.SwiftReturnOwnership = std::string(
Function.SwiftReturnOwnership);
971 FI.setRetainCountConvention(
Function.RetainCountConvention);
974 void convertTagContext(std::optional<Context> ParentContext,
const Tag &
T,
975 VersionTuple SwiftVersion) {
977 std::optional<ContextID> ParentContextID =
978 ParentContext ? std::optional<ContextID>(ParentContext->id)
980 convertCommonType(
T, TI,
T.Name);
982 if ((
T.SwiftRetainOp ||
T.SwiftReleaseOp) && !
T.SwiftImportAs) {
983 emitError(llvm::Twine(
"should declare SwiftImportAs to use "
984 "SwiftRetainOp and SwiftReleaseOp (for ") +
988 if (
T.SwiftReleaseOp.has_value() !=
T.SwiftRetainOp.has_value()) {
989 emitError(llvm::Twine(
"should declare both SwiftReleaseOp and "
990 "SwiftRetainOp (for ") +
999 if (
T.SwiftReleaseOp)
1001 if (
T.SwiftDestroyOp)
1003 if (
T.SwiftDefaultOwnership)
1006 if (
T.SwiftCopyable)
1008 if (
T.SwiftEscapable)
1011 if (
T.EnumConvenienceKind) {
1012 if (
T.EnumExtensibility) {
1014 llvm::Twine(
"cannot mix EnumKind and EnumExtensibility (for ") +
1019 emitError(llvm::Twine(
"cannot mix EnumKind and FlagEnum (for ") +
1023 switch (*
T.EnumConvenienceKind) {
1024 case EnumConvenienceAliasKind::None:
1028 case EnumConvenienceAliasKind::CFEnum:
1032 case EnumConvenienceAliasKind::CFOptions:
1036 case EnumConvenienceAliasKind::CFClosedEnum:
1046 Writer.
addTag(ParentContext,
T.Name, TI, SwiftVersion);
1049 auto TagCtxID = Writer.
addContext(ParentContextID,
T.Name, ContextKind::Tag,
1051 Context TagCtx(TagCtxID, ContextKind::Tag);
1053 for (
const auto &Field :
T.Fields) {
1055 convertVariable(Field, FI);
1059 for (
const auto &CXXMethod :
T.Methods) {
1061 convertFunction(CXXMethod, MI);
1062 Writer.
addCXXMethod(TagCtxID, CXXMethod.Name, MI, SwiftVersion);
1066 for (
const auto &Tag :
T.Tags)
1067 convertTagContext(TagCtx, Tag, SwiftVersion);
1070 void convertTopLevelItems(std::optional<Context> Ctx,
1071 const TopLevelItems &TLItems,
1072 VersionTuple SwiftVersion) {
1073 std::optional<ContextID> CtxID =
1074 Ctx ? std::optional(Ctx->id) :
std::nullopt;
1077 llvm::StringSet<> KnownClasses;
1078 for (
const auto &Class : TLItems.Classes) {
1080 if (!KnownClasses.insert(
Class.Name).second) {
1081 emitError(llvm::Twine(
"multiple definitions of class '") +
Class.Name +
1086 convertContext(CtxID, Class, ContextKind::ObjCClass, SwiftVersion);
1090 llvm::StringSet<> KnownProtocols;
1091 for (
const auto &Protocol : TLItems.Protocols) {
1093 if (!KnownProtocols.insert(
Protocol.Name).second) {
1094 emitError(llvm::Twine(
"multiple definitions of protocol '") +
1099 convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);
1103 llvm::StringSet<> KnownNamespaces;
1104 for (
const auto &Namespace : TLItems.Namespaces) {
1106 if (!KnownNamespaces.insert(
Namespace.Name).second) {
1107 emitError(llvm::Twine(
"multiple definitions of namespace '") +
1112 convertNamespaceContext(CtxID, Namespace, SwiftVersion);
1116 llvm::StringSet<> KnownGlobals;
1117 for (
const auto &
Global : TLItems.Globals) {
1119 if (!KnownGlobals.insert(
Global.Name).second) {
1120 emitError(llvm::Twine(
"multiple definitions of global variable '") +
1126 convertVariable(
Global, GVI);
1131 llvm::StringSet<> KnownFunctions;
1132 for (
const auto &Function : TLItems.Functions) {
1134 if (!KnownFunctions.insert(
Function.Name).second) {
1135 emitError(llvm::Twine(
"multiple definitions of global function '") +
1141 convertFunction(Function, GFI);
1146 llvm::StringSet<> KnownEnumConstants;
1147 for (
const auto &EnumConstant : TLItems.EnumConstants) {
1149 if (!KnownEnumConstants.insert(
EnumConstant.Name).second) {
1150 emitError(llvm::Twine(
"multiple definitions of enumerator '") +
1163 llvm::StringSet<> KnownTags;
1164 for (
const auto &Tag : TLItems.Tags) {
1166 if (!KnownTags.insert(
Tag.Name).second) {
1167 emitError(llvm::Twine(
"multiple definitions of tag '") +
Tag.Name +
1172 convertTagContext(Ctx, Tag, SwiftVersion);
1176 llvm::StringSet<> KnownTypedefs;
1177 for (
const auto &Typedef : TLItems.Typedefs) {
1179 if (!KnownTypedefs.insert(
Typedef.Name).second) {
1180 emitError(llvm::Twine(
"multiple definitions of typedef '") +
1186 convertCommonType(Typedef, TInfo,
Typedef.Name);
1193 bool convertModule() {
1195 convertTopLevelItems( std::nullopt, M.TopLevel,
1199 for (
const auto &Versioned : M.SwiftVersions)
1200 convertTopLevelItems( std::nullopt, Versioned.Items,
1206 return ErrorOccured;
1212 llvm::raw_ostream &OS,
1213 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1214 void *DiagHandlerCtxt) {
1215 YAMLConverter
C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
1216 return C.convertModule();
1221 Diag.print(
nullptr, llvm::errs());
1226 llvm::raw_ostream &OS,
1227 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1228 void *DiagHandlerCtxt) {
1234 if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))
1237 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)
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
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.
a trap message and trap category.
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.
ContextID addContext(std::optional< ContextID > ParentCtxID, llvm::StringRef Name, ContextKind Kind, const ContextInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific Objective-C class or protocol or a C++ namespace.
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 addField(ContextID CtxID, llvm::StringRef Name, const FieldInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific C record field.
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)
void addCXXMethod(ContextID CtxID, llvm::StringRef Name, const CXXMethodInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific C++ method.
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 a C++ method.
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 setSwiftConformance(std::optional< std::string > conformance)
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 Objective-C class or protocol or a C++ namespace.
void setDefaultNullability(NullabilityKind Kind)
Set the default nullability for properties and methods of this class.
void setSwiftObjCMembers(std::optional< bool > Value)
void setSwiftImportAsNonGeneric(std::optional< bool > Value)
Describes API notes data for an enumerator.
Describes API notes data for a C/C++ record field.
API notes for a function or method.
std::string SwiftReturnOwnership
Ownership convention for return value.
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 method.
unsigned DesignatedInit
Whether this is a designated initializer of its class.
std::optional< ParamInfo > Self
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 setLifetimebound(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< std::string > SwiftDefaultOwnership
std::optional< EnumExtensibilityKind > EnumExtensibility
void setSwiftCopyable(std::optional< bool > Value)
std::optional< std::string > SwiftDestroyOp
void setSwiftEscapable(std::optional< bool > Value)
void setFlagEnum(std::optional< bool > Value)
Describes API notes data for a typedef.
std::optional< SwiftNewTypeKind > SwiftWrapper
API notes for a variable/property.
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.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
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, Field &F)
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)