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 {
53struct BoundsSafetyNotes {
55 std::optional<unsigned> Level;
56 StringRef BoundsExpr =
"";
64 IO.enumCase(AA,
"counted_by",
66 IO.enumCase(AA,
"counted_by_or_null",
69 IO.enumCase(AA,
"sized_by_or_null",
79template <>
struct ScalarEnumerationTraits<APIAvailability> {
81 IO.enumCase(AA,
"none", APIAvailability::None);
82 IO.enumCase(AA,
"nonswift", APIAvailability::NonSwift);
83 IO.enumCase(AA,
"available", APIAvailability::Available);
90enum class MethodKind {
98template <>
struct ScalarEnumerationTraits<MethodKind> {
100 IO.enumCase(MK,
"Class", MethodKind::Class);
101 IO.enumCase(MK,
"Instance", MethodKind::Instance);
110 std::optional<bool> NoEscape =
false;
111 std::optional<bool> Lifetimebound =
false;
112 std::optional<NullabilityKind> Nullability;
113 std::optional<RetainCountConventionKind> RetainCountConvention;
114 std::optional<BoundsSafetyNotes> BoundsSafety;
118typedef std::vector<Param> ParamsSeq;
121LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
147 IO.enumCase(RCCK,
"CFReturnsRetained",
149 IO.enumCase(RCCK,
"CFReturnsNotRetained",
151 IO.enumCase(RCCK,
"NSReturnsRetained",
153 IO.enumCase(RCCK,
"NSReturnsNotRetained",
158template <>
struct MappingTraits<Param> {
160 IO.mapRequired(
"Position", P.Position);
161 IO.mapOptional(
"Nullability", P.Nullability, std::nullopt);
162 IO.mapOptional(
"RetainCountConvention", P.RetainCountConvention);
163 IO.mapOptional(
"NoEscape", P.NoEscape);
164 IO.mapOptional(
"Lifetimebound", P.Lifetimebound);
165 IO.mapOptional(
"Type", P.Type, StringRef(
""));
166 IO.mapOptional(
"BoundsSafety", P.BoundsSafety);
170template <>
struct MappingTraits<BoundsSafetyNotes> {
171 static void mapping(IO &IO, BoundsSafetyNotes &BS) {
172 IO.mapRequired(
"Kind", BS.Kind);
173 IO.mapRequired(
"BoundedBy", BS.BoundsExpr);
174 IO.mapOptional(
"Level", BS.Level);
181typedef std::vector<NullabilityKind> NullabilitySeq;
183struct AvailabilityItem {
184 APIAvailability Mode = APIAvailability::Available;
189enum class FactoryAsInitKind {
202 NullabilitySeq Nullability;
203 std::optional<NullabilityKind> NullabilityOfRet;
204 std::optional<RetainCountConventionKind> RetainCountConvention;
205 AvailabilityItem Availability;
206 std::optional<bool> SwiftPrivate;
208 FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
209 bool DesignatedInit =
false;
210 bool Required =
false;
211 StringRef ResultType;
212 StringRef SwiftReturnOwnership;
216typedef std::vector<Method> MethodsSeq;
219LLVM_YAML_IS_SEQUENCE_VECTOR(Method)
223template <>
struct ScalarEnumerationTraits<FactoryAsInitKind> {
225 IO.enumCase(FIK,
"A", FactoryAsInitKind::Infer);
226 IO.enumCase(FIK,
"C", FactoryAsInitKind::AsClassMethod);
227 IO.enumCase(FIK,
"I", FactoryAsInitKind::AsInitializer);
231template <>
struct MappingTraits<Method> {
233 IO.mapRequired(
"Selector", M.Selector);
234 IO.mapRequired(
"MethodKind", M.Kind);
235 IO.mapOptional(
"Parameters", M.Params);
236 IO.mapOptional(
"Nullability", M.Nullability);
237 IO.mapOptional(
"NullabilityOfRet", M.NullabilityOfRet, std::nullopt);
238 IO.mapOptional(
"RetainCountConvention", M.RetainCountConvention);
239 IO.mapOptional(
"Availability", M.Availability.Mode,
240 APIAvailability::Available);
241 IO.mapOptional(
"AvailabilityMsg", M.Availability.Msg, StringRef(
""));
242 IO.mapOptional(
"SwiftPrivate", M.SwiftPrivate);
243 IO.mapOptional(
"SwiftName", M.SwiftName, StringRef(
""));
244 IO.mapOptional(
"FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);
245 IO.mapOptional(
"DesignatedInit", M.DesignatedInit,
false);
246 IO.mapOptional(
"Required", M.Required,
false);
247 IO.mapOptional(
"ResultType", M.ResultType, StringRef(
""));
248 IO.mapOptional(
"SwiftReturnOwnership", M.SwiftReturnOwnership,
259 std::optional<MethodKind> Kind;
260 std::optional<NullabilityKind> Nullability;
261 AvailabilityItem Availability;
262 std::optional<bool> SwiftPrivate;
264 std::optional<bool> SwiftImportAsAccessors;
269typedef std::vector<Property> PropertiesSeq;
272LLVM_YAML_IS_SEQUENCE_VECTOR(Property)
276template <>
struct MappingTraits<Property> {
278 IO.mapRequired(
"Name", P.Name);
279 IO.mapOptional(
"PropertyKind", P.Kind);
280 IO.mapOptional(
"Nullability", P.Nullability, std::nullopt);
281 IO.mapOptional(
"Availability", P.Availability.Mode,
282 APIAvailability::Available);
283 IO.mapOptional(
"AvailabilityMsg", P.Availability.Msg, StringRef(
""));
284 IO.mapOptional(
"SwiftPrivate", P.SwiftPrivate);
285 IO.mapOptional(
"SwiftName", P.SwiftName, StringRef(
""));
286 IO.mapOptional(
"SwiftImportAsAccessors", P.SwiftImportAsAccessors);
287 IO.mapOptional(
"Type", P.Type, StringRef(
""));
297 bool AuditedForNullability =
false;
298 AvailabilityItem Availability;
299 std::optional<bool> SwiftPrivate;
301 std::optional<StringRef> SwiftBridge;
302 std::optional<StringRef> NSErrorDomain;
303 std::optional<bool> SwiftImportAsNonGeneric;
304 std::optional<bool> SwiftObjCMembers;
305 std::optional<std::string> SwiftConformance;
307 PropertiesSeq Properties;
311typedef std::vector<Class> ClassesSeq;
314LLVM_YAML_IS_SEQUENCE_VECTOR(Class)
318template <>
struct MappingTraits<Class> {
320 IO.mapRequired(
"Name",
C.Name);
321 IO.mapOptional(
"AuditedForNullability",
C.AuditedForNullability,
false);
322 IO.mapOptional(
"Availability",
C.Availability.Mode,
323 APIAvailability::Available);
324 IO.mapOptional(
"AvailabilityMsg",
C.Availability.Msg, StringRef(
""));
325 IO.mapOptional(
"SwiftPrivate",
C.SwiftPrivate);
326 IO.mapOptional(
"SwiftName",
C.SwiftName, StringRef(
""));
327 IO.mapOptional(
"SwiftBridge",
C.SwiftBridge);
328 IO.mapOptional(
"NSErrorDomain",
C.NSErrorDomain);
329 IO.mapOptional(
"SwiftImportAsNonGeneric",
C.SwiftImportAsNonGeneric);
330 IO.mapOptional(
"SwiftObjCMembers",
C.SwiftObjCMembers);
331 IO.mapOptional(
"SwiftConformsTo",
C.SwiftConformance);
332 IO.mapOptional(
"Methods",
C.Methods);
333 IO.mapOptional(
"Properties",
C.Properties);
344 NullabilitySeq Nullability;
345 std::optional<NullabilityKind> NullabilityOfRet;
346 std::optional<api_notes::RetainCountConventionKind> RetainCountConvention;
347 AvailabilityItem Availability;
348 std::optional<bool> SwiftPrivate;
351 StringRef ResultType;
352 StringRef SwiftReturnOwnership;
354 bool UnsafeBufferUsage =
false;
357typedef std::vector<Function> FunctionsSeq;
360LLVM_YAML_IS_SEQUENCE_VECTOR(Function)
364template <>
struct MappingTraits<Function> {
366 IO.mapRequired(
"Name", F.Name);
367 IO.mapOptional(
"Parameters", F.Params);
368 IO.mapOptional(
"Nullability", F.Nullability);
369 IO.mapOptional(
"NullabilityOfRet", F.NullabilityOfRet, std::nullopt);
370 IO.mapOptional(
"RetainCountConvention", F.RetainCountConvention);
371 IO.mapOptional(
"Availability", F.Availability.Mode,
372 APIAvailability::Available);
373 IO.mapOptional(
"AvailabilityMsg", F.Availability.Msg, StringRef(
""));
374 IO.mapOptional(
"SwiftPrivate", F.SwiftPrivate);
375 IO.mapOptional(
"SwiftName", F.SwiftName, StringRef(
""));
376 IO.mapOptional(
"ResultType", F.ResultType, StringRef(
""));
377 IO.mapOptional(
"SwiftReturnOwnership", F.SwiftReturnOwnership,
380 IO.mapOptional(
"UnsafeBufferUsage", F.UnsafeBufferUsage,
false);
387struct GlobalVariable {
389 std::optional<NullabilityKind> Nullability;
390 AvailabilityItem Availability;
391 std::optional<bool> SwiftPrivate;
397typedef std::vector<GlobalVariable> GlobalVariablesSeq;
400LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
404template <>
struct MappingTraits<GlobalVariable> {
405 static void mapping(IO &IO, GlobalVariable &GV) {
406 IO.mapRequired(
"Name", GV.Name);
407 IO.mapOptional(
"Nullability", GV.Nullability, std::nullopt);
408 IO.mapOptional(
"Availability", GV.Availability.Mode,
409 APIAvailability::Available);
410 IO.mapOptional(
"AvailabilityMsg", GV.Availability.Msg, StringRef(
""));
411 IO.mapOptional(
"SwiftPrivate", GV.SwiftPrivate);
412 IO.mapOptional(
"SwiftName", GV.SwiftName, StringRef(
""));
413 IO.mapOptional(
"Type", GV.Type, StringRef(
""));
423 AvailabilityItem Availability;
424 std::optional<bool> SwiftPrivate;
429typedef std::vector<EnumConstant> EnumConstantsSeq;
432LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
436template <>
struct MappingTraits<EnumConstant> {
437 static void mapping(IO &IO, EnumConstant &EC) {
438 IO.mapRequired(
"Name", EC.Name);
439 IO.mapOptional(
"Availability", EC.Availability.Mode,
440 APIAvailability::Available);
441 IO.mapOptional(
"AvailabilityMsg", EC.Availability.Msg, StringRef(
""));
442 IO.mapOptional(
"SwiftPrivate", EC.SwiftPrivate);
443 IO.mapOptional(
"SwiftName", EC.SwiftName, StringRef(
""));
452enum class EnumConvenienceAliasKind {
466template <>
struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
468 IO.enumCase(ECAK,
"none", EnumConvenienceAliasKind::None);
469 IO.enumCase(ECAK,
"CFEnum", EnumConvenienceAliasKind::CFEnum);
470 IO.enumCase(ECAK,
"NSEnum", EnumConvenienceAliasKind::CFEnum);
471 IO.enumCase(ECAK,
"CFOptions", EnumConvenienceAliasKind::CFOptions);
472 IO.enumCase(ECAK,
"NSOptions", EnumConvenienceAliasKind::CFOptions);
473 IO.enumCase(ECAK,
"CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
474 IO.enumCase(ECAK,
"NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
483 std::optional<NullabilityKind> Nullability;
484 AvailabilityItem Availability;
485 std::optional<bool> SwiftPrivate;
491typedef std::vector<Field> FieldsSeq;
494LLVM_YAML_IS_SEQUENCE_VECTOR(Field)
498template <>
struct MappingTraits<Field> {
500 IO.mapRequired(
"Name", F.Name);
501 IO.mapOptional(
"Nullability", F.Nullability, std::nullopt);
502 IO.mapOptional(
"Availability", F.Availability.Mode,
503 APIAvailability::Available);
504 IO.mapOptional(
"AvailabilityMsg", F.Availability.Msg, StringRef(
""));
505 IO.mapOptional(
"SwiftPrivate", F.SwiftPrivate);
506 IO.mapOptional(
"SwiftName", F.SwiftName, StringRef(
""));
507 IO.mapOptional(
"Type", F.Type, StringRef(
""));
516typedef std::vector<Tag> TagsSeq;
520 AvailabilityItem Availability;
522 std::optional<bool> SwiftPrivate;
523 std::optional<StringRef> SwiftBridge;
524 std::optional<StringRef> NSErrorDomain;
525 std::optional<std::string> SwiftImportAs;
526 std::optional<std::string> SwiftRetainOp;
527 std::optional<std::string> SwiftReleaseOp;
528 std::optional<std::string> SwiftDestroyOp;
529 std::optional<std::string> SwiftDefaultOwnership;
530 std::optional<std::string> SwiftConformance;
531 std::optional<EnumExtensibilityKind> EnumExtensibility;
532 std::optional<bool> FlagEnum;
533 std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
534 std::optional<bool> SwiftCopyable;
535 std::optional<bool> SwiftEscapable;
537 FunctionsSeq Methods;
546LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
558template <>
struct MappingTraits<Tag> {
560 IO.mapRequired(
"Name", T.Name);
561 IO.mapOptional(
"Availability", T.Availability.Mode,
562 APIAvailability::Available);
563 IO.mapOptional(
"AvailabilityMsg", T.Availability.Msg, StringRef(
""));
564 IO.mapOptional(
"SwiftPrivate", T.SwiftPrivate);
565 IO.mapOptional(
"SwiftName", T.SwiftName, StringRef(
""));
566 IO.mapOptional(
"SwiftBridge", T.SwiftBridge);
567 IO.mapOptional(
"NSErrorDomain", T.NSErrorDomain);
568 IO.mapOptional(
"SwiftImportAs", T.SwiftImportAs);
569 IO.mapOptional(
"SwiftReleaseOp", T.SwiftReleaseOp);
570 IO.mapOptional(
"SwiftRetainOp", T.SwiftRetainOp);
571 IO.mapOptional(
"SwiftDestroyOp", T.SwiftDestroyOp);
572 IO.mapOptional(
"SwiftDefaultOwnership", T.SwiftDefaultOwnership);
573 IO.mapOptional(
"SwiftConformsTo", T.SwiftConformance);
574 IO.mapOptional(
"EnumExtensibility", T.EnumExtensibility);
575 IO.mapOptional(
"FlagEnum", T.FlagEnum);
576 IO.mapOptional(
"EnumKind", T.EnumConvenienceKind);
577 IO.mapOptional(
"SwiftCopyable", T.SwiftCopyable);
578 IO.mapOptional(
"SwiftEscapable", T.SwiftEscapable);
579 IO.mapOptional(
"Methods", T.Methods);
580 IO.mapOptional(
"Fields", T.Fields);
581 IO.mapOptional(
"Tags", T.Tags);
591 AvailabilityItem Availability;
593 std::optional<bool> SwiftPrivate;
594 std::optional<StringRef> SwiftBridge;
595 std::optional<StringRef> NSErrorDomain;
596 std::optional<SwiftNewTypeKind> SwiftType;
597 std::optional<std::string> SwiftConformance;
601typedef std::vector<Typedef> TypedefsSeq;
604LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
616template <>
struct MappingTraits<Typedef> {
618 IO.mapRequired(
"Name", T.Name);
619 IO.mapOptional(
"Availability", T.Availability.Mode,
620 APIAvailability::Available);
621 IO.mapOptional(
"AvailabilityMsg", T.Availability.Msg, StringRef(
""));
622 IO.mapOptional(
"SwiftPrivate", T.SwiftPrivate);
623 IO.mapOptional(
"SwiftName", T.SwiftName, StringRef(
""));
624 IO.mapOptional(
"SwiftBridge", T.SwiftBridge);
625 IO.mapOptional(
"NSErrorDomain", T.NSErrorDomain);
626 IO.mapOptional(
"SwiftWrapper", T.SwiftType);
627 IO.mapOptional(
"SwiftConformsTo", T.SwiftConformance);
635typedef std::vector<Namespace> NamespacesSeq;
637struct TopLevelItems {
639 ClassesSeq Protocols;
640 FunctionsSeq Functions;
641 GlobalVariablesSeq Globals;
642 EnumConstantsSeq EnumConstants;
644 TypedefsSeq Typedefs;
645 NamespacesSeq Namespaces;
652 IO.mapOptional(
"Classes", TLI.Classes);
653 IO.mapOptional(
"Protocols", TLI.Protocols);
654 IO.mapOptional(
"Functions", TLI.Functions);
655 IO.mapOptional(
"Globals", TLI.Globals);
656 IO.mapOptional(
"Enumerators", TLI.EnumConstants);
657 IO.mapOptional(
"Tags", TLI.Tags);
658 IO.mapOptional(
"Typedefs", TLI.Typedefs);
659 IO.mapOptional(
"Namespaces", TLI.Namespaces);
667 AvailabilityItem Availability;
669 std::optional<bool> SwiftPrivate;
675LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)
679template <>
struct MappingTraits<Namespace> {
681 IO.mapRequired(
"Name", T.Name);
682 IO.mapOptional(
"Availability", T.Availability.Mode,
683 APIAvailability::Available);
684 IO.mapOptional(
"AvailabilityMsg", T.Availability.Msg, StringRef(
""));
685 IO.mapOptional(
"SwiftPrivate", T.SwiftPrivate);
686 IO.mapOptional(
"SwiftName", T.SwiftName, StringRef(
""));
695 VersionTuple Version;
699typedef std::vector<Versioned> VersionedSeq;
702LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
706template <>
struct MappingTraits<Versioned> {
708 IO.mapRequired(
"Version",
V.Version);
718 AvailabilityItem Availability;
719 TopLevelItems TopLevel;
720 VersionedSeq SwiftVersions;
722 std::optional<bool> SwiftInferImportAsMember;
724#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
725 LLVM_DUMP_METHOD
void dump() ;
732template <>
struct MappingTraits<
Module> {
734 IO.mapRequired(
"Name", M.
Name);
735 IO.mapOptional(
"Availability", M.Availability.Mode,
736 APIAvailability::Available);
737 IO.mapOptional(
"AvailabilityMsg", M.Availability.Msg, StringRef(
""));
738 IO.mapOptional(
"SwiftInferImportAsMember", M.SwiftInferImportAsMember);
740 IO.mapOptional(
"SwiftVersions", M.SwiftVersions);
746#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
748 llvm::yaml::Output OS(llvm::errs());
754bool parseAPINotes(StringRef YI,
Module &M, llvm::SourceMgr::DiagHandlerTy
Diag,
756 llvm::yaml::Input IS(YI,
nullptr,
Diag, DiagContext);
758 return static_cast<bool>(IS.error());
763 llvm::raw_ostream &OS) {
765 if (parseAPINotes(YI, M,
nullptr,
nullptr))
768 llvm::yaml::Output YOS(OS);
779 APINotesWriter Writer;
780 llvm::raw_ostream &
OS;
781 llvm::SourceMgr::DiagHandlerTy DiagHandler;
782 void *DiagHandlerCtxt;
786 bool emitError(llvm::Twine Message) {
788 llvm::SMDiagnostic(
"", llvm::SourceMgr::DK_Error,
Message.str()),
790 ErrorOccurred =
true;
795 YAMLConverter(
const Module &TheModule,
const FileEntry *SourceFile,
796 llvm::raw_ostream &OS,
797 llvm::SourceMgr::DiagHandlerTy DiagHandler,
798 void *DiagHandlerCtxt)
799 : M(TheModule), Writer(TheModule.Name, SourceFile),
OS(
OS),
800 DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),
801 ErrorOccurred(
false) {}
803 void convertAvailability(
const AvailabilityItem &Availability,
804 CommonEntityInfo &CEI, llvm::StringRef APIName) {
806 CEI.
Unavailable = (Availability.Mode == APIAvailability::None);
811 if (!Availability.Msg.empty())
812 emitError(llvm::Twine(
"availability message for available API '") +
813 APIName +
"' will not be used");
817 void convertParams(
const ParamsSeq &Params, FunctionInfo &OutInfo,
818 std::optional<ParamInfo> &thisOrSelf) {
819 for (
const auto &P : Params) {
825 PI.
setType(std::string(P.Type));
827 if (P.BoundsSafety) {
828 BoundsSafetyInfo BSI;
830 if (P.BoundsSafety->Level)
835 if (
static_cast<int>(OutInfo.
Params.size()) <= P.Position)
836 OutInfo.
Params.resize(P.Position + 1);
837 if (P.Position == -1)
839 else if (P.Position >= 0)
840 OutInfo.
Params[P.Position] |= PI;
842 emitError(
"invalid parameter position " + llvm::itostr(P.Position));
846 void convertNullability(
const NullabilitySeq &Nullability,
847 std::optional<NullabilityKind> ReturnNullability,
848 FunctionInfo &OutInfo, llvm::StringRef APIName) {
850 emitError(llvm::Twine(
"nullability info for '") + APIName +
855 bool audited =
false;
856 unsigned int idx = 1;
857 for (
const auto &N : Nullability)
859 audited =
Nullability.size() > 0 || ReturnNullability;
862 ReturnNullability.value_or(NullabilityKind::NonNull));
870 template <
typename T>
871 void convertCommonEntity(
const T &Common, CommonEntityInfo &Info,
873 convertAvailability(Common.Availability, Info, APIName);
875 if (Common.SafetyKind != SwiftSafetyKind::None)
877 Info.
SwiftName = std::string(Common.SwiftName);
881 template <
typename T>
882 void convertCommonType(
const T &Common, CommonTypeInfo &Info,
884 convertCommonEntity(Common, Info, APIName);
885 if (Common.SwiftBridge)
888 if (
auto conformance = Common.SwiftConformance)
893 void convertMethod(
const Method &M, ContextID ClassID, StringRef ClassName,
894 VersionTuple SwiftVersion) {
896 convertCommonEntity(M, MI, M.Selector);
899 bool takesArguments = M.Selector.ends_with(
":");
902 llvm::SmallVector<StringRef, 4> Args;
903 M.Selector.split(Args,
":", -1,
false);
904 if (!takesArguments && Args.size() > 1) {
905 emitError(
"selector '" + M.Selector +
"' is missing a ':' at the end");
910 api_notes::ObjCSelectorRef Selector;
911 Selector.
NumArgs = !takesArguments ? 0 : Args.size();
917 if (M.FactoryAsInit != FactoryAsInitKind::Infer)
918 emitError(
"'FactoryAsInit' is no longer valid; use 'SwiftName' instead");
924 convertParams(M.Params, MI, MI.
Self);
927 convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);
932 Writer.
addObjCMethod(ClassID, Selector, M.Kind == MethodKind::Instance, MI,
936 template <
typename T>
937 void convertVariable(
const T &Entity, VariableInfo &VI) {
938 convertAvailability(Entity.Availability, VI, Entity.Name);
940 VI.
SwiftName = std::string(Entity.SwiftName);
941 if (Entity.Nullability)
943 VI.
setType(std::string(Entity.Type));
946 void convertContext(std::optional<ContextID> ParentContextID,
const Class &
C,
950 convertCommonType(
C, CI,
C.Name);
952 if (
C.AuditedForNullability)
954 if (
C.SwiftImportAsNonGeneric)
956 if (
C.SwiftObjCMembers)
960 Writer.
addContext(ParentContextID,
C.Name, Kind, CI, SwiftVersion);
963 llvm::StringMap<std::pair<bool, bool>> KnownMethods;
964 for (
const auto &method :
C.Methods) {
968 : KnownMethods[method.Selector].second;
970 emitError(llvm::Twine(
"duplicate definition of method '") +
971 (IsInstanceMethod ?
"-" :
"+") +
"[" +
C.Name +
" " +
972 method.Selector +
"]'");
977 convertMethod(method, CtxID,
C.Name, SwiftVersion);
981 llvm::StringSet<> KnownInstanceProperties;
982 llvm::StringSet<> KnownClassProperties;
983 for (
const auto &
Property :
C.Properties) {
986 !KnownInstanceProperties.insert(
Property.Name).second) {
987 emitError(llvm::Twine(
"duplicate definition of instance property '") +
993 !KnownClassProperties.insert(
Property.Name).second) {
994 emitError(llvm::Twine(
"duplicate definition of class property '") +
1000 ObjCPropertyInfo PI;
1002 if (
Property.SwiftImportAsAccessors)
1008 *
Property.Kind == MethodKind::Instance, PI,
1017 void convertNamespaceContext(std::optional<ContextID> ParentContextID,
1019 VersionTuple SwiftVersion) {
1022 convertCommonEntity(TheNamespace, CI, TheNamespace.Name);
1025 Writer.
addContext(ParentContextID, TheNamespace.Name,
1026 ContextKind::Namespace, CI, SwiftVersion);
1028 convertTopLevelItems(Context(CtxID, ContextKind::Namespace),
1029 TheNamespace.Items, SwiftVersion);
1032 template <
typename FuncOrMethodInfo>
1035 FI.setSwiftPrivate(
Function.SwiftPrivate);
1036 if (
Function.SafetyKind != SwiftSafetyKind::None)
1037 FI.setSwiftSafety(
Function.SafetyKind);
1038 FI.SwiftName = std::string(
Function.SwiftName);
1039 std::optional<ParamInfo>
This;
1040 convertParams(
Function.Params, FI, This);
1041 if constexpr (std::is_same_v<FuncOrMethodInfo, CXXMethodInfo>)
1044 emitError(
"implicit instance parameter is only permitted on C++ and "
1045 "Objective-C methods");
1048 FI.ResultType = std::string(
Function.ResultType);
1049 FI.SwiftReturnOwnership = std::string(
Function.SwiftReturnOwnership);
1050 FI.setRetainCountConvention(
Function.RetainCountConvention);
1051 FI.UnsafeBufferUsage =
Function.UnsafeBufferUsage;
1054 void convertTagContext(std::optional<Context> ParentContext,
const Tag &T,
1055 VersionTuple SwiftVersion) {
1057 std::optional<ContextID> ParentContextID =
1058 ParentContext ? std::optional<ContextID>(ParentContext->id)
1060 convertCommonType(T, TI, T.Name);
1062 if ((T.SwiftRetainOp || T.SwiftReleaseOp) && !T.SwiftImportAs) {
1063 emitError(llvm::Twine(
"should declare SwiftImportAs to use "
1064 "SwiftRetainOp and SwiftReleaseOp (for ") +
1068 if (T.SwiftReleaseOp.has_value() != T.SwiftRetainOp.has_value()) {
1069 emitError(llvm::Twine(
"should declare both SwiftReleaseOp and "
1070 "SwiftRetainOp (for ") +
1075 if (T.SwiftImportAs)
1077 if (T.SwiftRetainOp)
1079 if (T.SwiftReleaseOp)
1081 if (T.SwiftDestroyOp)
1083 if (T.SwiftDefaultOwnership)
1086 if (T.SwiftCopyable)
1088 if (T.SwiftEscapable)
1091 if (T.EnumConvenienceKind) {
1092 if (T.EnumExtensibility) {
1094 llvm::Twine(
"cannot mix EnumKind and EnumExtensibility (for ") +
1099 emitError(llvm::Twine(
"cannot mix EnumKind and FlagEnum (for ") +
1103 switch (*T.EnumConvenienceKind) {
1104 case EnumConvenienceAliasKind::None:
1108 case EnumConvenienceAliasKind::CFEnum:
1112 case EnumConvenienceAliasKind::CFOptions:
1116 case EnumConvenienceAliasKind::CFClosedEnum:
1126 Writer.
addTag(ParentContext, T.Name, TI, SwiftVersion);
1129 auto TagCtxID = Writer.
addContext(ParentContextID, T.Name, ContextKind::Tag,
1131 Context TagCtx(TagCtxID, ContextKind::Tag);
1133 for (
const auto &Field : T.Fields) {
1135 convertVariable(Field, FI);
1139 for (
const auto &CXXMethod : T.Methods) {
1141 convertFunction(CXXMethod, MI);
1142 Writer.
addCXXMethod(TagCtxID, CXXMethod.Name, MI, SwiftVersion);
1146 for (
const auto &
Tag : T.Tags)
1147 convertTagContext(TagCtx,
Tag, SwiftVersion);
1150 void convertTopLevelItems(std::optional<Context> Ctx,
1151 const TopLevelItems &TLItems,
1152 VersionTuple SwiftVersion) {
1153 std::optional<ContextID> CtxID =
1154 Ctx ? std::optional(Ctx->id) : std::nullopt;
1157 llvm::StringSet<> KnownClasses;
1158 for (
const auto &
Class : TLItems.Classes) {
1160 if (!KnownClasses.insert(
Class.Name).second) {
1161 emitError(llvm::Twine(
"multiple definitions of class '") +
Class.Name +
1166 convertContext(CtxID,
Class, ContextKind::ObjCClass, SwiftVersion);
1170 llvm::StringSet<> KnownProtocols;
1171 for (
const auto &Protocol : TLItems.Protocols) {
1173 if (!KnownProtocols.insert(
Protocol.Name).second) {
1174 emitError(llvm::Twine(
"multiple definitions of protocol '") +
1179 convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);
1183 llvm::StringSet<> KnownNamespaces;
1184 for (
const auto &
Namespace : TLItems.Namespaces) {
1186 if (!KnownNamespaces.insert(
Namespace.Name).second) {
1187 emitError(llvm::Twine(
"multiple definitions of namespace '") +
1192 convertNamespaceContext(CtxID,
Namespace, SwiftVersion);
1196 llvm::StringSet<> KnownGlobals;
1197 for (
const auto &
Global : TLItems.Globals) {
1199 if (!KnownGlobals.insert(
Global.Name).second) {
1200 emitError(llvm::Twine(
"multiple definitions of global variable '") +
1205 GlobalVariableInfo GVI;
1206 convertVariable(
Global, GVI);
1211 llvm::StringSet<> KnownFunctions;
1212 for (
const auto &
Function : TLItems.Functions) {
1214 if (!KnownFunctions.insert(
Function.Name).second) {
1215 emitError(llvm::Twine(
"multiple definitions of global function '") +
1220 GlobalFunctionInfo GFI;
1226 llvm::StringSet<> KnownEnumConstants;
1227 for (
const auto &EnumConstant : TLItems.EnumConstants) {
1229 if (!KnownEnumConstants.insert(
EnumConstant.Name).second) {
1230 emitError(llvm::Twine(
"multiple definitions of enumerator '") +
1235 EnumConstantInfo ECI;
1243 llvm::StringSet<> KnownTags;
1244 for (
const auto &
Tag : TLItems.Tags) {
1246 if (!KnownTags.insert(
Tag.Name).second) {
1247 emitError(llvm::Twine(
"multiple definitions of tag '") +
Tag.Name +
1252 convertTagContext(Ctx,
Tag, SwiftVersion);
1256 llvm::StringSet<> KnownTypedefs;
1257 for (
const auto &
Typedef : TLItems.Typedefs) {
1259 if (!KnownTypedefs.insert(
Typedef.Name).second) {
1260 emitError(llvm::Twine(
"multiple definitions of typedef '") +
1273 bool convertModule() {
1275 convertTopLevelItems( std::nullopt, M.TopLevel,
1279 for (
const auto &Versioned : M.SwiftVersions)
1280 convertTopLevelItems( std::nullopt, Versioned.Items,
1286 return ErrorOccurred;
1292 llvm::raw_ostream &OS,
1293 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1294 void *DiagHandlerCtxt) {
1295 YAMLConverter
C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
1296 return C.convertModule();
1301 Diag.print(
nullptr, llvm::errs());
1306 llvm::raw_ostream &OS,
1307 llvm::SourceMgr::DiagHandlerTy DiagHandler,
1308 void *DiagHandlerCtxt) {
1314 if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))
1317 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).
std::string ExternalBounds
void setKindAudited(BoundsSafetyKind kind)
void setLevelAudited(unsigned level)
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)
std::optional< BoundsSafetyInfo > BoundsSafety
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.
@ 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, BoundsSafetyNotes &BS)
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, BoundsSafetyInfo::BoundsSafetyKind &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)