31enum class IsActive_t :
bool { Inactive, Active };
32enum class IsSubstitution_t :
bool { Original, Replacement };
34struct VersionedInfoMetadata {
40 unsigned IsActive : 1;
41 unsigned IsReplacement : 1;
43 VersionedInfoMetadata(VersionTuple Version,
unsigned SliceGroup,
44 IsActive_t Active, IsSubstitution_t Replacement)
45 : Version(Version), SliceGroup(SliceGroup),
46 IsActive(Active == IsActive_t::Active),
47 IsReplacement(Replacement == IsSubstitution_t::Replacement) {}
62 VersionedInfoMetadata metadata) {
63 if (typeString.empty())
70 auto *typeAttr = SwiftTypeAttr::CreateImplicit(S.
Context, typeString);
71 auto *versioned = SwiftVersionedAdditionAttr::CreateImplicit(
72 S.
Context, metadata.Version, typeAttr, metadata.IsReplacement,
74 decl->addAttr(versioned);
76 if (!metadata.IsActive)
84 VersionedInfoMetadata metadata) {
88 SwiftNullabilityAttr::Kind attrNullabilityKind;
89 switch (nullability) {
91 attrNullabilityKind = SwiftNullabilityAttr::Kind::NonNull;
94 attrNullabilityKind = SwiftNullabilityAttr::Kind::Nullable;
97 attrNullabilityKind = SwiftNullabilityAttr::Kind::Unspecified;
100 attrNullabilityKind = SwiftNullabilityAttr::Kind::NullableResult;
103 auto *nullabilityAttr =
104 SwiftNullabilityAttr::CreateImplicit(S.
Context, attrNullabilityKind);
105 auto *versioned = SwiftVersionedAdditionAttr::CreateImplicit(
106 S.
Context, metadata.Version, nullabilityAttr, metadata.IsReplacement,
107 metadata.SliceGroup);
108 decl->addAttr(versioned);
111 if (!metadata.IsActive)
120 void *mem = Ctx.
Allocate(String.size(),
alignof(
char *));
121 memcpy(mem, String.data(), String.size());
122 return StringRef(
static_cast<char *
>(mem), String.size());
134template <
typename A>
struct AttrKindFor {};
137 template <> struct AttrKindFor<X##Attr> { \
138 static const attr::Kind value = attr::X; \
140#include "clang/Basic/AttrList.inc"
148void handleAPINotedAttribute(
149 Sema &S,
Decl *D,
bool IsAddition, VersionedInfoMetadata Metadata,
150 llvm::function_ref<A *()> CreateAttr,
152 if (Metadata.IsActive) {
153 auto Existing = GetExistingAttr(D);
157 auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(
158 S.
Context, Metadata.Version, *Existing,
true,
159 Metadata.SliceGroup);
167 if (
auto Attr = CreateAttr())
174 if (
auto Attr = CreateAttr()) {
175 auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(
177 Metadata.IsReplacement, Metadata.SliceGroup);
184 auto *Versioned = SwiftVersionedRemovalAttr::CreateImplicit(
185 S.
Context, Metadata.Version, AttrKindFor<A>::value,
186 Metadata.IsReplacement, Metadata.SliceGroup);
192void handleAPINotedAttribute(
Sema &S,
Decl *D,
bool ShouldAddAttribute,
193 VersionedInfoMetadata Metadata,
194 llvm::function_ref<A *()> CreateAttr) {
195 handleAPINotedAttribute<A>(
196 S, D, ShouldAddAttribute, Metadata, CreateAttr, [](
const Decl *D) {
197 return llvm::find_if(D->
attrs(),
198 [](
const Attr *
Next) { return isa<A>(Next); });
205 bool ShouldAddAttribute,
206 VersionedInfoMetadata Metadata) {
209 handleAPINotedAttribute<A>(
210 S, D, ShouldAddAttribute, Metadata,
213 return llvm::find_if(D->
attrs(), [](
const Attr *
Next) ->
bool {
214 return isa<CFReturnsRetainedAttr>(Next) ||
215 isa<CFReturnsNotRetainedAttr>(Next) ||
216 isa<NSReturnsRetainedAttr>(Next) ||
217 isa<NSReturnsNotRetainedAttr>(Next) ||
218 isa<CFAuditedTransferAttr>(Next);
224 Sema &S,
Decl *D, VersionedInfoMetadata Metadata,
225 std::optional<api_notes::RetainCountConventionKind> Convention) {
228 switch (*Convention) {
232 S, D,
true, Metadata);
235 S, D,
false, Metadata);
240 S, D,
true, Metadata);
244 S, D,
true, Metadata);
248 S, D,
true, Metadata);
252 S, D,
true, Metadata);
260 if (A->getAttribute() == Attribute)
268 VersionedInfoMetadata Metadata) {
271 handleAPINotedAttribute<UnavailableAttr>(S, D,
true, Metadata, [&] {
279 handleAPINotedAttribute<AvailabilityAttr>(
280 S, D,
true, Metadata,
282 return new (S.
Context) AvailabilityAttr(
294 return llvm::find_if(D->
attrs(), [](
const Attr *next) ->
bool {
295 if (const auto *AA = dyn_cast<AvailabilityAttr>(next))
296 if (const auto *II = AA->getPlatform())
297 return II->isStr(
"swift");
305 handleAPINotedAttribute<SwiftPrivateAttr>(
306 S, D, *SwiftPrivate, Metadata, [&] {
315 handleAPINotedAttribute<SwiftAttrAttr>(
318 return SwiftAttrAttr::Create(
325 if (const auto *swiftAttr = dyn_cast<SwiftAttrAttr>(attr)) {
326 if (swiftAttr->getAttribute() ==
"safe" ||
327 swiftAttr->getAttribute() ==
"unsafe")
336 if (!Info.SwiftName.empty()) {
337 handleAPINotedAttribute<SwiftNameAttr>(
338 S, D,
true, Metadata, [&]() -> SwiftNameAttr * {
344 nullptr,
nullptr,
nullptr, ParsedAttr::Form::GNU());
359 VersionedInfoMetadata Metadata) {
362 handleAPINotedAttribute<SwiftBridgeAttr>(
363 S, D, !SwiftBridge->empty(), Metadata, [&] {
364 return new (S.Context)
365 SwiftBridgeAttr(S.Context, getPlaceholderAttrInfo(),
366 ASTAllocateString(S.Context, *SwiftBridge));
372 handleAPINotedAttribute<NSErrorDomainAttr>(
373 S, D, !NSErrorDomain->empty(), Metadata, [&] {
374 return new (S.Context)
375 NSErrorDomainAttr(S.Context, getPlaceholderAttrInfo(),
376 &S.Context.Idents.get(*NSErrorDomain));
395 S.
Diag(Loc, diag::err_incompatible_replacement_type)
396 << ReplacementType << OrigType;
410 if (
auto Var = dyn_cast<VarDecl>(D)) {
419 Var->getType(),
Type)) {
423 }
else if (
auto property = dyn_cast<ObjCPropertyDecl>(D)) {
425 property->getType(),
Type)) {
428 }
else if (
auto field = dyn_cast<FieldDecl>(D)) {
430 field->getType(),
Type)) {
431 field->setType(
Type);
435 llvm_unreachable(
"API notes allowed a type on an unknown declaration");
449 return (QT.getTypePtr() != Original.getTypePtr()) ? std::optional(QT)
453 if (
auto Function = dyn_cast<FunctionDecl>(D)) {
455 GetModified(D,
Function->getReturnType(), Nullability)) {
459 *Modified, proto->getParamTypes(), proto->getExtProtoInfo()));
464 }
else if (
auto Method = dyn_cast<ObjCMethodDecl>(D)) {
465 if (
auto Modified = GetModified(D,
Method->getReturnType(), Nullability)) {
466 Method->setReturnType(*Modified);
473 }
else if (
auto Value = dyn_cast<ValueDecl>(D)) {
474 if (
auto Modified = GetModified(D,
Value->
getType(), Nullability)) {
475 Value->setType(*Modified);
478 if (
auto Parm = dyn_cast<ParmVarDecl>(D)) {
484 }
else if (
auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
485 if (
auto Modified = GetModified(D,
Property->getType(), Nullability)) {
499 VersionedInfoMetadata Metadata) {
515 VersionedInfoMetadata Metadata) {
518 handleAPINotedAttribute<NoEscapeAttr>(S, D, *NoEscape, Metadata, [&] {
523 handleAPINotedAttribute<LifetimeBoundAttr>(
524 S, D, *Lifetimebound, Metadata, [&] {
541 VersionedInfoMetadata metadata) {
550 VersionedInfoMetadata metadata) {
559 VersionedInfoMetadata Metadata) {
565 handleAPINotedAttribute<SwiftImportPropertyAsAccessorsAttr>(
566 S, D, *AsAccessors, Metadata, [&] {
567 return new (S.
Context) SwiftImportPropertyAsAccessorsAttr(
574typedef llvm::PointerUnion<FunctionDecl *, ObjCMethodDecl *> FunctionOrMethod;
580 VersionedInfoMetadata Metadata) {
590 assert((FD || MD) &&
"Expecting Function or ObjCMethod");
598 handleAPINotedAttribute<UnsafeBufferUsageAttr>(S, D,
true, Metadata, [&]() {
607 bool AnyTypeChanged =
false;
608 for (
unsigned I = 0; I != NumParams; ++I) {
610 QualType ParamTypeBefore = Param->getType();
612 if (I < Info.
Params.size())
619 if (ParamTypeBefore.
getAsOpaquePtr() != Param->getType().getAsOpaquePtr())
620 AnyTypeChanged =
true;
629 if (Metadata.IsActive && !Info.
ResultType.empty() &&
639 auto ResultTypeInfo =
646 OverriddenResultType = ResultType;
647 AnyTypeChanged =
true;
654 if (FD && AnyTypeChanged) {
656 if (OverriddenResultType.
isNull())
657 OverriddenResultType = fnProtoType->getReturnType();
661 ParamTypes.push_back(Param->getType());
664 fnProtoType->getExtProtoInfo()));
665 }
else if (!OverriddenResultType.
isNull()) {
668 OverriddenResultType, FnNoProtoType->getExtInfo()));
684 VersionedInfoMetadata Metadata) {
685 if (Info.
This && Info.
This->isLifetimebound() &&
687 auto MethodType = Method->getType();
693 TLB.
pushFullCopy(Method->getTypeSourceInfo()->getTypeLoc());
696 Method->setType(AttributedType);
706 VersionedInfoMetadata Metadata) {
715 VersionedInfoMetadata Metadata) {
724 VersionedInfoMetadata Metadata) {
727 handleAPINotedAttribute<ObjCDesignatedInitializerAttr>(
728 S, D,
true, Metadata, [&] {
730 IFace->setHasDesignatedInitializers();
732 return new (S.
Context) ObjCDesignatedInitializerAttr(
744 VersionedInfoMetadata Metadata) {
757 S, D,
"returned_as_" + DefaultOwnership.value() +
"_by_default");
770 bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None);
771 handleAPINotedAttribute<EnumExtensibilityAttr>(
772 S, D, ShouldAddAttribute, Metadata, [&] {
773 EnumExtensibilityAttr::Kind
kind;
774 switch (*Extensibility) {
775 case EnumExtensibilityKind::None:
776 llvm_unreachable(
"remove only");
777 case EnumExtensibilityKind::Open:
778 kind = EnumExtensibilityAttr::Open;
780 case EnumExtensibilityKind::Closed:
781 kind = EnumExtensibilityAttr::Closed;
790 handleAPINotedAttribute<FlagEnumAttr>(S, D, *FlagEnum, Metadata, [&] {
803 VersionedInfoMetadata Metadata) {
808 handleAPINotedAttribute<SwiftNewTypeAttr>(
809 S, D, *SwiftWrapper != SwiftWrapperKind::None, Metadata, [&] {
810 SwiftNewTypeAttr::NewtypeKind Kind;
811 switch (*SwiftWrapper) {
812 case SwiftWrapperKind::None:
813 llvm_unreachable(
"Shouldn't build an attribute");
815 case SwiftWrapperKind::Struct:
816 Kind = SwiftNewTypeAttr::NK_Struct;
819 case SwiftWrapperKind::Enum:
820 Kind = SwiftNewTypeAttr::NK_Enum;
825 AttributeCommonInfo::AT_SwiftNewType,
828 return new (S.
Context) SwiftNewTypeAttr(S.
Context, SyntaxInfo, Kind);
840 VersionedInfoMetadata Metadata) {
849 VersionedInfoMetadata Metadata) {
851 handleAPINotedAttribute<SwiftImportAsNonGenericAttr>(
852 S, D, *AsNonGeneric, Metadata, [&] {
859 handleAPINotedAttribute<SwiftObjCMembersAttr>(
860 S, D, *ObjcMembers, Metadata, [&] {
879template <
typename SpecificInfo>
883 unsigned SliceGroup) {
884 if (D->
hasAttr<SwiftNameAttr>())
890 VersionTuple SelectedVersion;
891 SpecificInfo SelectedInfoSlice;
892 std::tie(SelectedVersion, SelectedInfoSlice) = Info[*Info.
getSelected()];
893 if (SelectedVersion.empty())
895 if (SelectedInfoSlice.SwiftName.empty())
899 for (
const auto &VersionAndInfoSlice : Info) {
900 if (!VersionAndInfoSlice.first.empty())
902 if (!VersionAndInfoSlice.second.SwiftName.empty())
907 VersionedInfoMetadata DummyFutureMetadata(SelectedVersion, SliceGroup,
908 IsActive_t::Inactive,
909 IsSubstitution_t::Replacement);
910 handleAPINotedAttribute<SwiftNameAttr>(
911 S, D,
false, DummyFutureMetadata, []() -> SwiftNameAttr * {
912 llvm_unreachable(
"should not try to add an attribute here");
922template <
typename SpecificDecl,
typename SpecificInfo>
924 Sema &S, SpecificDecl *D,
926 unsigned SliceGroup) {
933 VersionTuple Version;
934 SpecificInfo InfoSlice;
935 for (
unsigned i = 0, e = Info.
size(); i != e; ++i) {
936 std::tie(Version, InfoSlice) = Info[i];
937 auto Active = (i == Selected) ? IsActive_t::Active : IsActive_t::Inactive;
938 auto Replacement = IsSubstitution_t::Original;
944 Active = IsActive_t::Inactive;
951 D->addAttr(SwiftVersionedSliceAttr::CreateImplicit(S.
Context, Version,
953 }
else if (Active == IsActive_t::Inactive && Version.empty()) {
954 Replacement = IsSubstitution_t::Replacement;
955 Version = Info[Selected].first;
960 VersionedInfoMetadata(Version, SliceGroup, Active, Replacement));
964static std::optional<api_notes::Context>
966 if (
auto NamespaceContext = dyn_cast<NamespaceDecl>(DC)) {
967 for (
auto Reader : APINotes.
findAPINotes(NamespaceContext->getLocation())) {
969 std::stack<NamespaceDecl *> NamespaceStack;
971 for (
auto CurrentNamespace = NamespaceContext; CurrentNamespace;
973 dyn_cast<NamespaceDecl>(CurrentNamespace->getParent())) {
974 if (!CurrentNamespace->isInlineNamespace())
975 NamespaceStack.push(CurrentNamespace);
978 std::optional<api_notes::ContextID> NamespaceID;
979 while (!NamespaceStack.empty()) {
980 auto CurrentNamespace = NamespaceStack.top();
981 NamespaceStack.pop();
983 Reader->lookupNamespaceID(CurrentNamespace->getName(), NamespaceID);
995static std::optional<api_notes::Context>
997 assert(DC &&
"tag context must not be null");
1000 std::stack<TagDecl *> TagStack;
1002 for (
auto CurrentTag = DC; CurrentTag;
1003 CurrentTag = dyn_cast<TagDecl>(CurrentTag->getParent()))
1004 TagStack.push(CurrentTag);
1006 assert(!TagStack.empty());
1007 std::optional<api_notes::Context> Ctx =
1009 while (!TagStack.empty()) {
1010 auto CurrentTag = TagStack.top();
1012 auto CtxID = Reader->lookupTagID(CurrentTag->getName(), Ctx);
1014 return std::nullopt;
1019 return std::nullopt;
1031 return !(*
this ==
Other);
1044 Policy.PrintAsCanonical =
false;
1045 Policy.FullyQualifiedName =
false;
1047 Policy.UsePreferredNames =
false;
1048 Policy.MSVCFormatting =
false;
1070static std::optional<APINotesParameterSelectorCandidates>
1074 return std::nullopt;
1079 Desugared.
Parameters.reserve(FPT->getNumParams());
1083 for (
QualType ParamType : FPT->param_types()) {
1088 ParamType, S.
Context, Policy,
true));
1091 if (Candidates.
Source != Desugared)
1092 Candidates.
Desugared = std::move(Desugared);
1100 auto [StateIt, Inserted] =
Readers.try_emplace(&Reader);
1107 State.addSelectors(Selectors);
1115 std::make_unique<APINotesSelectorDiagnosticState>();
1121 llvm::function_ref<std::optional<api_notes::APINotesFunctionSelectorKey>(
1128 if (
auto Key = GetSelectorKey(Candidates.
Desugared->Parameters))
1140template <
typename SpecificInfo,
typename SpecificDecl>
1142 Sema &S, SpecificDecl *D,
1147 unsigned SliceGroup) {
1149 auto Info = LookupExact(
Selector.Parameters);
1150 if (Info.size() == 0)
1157 if (ProcessSelector(ParameterSelectorCandidates.
Source))
1160 if (ParameterSelectorCandidates.
Desugared)
1161 ProcessSelector(*ParameterSelectorCandidates.
Desugared);
1172 if (Readers.empty())
1177 unsigned NextSliceGroup = 0;
1181 if (DC->isFileContext() || DC->isNamespace() ||
1182 DC->getDeclKind() == Decl::LinkageSpec) {
1183 std::optional<api_notes::Context> APINotesContext =
1186 if (
auto VD = dyn_cast<VarDecl>(D)) {
1187 for (
auto Reader : Readers) {
1189 Reader->lookupGlobalVariable(VD->getName(), APINotesContext);
1197 if (
auto FD = dyn_cast<FunctionDecl>(D)) {
1198 if (FD->getDeclName().isIdentifier()) {
1199 auto ParameterSelectorCandidates =
1202 for (
auto Reader : Readers) {
1204 Reader->lookupGlobalFunction(FD->getName(), APINotesContext);
1207 if (ParameterSelectorCandidates)
1209 *
this, FD, *ParameterSelectorCandidates,
1211 return Reader->lookupGlobalFunction(FD->getName(), Parameters,
1216 if (ParameterSelectorCandidates) {
1217 auto &DiagnosticState =
1219 if (
auto BroadKey = Reader->getGlobalFunctionSelectorKey(
1220 FD->getName(), APINotesContext))
1221 DiagnosticState.noteSeenDeclaration(*BroadKey, FD->getName(),
1223 DiagnosticState.markCandidatesUsed(
1225 return Reader->getGlobalFunctionSelectorKey(
1226 FD->getName(), Parameters, APINotesContext);
1228 *ParameterSelectorCandidates);
1237 if (
auto Class = dyn_cast<ObjCInterfaceDecl>(D)) {
1238 for (
auto Reader : Readers) {
1239 auto Info = Reader->lookupObjCClassInfo(
Class->getName());
1247 if (
auto Protocol = dyn_cast<ObjCProtocolDecl>(D)) {
1248 for (
auto Reader : Readers) {
1249 auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName());
1257 if (
auto Tag = dyn_cast<TagDecl>(D)) {
1263 if (
auto typedefName = Tag->getTypedefNameForAnonDecl())
1273 std::string MacroName =
1274 LookupName.empty() && Tag->getOuterLocStart().isMacroID()
1276 Tag->getOuterLocStart(),
1277 Tag->getASTContext().getSourceManager(),
LangOpts)
1282 (MacroName ==
"CF_OPTIONS" || MacroName ==
"NS_OPTIONS" ||
1283 MacroName ==
"OBJC_OPTIONS" || MacroName ==
"SWIFT_OPTIONS")) {
1290 for (
auto Reader : Readers) {
1291 if (
auto ParentTag = dyn_cast<TagDecl>(Tag->getDeclContext()))
1293 auto Info = Reader->lookupTag(
LookupName, APINotesContext);
1301 if (
auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
1302 for (
auto Reader : Readers) {
1303 auto Info = Reader->lookupTypedef(
Typedef->getName(), APINotesContext);
1312 if (DC->getRedeclContext()->isFileContext() ||
1313 DC->getRedeclContext()->isExternCContext()) {
1314 if (
auto EnumConstant = dyn_cast<EnumConstantDecl>(D)) {
1315 for (
auto Reader : Readers) {
1316 auto Info = Reader->lookupEnumConstant(EnumConstant->getName());
1324 if (
auto ObjCContainer = dyn_cast<ObjCContainerDecl>(DC)) {
1327 -> std::optional<api_notes::ContextID> {
1328 if (
auto Protocol = dyn_cast<ObjCProtocolDecl>(ObjCContainer)) {
1329 if (
auto Found = Reader->lookupObjCProtocolID(Protocol->getName()))
1332 return std::nullopt;
1335 if (
auto Impl = dyn_cast<ObjCCategoryImplDecl>(ObjCContainer)) {
1336 if (
auto Cat = Impl->getCategoryDecl())
1337 ObjCContainer = Cat->getClassInterface();
1339 return std::nullopt;
1342 if (
auto Category = dyn_cast<ObjCCategoryDecl>(ObjCContainer)) {
1343 if (Category->getClassInterface())
1344 ObjCContainer = Category->getClassInterface();
1346 return std::nullopt;
1349 if (
auto Impl = dyn_cast<ObjCImplDecl>(ObjCContainer)) {
1350 if (Impl->getClassInterface())
1351 ObjCContainer = Impl->getClassInterface();
1353 return std::nullopt;
1356 if (
auto Class = dyn_cast<ObjCInterfaceDecl>(ObjCContainer)) {
1357 if (
auto Found = Reader->lookupObjCClassID(
Class->getName()))
1360 return std::nullopt;
1363 return std::nullopt;
1367 if (
auto Method = dyn_cast<ObjCMethodDecl>(D)) {
1368 for (
auto Reader : Readers) {
1369 if (
auto Context = GetContext(Reader)) {
1376 for (
unsigned i = 0, n = Sel.
getNumArgs(); i != n; ++i)
1384 auto Info = Reader->lookupObjCMethod(*
Context, SelectorRef,
1385 Method->isInstanceMethod());
1392 if (
auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
1394 if (
auto Context = GetContext(Reader)) {
1395 bool isInstanceProperty =
1396 (
Property->getPropertyAttributesAsWritten() &
1399 isInstanceProperty);
1408 if (
auto TagContext = dyn_cast<TagDecl>(DC)) {
1409 if (
auto CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
1413 auto ParameterSelectorCandidates =
1415 for (
auto Reader : Readers) {
1417 std::string MethodName;
1418 if (CXXMethod->isOverloadedOperator())
1420 std::string(
"operator") +
1423 MethodName = CXXMethod->getName();
1425 auto Info = Reader->lookupCXXMethod(
Context->id, MethodName);
1428 if (ParameterSelectorCandidates)
1430 *
this, CXXMethod, *ParameterSelectorCandidates,
1432 return Reader->lookupCXXMethod(
Context->id, MethodName,
1437 if (ParameterSelectorCandidates) {
1438 auto &DiagnosticState =
1441 Reader->getCXXMethodSelectorKey(
Context->id, MethodName))
1442 DiagnosticState.noteSeenDeclaration(*BroadKey, MethodName,
1443 CXXMethod->getLocation());
1444 DiagnosticState.markCandidatesUsed(
1446 return Reader->getCXXMethodSelectorKey(
1447 Context->id, MethodName, Parameters);
1449 *ParameterSelectorCandidates);
1456 if (
auto Field = dyn_cast<FieldDecl>(D)) {
1457 if (!Field->isUnnamedBitField() && !Field->isAnonymousStructOrUnion()) {
1458 for (
auto Reader : Readers) {
1460 auto Info = Reader->lookupField(
Context->id, Field->getName());
1467 if (
auto Tag = dyn_cast<TagDecl>(D)) {
1468 for (
auto Reader : Readers) {
1470 auto Info = Reader->lookupTag(Tag->getName(),
Context);
1489 std::optional<SmallVector<std::string, 4>> ParameterSpellings =
1491 if (!ParameterSpellings)
1494 S.
Diag(SeenName->second.Loc, diag::warn_apinotes_message)
1495 << (llvm::Twine(
"API notes entry for '") + SeenName->second.Name +
1496 "' has unmatched Where.Parameters " +
1503 for (
const auto &ReaderSelectors :
Readers)
1504 ReaderSelectors.second.diagnoseUnused(S, *ReaderSelectors.first);
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
static std::optional< api_notes::Context > UnwindNamespaceContext(DeclContext *DC, api_notes::APINotesManager &APINotes)
static std::string getAPINotesParameterSelectorSpelling(QualType ParamType, const ASTContext &Context, const PrintingPolicy &Policy, bool Desugar)
static std::optional< APINotesParameterSelectorCandidates > getAPINotesParameterSelectorCandidates(const Sema &S, const FunctionDecl *FD)
static void addSwiftAttrIfAbsent(Sema &S, Decl *D, StringRef Attribute)
Add a 'swift_attr' unless D already carries that exact annotation.
static bool checkAPINotesReplacementType(Sema &S, SourceLocation Loc, QualType OrigType, QualType ReplacementType)
Check that the replacement type provided by API notes is reasonable.
static PrintingPolicy getAPINotesParameterSelectorPrintingPolicy(const ASTContext &Context)
static std::optional< api_notes::Context > UnwindTagContext(TagDecl *DC, api_notes::APINotesManager &APINotes)
static StringRef ASTAllocateString(ASTContext &Ctx, StringRef String)
Copy a string into ASTContext-allocated memory.
static void ProcessVersionedAPINotes(Sema &S, SpecificDecl *D, const api_notes::APINotesReader::VersionedInfo< SpecificInfo > Info, unsigned SliceGroup)
Processes all versions of versioned API notes.
static void applyAPINotesType(Sema &S, Decl *decl, StringRef typeString, VersionedInfoMetadata metadata)
static void handleAPINotedRetainCountConvention(Sema &S, Decl *D, VersionedInfoMetadata Metadata, std::optional< api_notes::RetainCountConventionKind > Convention)
static void handleAPINotedRetainCountAttribute(Sema &S, Decl *D, bool ShouldAddAttribute, VersionedInfoMetadata Metadata)
static AttributeCommonInfo getPlaceholderAttrInfo()
static void ProcessAPINotes(Sema &S, Decl *D, const api_notes::CommonEntityInfo &Info, VersionedInfoMetadata Metadata)
static void applyNullability(Sema &S, Decl *decl, NullabilityKind nullability, VersionedInfoMetadata metadata)
Apply nullability to the given declaration.
static void maybeAttachUnversionedSwiftName(Sema &S, Decl *D, const api_notes::APINotesReader::VersionedInfo< SpecificInfo > Info, unsigned SliceGroup)
If we're applying API notes with an active, non-default version, and the versioned API notes have a S...
static APINotesSelectorDiagnosticReaderState & getAPINotesSelectorDiagnosticState(Sema &S, api_notes::APINotesReader *Reader)
static bool isIndirectPointerType(QualType Type)
Determine whether this is a multi-level pointer type.
static void processExactAPINotes(Sema &S, SpecificDecl *D, const APINotesParameterSelectorCandidates &ParameterSelectorCandidates, llvm::function_ref< api_notes::APINotesReader::VersionedInfo< SpecificInfo >(ArrayRef< std::string >)> LookupExact, unsigned SliceGroup)
Apply the first exact selector entry found.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis functions specific to Swift.
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType, const Attr *attr=nullptr) const
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
void * Allocate(size_t Size, unsigned Align=8) const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Attr - This represents one attribute.
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
ParsedAttr * create(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Type source information for an attributed type.
void setAttr(const Attr *A)
Represents a static or instance method of a struct/union/class.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Decl - This represents one declaration (or definition), e.g.
attr_iterator attr_end() const
AttrVec::const_iterator attr_iterator
ObjCDeclQualifier
ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...
@ OBJC_TQ_CSNullability
The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
An instance of this object exists for each enum constant that is defined.
Represents a member of a struct/union/class.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
ExtInfo getExtInfo() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
ObjCContainerDecl - Represents a container for method declarations.
Represents an ObjC class declaration.
ObjCMethodDecl - Represents an instance or class method declaration.
unsigned param_size() const
void setReturnTypeSourceInfo(TypeSourceInfo *TInfo)
param_const_iterator param_begin() const
void setReturnType(QualType T)
QualType getReturnType() const
ObjCInterfaceDecl * getClassInterface()
Represents one property declaration in an Objective-C interface.
Represents a parameter to a function.
ParsedAttr - Represents a syntactic attribute.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void removeLocalVolatile()
std::string getAsString() const
void * getAsOpaquePtr() const
QualType stripNullability(const ASTContext &ctx) const
Strip nullability attributes from the given type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
bool isUnarySelector() const
unsigned getNumArgs() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
QualType AdjustParameterTypeForObjCAutoRefCount(QualType T, SourceLocation NameLoc, TypeSourceInfo *TSInfo)
bool DiagnoseName(Decl *D, StringRef Name, SourceLocation Loc, const ParsedAttr &AL, bool IsAsync)
Do a check to make sure Name looks like a legal argument for the swift_name attribute applied to decl...
Sema - This implements semantic analysis and AST building for C.
bool captureSwiftVersionIndependentAPINotes()
Whether APINotes should be gathered for all applicable Swift language versions, without being applied...
ASTContext & getASTContext() const
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
api_notes::APINotesManager APINotes
const LangOptions & LangOpts
std::function< TypeResult(StringRef, StringRef, SourceLocation)> ParseTypeFromStringCallback
Callback to the parser to parse a type expressed as a string.
void ApplyNullability(Decl *D, NullabilityKind Nullability)
Apply the 'Nullability:' annotation to the specified declaration.
bool CheckImplicitNullabilityTypeSpecifier(QualType &Type, NullabilityKind Nullability, SourceLocation DiagLoc, bool AllowArrayTypes, bool OverrideExisting)
Check whether a nullability type specifier can be added to the given type through some means not writ...
@ AP_Explicit
The availability attribute was specified explicitly next to the declaration.
DiagnosticsEngine & Diags
std::unique_ptr< APINotesSelectorDiagnosticState > APINotesSelectorDiagnostics
void ApplyAPINotesType(Decl *D, StringRef TypeString)
Apply the 'Type:' annotation to the specified declaration.
void ProcessAPINotes(Decl *D)
Map any API notes provided for this declaration to attributes on the declaration.
void DiagnoseUnusedAPINotesSelectors()
Diagnose exact API notes selectors that were not matched by any declaration processed in this transla...
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Encodes a location in the source.
A trivial tuple used to represent a source range.
Represents the declaration of a struct/union/class/enum.
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
void pushFullCopy(TypeLoc L)
Pushes a copy of the given TypeLoc onto this builder.
TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)
Creates a TypeSourceInfo for the given type.
The base class of the type hierarchy.
const T * castAs() const
Member-template castAs<specific type>.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isMemberPointerType() const
bool isObjCObjectPointerType() const
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
Base class for declarations which introduce a typedef-name.
void setType(QualType newType)
Represents a variable declaration or definition.
The API notes manager helps find API notes associated with declarations.
llvm::SmallVector< APINotesReader *, 2 > findAPINotes(SourceLocation Loc)
Find the API notes readers that correspond to the given source location.
Captures the completed versioned information for a particular part of API notes, including both unver...
unsigned size() const
Return the number of versioned results we know about.
std::optional< unsigned > getSelected() const
Retrieve the selected index in the result set.
A class that reads API notes data from a binary file that was written by the APINotesWriter.
std::optional< llvm::SmallVector< std::string, 4 > > getParameterSelectorSpellingsForDiagnostics(const APINotesFunctionSelectorKey &Key)
Reconstruct parameter selector strings for a stored exact selector key.
void collectExactFunctionParameterSelectors(llvm::SmallVectorImpl< APINotesFunctionSelectorKey > &Selectors)
Collect exact parameter selector keys stored by this reader.
Describes API notes data for a C++ method.
std::optional< ParamInfo > This
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 UnavailableMsg
Message to use when this entity is unavailable.
std::optional< SwiftSafetyKind > getSwiftSafety() const
std::optional< bool > isSwiftPrivate() const
Describes API notes for types.
std::optional< std::string > getSwiftConformance() const
const std::optional< std::string > & getSwiftBridge() const
const std::optional< std::string > & getNSErrorDomain() const
Describes API notes data for an Objective-C class or protocol or a C++ namespace.
std::optional< bool > getSwiftImportAsNonGeneric() const
std::optional< bool > getSwiftObjCMembers() const
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.
std::optional< RetainCountConventionKind > getRetainCountConvention() const
std::vector< ParamInfo > Params
The function parameters.
NullabilityKind getReturnTypeInfo() const
NullabilityKind getParamTypeInfo(unsigned index) const
std::string ResultType
The result type of this function, as a C type.
unsigned UnsafeBufferUsage
Whether the function has the [[clang::unsafe_buffer_usage]] attribute.
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.
Describes API notes data for an Objective-C property.
std::optional< bool > getSwiftImportAsAccessors() const
Describes a function or method parameter.
std::optional< bool > isNoEscape() const
std::optional< bool > isLifetimebound() const
std::optional< RetainCountConventionKind > getRetainCountConvention() const
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
std::optional< std::string > SwiftDestroyOp
std::optional< bool > isFlagEnum() const
std::optional< bool > isSwiftCopyable() const
std::optional< bool > isSwiftEscapable() const
Describes API notes data for a typedef.
std::optional< SwiftNewTypeKind > SwiftWrapper
API notes for a variable/property.
const std::string & getType() const
NullabilityKindOrNone getNullability() const
SwiftNewTypeKind
The kind of a swift_wrapper/swift_newtype.
EnumExtensibilityKind
The payload for an enum_extensibility attribute.
std::string formatAPINotesParameterSelector(RangeT &&Parameters)
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
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.
@ Property
The type of a property.
const FunctionProtoType * T
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
U cast(CodeGen::Address addr)
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
APINotesParameterSelector Source
std::optional< APINotesParameterSelector > Desugared
SmallVector< std::string, 4 > Parameters
bool operator==(const APINotesParameterSelector &Other) const
bool operator!=(const APINotesParameterSelector &Other) const
Tracks exact Where.Parameters selectors from one API notes reader.
void markUsed(const api_notes::APINotesFunctionSelectorKey &Key)
void diagnoseUnused(Sema &S, api_notes::APINotesReader &Reader) const
llvm::DenseMap< api_notes::APINotesFunctionSelectorKey, bool > SelectorUsed
Exact Where.Parameters selector keys stored by API notes.
void markCandidatesUsed(llvm::function_ref< std::optional< api_notes::APINotesFunctionSelectorKey >(llvm::ArrayRef< std::string >)> GetSelectorKey, const APINotesParameterSelectorCandidates &Candidates)
llvm::DenseMap< api_notes::APINotesFunctionSelectorKey, APINotesSelectorDiagnosticName > SeenNames
Maps broad/name-only keys to a declaration location/name used for diagnostics.
APINotesSelectorDiagnosticReaderState & getOrCreateReaderState(api_notes::APINotesReader &Reader)
void diagnoseUnused(Sema &S) const
llvm::DenseMap< api_notes::APINotesReader *, APINotesSelectorDiagnosticReaderState > Readers
Describes how types, statements, expressions, and declarations should be printed.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned IncludeNewlines
When true, include newlines after statements like "break", etc.
A temporary reference to an Objective-C selector, suitable for referencing selector data on the stack...
llvm::ArrayRef< llvm::StringRef > Identifiers