31enum class IsActive_t :
bool { Inactive, Active };
32enum class IsSubstitution_t :
bool { Original, Replacement };
34struct VersionedInfoMetadata {
37 unsigned IsActive : 1;
38 unsigned IsReplacement : 1;
40 VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
41 IsSubstitution_t Replacement)
42 : Version(Version), IsActive(Active == IsActive_t::Active),
43 IsReplacement(Replacement == IsSubstitution_t::Replacement) {}
58 VersionedInfoMetadata metadata) {
59 if (typeString.empty())
66 auto *typeAttr = SwiftTypeAttr::CreateImplicit(S.
Context, typeString);
67 auto *versioned = SwiftVersionedAdditionAttr::CreateImplicit(
68 S.
Context, metadata.Version, typeAttr, metadata.IsReplacement);
69 decl->addAttr(versioned);
71 if (!metadata.IsActive)
79 VersionedInfoMetadata metadata) {
83 SwiftNullabilityAttr::Kind attrNullabilityKind;
84 switch (nullability) {
86 attrNullabilityKind = SwiftNullabilityAttr::Kind::NonNull;
89 attrNullabilityKind = SwiftNullabilityAttr::Kind::Nullable;
92 attrNullabilityKind = SwiftNullabilityAttr::Kind::Unspecified;
95 attrNullabilityKind = SwiftNullabilityAttr::Kind::NullableResult;
98 auto *nullabilityAttr =
99 SwiftNullabilityAttr::CreateImplicit(S.
Context, attrNullabilityKind);
100 auto *versioned = SwiftVersionedAdditionAttr::CreateImplicit(
101 S.
Context, metadata.Version, nullabilityAttr, metadata.IsReplacement);
102 decl->addAttr(versioned);
105 if (!metadata.IsActive)
114 void *mem = Ctx.
Allocate(String.size(),
alignof(
char *));
115 memcpy(mem, String.data(), String.size());
116 return StringRef(
static_cast<char *
>(mem), String.size());
128template <
typename A>
struct AttrKindFor {};
131 template <> struct AttrKindFor<X##Attr> { \
132 static const attr::Kind value = attr::X; \
134#include "clang/Basic/AttrList.inc"
142void handleAPINotedAttribute(
143 Sema &S,
Decl *D,
bool IsAddition, VersionedInfoMetadata Metadata,
144 llvm::function_ref<A *()> CreateAttr,
146 if (Metadata.IsActive) {
147 auto Existing = GetExistingAttr(D);
151 auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(
152 S.
Context, Metadata.Version, *Existing,
true);
160 if (
auto Attr = CreateAttr())
167 if (
auto Attr = CreateAttr()) {
168 auto *Versioned = SwiftVersionedAdditionAttr::CreateImplicit(
170 Metadata.IsReplacement);
177 auto *Versioned = SwiftVersionedRemovalAttr::CreateImplicit(
178 S.
Context, Metadata.Version, AttrKindFor<A>::value,
179 Metadata.IsReplacement);
185void handleAPINotedAttribute(
Sema &S,
Decl *D,
bool ShouldAddAttribute,
186 VersionedInfoMetadata Metadata,
187 llvm::function_ref<A *()> CreateAttr) {
188 handleAPINotedAttribute<A>(
189 S, D, ShouldAddAttribute, Metadata, CreateAttr, [](
const Decl *D) {
190 return llvm::find_if(D->
attrs(),
191 [](
const Attr *
Next) { return isa<A>(Next); });
198 bool ShouldAddAttribute,
199 VersionedInfoMetadata Metadata) {
202 handleAPINotedAttribute<A>(
203 S, D, ShouldAddAttribute, Metadata,
206 return llvm::find_if(D->
attrs(), [](
const Attr *
Next) ->
bool {
207 return isa<CFReturnsRetainedAttr>(Next) ||
208 isa<CFReturnsNotRetainedAttr>(Next) ||
209 isa<NSReturnsRetainedAttr>(Next) ||
210 isa<NSReturnsNotRetainedAttr>(Next) ||
211 isa<CFAuditedTransferAttr>(Next);
217 Sema &S,
Decl *D, VersionedInfoMetadata Metadata,
218 std::optional<api_notes::RetainCountConventionKind> Convention) {
221 switch (*Convention) {
225 S, D,
true, Metadata);
228 S, D,
false, Metadata);
233 S, D,
true, Metadata);
237 S, D,
true, Metadata);
241 S, D,
true, Metadata);
245 S, D,
true, Metadata);
252 VersionedInfoMetadata Metadata) {
255 handleAPINotedAttribute<UnavailableAttr>(S, D,
true, Metadata, [&] {
263 handleAPINotedAttribute<AvailabilityAttr>(
264 S, D,
true, Metadata,
266 return new (S.
Context) AvailabilityAttr(
278 return llvm::find_if(D->
attrs(), [](
const Attr *next) ->
bool {
279 if (const auto *AA = dyn_cast<AvailabilityAttr>(next))
280 if (const auto *II = AA->getPlatform())
281 return II->isStr(
"swift");
289 handleAPINotedAttribute<SwiftPrivateAttr>(
290 S, D, *SwiftPrivate, Metadata, [&] {
299 handleAPINotedAttribute<SwiftAttrAttr>(
302 return SwiftAttrAttr::Create(
309 if (const auto *swiftAttr = dyn_cast<SwiftAttrAttr>(attr)) {
310 if (swiftAttr->getAttribute() ==
"safe" ||
311 swiftAttr->getAttribute() ==
"unsafe")
320 if (!Info.SwiftName.empty()) {
321 handleAPINotedAttribute<SwiftNameAttr>(
322 S, D,
true, Metadata, [&]() -> SwiftNameAttr * {
328 nullptr,
nullptr,
nullptr, ParsedAttr::Form::GNU());
343 VersionedInfoMetadata Metadata) {
346 handleAPINotedAttribute<SwiftBridgeAttr>(
347 S, D, !SwiftBridge->empty(), Metadata, [&] {
348 return new (S.Context)
349 SwiftBridgeAttr(S.Context, getPlaceholderAttrInfo(),
350 ASTAllocateString(S.Context, *SwiftBridge));
356 handleAPINotedAttribute<NSErrorDomainAttr>(
357 S, D, !NSErrorDomain->empty(), Metadata, [&] {
358 return new (S.Context)
359 NSErrorDomainAttr(S.Context, getPlaceholderAttrInfo(),
360 &S.Context.Idents.get(*NSErrorDomain));
366 SwiftAttrAttr::Create(S.
Context,
"conforms_to:" + ConformsTo.value()));
380 S.
Diag(Loc, diag::err_incompatible_replacement_type)
381 << ReplacementType << OrigType;
395 if (
auto Var = dyn_cast<VarDecl>(D)) {
404 Var->getType(),
Type)) {
408 }
else if (
auto property = dyn_cast<ObjCPropertyDecl>(D)) {
410 property->getType(),
Type)) {
413 }
else if (
auto field = dyn_cast<FieldDecl>(D)) {
415 field->getType(),
Type)) {
416 field->setType(
Type);
420 llvm_unreachable(
"API notes allowed a type on an unknown declaration");
434 return (QT.getTypePtr() != Original.getTypePtr()) ? std::optional(QT)
438 if (
auto Function = dyn_cast<FunctionDecl>(D)) {
440 GetModified(D,
Function->getReturnType(), Nullability)) {
444 *Modified, proto->getParamTypes(), proto->getExtProtoInfo()));
449 }
else if (
auto Method = dyn_cast<ObjCMethodDecl>(D)) {
450 if (
auto Modified = GetModified(D,
Method->getReturnType(), Nullability)) {
451 Method->setReturnType(*Modified);
458 }
else if (
auto Value = dyn_cast<ValueDecl>(D)) {
459 if (
auto Modified = GetModified(D,
Value->
getType(), Nullability)) {
460 Value->setType(*Modified);
463 if (
auto Parm = dyn_cast<ParmVarDecl>(D)) {
469 }
else if (
auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
470 if (
auto Modified = GetModified(D,
Property->getType(), Nullability)) {
484 VersionedInfoMetadata Metadata) {
500 VersionedInfoMetadata Metadata) {
503 handleAPINotedAttribute<NoEscapeAttr>(S, D, *NoEscape, Metadata, [&] {
508 handleAPINotedAttribute<LifetimeBoundAttr>(
509 S, D, *Lifetimebound, Metadata, [&] {
526 VersionedInfoMetadata metadata) {
535 VersionedInfoMetadata metadata) {
544 VersionedInfoMetadata Metadata) {
550 handleAPINotedAttribute<SwiftImportPropertyAsAccessorsAttr>(
551 S, D, *AsAccessors, Metadata, [&] {
552 return new (S.
Context) SwiftImportPropertyAsAccessorsAttr(
559typedef llvm::PointerUnion<FunctionDecl *, ObjCMethodDecl *> FunctionOrMethod;
565 VersionedInfoMetadata Metadata) {
575 assert((FD || MD) &&
"Expecting Function or ObjCMethod");
583 handleAPINotedAttribute<UnsafeBufferUsageAttr>(S, D,
true, Metadata, [&]() {
592 bool AnyTypeChanged =
false;
593 for (
unsigned I = 0; I != NumParams; ++I) {
595 QualType ParamTypeBefore = Param->getType();
597 if (I < Info.
Params.size())
604 if (ParamTypeBefore.
getAsOpaquePtr() != Param->getType().getAsOpaquePtr())
605 AnyTypeChanged =
true;
615 if (Metadata.IsActive && !Info.
ResultType.empty() &&
625 auto ResultTypeInfo =
632 OverriddenResultType = ResultType;
633 AnyTypeChanged =
true;
640 if (FD && AnyTypeChanged) {
642 if (OverriddenResultType.
isNull())
643 OverriddenResultType = fnProtoType->getReturnType();
647 ParamTypes.push_back(Param->getType());
650 fnProtoType->getExtProtoInfo()));
651 }
else if (!OverriddenResultType.
isNull()) {
654 OverriddenResultType, FnNoProtoType->getExtInfo()));
670 VersionedInfoMetadata Metadata) {
671 if (Info.
This && Info.
This->isLifetimebound() &&
673 auto MethodType = Method->getType();
679 TLB.
pushFullCopy(Method->getTypeSourceInfo()->getTypeLoc());
682 Method->setType(AttributedType);
692 VersionedInfoMetadata Metadata) {
701 VersionedInfoMetadata Metadata) {
710 VersionedInfoMetadata Metadata) {
713 handleAPINotedAttribute<ObjCDesignatedInitializerAttr>(
714 S, D,
true, Metadata, [&] {
716 IFace->setHasDesignatedInitializers();
718 return new (S.
Context) ObjCDesignatedInitializerAttr(
730 if (A->getAttribute() == Attribute)
738 VersionedInfoMetadata Metadata) {
740 D->
addAttr(SwiftAttrAttr::Create(S.
Context,
"import_" + ImportAs.value()));
743 D->
addAttr(SwiftAttrAttr::Create(S.
Context,
"retain:" + RetainOp.value()));
747 SwiftAttrAttr::Create(S.
Context,
"release:" + ReleaseOp.value()));
750 SwiftAttrAttr::Create(S.
Context,
"destroy:" + DestroyOp.value()));
752 D->
addAttr(SwiftAttrAttr::Create(
753 S.
Context,
"returned_as_" + DefaultOwnership.value() +
"_by_default"));
766 bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None);
767 handleAPINotedAttribute<EnumExtensibilityAttr>(
768 S, D, ShouldAddAttribute, Metadata, [&] {
769 EnumExtensibilityAttr::Kind
kind;
770 switch (*Extensibility) {
771 case EnumExtensibilityKind::None:
772 llvm_unreachable(
"remove only");
773 case EnumExtensibilityKind::Open:
774 kind = EnumExtensibilityAttr::Open;
776 case EnumExtensibilityKind::Closed:
777 kind = EnumExtensibilityAttr::Closed;
786 handleAPINotedAttribute<FlagEnumAttr>(S, D, *FlagEnum, Metadata, [&] {
799 VersionedInfoMetadata Metadata) {
804 handleAPINotedAttribute<SwiftNewTypeAttr>(
805 S, D, *SwiftWrapper != SwiftWrapperKind::None, Metadata, [&] {
806 SwiftNewTypeAttr::NewtypeKind Kind;
807 switch (*SwiftWrapper) {
808 case SwiftWrapperKind::None:
809 llvm_unreachable(
"Shouldn't build an attribute");
811 case SwiftWrapperKind::Struct:
812 Kind = SwiftNewTypeAttr::NK_Struct;
815 case SwiftWrapperKind::Enum:
816 Kind = SwiftNewTypeAttr::NK_Enum;
821 AttributeCommonInfo::AT_SwiftNewType,
824 return new (S.
Context) SwiftNewTypeAttr(S.
Context, SyntaxInfo, Kind);
836 VersionedInfoMetadata Metadata) {
845 VersionedInfoMetadata Metadata) {
847 handleAPINotedAttribute<SwiftImportAsNonGenericAttr>(
848 S, D, *AsNonGeneric, Metadata, [&] {
855 handleAPINotedAttribute<SwiftObjCMembersAttr>(
856 S, D, *ObjcMembers, Metadata, [&] {
875template <
typename SpecificInfo>
879 if (D->
hasAttr<SwiftNameAttr>())
885 VersionTuple SelectedVersion;
886 SpecificInfo SelectedInfoSlice;
887 std::tie(SelectedVersion, SelectedInfoSlice) = Info[*Info.
getSelected()];
888 if (SelectedVersion.empty())
890 if (SelectedInfoSlice.SwiftName.empty())
894 for (
const auto &VersionAndInfoSlice : Info) {
895 if (!VersionAndInfoSlice.first.empty())
897 if (!VersionAndInfoSlice.second.SwiftName.empty())
902 VersionedInfoMetadata DummyFutureMetadata(
903 SelectedVersion, IsActive_t::Inactive, IsSubstitution_t::Replacement);
904 handleAPINotedAttribute<SwiftNameAttr>(
905 S, D,
false, DummyFutureMetadata, []() -> SwiftNameAttr * {
906 llvm_unreachable(
"should not try to add an attribute here");
913template <
typename SpecificDecl,
typename SpecificInfo>
915 Sema &S, SpecificDecl *D,
923 VersionTuple Version;
924 SpecificInfo InfoSlice;
925 for (
unsigned i = 0, e = Info.
size(); i != e; ++i) {
926 std::tie(Version, InfoSlice) = Info[i];
927 auto Active = (i == Selected) ? IsActive_t::Active : IsActive_t::Inactive;
928 auto Replacement = IsSubstitution_t::Original;
934 Active = IsActive_t::Inactive;
935 Replacement = IsSubstitution_t::Original;
936 }
else if (Active == IsActive_t::Inactive && Version.empty()) {
937 Replacement = IsSubstitution_t::Replacement;
938 Version = Info[Selected].first;
942 VersionedInfoMetadata(Version, Active, Replacement));
946static std::optional<api_notes::Context>
948 if (
auto NamespaceContext = dyn_cast<NamespaceDecl>(DC)) {
949 for (
auto Reader : APINotes.
findAPINotes(NamespaceContext->getLocation())) {
951 std::stack<NamespaceDecl *> NamespaceStack;
953 for (
auto CurrentNamespace = NamespaceContext; CurrentNamespace;
955 dyn_cast<NamespaceDecl>(CurrentNamespace->getParent())) {
956 if (!CurrentNamespace->isInlineNamespace())
957 NamespaceStack.push(CurrentNamespace);
960 std::optional<api_notes::ContextID> NamespaceID;
961 while (!NamespaceStack.empty()) {
962 auto CurrentNamespace = NamespaceStack.top();
963 NamespaceStack.pop();
965 Reader->lookupNamespaceID(CurrentNamespace->getName(), NamespaceID);
977static std::optional<api_notes::Context>
979 assert(DC &&
"tag context must not be null");
982 std::stack<TagDecl *> TagStack;
984 for (
auto CurrentTag = DC; CurrentTag;
985 CurrentTag = dyn_cast<TagDecl>(CurrentTag->getParent()))
986 TagStack.push(CurrentTag);
988 assert(!TagStack.empty());
989 std::optional<api_notes::Context> Ctx =
991 while (!TagStack.empty()) {
992 auto CurrentTag = TagStack.top();
994 auto CtxID = Reader->lookupTagID(CurrentTag->getName(), Ctx);
1001 return std::nullopt;
1013 return !(*
this ==
Other);
1052static std::optional<APINotesParameterSelectorCandidates>
1056 return std::nullopt;
1061 Desugared.
Parameters.reserve(FPT->getNumParams());
1065 for (
QualType ParamType : FPT->param_types()) {
1070 ParamType, S.
Context, Policy,
true));
1073 if (Candidates.
Source != Desugared)
1074 Candidates.
Desugared = std::move(Desugared);
1082 auto [StateIt, Inserted] =
Readers.try_emplace(&Reader);
1089 State.addSelectors(Selectors);
1097 std::make_unique<APINotesSelectorDiagnosticState>();
1103 llvm::function_ref<std::optional<api_notes::APINotesFunctionSelectorKey>(
1110 if (
auto Key = GetSelectorKey(Candidates.
Desugared->Parameters))
1118template <
typename SpecificInfo,
typename SpecificDecl>
1120 Sema &S, SpecificDecl *D,
1126 auto Info = LookupExact(
Selector.Parameters);
1127 if (Info.size() == 0)
1134 if (ProcessSelector(ParameterSelectorCandidates.
Source))
1137 if (ParameterSelectorCandidates.
Desugared)
1138 ProcessSelector(*ParameterSelectorCandidates.
Desugared);
1149 if (Readers.empty())
1154 if (DC->isFileContext() || DC->isNamespace() ||
1155 DC->getDeclKind() == Decl::LinkageSpec) {
1156 std::optional<api_notes::Context> APINotesContext =
1159 if (
auto VD = dyn_cast<VarDecl>(D)) {
1160 for (
auto Reader : Readers) {
1162 Reader->lookupGlobalVariable(VD->getName(), APINotesContext);
1170 if (
auto FD = dyn_cast<FunctionDecl>(D)) {
1171 if (FD->getDeclName().isIdentifier()) {
1172 auto ParameterSelectorCandidates =
1175 for (
auto Reader : Readers) {
1177 Reader->lookupGlobalFunction(FD->getName(), APINotesContext);
1180 if (ParameterSelectorCandidates)
1182 *
this, FD, *ParameterSelectorCandidates,
1184 return Reader->lookupGlobalFunction(FD->getName(), Parameters,
1188 if (ParameterSelectorCandidates) {
1189 auto &DiagnosticState =
1191 if (
auto BroadKey = Reader->getGlobalFunctionSelectorKey(
1192 FD->getName(), APINotesContext))
1193 DiagnosticState.noteSeenDeclaration(*BroadKey, FD->getName(),
1195 DiagnosticState.markCandidatesUsed(
1197 return Reader->getGlobalFunctionSelectorKey(
1198 FD->getName(), Parameters, APINotesContext);
1200 *ParameterSelectorCandidates);
1209 if (
auto Class = dyn_cast<ObjCInterfaceDecl>(D)) {
1210 for (
auto Reader : Readers) {
1211 auto Info = Reader->lookupObjCClassInfo(
Class->getName());
1219 if (
auto Protocol = dyn_cast<ObjCProtocolDecl>(D)) {
1220 for (
auto Reader : Readers) {
1221 auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName());
1229 if (
auto Tag = dyn_cast<TagDecl>(D)) {
1235 if (
auto typedefName = Tag->getTypedefNameForAnonDecl())
1245 std::string MacroName =
1246 LookupName.empty() && Tag->getOuterLocStart().isMacroID()
1248 Tag->getOuterLocStart(),
1249 Tag->getASTContext().getSourceManager(),
LangOpts)
1254 (MacroName ==
"CF_OPTIONS" || MacroName ==
"NS_OPTIONS" ||
1255 MacroName ==
"OBJC_OPTIONS" || MacroName ==
"SWIFT_OPTIONS")) {
1262 for (
auto Reader : Readers) {
1263 if (
auto ParentTag = dyn_cast<TagDecl>(Tag->getDeclContext()))
1265 auto Info = Reader->lookupTag(
LookupName, APINotesContext);
1273 if (
auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
1274 for (
auto Reader : Readers) {
1275 auto Info = Reader->lookupTypedef(
Typedef->getName(), APINotesContext);
1284 if (DC->getRedeclContext()->isFileContext() ||
1285 DC->getRedeclContext()->isExternCContext()) {
1286 if (
auto EnumConstant = dyn_cast<EnumConstantDecl>(D)) {
1287 for (
auto Reader : Readers) {
1288 auto Info = Reader->lookupEnumConstant(EnumConstant->getName());
1296 if (
auto ObjCContainer = dyn_cast<ObjCContainerDecl>(DC)) {
1299 -> std::optional<api_notes::ContextID> {
1300 if (
auto Protocol = dyn_cast<ObjCProtocolDecl>(ObjCContainer)) {
1301 if (
auto Found = Reader->lookupObjCProtocolID(Protocol->getName()))
1304 return std::nullopt;
1307 if (
auto Impl = dyn_cast<ObjCCategoryImplDecl>(ObjCContainer)) {
1308 if (
auto Cat = Impl->getCategoryDecl())
1309 ObjCContainer = Cat->getClassInterface();
1311 return std::nullopt;
1314 if (
auto Category = dyn_cast<ObjCCategoryDecl>(ObjCContainer)) {
1315 if (Category->getClassInterface())
1316 ObjCContainer = Category->getClassInterface();
1318 return std::nullopt;
1321 if (
auto Impl = dyn_cast<ObjCImplDecl>(ObjCContainer)) {
1322 if (Impl->getClassInterface())
1323 ObjCContainer = Impl->getClassInterface();
1325 return std::nullopt;
1328 if (
auto Class = dyn_cast<ObjCInterfaceDecl>(ObjCContainer)) {
1329 if (
auto Found = Reader->lookupObjCClassID(
Class->getName()))
1332 return std::nullopt;
1335 return std::nullopt;
1339 if (
auto Method = dyn_cast<ObjCMethodDecl>(D)) {
1340 for (
auto Reader : Readers) {
1341 if (
auto Context = GetContext(Reader)) {
1348 for (
unsigned i = 0, n = Sel.
getNumArgs(); i != n; ++i)
1356 auto Info = Reader->lookupObjCMethod(*
Context, SelectorRef,
1357 Method->isInstanceMethod());
1364 if (
auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
1366 if (
auto Context = GetContext(Reader)) {
1367 bool isInstanceProperty =
1368 (
Property->getPropertyAttributesAsWritten() &
1371 isInstanceProperty);
1380 if (
auto TagContext = dyn_cast<TagDecl>(DC)) {
1381 if (
auto CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
1385 auto ParameterSelectorCandidates =
1387 for (
auto Reader : Readers) {
1389 std::string MethodName;
1390 if (CXXMethod->isOverloadedOperator())
1392 std::string(
"operator") +
1395 MethodName = CXXMethod->getName();
1397 auto Info = Reader->lookupCXXMethod(
Context->id, MethodName);
1400 if (ParameterSelectorCandidates)
1402 *
this, CXXMethod, *ParameterSelectorCandidates,
1404 return Reader->lookupCXXMethod(
Context->id, MethodName,
1408 if (ParameterSelectorCandidates) {
1409 auto &DiagnosticState =
1412 Reader->getCXXMethodSelectorKey(
Context->id, MethodName))
1413 DiagnosticState.noteSeenDeclaration(*BroadKey, MethodName,
1414 CXXMethod->getLocation());
1415 DiagnosticState.markCandidatesUsed(
1417 return Reader->getCXXMethodSelectorKey(
1418 Context->id, MethodName, Parameters);
1420 *ParameterSelectorCandidates);
1427 if (
auto Field = dyn_cast<FieldDecl>(D)) {
1428 if (!Field->isUnnamedBitField() && !Field->isAnonymousStructOrUnion()) {
1429 for (
auto Reader : Readers) {
1431 auto Info = Reader->lookupField(
Context->id, Field->getName());
1438 if (
auto Tag = dyn_cast<TagDecl>(D)) {
1439 for (
auto Reader : Readers) {
1441 auto Info = Reader->lookupTag(Tag->getName(),
Context);
1460 std::optional<SmallVector<std::string, 4>> ParameterSpellings =
1462 if (!ParameterSpellings)
1465 S.
Diag(SeenName->second.Loc, diag::warn_apinotes_message)
1466 << (llvm::Twine(
"API notes entry for '") + SeenName->second.Name +
1467 "' has unmatched Where.Parameters " +
1474 for (
const auto &ReaderSelectors :
Readers)
1475 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)
static void ProcessVersionedAPINotes(Sema &S, SpecificDecl *D, const api_notes::APINotesReader::VersionedInfo< SpecificInfo > Info)
Processes all versions of versioned API notes.
static bool checkAPINotesReplacementType(Sema &S, SourceLocation Loc, QualType OrigType, QualType ReplacementType)
Check that the replacement type provided by API notes is reasonable.
static void processExactAPINotes(Sema &S, SpecificDecl *D, const APINotesParameterSelectorCandidates &ParameterSelectorCandidates, llvm::function_ref< api_notes::APINotesReader::VersionedInfo< SpecificInfo >(ArrayRef< std::string >)> LookupExact)
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 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 APINotesSelectorDiagnosticReaderState & getAPINotesSelectorDiagnosticState(Sema &S, api_notes::APINotesReader *Reader)
static void maybeAttachUnversionedSwiftName(Sema &S, Decl *D, const api_notes::APINotesReader::VersionedInfo< SpecificInfo > Info)
If we're applying API notes with an active, non-default version, and the versioned API notes have a S...
static bool isIndirectPointerType(QualType Type)
Determine whether this is a multi-level pointer type.
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 FullyQualifiedName
When true, print the fully qualified name of function declarations.
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned IncludeNewlines
When true, include newlines after statements like "break", etc.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.
A temporary reference to an Objective-C selector, suitable for referencing selector data on the stack...
llvm::ArrayRef< llvm::StringRef > Identifiers