28#include "llvm/ADT/StringRef.h"
35 const AvailabilityAttr *AA) {
37 auto Environment = Context.getTargetInfo().getTriple().getEnvironment();
38 if (!IIEnvironment || Environment == llvm::Triple::UnknownEnvironment)
41 llvm::Triple::EnvironmentType ET =
42 AvailabilityAttr::getEnvironmentType(IIEnvironment->
getName());
43 return Environment == ET;
48 AvailabilityAttr
const *PartialMatch =
nullptr;
54 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
55 D = FTD->getTemplatedDecl();
56 for (
const auto *A : D->
attrs()) {
57 if (
const auto *Avail = dyn_cast<AvailabilityAttr>(A)) {
64 const AvailabilityAttr *EffectiveAvail = Avail->getEffectiveAttr();
68 StringRef ActualPlatform = EffectiveAvail->getPlatform()->getName();
69 StringRef RealizedPlatform = ActualPlatform;
70 if (Context.getLangOpts().AppExt) {
71 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
72 if (suffix != StringRef::npos)
73 RealizedPlatform = RealizedPlatform.slice(0, suffix);
76 StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
79 if (RealizedPlatform == TargetPlatform) {
98std::pair<AvailabilityResult, const NamedDecl *>
105 while (
const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
108 for (
const Type *T = TD->getUnderlyingType().getTypePtr(); ; ) {
109 if (
auto *TT = dyn_cast<TagType>(T)) {
110 D = TT->getDecl()->getDefinitionOrSelf();
130 if (
const auto *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
131 if (IDecl->getDefinition()) {
132 D = IDecl->getDefinition();
137 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D))
140 if (
const auto *TheEnumDecl = dyn_cast<EnumDecl>(DC)) {
141 Result = TheEnumDecl->getAvailability(Message);
147 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
148 if (
ObjC().NSAPIObj && ClassReceiver) {
150 ObjC().NSAPIObj->getInitSelector());
152 MD->getSelector() ==
ObjC().NSAPIObj->getNewSelector() &&
169 assert(K !=
AR_Available &&
"Expected an unavailable declaration here!");
174 if (DeclLoc.isMacroID() && S.
getLangOpts().CPlusPlus &&
177 if (MacroName ==
"CF_OPTIONS" || MacroName ==
"OBJC_OPTIONS" ||
178 MacroName ==
"SWIFT_OPTIONS" || MacroName ==
"NS_OPTIONS") {
193 (DeclEnv !=
nullptr &&
195 llvm::Triple::EnvironmentType::Library))
200 if (
const auto *VD = dyn_cast<VarDecl>(OffendingDecl))
201 if (VD->isLocalVarDeclOrParm() && VD->isDeprecated())
206 auto CheckContext = [&](
const Decl *
C) {
209 if (AA->getEffectiveIntroduced() >= DeclVersion &&
210 AA->getEffectiveEnvironment() == DeclEnv)
213 if (
C->isDeprecated())
219 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) {
220 if (
const auto *Impl = dyn_cast<ObjCImplDecl>(
C)) {
221 if (MD->getClassInterface() == Impl->getClassInterface())
227 if (
C->isUnavailable())
233 if (CheckContext(Ctx))
238 if (
const auto *MethodD = dyn_cast<ObjCMethodDecl>(Ctx))
239 if (MethodD->isClassMethod() &&
240 MethodD->getSelector().getAsString() ==
"load")
243 if (
const auto *CatOrImpl = dyn_cast<ObjCImplDecl>(Ctx)) {
249 else if (
const auto *CatD = dyn_cast<ObjCCategoryDecl>(Ctx))
259 const ASTContext &Context,
const VersionTuple &DeploymentVersion,
260 const VersionTuple &DeclVersion,
bool HasMatchingEnv) {
261 const auto &Triple = Context.getTargetInfo().getTriple();
262 VersionTuple ForceAvailabilityFromVersion;
263 switch (Triple.getOS()) {
268 case llvm::Triple::IOS:
269 case llvm::Triple::TvOS:
270 ForceAvailabilityFromVersion = VersionTuple(11);
272 case llvm::Triple::WatchOS:
273 ForceAvailabilityFromVersion = VersionTuple(4);
275 case llvm::Triple::Darwin:
276 case llvm::Triple::MacOSX:
277 ForceAvailabilityFromVersion = VersionTuple(10, 13);
283 case llvm::Triple::ShaderModel:
284 return HasMatchingEnv ? diag::warn_hlsl_availability
285 : diag::warn_hlsl_availability_unavailable;
288 ForceAvailabilityFromVersion =
289 (Triple.getVendor() == llvm::Triple::Apple)
291 : VersionTuple((
unsigned)-1, (
unsigned)-1);
293 if (DeploymentVersion >= ForceAvailabilityFromVersion ||
294 DeclVersion >= ForceAvailabilityFromVersion)
295 return HasMatchingEnv ? diag::warn_unguarded_availability_new
296 : diag::warn_unguarded_availability_unavailable_new;
297 return HasMatchingEnv ? diag::warn_unguarded_availability
298 : diag::warn_unguarded_availability_unavailable;
302 for (
Decl *Ctx = OrigCtx; Ctx;
303 Ctx = cast_or_null<Decl>(Ctx->getDeclContext())) {
306 if (
auto *CD = dyn_cast<ObjCContainerDecl>(Ctx)) {
307 if (
auto *Imp = dyn_cast<ObjCImplDecl>(Ctx))
308 return Imp->getClassInterface();
313 return dyn_cast<NamedDecl>(OrigCtx);
318struct AttributeInsertion {
323 static AttributeInsertion createInsertionAfter(
const NamedDecl *D) {
326 static AttributeInsertion createInsertionAfter(SourceLocation Loc) {
327 return {
" ", Loc,
""};
329 static AttributeInsertion createInsertionBefore(
const NamedDecl *D) {
344static std::optional<unsigned>
348 if (!Name.empty() && (Name.front() ==
'-' || Name.front() ==
'+'))
349 Name = Name.drop_front(1);
352 Name.split(SlotNames,
':');
354 if (Name.back() ==
':') {
356 SlotNames.pop_back();
357 NumParams = SlotNames.size();
359 if (SlotNames.size() != 1)
365 bool AllowDollar = LangOpts.DollarIdents;
366 for (StringRef S : SlotNames) {
377static std::optional<AttributeInsertion>
381 return AttributeInsertion::createInsertionAfter(D);
382 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
385 return AttributeInsertion::createInsertionAfter(D);
387 if (
const auto *TD = dyn_cast<TagDecl>(D)) {
393 return AttributeInsertion::createInsertionAfter(Loc);
395 return AttributeInsertion::createInsertionBefore(D);
415 bool ObjCPropertyAccess) {
417 unsigned diag, diag_message, diag_fwdclass_message;
418 unsigned diag_available_here = diag::note_availability_specified_here;
422 unsigned property_note_select;
425 unsigned available_here_select_kind;
427 VersionTuple DeclVersion;
431 DeclVersion = AA->getEffectiveIntroduced();
432 IIEnv = AA->getEffectiveEnvironment();
443 if (AA && AA->isInherited()) {
446 const AvailabilityAttr *AForRedecl =
448 if (AForRedecl && !AForRedecl->isInherited()) {
451 NoteLocation = Redecl->getLocation();
463 assert(AA !=
nullptr &&
"expecting valid availability attribute");
464 VersionTuple Introduced = AA->getEffectiveIntroduced();
465 bool EnvironmentMatchesOrNone =
469 std::string PlatformName(
471 llvm::StringRef TargetEnvironment(
472 llvm::Triple::getEnvironmentTypeName(TI.
getTriple().getEnvironment()));
473 llvm::StringRef AttrEnvironment =
474 AA->getEnvironment() ? AA->getEnvironment()->getName() :
"";
475 bool UseEnvironment =
476 (!AttrEnvironment.empty() && !TargetEnvironment.empty());
480 Introduced, EnvironmentMatchesOrNone);
482 S.
Diag(Loc, DiagKind) << OffendingDecl << PlatformName
483 << Introduced.getAsString() << UseEnvironment
484 << TargetEnvironment;
487 diag::note_partial_availability_specified_here)
488 << OffendingDecl << PlatformName << Introduced.getAsString()
490 << UseEnvironment << AttrEnvironment << TargetEnvironment;
497 if (
const auto *TD = dyn_cast<TagDecl>(Enclosing))
498 if (TD->getDeclName().isEmpty()) {
499 S.
Diag(TD->getLocation(),
500 diag::note_decl_unguarded_availability_silence)
501 << 1 << TD->getKindName();
505 S.
Diag(Enclosing->getLocation(),
506 diag::note_decl_unguarded_availability_silence)
509 if (Enclosing->hasAttr<AvailabilityAttr>())
518 StringRef PlatformName =
531 std::vector<StringRef> EquivalentPlatforms =
532 AvailabilityAttr::equivalentPlatformNames(PlatformName);
533 llvm::Twine MacroPrefix =
"__API_AVAILABLE_PLATFORM_";
534 auto AvailablePlatform =
535 llvm::find_if(EquivalentPlatforms, [&](StringRef EquivalentPlatform) {
536 return PP.
isMacroDefined((MacroPrefix + EquivalentPlatform).str());
538 if (AvailablePlatform == EquivalentPlatforms.end())
540 std::string Introduced =
544 (llvm::Twine(Insertion->Prefix) +
"API_AVAILABLE(" +
545 *AvailablePlatform +
"(" + Introduced +
"))" + Insertion->Suffix)
554 FD && FD->isImplicit())
557 if (ObjCPropertyAccess)
558 diag = diag::warn_property_method_deprecated;
560 diag = diag::warn_deprecated_switch_case;
562 diag = diag::warn_deprecated;
564 diag_message = diag::warn_deprecated_message;
565 diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
566 property_note_select = 0;
567 available_here_select_kind = 2;
568 if (
const auto *AL = OffendingDecl->
getAttr<DeprecatedAttr>())
569 NoteLocation = AL->getLocation();
573 diag = !ObjCPropertyAccess ? diag::err_unavailable
574 : diag::err_property_method_unavailable;
575 diag_message = diag::err_unavailable_message;
576 diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
577 property_note_select = 1;
578 available_here_select_kind = 0;
580 if (
auto AL = OffendingDecl->
getAttr<UnavailableAttr>()) {
581 if (AL->isImplicit() && AL->getImplicitReason()) {
584 auto flagARCError = [&] {
588 diag = diag::err_unavailable_in_arc;
591 switch (AL->getImplicitReason()) {
592 case UnavailableAttr::IR_None:
break;
594 case UnavailableAttr::IR_ARCForbiddenType:
596 diag_available_here = diag::note_arc_forbidden_type;
599 case UnavailableAttr::IR_ForbiddenWeak:
601 diag_available_here = diag::note_arc_weak_disabled;
603 diag_available_here = diag::note_arc_weak_no_runtime;
606 case UnavailableAttr::IR_ARCForbiddenConversion:
608 diag_available_here = diag::note_performs_forbidden_arc_conversion;
611 case UnavailableAttr::IR_ARCInitReturnsUnrelated:
613 diag_available_here = diag::note_arc_init_returns_unrelated;
616 case UnavailableAttr::IR_ARCFieldWithOwnership:
618 diag_available_here = diag::note_arc_field_with_ownership;
626 llvm_unreachable(
"Warning for availability of available declaration?");
631 StringRef Replacement;
632 if (
auto AL = OffendingDecl->
getAttr<DeprecatedAttr>())
633 Replacement = AL->getReplacement();
635 Replacement = AL->getReplacement();
638 if (!Replacement.empty())
642 if (
const auto *MethodDecl = dyn_cast<ObjCMethodDecl>(ReferringDecl)) {
643 Selector Sel = MethodDecl->getSelector();
647 if (NumParams && *NumParams == Sel.
getNumArgs()) {
648 assert(SelectorSlotNames.size() == Locs.size());
649 for (
unsigned I = 0; I < Locs.size(); ++I) {
654 NameRange, SelectorSlotNames[I]));
672 bool ShouldAllowWarningInSystemHeader =
673 InstantiationLoc != Loc &&
675 struct AllowWarningInSystemHeaders {
677 bool AllowWarningInSystemHeaders)
679 if (AllowWarningInSystemHeaders)
680 Engine.setForceSystemWarnings(
true);
682 ~AllowWarningInSystemHeaders() { Engine.setForceSystemWarnings(Prev); }
688 ShouldAllowWarningInSystemHeader);
690 if (!Message.empty()) {
691 S.
Diag(Loc, diag_message) << ReferringDecl << Message << FixIts;
694 << ObjCProperty->
getDeclName() << property_note_select;
695 }
else if (!UnknownObjCClass) {
696 S.
Diag(Loc,
diag) << ReferringDecl << FixIts;
699 << ObjCProperty->
getDeclName() << property_note_select;
701 S.
Diag(Loc, diag_fwdclass_message) << ReferringDecl << FixIts;
705 S.
Diag(NoteLocation, diag_available_here)
706 << OffendingDecl << available_here_select_kind;
711 "Expected an availability diagnostic here");
728 bool ObjCPropertyAccess) {
733 AR, Locs, ReferringDecl, OffendingDecl, UnknownObjCClass,
734 ObjCProperty, Message, ObjCPropertyAccess));
740 Message, Locs, UnknownObjCClass, ObjCProperty,
747bool isBodyLikeChildStmt(
const Stmt *S,
const Stmt *Parent) {
749 case Stmt::IfStmtClass:
752 case Stmt::WhileStmtClass:
754 case Stmt::DoStmtClass:
756 case Stmt::ForStmtClass:
758 case Stmt::CXXForRangeStmtClass:
760 case Stmt::ObjCForCollectionStmtClass:
762 case Stmt::CaseStmtClass:
763 case Stmt::DefaultStmtClass:
774 bool VisitStmt(Stmt *S)
override {
return S !=
Target; }
777 static bool isContained(
const Stmt *
Target,
const Decl *D) {
778 StmtUSEFinder Visitor;
780 return !Visitor.TraverseDecl(
const_cast<Decl *
>(D));
790 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
796 static const Stmt *findLastStmtThatUsesDecl(
const Decl *D,
798 LastDeclUSEFinder Visitor;
800 for (
const Stmt *S : llvm::reverse(Scope->
body())) {
801 if (!Visitor.TraverseStmt(
const_cast<Stmt *
>(S)))
819 SmallVector<VersionTuple, 8> AvailabilityStack;
820 SmallVector<const Stmt *, 16> StmtStack;
822 void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range,
823 ObjCInterfaceDecl *ClassReceiver =
nullptr);
826 DiagnoseUnguardedAvailability(Sema &SemaRef, Decl *Ctx)
827 : SemaRef(SemaRef), Ctx(Ctx) {
828 AvailabilityStack.push_back(
832 bool TraverseStmt(Stmt *S)
override {
835 StmtStack.push_back(S);
837 StmtStack.pop_back();
841 void IssueDiagnostics(Stmt *S) { TraverseStmt(S); }
843 bool TraverseIfStmt(IfStmt *
If)
override;
847 bool TraverseCaseStmt(CaseStmt *CS)
override {
851 bool VisitObjCMessageExpr(ObjCMessageExpr *Msg)
override {
853 ObjCInterfaceDecl *
ID =
nullptr;
858 DiagnoseDeclAvailability(
864 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
865 DiagnoseDeclAvailability(DRE->
getDecl(),
870 bool VisitMemberExpr(MemberExpr *ME)
override {
876 bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E)
override {
882 bool VisitTypeLoc(TypeLoc Ty)
override;
885void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
889 std::tie(
Result, OffendingDecl) =
897 const AvailabilityAttr *AA =
899 assert(AA !=
nullptr &&
"expecting valid availability attribute");
902 VersionTuple Introduced = AA->getEffectiveIntroduced();
904 if (EnvironmentMatchesOrNone && AvailabilityStack.back() >= Introduced)
910 AA->getEffectiveEnvironment(), Ctx,
915 std::string PlatformName(
917 llvm::StringRef TargetEnvironment(TI.
getTriple().getEnvironmentName());
918 llvm::StringRef AttrEnvironment =
919 AA->getEnvironment() ? AA->getEnvironment()->getName() :
"";
920 bool UseEnvironment =
921 (!AttrEnvironment.empty() && !TargetEnvironment.empty());
926 EnvironmentMatchesOrNone);
929 <<
Range << D << PlatformName << Introduced.getAsString()
930 << UseEnvironment << TargetEnvironment;
933 diag::note_partial_availability_specified_here)
934 << OffendingDecl << PlatformName << Introduced.getAsString()
936 << UseEnvironment << AttrEnvironment << TargetEnvironment;
943 SemaRef.
Diag(
Range.getBegin(), diag::note_unguarded_available_silence)
949 if (StmtStack.empty())
951 const Stmt *StmtOfUse = StmtStack.back();
953 for (
const Stmt *S : llvm::reverse(StmtStack)) {
954 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
958 if (isBodyLikeChildStmt(StmtOfUse, S)) {
966 const Stmt *LastStmtOfUse =
nullptr;
969 if (StmtUSEFinder::isContained(StmtStack.back(), D)) {
970 LastStmtOfUse = LastDeclUSEFinder::findLastStmtThatUsesDecl(D,
Scope);
980 SM.getExpansionRange(
981 (LastStmtOfUse ? LastStmtOfUse : StmtOfUse)->getEndLoc())
983 if (
SM.getFileID(IfInsertionLoc) !=
SM.getFileID(StmtEndLoc))
987 const char *ExtraIndentation =
" ";
988 std::string FixItString;
989 llvm::raw_string_ostream FixItOS(FixItString);
990 StringRef FixItPlatformName;
991 VersionTuple FixItVersion;
993 if (AA->getInferredAttr()) {
994 FixItPlatformName =
"anyAppleOS";
995 FixItVersion = AA->getIntroduced();
997 FixItPlatformName = AvailabilityAttr::getPlatformNameSourceSpelling(
999 FixItVersion = AA->getEffectiveIntroduced();
1003 :
"__builtin_available")
1004 <<
"(" << FixItPlatformName <<
" " << FixItVersion.getAsString()
1006 << Indentation << ExtraIndentation;
1014 FixItOS.str().clear();
1016 << Indentation <<
"} else {\n"
1017 << Indentation << ExtraIndentation
1018 <<
"// Fallback on earlier versions\n"
1019 << Indentation <<
"}";
1024bool DiagnoseUnguardedAvailability::VisitTypeLoc(
TypeLoc Ty) {
1028 if (
Range.isInvalid())
1031 if (
const auto *TT = dyn_cast<TagType>(TyPtr)) {
1033 DiagnoseDeclAvailability(TD, Range);
1035 }
else if (
const auto *TD = dyn_cast<TypedefType>(TyPtr)) {
1037 DiagnoseDeclAvailability(D, Range);
1039 }
else if (
const auto *ObjCO = dyn_cast<ObjCObjectType>(TyPtr)) {
1040 if (
NamedDecl *D = ObjCO->getInterface())
1041 DiagnoseDeclAvailability(D, Range);
1047struct ExtractedAvailabilityExpr {
1048 const ObjCAvailabilityCheckExpr *E =
nullptr;
1049 bool isNegated =
false;
1052ExtractedAvailabilityExpr extractAvailabilityExpr(
const Expr *IfCond) {
1053 const auto *E = IfCond;
1054 bool IsNegated =
false;
1057 if (
const auto *AE = dyn_cast<ObjCAvailabilityCheckExpr>(E)) {
1058 return ExtractedAvailabilityExpr{AE, IsNegated};
1061 const auto *UO = dyn_cast<UnaryOperator>(E);
1062 if (!UO || UO->getOpcode() != UO_LNot) {
1063 return ExtractedAvailabilityExpr{};
1065 E = UO->getSubExpr();
1066 IsNegated = !IsNegated;
1070bool DiagnoseUnguardedAvailability::TraverseIfStmt(
IfStmt *
If) {
1071 ExtractedAvailabilityExpr IfCond = extractAvailabilityExpr(
If->getCond());
1074 return DynamicRecursiveASTVisitor::TraverseIfStmt(
If);
1077 VersionTuple CondVersion = IfCond.E->
getVersion();
1080 if (CondVersion.empty() || CondVersion <= AvailabilityStack.back()) {
1081 return TraverseStmt(
If->getThen()) && TraverseStmt(
If->getElse());
1084 auto *Guarded =
If->getThen();
1085 auto *Unguarded =
If->getElse();
1086 if (IfCond.isNegated) {
1087 std::swap(Guarded, Unguarded);
1090 AvailabilityStack.push_back(CondVersion);
1091 bool ShouldContinue = TraverseStmt(Guarded);
1092 AvailabilityStack.pop_back();
1094 return ShouldContinue && TraverseStmt(Unguarded);
1100 Stmt *Body =
nullptr;
1103 Body = FD->getBody();
1105 if (
auto *CD = dyn_cast<CXXConstructorDecl>(FD))
1107 DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(CI->getInit());
1109 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
1110 Body = MD->getBody();
1111 else if (
auto *BD = dyn_cast<BlockDecl>(D))
1112 Body = BD->getBody();
1114 assert(Body &&
"Need a body here!");
1116 DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(Body);
1133 bool ObjCPropertyAccess,
1134 bool AvoidPartialAvailabilityChecks,
1137 std::string Message;
1141 std::tie(
Result, OffendingDecl) =
1147 if (AvoidPartialAvailabilityChecks)
1154 Context->HasPotentialAvailabilityViolations =
true;
1160 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
1163 if (PDeclResult ==
Result)
1169 UnknownObjCClass, ObjCPDecl, ObjCPropertyAccess);
Defines the C++ template declaration subclasses.
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
Defines the clang::Preprocessor interface.
static unsigned getAvailabilityDiagnosticKind(const ASTContext &Context, const VersionTuple &DeploymentVersion, const VersionTuple &DeclVersion, bool HasMatchingEnv)
static bool hasMatchingEnvironmentOrNone(const ASTContext &Context, const AvailabilityAttr *AA)
static std::optional< AttributeInsertion > createAttributeInsertion(const NamedDecl *D, const SourceManager &SM, const LangOptions &LangOpts)
Returns a source location in which it's appropriate to insert a new attribute for the given declarati...
static void EmitAvailabilityWarning(Sema &S, AvailabilityResult AR, const NamedDecl *ReferringDecl, const NamedDecl *OffendingDecl, StringRef Message, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass, const ObjCPropertyDecl *ObjCProperty, bool ObjCPropertyAccess)
static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, Decl *Ctx, const NamedDecl *ReferringDecl, const NamedDecl *OffendingDecl, StringRef Message, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass, const ObjCPropertyDecl *ObjCProperty, bool ObjCPropertyAccess)
Actually emit an availability diagnostic for a reference to an unavailable decl.
static NamedDecl * findEnclosingDeclToAnnotate(Decl *OrigCtx)
static std::optional< unsigned > tryParseObjCMethodName(StringRef Name, SmallVectorImpl< StringRef > &SlotNames, const LangOptions &LangOpts)
Tries to parse a string as ObjC method name.
static const AvailabilityAttr * getAttrForPlatform(ASTContext &Context, const Decl *D)
static bool ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K, VersionTuple DeclVersion, const IdentifierInfo *DeclEnv, Decl *Ctx, const NamedDecl *OffendingDecl)
whether we should emit a diagnostic for K and DeclVersion in the context of Ctx.
This file declares semantic analysis for Objective-C.
Defines the Objective-C statement AST node classes.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const TargetInfo & getTargetInfo() const
Represents a C++ base or member initializer.
Represents a byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
CompoundStmt - This represents a group of statements like { stmt stmt }.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getBeginLoc() const
Decl - This represents one declaration (or definition), e.g.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
SourceLocation getEndLoc() const LLVM_READONLY
AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple(), StringRef *RealizedPlatform=nullptr) const
Determine the availability of the given declaration.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
VersionTuple getVersionIntroduced() const
Retrieve the version of the target platform in which this declaration was introduced.
Concrete class used by the front-end to report problems and issues.
bool getForceSystemWarnings() const
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IfStmt - This represents an if/then/else.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static SourceLocation findLocationAfterToken(SourceLocation loc, tok::TokenKind TKind, const SourceManager &SM, const LangOptions &LangOpts, bool SkipTrailingWhitespaceAndNewLine)
Checks that the given token is the first token that occurs after the given location (this excludes co...
static StringRef getIndentationForLine(SourceLocation Loc, const SourceManager &SM)
Returns the leading whitespace for line that corresponds to the given location Loc.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getBeginLoc() const LLVM_READONLY
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
NamedDecl * getMostRecentDecl()
SourceLocation getBeginLoc() const
VersionTuple getVersion() const
Represents an ObjC class declaration.
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
const ObjCMethodDecl * getMethodDecl() const
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getSelectorStartLoc() const
ObjCMethodDecl - Represents an instance or class method declaration.
Represents one property declaration in an Objective-C interface.
static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, ObjCPropertyQueryKind queryKind)
Lookup a property by name in the specified DeclContext.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isMacroDefined(StringRef Id)
StringRef getImmediateMacroName(SourceLocation Loc)
Retrieve the name of the immediate macro expansion.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Scope - A scope is a transient data structure that is used while parsing the program.
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.
unsigned getNumArgs() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
Sema - This implements semantic analysis and AST building for C.
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
Preprocessor & getPreprocessor() const
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
class clang::Sema::DelayedDiagnostics DelayedDiagnostics
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
DiagnosticsEngine & getDiagnostics() const
ASTContext & getASTContext() const
void DiagnoseUnguardedAvailabilityViolations(Decl *FD)
Issue any -Wunguarded-availability warnings in FD.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() const
DeclContext * getCurLexicalContext() const
SourceManager & getSourceManager() const
void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass, bool ObjCPropertyAccess, bool AvoidPartialAvailabilityChecks, ObjCInterfaceDecl *ClassReceiver)
std::pair< AvailabilityResult, const NamedDecl * > ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message, ObjCInterfaceDecl *ClassReceiver)
The diagnostic we should emit for D, and the declaration that originated it, or AR_Available.
sema::FunctionScopeInfo * getCurFunctionAvailabilityContext()
Retrieve the current function, if any, that should be analyzed for potential availability violations.
SourceLocation getTopMostPointOfInstantiation(const NamedDecl *) const
Returns the top most location responsible for the definition of N.
void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
Encodes a location in the source.
This class handles loading and caching of source files into memory.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents the declaration of a struct/union/class/enum.
TagDecl * getDefinitionOrSelf() const
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
Base wrapper for a particular "section" of type source info.
SourceLocation getEndLoc() const
Get the end source location.
SourceLocation getBeginLoc() const
Get the begin source location.
const Type * getTypePtr() const
The base class of the type hierarchy.
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
const ObjCObjectType * getAsObjCInterfaceType() const
Base class for declarations which introduce a typedef-name.
A diagnostic message which has been conditionally emitted pending the complete parsing of the current...
static DelayedDiagnostic makeAvailability(AvailabilityResult AR, ArrayRef< SourceLocation > Locs, const NamedDecl *ReferringDecl, const NamedDecl *OffendingDecl, const ObjCInterfaceDecl *UnknownObjCClass, const ObjCPropertyDecl *ObjCProperty, StringRef Msg, bool ObjCPropertyAccess)
const ObjCInterfaceDecl * getUnknownObjCClass() const
const NamedDecl * getAvailabilityOffendingDecl() const
const ObjCPropertyDecl * getObjCProperty() const
StringRef getAvailabilityMessage() const
ArrayRef< SourceLocation > getAvailabilitySelectorLocs() const
AvailabilityResult getAvailabilityResult() const
const NamedDecl * getAvailabilityReferringDecl() const
Retains information about a function, method, or block that is currently being parsed.
Defines the clang::TargetInfo interface.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
@ Result
The result type of a method or function.
AvailabilityResult
Captures the result of checking the availability of a declaration.
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
U cast(CodeGen::Address addr)
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
bool IsCaseExpr
Whether evaluating an expression for a switch case label.