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;
1006 if (!AttributedType::stripOuterNullability(ParamType))
1020 return !(*
this ==
Other);
1058static std::optional<APINotesParameterSelectorCandidates>
1062 return std::nullopt;
1067 Desugared.
Parameters.reserve(FPT->getNumParams());
1071 for (
QualType ParamType : FPT->param_types()) {
1076 ParamType, S.
Context, Policy,
true));
1079 if (Candidates.
Source != Desugared)
1080 Candidates.
Desugared = std::move(Desugared);
1088 auto [StateIt, Inserted] =
Readers.try_emplace(&Reader);
1095 State.addSelectors(Selectors);
1103 std::make_unique<APINotesSelectorDiagnosticState>();
1109 llvm::function_ref<std::optional<api_notes::APINotesFunctionSelectorKey>(
1116 if (
auto Key = GetSelectorKey(Candidates.
Desugared->Parameters))
1124template <
typename SpecificInfo,
typename SpecificDecl>
1126 Sema &S, SpecificDecl *D,
1132 auto Info = LookupExact(
Selector.Parameters);
1133 if (Info.size() == 0)
1140 if (ProcessSelector(ParameterSelectorCandidates.
Source))
1143 if (ParameterSelectorCandidates.
Desugared)
1144 ProcessSelector(*ParameterSelectorCandidates.
Desugared);
1155 if (Readers.empty())
1160 if (DC->isFileContext() || DC->isNamespace() ||
1161 DC->getDeclKind() == Decl::LinkageSpec) {
1162 std::optional<api_notes::Context> APINotesContext =
1165 if (
auto VD = dyn_cast<VarDecl>(D)) {
1166 for (
auto Reader : Readers) {
1168 Reader->lookupGlobalVariable(VD->getName(), APINotesContext);
1176 if (
auto FD = dyn_cast<FunctionDecl>(D)) {
1177 if (FD->getDeclName().isIdentifier()) {
1178 auto ParameterSelectorCandidates =
1181 for (
auto Reader : Readers) {
1183 Reader->lookupGlobalFunction(FD->getName(), APINotesContext);
1186 if (ParameterSelectorCandidates)
1188 *
this, FD, *ParameterSelectorCandidates,
1190 return Reader->lookupGlobalFunction(FD->getName(), Parameters,
1194 if (ParameterSelectorCandidates) {
1195 auto &DiagnosticState =
1197 if (
auto BroadKey = Reader->getGlobalFunctionSelectorKey(
1198 FD->getName(), APINotesContext))
1199 DiagnosticState.noteSeenDeclaration(*BroadKey, FD->getName(),
1201 DiagnosticState.markCandidatesUsed(
1203 return Reader->getGlobalFunctionSelectorKey(
1204 FD->getName(), Parameters, APINotesContext);
1206 *ParameterSelectorCandidates);
1215 if (
auto Class = dyn_cast<ObjCInterfaceDecl>(D)) {
1216 for (
auto Reader : Readers) {
1217 auto Info = Reader->lookupObjCClassInfo(
Class->getName());
1225 if (
auto Protocol = dyn_cast<ObjCProtocolDecl>(D)) {
1226 for (
auto Reader : Readers) {
1227 auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName());
1235 if (
auto Tag = dyn_cast<TagDecl>(D)) {
1241 if (
auto typedefName = Tag->getTypedefNameForAnonDecl())
1251 std::string MacroName =
1252 LookupName.empty() && Tag->getOuterLocStart().isMacroID()
1254 Tag->getOuterLocStart(),
1255 Tag->getASTContext().getSourceManager(),
LangOpts)
1260 (MacroName ==
"CF_OPTIONS" || MacroName ==
"NS_OPTIONS" ||
1261 MacroName ==
"OBJC_OPTIONS" || MacroName ==
"SWIFT_OPTIONS")) {
1268 for (
auto Reader : Readers) {
1269 if (
auto ParentTag = dyn_cast<TagDecl>(Tag->getDeclContext()))
1271 auto Info = Reader->lookupTag(
LookupName, APINotesContext);
1279 if (
auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
1280 for (
auto Reader : Readers) {
1281 auto Info = Reader->lookupTypedef(
Typedef->getName(), APINotesContext);
1290 if (DC->getRedeclContext()->isFileContext() ||
1291 DC->getRedeclContext()->isExternCContext()) {
1292 if (
auto EnumConstant = dyn_cast<EnumConstantDecl>(D)) {
1293 for (
auto Reader : Readers) {
1294 auto Info = Reader->lookupEnumConstant(EnumConstant->getName());
1302 if (
auto ObjCContainer = dyn_cast<ObjCContainerDecl>(DC)) {
1305 -> std::optional<api_notes::ContextID> {
1306 if (
auto Protocol = dyn_cast<ObjCProtocolDecl>(ObjCContainer)) {
1307 if (
auto Found = Reader->lookupObjCProtocolID(Protocol->getName()))
1310 return std::nullopt;
1313 if (
auto Impl = dyn_cast<ObjCCategoryImplDecl>(ObjCContainer)) {
1314 if (
auto Cat = Impl->getCategoryDecl())
1315 ObjCContainer = Cat->getClassInterface();
1317 return std::nullopt;
1320 if (
auto Category = dyn_cast<ObjCCategoryDecl>(ObjCContainer)) {
1321 if (Category->getClassInterface())
1322 ObjCContainer = Category->getClassInterface();
1324 return std::nullopt;
1327 if (
auto Impl = dyn_cast<ObjCImplDecl>(ObjCContainer)) {
1328 if (Impl->getClassInterface())
1329 ObjCContainer = Impl->getClassInterface();
1331 return std::nullopt;
1334 if (
auto Class = dyn_cast<ObjCInterfaceDecl>(ObjCContainer)) {
1335 if (
auto Found = Reader->lookupObjCClassID(
Class->getName()))
1338 return std::nullopt;
1341 return std::nullopt;
1345 if (
auto Method = dyn_cast<ObjCMethodDecl>(D)) {
1346 for (
auto Reader : Readers) {
1347 if (
auto Context = GetContext(Reader)) {
1354 for (
unsigned i = 0, n = Sel.
getNumArgs(); i != n; ++i)
1362 auto Info = Reader->lookupObjCMethod(*
Context, SelectorRef,
1363 Method->isInstanceMethod());
1370 if (
auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
1372 if (
auto Context = GetContext(Reader)) {
1373 bool isInstanceProperty =
1374 (
Property->getPropertyAttributesAsWritten() &
1377 isInstanceProperty);
1386 if (
auto TagContext = dyn_cast<TagDecl>(DC)) {
1387 if (
auto CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
1391 auto ParameterSelectorCandidates =
1393 for (
auto Reader : Readers) {
1395 std::string MethodName;
1396 if (CXXMethod->isOverloadedOperator())
1398 std::string(
"operator") +
1401 MethodName = CXXMethod->getName();
1403 auto Info = Reader->lookupCXXMethod(
Context->id, MethodName);
1406 if (ParameterSelectorCandidates)
1408 *
this, CXXMethod, *ParameterSelectorCandidates,
1410 return Reader->lookupCXXMethod(
Context->id, MethodName,
1414 if (ParameterSelectorCandidates) {
1415 auto &DiagnosticState =
1418 Reader->getCXXMethodSelectorKey(
Context->id, MethodName))
1419 DiagnosticState.noteSeenDeclaration(*BroadKey, MethodName,
1420 CXXMethod->getLocation());
1421 DiagnosticState.markCandidatesUsed(
1423 return Reader->getCXXMethodSelectorKey(
1424 Context->id, MethodName, Parameters);
1426 *ParameterSelectorCandidates);
1433 if (
auto Field = dyn_cast<FieldDecl>(D)) {
1434 if (!Field->isUnnamedBitField() && !Field->isAnonymousStructOrUnion()) {
1435 for (
auto Reader : Readers) {
1437 auto Info = Reader->lookupField(
Context->id, Field->getName());
1444 if (
auto Tag = dyn_cast<TagDecl>(D)) {
1445 for (
auto Reader : Readers) {
1447 auto Info = Reader->lookupTag(Tag->getName(),
Context);
1466 std::optional<SmallVector<std::string, 4>> ParameterSpellings =
1468 if (!ParameterSpellings)
1471 S.
Diag(SeenName->second.Loc, diag::warn_apinotes_message)
1472 << (llvm::Twine(
"API notes entry for '") + SeenName->second.Name +
1473 "' has unmatched Where.Parameters " +
1480 for (
const auto &ReaderSelectors :
Readers)
1481 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 void stripAPINotesParameterNullability(QualType &ParamType)
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.
std::string getAsString() const
void * getAsOpaquePtr() const
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)
The JSON file list parser is used to communicate input to InstallAPI.
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