21#include "llvm/ADT/StringSet.h"
22#include "llvm/Support/SourceMgr.h"
23#include "llvm/Support/VersionTuple.h"
24#include "llvm/Support/YAMLTraits.h"
45enum class APIAvailability {
54template <>
struct ScalarEnumerationTraits<APIAvailability> {
56 IO.enumCase(AA,
"none", APIAvailability::None);
57 IO.enumCase(AA,
"nonswift", APIAvailability::NonSwift);
58 IO.enumCase(AA,
"available", APIAvailability::Available);
65enum class MethodKind {
73template <>
struct ScalarEnumerationTraits<MethodKind> {
75 IO.enumCase(MK,
"Class", MethodKind::Class);
76 IO.enumCase(MK,
"Instance", MethodKind::Instance);
85 std::optional<bool> NoEscape =
false;
86 std::optional<bool> Lifetimebound =
false;
87 std::optional<NullabilityKind> Nullability;
88 std::optional<RetainCountConventionKind> RetainCountConvention;
92typedef std::vector<Param> ParamsSeq;
95LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
121 IO.enumCase(RCCK,
"CFReturnsRetained",
123 IO.enumCase(RCCK,
"CFReturnsNotRetained",
125 IO.enumCase(RCCK,
"NSReturnsRetained",
127 IO.enumCase(RCCK,
"NSReturnsNotRetained",
132template <>
struct MappingTraits<Param> {
134 IO.mapRequired(
"Position", P.Position);
135 IO.mapOptional(
"Nullability", P.Nullability, std::nullopt);
136 IO.mapOptional(
"RetainCountConvention", P.RetainCountConvention);
137 IO.mapOptional(
"NoEscape", P.NoEscape);
138 IO.mapOptional(
"Lifetimebound", P.Lifetimebound);
139 IO.mapOptional(
"Type", P.Type, StringRef(
""));
146typedef std::vector<NullabilityKind> NullabilitySeq;
148struct AvailabilityItem {
149 APIAvailability Mode = APIAvailability::Available;
154enum class FactoryAsInitKind {
167 NullabilitySeq Nullability;
168 std::optional<NullabilityKind> NullabilityOfRet;
169 std::optional<RetainCountConventionKind> RetainCountConvention;
170 AvailabilityItem Availability;
171 std::optional<bool> SwiftPrivate;
173 FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
174 bool DesignatedInit =
false;
175 bool Required =
false;
176 StringRef ResultType;
177 StringRef SwiftReturnOwnership;
181typedef std::vector<Method> MethodsSeq;
184LLVM_YAML_IS_SEQUENCE_VECTOR(Method)
188template <>
struct ScalarEnumerationTraits<FactoryAsInitKind> {
190 IO.enumCase(FIK,
"A", FactoryAsInitKind::Infer);
191 IO.enumCase(FIK,
"C", FactoryAsInitKind::AsClassMethod);
192 IO.enumCase(FIK,
"I", FactoryAsInitKind::AsInitializer);
196template <>
struct MappingTraits<Method> {
198 IO.mapRequired(
"Selector", M.Selector);
199 IO.mapRequired(
"MethodKind", M.Kind);
200 IO.mapOptional(
"Parameters", M.Params);
201 IO.mapOptional(
"Nullability", M.Nullability);
202 IO.mapOptional(
"NullabilityOfRet", M.NullabilityOfRet, std::nullopt);
203 IO.mapOptional(
"RetainCountConvention", M.RetainCountConvention);
204 IO.mapOptional(
"Availability", M.Availability.Mode,
205 APIAvailability::Available);
206 IO.mapOptional(
"AvailabilityMsg", M.Availability.Msg, StringRef(
""));
207 IO.mapOptional(
"SwiftPrivate", M.SwiftPrivate);
208 IO.mapOptional(
"SwiftName", M.SwiftName, StringRef(
""));
209 IO.mapOptional(
"FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);
210 IO.mapOptional(
"DesignatedInit", M.DesignatedInit,
false);
211 IO.mapOptional(
"Required", M.Required,
false);
212 IO.mapOptional(
"ResultType", M.ResultType, StringRef(
""));
213 IO.mapOptional(
"SwiftReturnOwnership", M.SwiftReturnOwnership,
224 std::optional<MethodKind> Kind;
225 std::optional<NullabilityKind> Nullability;
226 AvailabilityItem Availability;
227 std::optional<bool> SwiftPrivate;
229 std::optional<bool> SwiftImportAsAccessors;
234typedef std::vector<Property> PropertiesSeq;
237LLVM_YAML_IS_SEQUENCE_VECTOR(Property)
241template <>
struct MappingTraits<Property> {
243 IO.mapRequired(
"Name", P.Name);
244 IO.mapOptional(
"PropertyKind", P.Kind);
245 IO.mapOptional(
"Nullability", P.Nullability, std::nullopt);
246 IO.mapOptional(
"Availability", P.Availability.Mode,
247 APIAvailability::Available);
248 IO.mapOptional(
"AvailabilityMsg", P.Availability.Msg, StringRef(
""));
249 IO.mapOptional(
"SwiftPrivate", P.SwiftPrivate);
250 IO.mapOptional(
"SwiftName", P.SwiftName, StringRef(
""));
251 IO.mapOptional(
"SwiftImportAsAccessors", P.SwiftImportAsAccessors);
252 IO.mapOptional(
"Type", P.Type, StringRef(
""));
262 bool AuditedForNullability =
false;
263 AvailabilityItem Availability;
264 std::optional<bool> SwiftPrivate;
266 std::optional<StringRef> SwiftBridge;
267 std::optional<StringRef> NSErrorDomain;
268 std::optional<bool> SwiftImportAsNonGeneric;
269 std::optional<bool> SwiftObjCMembers;
270 std::optional<std::string> SwiftConformance;
272 PropertiesSeq Properties;
276typedef std::vector<Class> ClassesSeq;
279LLVM_YAML_IS_SEQUENCE_VECTOR(Class)
283template <>
struct MappingTraits<Class> {
285 IO.mapRequired(
"Name",
C.Name);
286 IO.mapOptional(
"AuditedForNullability",
C.AuditedForNullability,
false);
287 IO.mapOptional(
"Availability",
C.Availability.Mode,
288 APIAvailability::Available);
289 IO.mapOptional(
"AvailabilityMsg",
C.Availability.Msg, StringRef(
""));
290 IO.mapOptional(
"SwiftPrivate",
C.SwiftPrivate);
291 IO.mapOptional(
"SwiftName",
C.SwiftName, StringRef(
""));
292 IO.mapOptional(
"SwiftBridge",
C.SwiftBridge);
293 IO.mapOptional(
"NSErrorDomain",
C.NSErrorDomain);
294 IO.mapOptional(
"SwiftImportAsNonGeneric",
C.SwiftImportAsNonGeneric);
295 IO.mapOptional(
"SwiftObjCMembers",
C.SwiftObjCMembers);
296 IO.mapOptional(
"SwiftConformsTo",
C.SwiftConformance);
297 IO.mapOptional(
"Methods",
C.Methods);
298 IO.mapOptional(
"Properties",
C.Properties);
309 NullabilitySeq Nullability;
310 std::optional<NullabilityKind> NullabilityOfRet;
311 std::optional<api_notes::RetainCountConventionKind> RetainCountConvention;
312 AvailabilityItem Availability;
313 std::optional<bool> SwiftPrivate;
316 StringRef ResultType;
317 StringRef SwiftReturnOwnership;
321typedef std::vector<Function> FunctionsSeq;
324LLVM_YAML_IS_SEQUENCE_VECTOR(Function)
328template <>
struct MappingTraits<Function> {
330 IO.mapRequired(
"Name", F.Name);
331 IO.mapOptional(
"Parameters", F.Params);
332 IO.mapOptional(
"Nullability", F.Nullability);
333 IO.mapOptional(
"NullabilityOfRet", F.NullabilityOfRet, std::nullopt);
334 IO.mapOptional(
"RetainCountConvention", F.RetainCountConvention);
335 IO.mapOptional(
"Availability", F.Availability.Mode,
336 APIAvailability::Available);
337 IO.mapOptional(
"AvailabilityMsg", F.Availability.Msg, StringRef(
""));
338 IO.mapOptional(
"SwiftPrivate", F.SwiftPrivate);
339 IO.mapOptional(
"SwiftName", F.SwiftName, StringRef(
""));
340 IO.mapOptional(
"ResultType", F.ResultType, StringRef(
""));
341 IO.mapOptional(
"SwiftReturnOwnership", F.SwiftReturnOwnership,
350struct GlobalVariable {
352 std::optional<NullabilityKind> Nullability;
353 AvailabilityItem Availability;
354 std::optional<bool> SwiftPrivate;
360typedef std::vector<GlobalVariable> GlobalVariablesSeq;
363LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
367template <>
struct MappingTraits<GlobalVariable> {
368 static void mapping(IO &IO, GlobalVariable &GV) {
369 IO.mapRequired(
"Name", GV.Name);
370 IO.mapOptional(
"Nullability", GV.Nullability, std::nullopt);
371 IO.mapOptional(
"Availability", GV.Availability.Mode,
372 APIAvailability::Available);
373 IO.mapOptional(
"AvailabilityMsg", GV.Availability.Msg, StringRef(
""));
374 IO.mapOptional(
"SwiftPrivate", GV.SwiftPrivate);
375 IO.mapOptional(
"SwiftName", GV.SwiftName, StringRef(
""));
376 IO.mapOptional(
"Type", GV.Type, StringRef(
""));
386 AvailabilityItem Availability;
387 std::optional<bool> SwiftPrivate;
392typedef std::vector<EnumConstant> EnumConstantsSeq;
395LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
399template <>
struct MappingTraits<EnumConstant> {
400 static void mapping(IO &IO, EnumConstant &EC) {
401 IO.mapRequired(
"Name", EC.Name);
402 IO.mapOptional(
"Availability", EC.Availability.Mode,
403 APIAvailability::Available);
404 IO.mapOptional(
"AvailabilityMsg", EC.Availability.Msg, StringRef(
""));
405 IO.mapOptional(
"SwiftPrivate", EC.SwiftPrivate);
406 IO.mapOptional(
"SwiftName", EC.SwiftName, StringRef(
""));
415enum class EnumConvenienceAliasKind {
429template <>
struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
431 IO.enumCase(ECAK,
"none", EnumConvenienceAliasKind::None);
432 IO.enumCase(ECAK,
"CFEnum", EnumConvenienceAliasKind::CFEnum);
433 IO.enumCase(ECAK,
"NSEnum", EnumConvenienceAliasKind::CFEnum);
434 IO.enumCase(ECAK,
"CFOptions", EnumConvenienceAliasKind::CFOptions);
435 IO.enumCase(ECAK,
"NSOptions", EnumConvenienceAliasKind::CFOptions);
436 IO.enumCase(ECAK,
"CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
437 IO.enumCase(ECAK,
"NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
446 std::optional<NullabilityKind> Nullability;
447 AvailabilityItem Availability;
448 std::optional<bool> SwiftPrivate;
454typedef std::vector<Field> FieldsSeq;
457LLVM_YAML_IS_SEQUENCE_VECTOR(Field)
461template <>
struct MappingTraits<Field> {
463 IO.mapRequired(
"Name", F.Name);
464 IO.mapOptional(
"Nullability", F.Nullability, std::nullopt);
465 IO.mapOptional(
"Availability", F.Availability.Mode,
466 APIAvailability::Available);
467 IO.mapOptional(
"AvailabilityMsg", F.Availability.Msg, StringRef(
""));
468 IO.mapOptional(
"SwiftPrivate", F.SwiftPrivate);
469 IO.mapOptional(
"SwiftName", F.SwiftName, StringRef(
""));
470 IO.mapOptional(
"Type", F.Type, StringRef(
""));
479typedef std::vector<Tag> TagsSeq;
483 AvailabilityItem Availability;
485 std::optional<bool> SwiftPrivate;
486 std::optional<StringRef> SwiftBridge;
487 std::optional<StringRef> NSErrorDomain;
488 std::optional<std::string> SwiftImportAs;
489 std::optional<std::string> SwiftRetainOp;
490 std::optional<std::string> SwiftReleaseOp;
491 std::optional<std::string> SwiftDestroyOp;
492 std::optional<std::string> SwiftDefaultOwnership;
493 std::optional<std::string> SwiftConformance;
494 std::optional<EnumExtensibilityKind> EnumExtensibility;
495 std::optional<bool> FlagEnum;
496 std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
497 std::optional<bool> SwiftCopyable;
498 std::optional<bool> SwiftEscapable;
500 FunctionsSeq Methods;
509LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
521template <>
struct MappingTraits<Tag> {
523 IO.mapRequired(
"Name",
T.Name);
524 IO.mapOptional(
"Availability",
T.Availability.Mode,
525 APIAvailability::Available);
526 IO.mapOptional(
"AvailabilityMsg",
T.Availability.Msg, StringRef(
""));
527 IO.mapOptional(
"SwiftPrivate",
T.SwiftPrivate);
528 IO.mapOptional(
"SwiftName",
T.SwiftName, StringRef(
""));
529 IO.mapOptional(
"SwiftBridge",
T.SwiftBridge);
530 IO.mapOptional(
"NSErrorDomain",
T.NSErrorDomain);
531 IO.mapOptional(
"SwiftImportAs",
T.SwiftImportAs);
532 IO.mapOptional(
"SwiftReleaseOp",
T.SwiftReleaseOp);
533 IO.mapOptional(
"SwiftRetainOp",
T.SwiftRetainOp);
534 IO.mapOptional(
"SwiftDestroyOp",
T.SwiftDestroyOp);
535 IO.mapOptional(
"SwiftDefaultOwnership",
T.SwiftDefaultOwnership);
536 IO.mapOptional(
"SwiftConformsTo",
T.SwiftConformance);
537 IO.mapOptional(
"EnumExtensibility",
T.EnumExtensibility);
538 IO.mapOptional(
"FlagEnum",
T.FlagEnum);
539 IO.mapOptional(
"EnumKind",
T.EnumConvenienceKind);
540 IO.mapOptional(
"SwiftCopyable",
T.SwiftCopyable);
541 IO.mapOptional(
"SwiftEscapable",
T.SwiftEscapable);
542 IO.mapOptional(
"Methods",
T.Methods);
543 IO.mapOptional(
"Fields",
T.Fields);
544 IO.mapOptional(
"Tags",
T.Tags);
554 AvailabilityItem Availability;
556 std::optional<bool> SwiftPrivate;
557 std::optional<StringRef> SwiftBridge;
558 std::optional<StringRef> NSErrorDomain;
559 std::optional<SwiftNewTypeKind> SwiftType;
560 std::optional<std::string> SwiftConformance;
564typedef std::vector<Typedef> TypedefsSeq;
567LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
579template <>
struct MappingTraits<Typedef> {
581 IO.mapRequired(
"Name",
T.Name);
582 IO.mapOptional(
"Availability",
T.Availability.Mode,
583 APIAvailability::Available);
584 IO.mapOptional(
"AvailabilityMsg",
T.Availability.Msg, StringRef(
""));
585 IO.mapOptional(
"SwiftPrivate",
T.SwiftPrivate);
586 IO.mapOptional(
"SwiftName",
T.SwiftName, StringRef(
""));
587 IO.mapOptional(
"SwiftBridge",
T.SwiftBridge);
588 IO.mapOptional(
"NSErrorDomain",
T.NSErrorDomain);
589 IO.mapOptional(
"SwiftWrapper",
T.SwiftType);
590 IO.mapOptional(
"SwiftConformsTo",
T.SwiftConformance);
598typedef std::vector<Namespace> NamespacesSeq;
600struct TopLevelItems {
602 ClassesSeq Protocols;
603 FunctionsSeq Functions;
604 GlobalVariablesSeq Globals;
605 EnumConstantsSeq EnumConstants;
607 TypedefsSeq Typedefs;
608 NamespacesSeq Namespaces;
615 IO.mapOptional(
"Classes", TLI.Classes);
616 IO.mapOptional(
"Protocols", TLI.Protocols);
617 IO.mapOptional(
"Functions", TLI.Functions);
618 IO.mapOptional(
"Globals", TLI.Globals);
619 IO.mapOptional(
"Enumerators", TLI.EnumConstants);
620 IO.mapOptional(
"Tags", TLI.Tags);
621 IO.mapOptional(
"Typedefs", TLI.Typedefs);
622 IO.mapOptional(
"Namespaces", TLI.Namespaces);
630 AvailabilityItem Availability;
632 std::optional<bool> SwiftPrivate;
638LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)
642template <>
struct MappingTraits<Namespace> {
644 IO.mapRequired(
"Name",
T.Name);
645 IO.mapOptional(
"Availability",
T.Availability.Mode,
646 APIAvailability::Available);
647 IO.mapOptional(
"AvailabilityMsg",
T.Availability.Msg, StringRef(
""));
648 IO.mapOptional(
"SwiftPrivate",
T.SwiftPrivate);
649 IO.mapOptional(
"SwiftName",
T.SwiftName, StringRef(
""));
658 VersionTuple Version;
662typedef std::vector<Versioned> VersionedSeq;
665LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
669template <>
struct MappingTraits<Versioned> {
671 IO.mapRequired(
"Version",
V.Version);
681 AvailabilityItem Availability;
682 TopLevelItems TopLevel;
683 VersionedSeq SwiftVersions;
685 std::optional<bool> SwiftInferImportAsMember;
687#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
688 LLVM_DUMP_METHOD
void dump() ;
695template <>
struct MappingTraits<
Module> {
697 IO.mapRequired(
"Name", M.
Name);
698 IO.mapOptional(
"Availability", M.Availability.Mode,
699 APIAvailability::Available);
700 IO.mapOptional(
"AvailabilityMsg", M.Availability.Msg, StringRef(
""));
701 IO.mapOptional(
"SwiftInferImportAsMember", M.SwiftInferImportAsMember);
703 IO.mapOptional(
"SwiftVersions", M.SwiftVersions);
709#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
711 llvm::yaml::Output OS(llvm::errs());
717bool parseAPINotes(StringRef YI,
Module &M, llvm::SourceMgr::DiagHandlerTy
Diag,
719 llvm::yaml::Input IS(YI,
nullptr,
Diag, DiagContext);
721 return static_cast<bool>(IS.error());
726 llvm::raw_ostream &OS) {
728 if (parseAPINotes(YI, M,
nullptr,
nullptr))
731 llvm::yaml::Output YOS(OS);
742 APINotesWriter Writer;
743 llvm::raw_ostream &
OS;
744 llvm::SourceMgr::DiagHandlerTy DiagHandler;
745 void *DiagHandlerCtxt;
749 bool emitError(llvm::Twine Message) {
751 llvm::SMDiagnostic(
"", llvm::SourceMgr::DK_Error,
Message.str()),
758 YAMLConverter(
const Module &TheModule,
const FileEntry *SourceFile,
759 llvm::raw_ostream &OS,
760 llvm::SourceMgr::DiagHandlerTy DiagHandler,
761 void *DiagHandlerCtxt)
762 : M(TheModule), Writer(TheModule.Name, SourceFile),
OS(
OS),
763 DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),
764 ErrorOccured(
false) {}
766 void convertAvailability(
const AvailabilityItem &Availability,
767 CommonEntityInfo &CEI, llvm::StringRef APIName) {
769 CEI.
Unavailable = (Availability.Mode == APIAvailability::None);
774 if (!Availability.Msg.empty())
775 emitError(llvm::Twine(
"availability message for available API '") +
776 APIName +
"' will not be used");
780 void convertParams(
const ParamsSeq &Params, FunctionInfo &OutInfo,
781 std::optional<ParamInfo> &thisOrSelf) {
782 for (
const auto &P : Params) {
788 PI.
setType(std::string(P.Type));
790 if (
static_cast<int>(OutInfo.
Params.size()) <= P.Position)
791 OutInfo.
Params.resize(P.Position + 1);
792 if (P.Position == -1)
794 else if (P.Position >= 0)
795 OutInfo.
Params[P.Position] |= PI;
797 emitError(
"invalid parameter position " + llvm::itostr(P.Position));
801 void convertNullability(
const NullabilitySeq &Nullability,
802 std::optional<NullabilityKind> ReturnNullability,
803 FunctionInfo &OutInfo, llvm::StringRef APIName) {
805 emitError(llvm::Twine(
"nullability info for '") + APIName +
810 bool audited =
false;
811 unsigned int idx = 1;
812 for (
const auto &N : Nullability)
814 audited =
Nullability.size() > 0 || ReturnNullability;
817 ReturnNullability.value_or(NullabilityKind::NonNull));
825 template <
typename T>
826 void convertCommonEntity(
const T &Common, CommonEntityInfo &Info,
828 convertAvailability(Common.Availability, Info, APIName);
830 if (Common.SafetyKind != SwiftSafetyKind::None)
832 Info.
SwiftName = std::string(Common.SwiftName);
836 template <
typename T>
837 void convertCommonType(
const T &Common, CommonTypeInfo &Info,
839 convertCommonEntity(Common, Info, APIName);
840 if (Common.SwiftBridge)
843 if (
auto conformance = Common.SwiftConformance)
848 void convertMethod(
const Method &M, ContextID ClassID, StringRef ClassName,
849 VersionTuple SwiftVersion) {
851 convertCommonEntity(M, MI, M.Selector);
854 bool takesArguments = M.Selector.ends_with(
":");
857 llvm::SmallVector<StringRef, 4> Args;
858 M.Selector.split(Args,
":", -1,
false);
859 if (!takesArguments && Args.size() > 1) {
860 emitError(
"selector '" + M.Selector +
"' is missing a ':' at the end");
865 api_notes::ObjCSelectorRef Selector;
866 Selector.
NumArgs = !takesArguments ? 0 : Args.size();
872 if (M.FactoryAsInit != FactoryAsInitKind::Infer)
873 emitError(
"'FactoryAsInit' is no longer valid; use 'SwiftName' instead");
879 convertParams(M.Params, MI, MI.
Self);
882 convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);
887 Writer.
addObjCMethod(ClassID, Selector, M.Kind == MethodKind::Instance, MI,
891 template <
typename T>
892 void convertVariable(
const T &Entity, VariableInfo &VI) {
893 convertAvailability(Entity.Availability, VI, Entity.Name);
895 VI.
SwiftName = std::string(Entity.SwiftName);
896 if (Entity.Nullability)
898 VI.
setType(std::string(Entity.Type));
901 void convertContext(std::optional<ContextID> ParentContextID,
const Class &
C,
905 convertCommonType(
C, CI,
C.Name);
907 if (
C.AuditedForNullability)
909 if (
C.SwiftImportAsNonGeneric)
911 if (
C.SwiftObjCMembers)
915 Writer.
addContext(ParentContextID,
C.Name, Kind, CI, SwiftVersion);
918 llvm::StringMap<std::pair<bool, bool>> KnownMethods;
919 for (
const auto &method :
C.Methods) {
923 : KnownMethods[method.Selector].second;
925 emitError(llvm::Twine(
"duplicate definition of method '") +
926 (IsInstanceMethod ?
"-" :
"+") +
"[" +
C.Name +
" " +
927 method.Selector +
"]'");
932 convertMethod(method, CtxID,
C.Name, SwiftVersion);
936 llvm::StringSet<> KnownInstanceProperties;
937 llvm::StringSet<> KnownClassProperties;
938 for (
const auto &
Property :
C.Properties) {
941 !KnownInstanceProperties.insert(
Property.Name).second) {
942 emitError(llvm::Twine(
"duplicate definition of instance property '") +
948 !KnownClassProperties.insert(
Property.Name).second) {
949 emitError(llvm::Twine(
"duplicate definition of class property '") +
957 if (
Property.SwiftImportAsAccessors)
963 *
Property.Kind == MethodKind::Instance, PI,
972 void convertNamespaceContext(std::optional<ContextID> ParentContextID,
974 VersionTuple SwiftVersion) {
977 convertCommonEntity(TheNamespace, CI, TheNamespace.Name);
980 Writer.
addContext(ParentContextID, TheNamespace.Name,
981 ContextKind::Namespace, CI, SwiftVersion);
983 convertTopLevelItems(Context(CtxID, ContextKind::Namespace),
984 TheNamespace.Items, SwiftVersion);
987 template <
typename FuncOrMethodInfo>
990 FI.setSwiftPrivate(
Function.SwiftPrivate);
991 if (
Function.SafetyKind != SwiftSafetyKind::None)
992 FI.setSwiftSafety(
Function.SafetyKind);
993 FI.SwiftName = std::string(
Function.SwiftName);
994 std::optional<ParamInfo>
This;
995 convertParams(
Function.Params, FI, This);
996 if constexpr (std::is_same_v<FuncOrMethodInfo, CXXMethodInfo>)
999 emitError(
"implicit instance parameter is only permitted on C++ and "
1000 "Objective-C methods");
1003 FI.ResultType = std::string(
Function.ResultType);
1004 FI.SwiftReturnOwnership = std::string(
Function.SwiftReturnOwnership);
1005 FI.setRetainCountConvention(
Function.RetainCountConvention);
1008 void convertTagContext(std::optional<Context> ParentContext,
const Tag &
T,
1009 VersionTuple SwiftVersion) {
1011 std::optional<ContextID> ParentContextID =
1012 ParentContext ? std::optional<ContextID>(ParentContext->id)
1014 convertCommonType(
T, TI,
T.Name);
1016 if ((
T.SwiftRetainOp ||
T.SwiftReleaseOp) && !
T.SwiftImportAs) {
1017 emitError(llvm::Twine(
"should declare SwiftImportAs to use "
1018 "SwiftRetainOp and SwiftReleaseOp (for ") +
1022 if (
T.SwiftReleaseOp.has_value() !=
T.SwiftRetainOp.has_value()) {
1023 emitError(llvm::Twine(
"should declare both SwiftReleaseOp and "
1024 "SwiftRetainOp (for ") +
1029 if (
T.SwiftImportAs)
1031 if (
T.SwiftRetainOp)
1033 if (
T.SwiftReleaseOp)
1035 if (
T.SwiftDestroyOp)
1037 if (
T.SwiftDefaultOwnership)
1040 if (
T.SwiftCopyable)
1042 if (
T.SwiftEscapable)
1045 if (
T.EnumConvenienceKind) {
1046 if (
T.EnumExtensibility) {
1048 llvm::Twine(
"cannot mix EnumKind and EnumExtensibility (for ") +
1053 emitError(llvm::Twine(
"cannot mix EnumKind and FlagEnum (for ") +
1057 switch (*
T.EnumConvenienceKind) {
1058 case EnumConvenienceAliasKind::None:
1062 case EnumConvenienceAliasKind::CFEnum:
1066 case EnumConvenienceAliasKind::CFOptions:
1070 case EnumConvenienceAliasKind::CFClosedEnum:
1080 Writer.
addTag(ParentContext,
T.Name, TI, SwiftVersion);
1083 auto TagCtxID = Writer.
addContext(ParentContextID,
T.Name, ContextKind::Tag,
1085 Context TagCtx(TagCtxID, ContextKind::Tag);
1087 for (
const auto &Field :
T.Fields) {
1089 convertVariable(Field, FI);
1093 for (
const auto &CXXMethod :
T.Methods) {
1095 convertFunction(CXXMethod, MI);
1096 Writer.
addCXXMethod(TagCtxID, CXXMethod.Name, MI, SwiftVersion);
1100 for (
const auto &
Tag :
T.Tags)
1101 convertTagContext(TagCtx,
Tag, SwiftVersion);
1104 void convertTopLevelItems(std::optional<Context> Ctx,
1105 const TopLevelItems &TLItems,
1106 VersionTuple SwiftVersion) {
1107 std::optional<ContextID> CtxID =
1108 Ctx ? std::optional(Ctx->id) : std::nullopt;
1111 llvm::StringSet<> KnownClasses;
1112 for (
const auto &
Class : TLItems.Classes) {
1114 if (!KnownClasses.insert(
Class.Name).second) {
1115 emitError(llvm::Twine(
"multiple definitions of class '") +
Class.Name +
1120 convertContext(CtxID,
Class, ContextKind::ObjCClass, SwiftVersion);
1124 llvm::StringSet<> KnownProtocols;
1125 for (
const auto &Protocol : TLItems.Protocols) {
1127 if (!KnownProtocols.insert(
Protocol.Name).second) {
1128 emitError(llvm::Twine(
"multiple definitions of protocol '") +
1133 convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);
1137 llvm::StringSet<> KnownNamespaces;
1138 for (
const auto &
Namespace : TLItems.Namespaces) {
1140 if (!KnownNamespaces.insert(
Namespace.Name).second) {
1141 emitError(llvm::Twine(
"multiple definitions of namespace '") +
1146 convertNamespaceContext(CtxID,
Namespace, SwiftVersion);
1150 llvm::StringSet<> KnownGlobals;
1151 for (
const auto &
Global : TLItems.Globals) {
1153 if (!KnownGlobals.insert(
Global.Name).second) {
1154 emitError(llvm::Twine(
"multiple definitions of global variable '") +
1159 GlobalVariableInfo GVI;
1160 convertVariable(
Global, GVI);
1165 llvm::StringSet<> KnownFunctions;
1166 for (
const auto &
Function : TLItems.Functions) {
1168 if (!KnownFunctions.insert(
Function.Name).second) {
1169 emitError(llvm::Twine(
"multiple definitions of global function '") +
1174 GlobalFunctionInfo GFI;
1180 llvm::StringSet<> KnownEnumConstants;
1181 for (
const auto &EnumConstant : TLItems.EnumConstants) {
1183 if (!KnownEnumConstants.insert(
EnumConstant.Name).second) {
1184 emitError(llvm::Twine(
"multiple definitions of enumerator '") +
1189 EnumConstantInfo ECI;
1197 llvm::StringSet<> KnownTags;
1198 for (
const auto &
Tag : TLItems.Tags) {
1200 if (!KnownTags.insert(
Tag.Name).second) {
1201 emitError(llvm::Twine(
"multiple definitions of tag '") +
Tag.Name +
1206 convertTagContext(Ctx,
Tag, SwiftVersion);
1210 llvm::StringSet<> KnownTypedefs;
1211 for (
const auto &
Typedef : TLItems.Typedefs) {
1213 if (!KnownTypedefs.insert(
Typedef.Name).second) {
1214 emitError(llvm::Twine(
"multiple definitions of typedef '") +
1227 bool convertModule() {
1229 convertTopLevelItems( std::nullopt, M.TopLevel,
1233 for (
const auto &Versioned : M.SwiftVersions)
1234 convertTopLevelItems( std::nullopt, Versioned.Items,
1240 return ErrorOccured;
1246 llvm::raw_ostream &OS,
1247 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1248 void *DiagHandlerCtxt) {
1249 YAMLConverter
C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
1250 return C.convertModule();
1255 Diag.print(
nullptr, llvm::errs());
1260 llvm::raw_ostream &OS,
1261 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1262 void *DiagHandlerCtxt) {
1268 if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))
1271 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.
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).
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 setSwiftSafety(SwiftSafetyKind Safety)
void setSwiftPrivate(std::optional< bool > Private)
std::string UnavailableMsg
Message to use when this entity is unavailable.
void setSwiftConformance(std::optional< std::string > conformance)
void setNSErrorDomain(const std::optional< std::string > &Domain)
void setSwiftBridge(std::optional< std::string > SwiftType)
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)
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.
unsigned DesignatedInit
Whether this is a designated initializer of its class.
std::optional< ParamInfo > Self
unsigned RequiredInit
Whether this is a required initializer.
void setSwiftImportAsAccessors(std::optional< bool > Value)
void setNoEscape(std::optional< bool > Value)
void setLifetimebound(std::optional< bool > Value)
void setRetainCountConvention(std::optional< RetainCountConventionKind > Value)
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)
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.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
bool This(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
NullabilityKind
Describes the nullability of a particular type.
@ Nullable
Values of this type can be null.
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ NonNull
Values of this type can never be null.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ 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.
llvm::ArrayRef< llvm::StringRef > Identifiers
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)
static void enumeration(IO &IO, SwiftSafetyKind &SK)