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);
253 if (A->getAttribute() == Attribute)
261 VersionedInfoMetadata Metadata) {
264 handleAPINotedAttribute<UnavailableAttr>(S, D,
true, Metadata, [&] {
272 handleAPINotedAttribute<AvailabilityAttr>(
273 S, D,
true, Metadata,
275 return new (S.
Context) AvailabilityAttr(
287 return llvm::find_if(D->
attrs(), [](
const Attr *next) ->
bool {
288 if (const auto *AA = dyn_cast<AvailabilityAttr>(next))
289 if (const auto *II = AA->getPlatform())
290 return II->isStr(
"swift");
298 handleAPINotedAttribute<SwiftPrivateAttr>(
299 S, D, *SwiftPrivate, Metadata, [&] {
308 handleAPINotedAttribute<SwiftAttrAttr>(
311 return SwiftAttrAttr::Create(
318 if (const auto *swiftAttr = dyn_cast<SwiftAttrAttr>(attr)) {
319 if (swiftAttr->getAttribute() ==
"safe" ||
320 swiftAttr->getAttribute() ==
"unsafe")
329 if (!Info.SwiftName.empty()) {
330 handleAPINotedAttribute<SwiftNameAttr>(
331 S, D,
true, Metadata, [&]() -> SwiftNameAttr * {
337 nullptr,
nullptr,
nullptr, ParsedAttr::Form::GNU());
352 VersionedInfoMetadata Metadata) {
355 handleAPINotedAttribute<SwiftBridgeAttr>(
356 S, D, !SwiftBridge->empty(), Metadata, [&] {
357 return new (S.Context)
358 SwiftBridgeAttr(S.Context, getPlaceholderAttrInfo(),
359 ASTAllocateString(S.Context, *SwiftBridge));
365 handleAPINotedAttribute<NSErrorDomainAttr>(
366 S, D, !NSErrorDomain->empty(), Metadata, [&] {
367 return new (S.Context)
368 NSErrorDomainAttr(S.Context, getPlaceholderAttrInfo(),
369 &S.Context.Idents.get(*NSErrorDomain));
388 S.
Diag(Loc, diag::err_incompatible_replacement_type)
389 << ReplacementType << OrigType;
403 if (
auto Var = dyn_cast<VarDecl>(D)) {
412 Var->getType(),
Type)) {
416 }
else if (
auto property = dyn_cast<ObjCPropertyDecl>(D)) {
418 property->getType(),
Type)) {
421 }
else if (
auto field = dyn_cast<FieldDecl>(D)) {
423 field->getType(),
Type)) {
424 field->setType(
Type);
428 llvm_unreachable(
"API notes allowed a type on an unknown declaration");
442 return (QT.getTypePtr() != Original.getTypePtr()) ? std::optional(QT)
446 if (
auto Function = dyn_cast<FunctionDecl>(D)) {
448 GetModified(D,
Function->getReturnType(), Nullability)) {
452 *Modified, proto->getParamTypes(), proto->getExtProtoInfo()));
457 }
else if (
auto Method = dyn_cast<ObjCMethodDecl>(D)) {
458 if (
auto Modified = GetModified(D,
Method->getReturnType(), Nullability)) {
459 Method->setReturnType(*Modified);
466 }
else if (
auto Value = dyn_cast<ValueDecl>(D)) {
467 if (
auto Modified = GetModified(D,
Value->
getType(), Nullability)) {
468 Value->setType(*Modified);
471 if (
auto Parm = dyn_cast<ParmVarDecl>(D)) {
477 }
else if (
auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
478 if (
auto Modified = GetModified(D,
Property->getType(), Nullability)) {
492 VersionedInfoMetadata Metadata) {
508 VersionedInfoMetadata Metadata) {
511 handleAPINotedAttribute<NoEscapeAttr>(S, D, *NoEscape, Metadata, [&] {
516 handleAPINotedAttribute<LifetimeBoundAttr>(
517 S, D, *Lifetimebound, Metadata, [&] {
534 VersionedInfoMetadata metadata) {
543 VersionedInfoMetadata metadata) {
552 VersionedInfoMetadata Metadata) {
558 handleAPINotedAttribute<SwiftImportPropertyAsAccessorsAttr>(
559 S, D, *AsAccessors, Metadata, [&] {
560 return new (S.
Context) SwiftImportPropertyAsAccessorsAttr(
567typedef llvm::PointerUnion<FunctionDecl *, ObjCMethodDecl *> FunctionOrMethod;
573 VersionedInfoMetadata Metadata) {
583 assert((FD || MD) &&
"Expecting Function or ObjCMethod");
591 handleAPINotedAttribute<UnsafeBufferUsageAttr>(S, D,
true, Metadata, [&]() {
600 bool AnyTypeChanged =
false;
601 for (
unsigned I = 0; I != NumParams; ++I) {
603 QualType ParamTypeBefore = Param->getType();
605 if (I < Info.
Params.size())
612 if (ParamTypeBefore.
getAsOpaquePtr() != Param->getType().getAsOpaquePtr())
613 AnyTypeChanged =
true;
622 if (Metadata.IsActive && !Info.
ResultType.empty() &&
632 auto ResultTypeInfo =
639 OverriddenResultType = ResultType;
640 AnyTypeChanged =
true;
647 if (FD && AnyTypeChanged) {
649 if (OverriddenResultType.
isNull())
650 OverriddenResultType = fnProtoType->getReturnType();
654 ParamTypes.push_back(Param->getType());
657 fnProtoType->getExtProtoInfo()));
658 }
else if (!OverriddenResultType.
isNull()) {
661 OverriddenResultType, FnNoProtoType->getExtInfo()));
677 VersionedInfoMetadata Metadata) {
678 if (Info.
This && Info.
This->isLifetimebound() &&
680 auto MethodType = Method->getType();
686 TLB.
pushFullCopy(Method->getTypeSourceInfo()->getTypeLoc());
689 Method->setType(AttributedType);
699 VersionedInfoMetadata Metadata) {
708 VersionedInfoMetadata Metadata) {
717 VersionedInfoMetadata Metadata) {
720 handleAPINotedAttribute<ObjCDesignatedInitializerAttr>(
721 S, D,
true, Metadata, [&] {
723 IFace->setHasDesignatedInitializers();
725 return new (S.
Context) ObjCDesignatedInitializerAttr(
737 VersionedInfoMetadata Metadata) {
750 S, D,
"returned_as_" + DefaultOwnership.value() +
"_by_default");
763 bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None);
764 handleAPINotedAttribute<EnumExtensibilityAttr>(
765 S, D, ShouldAddAttribute, Metadata, [&] {
766 EnumExtensibilityAttr::Kind
kind;
767 switch (*Extensibility) {
768 case EnumExtensibilityKind::None:
769 llvm_unreachable(
"remove only");
770 case EnumExtensibilityKind::Open:
771 kind = EnumExtensibilityAttr::Open;
773 case EnumExtensibilityKind::Closed:
774 kind = EnumExtensibilityAttr::Closed;
783 handleAPINotedAttribute<FlagEnumAttr>(S, D, *FlagEnum, Metadata, [&] {
796 VersionedInfoMetadata Metadata) {
801 handleAPINotedAttribute<SwiftNewTypeAttr>(
802 S, D, *SwiftWrapper != SwiftWrapperKind::None, Metadata, [&] {
803 SwiftNewTypeAttr::NewtypeKind Kind;
804 switch (*SwiftWrapper) {
805 case SwiftWrapperKind::None:
806 llvm_unreachable(
"Shouldn't build an attribute");
808 case SwiftWrapperKind::Struct:
809 Kind = SwiftNewTypeAttr::NK_Struct;
812 case SwiftWrapperKind::Enum:
813 Kind = SwiftNewTypeAttr::NK_Enum;
818 AttributeCommonInfo::AT_SwiftNewType,
821 return new (S.
Context) SwiftNewTypeAttr(S.
Context, SyntaxInfo, Kind);
833 VersionedInfoMetadata Metadata) {
842 VersionedInfoMetadata Metadata) {
844 handleAPINotedAttribute<SwiftImportAsNonGenericAttr>(
845 S, D, *AsNonGeneric, Metadata, [&] {
852 handleAPINotedAttribute<SwiftObjCMembersAttr>(
853 S, D, *ObjcMembers, Metadata, [&] {
872template <
typename SpecificInfo>
876 if (D->
hasAttr<SwiftNameAttr>())
882 VersionTuple SelectedVersion;
883 SpecificInfo SelectedInfoSlice;
884 std::tie(SelectedVersion, SelectedInfoSlice) = Info[*Info.
getSelected()];
885 if (SelectedVersion.empty())
887 if (SelectedInfoSlice.SwiftName.empty())
891 for (
const auto &VersionAndInfoSlice : Info) {
892 if (!VersionAndInfoSlice.first.empty())
894 if (!VersionAndInfoSlice.second.SwiftName.empty())
899 VersionedInfoMetadata DummyFutureMetadata(
900 SelectedVersion, IsActive_t::Inactive, IsSubstitution_t::Replacement);
901 handleAPINotedAttribute<SwiftNameAttr>(
902 S, D,
false, DummyFutureMetadata, []() -> SwiftNameAttr * {
903 llvm_unreachable(
"should not try to add an attribute here");
910template <
typename SpecificDecl,
typename SpecificInfo>
912 Sema &S, SpecificDecl *D,
920 VersionTuple Version;
921 SpecificInfo InfoSlice;
922 for (
unsigned i = 0, e = Info.
size(); i != e; ++i) {
923 std::tie(Version, InfoSlice) = Info[i];
924 auto Active = (i == Selected) ? IsActive_t::Active : IsActive_t::Inactive;
925 auto Replacement = IsSubstitution_t::Original;
931 Active = IsActive_t::Inactive;
932 Replacement = IsSubstitution_t::Original;
933 }
else if (Active == IsActive_t::Inactive && Version.empty()) {
934 Replacement = IsSubstitution_t::Replacement;
935 Version = Info[Selected].first;
939 VersionedInfoMetadata(Version, Active, Replacement));
943static std::optional<api_notes::Context>
945 if (
auto NamespaceContext = dyn_cast<NamespaceDecl>(DC)) {
946 for (
auto Reader : APINotes.
findAPINotes(NamespaceContext->getLocation())) {
948 std::stack<NamespaceDecl *> NamespaceStack;
950 for (
auto CurrentNamespace = NamespaceContext; CurrentNamespace;
952 dyn_cast<NamespaceDecl>(CurrentNamespace->getParent())) {
953 if (!CurrentNamespace->isInlineNamespace())
954 NamespaceStack.push(CurrentNamespace);
957 std::optional<api_notes::ContextID> NamespaceID;
958 while (!NamespaceStack.empty()) {
959 auto CurrentNamespace = NamespaceStack.top();
960 NamespaceStack.pop();
962 Reader->lookupNamespaceID(CurrentNamespace->getName(), NamespaceID);
974static std::optional<api_notes::Context>
976 assert(DC &&
"tag context must not be null");
979 std::stack<TagDecl *> TagStack;
981 for (
auto CurrentTag = DC; CurrentTag;
982 CurrentTag = dyn_cast<TagDecl>(CurrentTag->getParent()))
983 TagStack.push(CurrentTag);
985 assert(!TagStack.empty());
986 std::optional<api_notes::Context> Ctx =
988 while (!TagStack.empty()) {
989 auto CurrentTag = TagStack.top();
991 auto CtxID = Reader->lookupTagID(CurrentTag->getName(), Ctx);
1010 return !(*
this ==
Other);
1023 Policy.PrintAsCanonical =
false;
1024 Policy.FullyQualifiedName =
false;
1026 Policy.UsePreferredNames =
false;
1027 Policy.MSVCFormatting =
false;
1049static std::optional<APINotesParameterSelectorCandidates>
1053 return std::nullopt;
1058 Desugared.
Parameters.reserve(FPT->getNumParams());
1062 for (
QualType ParamType : FPT->param_types()) {
1067 ParamType, S.
Context, Policy,
true));
1070 if (Candidates.
Source != Desugared)
1071 Candidates.
Desugared = std::move(Desugared);
1079 auto [StateIt, Inserted] =
Readers.try_emplace(&Reader);
1086 State.addSelectors(Selectors);
1094 std::make_unique<APINotesSelectorDiagnosticState>();
1100 llvm::function_ref<std::optional<api_notes::APINotesFunctionSelectorKey>(
1107 if (
auto Key = GetSelectorKey(Candidates.
Desugared->Parameters))
1115template <
typename SpecificInfo,
typename SpecificDecl>
1117 Sema &S, SpecificDecl *D,
1123 auto Info = LookupExact(
Selector.Parameters);
1124 if (Info.size() == 0)
1131 if (ProcessSelector(ParameterSelectorCandidates.
Source))
1134 if (ParameterSelectorCandidates.
Desugared)
1135 ProcessSelector(*ParameterSelectorCandidates.
Desugared);
1146 if (Readers.empty())
1151 if (DC->isFileContext() || DC->isNamespace() ||
1152 DC->getDeclKind() == Decl::LinkageSpec) {
1153 std::optional<api_notes::Context> APINotesContext =
1156 if (
auto VD = dyn_cast<VarDecl>(D)) {
1157 for (
auto Reader : Readers) {
1159 Reader->lookupGlobalVariable(VD->getName(), APINotesContext);
1167 if (
auto FD = dyn_cast<FunctionDecl>(D)) {
1168 if (FD->getDeclName().isIdentifier()) {
1169 auto ParameterSelectorCandidates =
1172 for (
auto Reader : Readers) {
1174 Reader->lookupGlobalFunction(FD->getName(), APINotesContext);
1177 if (ParameterSelectorCandidates)
1179 *
this, FD, *ParameterSelectorCandidates,
1181 return Reader->lookupGlobalFunction(FD->getName(), Parameters,
1185 if (ParameterSelectorCandidates) {
1186 auto &DiagnosticState =
1188 if (
auto BroadKey = Reader->getGlobalFunctionSelectorKey(
1189 FD->getName(), APINotesContext))
1190 DiagnosticState.noteSeenDeclaration(*BroadKey, FD->getName(),
1192 DiagnosticState.markCandidatesUsed(
1194 return Reader->getGlobalFunctionSelectorKey(
1195 FD->getName(), Parameters, APINotesContext);
1197 *ParameterSelectorCandidates);
1206 if (
auto Class = dyn_cast<ObjCInterfaceDecl>(D)) {
1207 for (
auto Reader : Readers) {
1208 auto Info = Reader->lookupObjCClassInfo(
Class->getName());
1216 if (
auto Protocol = dyn_cast<ObjCProtocolDecl>(D)) {
1217 for (
auto Reader : Readers) {
1218 auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName());
1226 if (
auto Tag = dyn_cast<TagDecl>(D)) {
1232 if (
auto typedefName = Tag->getTypedefNameForAnonDecl())
1242 std::string MacroName =
1243 LookupName.empty() && Tag->getOuterLocStart().isMacroID()
1245 Tag->getOuterLocStart(),
1246 Tag->getASTContext().getSourceManager(),
LangOpts)
1251 (MacroName ==
"CF_OPTIONS" || MacroName ==
"NS_OPTIONS" ||
1252 MacroName ==
"OBJC_OPTIONS" || MacroName ==
"SWIFT_OPTIONS")) {
1259 for (
auto Reader : Readers) {
1260 if (
auto ParentTag = dyn_cast<TagDecl>(Tag->getDeclContext()))
1262 auto Info = Reader->lookupTag(
LookupName, APINotesContext);
1270 if (
auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
1271 for (
auto Reader : Readers) {
1272 auto Info = Reader->lookupTypedef(
Typedef->getName(), APINotesContext);
1281 if (DC->getRedeclContext()->isFileContext() ||
1282 DC->getRedeclContext()->isExternCContext()) {
1283 if (
auto EnumConstant = dyn_cast<EnumConstantDecl>(D)) {
1284 for (
auto Reader : Readers) {
1285 auto Info = Reader->lookupEnumConstant(EnumConstant->getName());
1293 if (
auto ObjCContainer = dyn_cast<ObjCContainerDecl>(DC)) {
1296 -> std::optional<api_notes::ContextID> {
1297 if (
auto Protocol = dyn_cast<ObjCProtocolDecl>(ObjCContainer)) {
1298 if (
auto Found = Reader->lookupObjCProtocolID(Protocol->getName()))
1301 return std::nullopt;
1304 if (
auto Impl = dyn_cast<ObjCCategoryImplDecl>(ObjCContainer)) {
1305 if (
auto Cat = Impl->getCategoryDecl())
1306 ObjCContainer = Cat->getClassInterface();
1308 return std::nullopt;
1311 if (
auto Category = dyn_cast<ObjCCategoryDecl>(ObjCContainer)) {
1312 if (Category->getClassInterface())
1313 ObjCContainer = Category->getClassInterface();
1315 return std::nullopt;
1318 if (
auto Impl = dyn_cast<ObjCImplDecl>(ObjCContainer)) {
1319 if (Impl->getClassInterface())
1320 ObjCContainer = Impl->getClassInterface();
1322 return std::nullopt;
1325 if (
auto Class = dyn_cast<ObjCInterfaceDecl>(ObjCContainer)) {
1326 if (
auto Found = Reader->lookupObjCClassID(
Class->getName()))
1329 return std::nullopt;
1332 return std::nullopt;
1336 if (
auto Method = dyn_cast<ObjCMethodDecl>(D)) {
1337 for (
auto Reader : Readers) {
1338 if (
auto Context = GetContext(Reader)) {
1345 for (
unsigned i = 0, n = Sel.
getNumArgs(); i != n; ++i)
1353 auto Info = Reader->lookupObjCMethod(*
Context, SelectorRef,
1354 Method->isInstanceMethod());
1361 if (
auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
1363 if (
auto Context = GetContext(Reader)) {
1364 bool isInstanceProperty =
1365 (
Property->getPropertyAttributesAsWritten() &
1368 isInstanceProperty);
1377 if (
auto TagContext = dyn_cast<TagDecl>(DC)) {
1378 if (
auto CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
1382 auto ParameterSelectorCandidates =
1384 for (
auto Reader : Readers) {
1386 std::string MethodName;
1387 if (CXXMethod->isOverloadedOperator())
1389 std::string(
"operator") +
1392 MethodName = CXXMethod->getName();
1394 auto Info = Reader->lookupCXXMethod(
Context->id, MethodName);
1397 if (ParameterSelectorCandidates)
1399 *
this, CXXMethod, *ParameterSelectorCandidates,
1401 return Reader->lookupCXXMethod(
Context->id, MethodName,
1405 if (ParameterSelectorCandidates) {
1406 auto &DiagnosticState =
1409 Reader->getCXXMethodSelectorKey(
Context->id, MethodName))
1410 DiagnosticState.noteSeenDeclaration(*BroadKey, MethodName,
1411 CXXMethod->getLocation());
1412 DiagnosticState.markCandidatesUsed(
1414 return Reader->getCXXMethodSelectorKey(
1415 Context->id, MethodName, Parameters);
1417 *ParameterSelectorCandidates);
1424 if (
auto Field = dyn_cast<FieldDecl>(D)) {
1425 if (!Field->isUnnamedBitField() && !Field->isAnonymousStructOrUnion()) {
1426 for (
auto Reader : Readers) {
1428 auto Info = Reader->lookupField(
Context->id, Field->getName());
1435 if (
auto Tag = dyn_cast<TagDecl>(D)) {
1436 for (
auto Reader : Readers) {
1438 auto Info = Reader->lookupTag(Tag->getName(),
Context);
1457 std::optional<SmallVector<std::string, 4>> ParameterSpellings =
1459 if (!ParameterSpellings)
1462 S.
Diag(SeenName->second.Loc, diag::warn_apinotes_message)
1463 << (llvm::Twine(
"API notes entry for '") + SeenName->second.Name +
1464 "' has unmatched Where.Parameters " +
1471 for (
const auto &ReaderSelectors :
Readers)
1472 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 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 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