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)) {
63 StringRef ActualPlatform = Avail->getPlatform()->getName();
64 StringRef RealizedPlatform = ActualPlatform;
65 if (Context.getLangOpts().AppExt) {
66 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
67 if (suffix != StringRef::npos)
68 RealizedPlatform = RealizedPlatform.slice(0, suffix);
71 StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
74 if (RealizedPlatform == TargetPlatform) {
93std::pair<AvailabilityResult, const NamedDecl *>
100 while (
const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
103 for (
const Type *T = TD->getUnderlyingType().getTypePtr(); ; ) {
104 if (
auto *TT = dyn_cast<TagType>(T)) {
105 D = TT->getDecl()->getDefinitionOrSelf();
125 if (
const auto *ADecl = dyn_cast<TypeAliasTemplateDecl>(D)) {
126 D = ADecl->getTemplatedDecl();
131 if (
const auto *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
132 if (IDecl->getDefinition()) {
133 D = IDecl->getDefinition();
138 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D))
141 if (
const auto *TheEnumDecl = dyn_cast<EnumDecl>(DC)) {
142 Result = TheEnumDecl->getAvailability(Message);
148 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
149 if (
ObjC().NSAPIObj && ClassReceiver) {
151 ObjC().NSAPIObj->getInitSelector());
153 MD->getSelector() ==
ObjC().NSAPIObj->getNewSelector() &&
170 assert(K !=
AR_Available &&
"Expected an unavailable declaration here!");
175 if (DeclLoc.isMacroID() && S.
getLangOpts().CPlusPlus &&
178 if (MacroName ==
"CF_OPTIONS" || MacroName ==
"OBJC_OPTIONS" ||
179 MacroName ==
"SWIFT_OPTIONS" || MacroName ==
"NS_OPTIONS") {
194 (DeclEnv !=
nullptr &&
196 llvm::Triple::EnvironmentType::Library))
201 if (
const auto *VD = dyn_cast<VarDecl>(OffendingDecl))
202 if (VD->isLocalVarDeclOrParm() && VD->isDeprecated())
207 auto CheckContext = [&](
const Decl *
C) {
210 if (AA->getIntroduced() >= DeclVersion &&
211 AA->getEnvironment() == DeclEnv)
214 if (
C->isDeprecated())
220 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) {
221 if (
const auto *Impl = dyn_cast<ObjCImplDecl>(
C)) {
222 if (MD->getClassInterface() == Impl->getClassInterface())
228 if (
C->isUnavailable())
234 if (CheckContext(Ctx))
239 if (
const auto *MethodD = dyn_cast<ObjCMethodDecl>(Ctx))
240 if (MethodD->isClassMethod() &&
241 MethodD->getSelector().getAsString() ==
"load")
244 if (
const auto *CatOrImpl = dyn_cast<ObjCImplDecl>(Ctx)) {
250 else if (
const auto *CatD = dyn_cast<ObjCCategoryDecl>(Ctx))
260 const ASTContext &Context,
const VersionTuple &DeploymentVersion,
261 const VersionTuple &DeclVersion,
bool HasMatchingEnv) {
262 const auto &Triple = Context.getTargetInfo().getTriple();
263 VersionTuple ForceAvailabilityFromVersion;
264 switch (Triple.getOS()) {
269 case llvm::Triple::IOS:
270 case llvm::Triple::TvOS:
271 ForceAvailabilityFromVersion = VersionTuple(11);
273 case llvm::Triple::WatchOS:
274 ForceAvailabilityFromVersion = VersionTuple(4);
276 case llvm::Triple::Darwin:
277 case llvm::Triple::MacOSX:
278 ForceAvailabilityFromVersion = VersionTuple(10, 13);
284 case llvm::Triple::ShaderModel:
285 return HasMatchingEnv ? diag::warn_hlsl_availability
286 : diag::warn_hlsl_availability_unavailable;
289 ForceAvailabilityFromVersion =
290 (Triple.getVendor() == llvm::Triple::Apple)
292 : VersionTuple((
unsigned)-1, (
unsigned)-1);
294 if (DeploymentVersion >= ForceAvailabilityFromVersion ||
295 DeclVersion >= ForceAvailabilityFromVersion)
296 return HasMatchingEnv ? diag::warn_unguarded_availability_new
297 : diag::warn_unguarded_availability_unavailable_new;
298 return HasMatchingEnv ? diag::warn_unguarded_availability
299 : diag::warn_unguarded_availability_unavailable;
303 for (
Decl *Ctx = OrigCtx; Ctx;
304 Ctx = cast_or_null<Decl>(Ctx->getDeclContext())) {
307 if (
auto *CD = dyn_cast<ObjCContainerDecl>(Ctx)) {
308 if (
auto *Imp = dyn_cast<ObjCImplDecl>(Ctx))
309 return Imp->getClassInterface();
314 return dyn_cast<NamedDecl>(OrigCtx);
319struct AttributeInsertion {
324 static AttributeInsertion createInsertionAfter(
const NamedDecl *D) {
327 static AttributeInsertion createInsertionAfter(SourceLocation Loc) {
328 return {
" ", Loc,
""};
330 static AttributeInsertion createInsertionBefore(
const NamedDecl *D) {
345static std::optional<unsigned>
349 if (!Name.empty() && (Name.front() ==
'-' || Name.front() ==
'+'))
350 Name = Name.drop_front(1);
353 Name.split(SlotNames,
':');
355 if (Name.back() ==
':') {
357 SlotNames.pop_back();
358 NumParams = SlotNames.size();
360 if (SlotNames.size() != 1)
366 bool AllowDollar = LangOpts.DollarIdents;
367 for (StringRef S : SlotNames) {
378static std::optional<AttributeInsertion>
382 return AttributeInsertion::createInsertionAfter(D);
383 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
386 return AttributeInsertion::createInsertionAfter(D);
388 if (
const auto *TD = dyn_cast<TagDecl>(D)) {
394 return AttributeInsertion::createInsertionAfter(Loc);
396 return AttributeInsertion::createInsertionBefore(D);
416 bool ObjCPropertyAccess) {
418 unsigned diag, diag_message, diag_fwdclass_message;
419 unsigned diag_available_here = diag::note_availability_specified_here;
423 unsigned property_note_select;
426 unsigned available_here_select_kind;
428 VersionTuple DeclVersion;
432 DeclVersion = AA->getIntroduced();
433 IIEnv = AA->getEnvironment();
444 if (AA && AA->isInherited()) {
447 const AvailabilityAttr *AForRedecl =
449 if (AForRedecl && !AForRedecl->isInherited()) {
452 NoteLocation = Redecl->getLocation();
464 assert(AA !=
nullptr &&
"expecting valid availability attribute");
465 VersionTuple Introduced = AA->getIntroduced();
466 bool EnvironmentMatchesOrNone =
470 std::string PlatformName(
472 llvm::StringRef TargetEnvironment(
473 llvm::Triple::getEnvironmentTypeName(TI.
getTriple().getEnvironment()));
474 llvm::StringRef AttrEnvironment =
475 AA->getEnvironment() ? AA->getEnvironment()->getName() :
"";
476 bool UseEnvironment =
477 (!AttrEnvironment.empty() && !TargetEnvironment.empty());
481 Introduced, EnvironmentMatchesOrNone);
483 S.
Diag(Loc, DiagKind) << OffendingDecl << PlatformName
484 << Introduced.getAsString() << UseEnvironment
485 << TargetEnvironment;
488 diag::note_partial_availability_specified_here)
489 << OffendingDecl << PlatformName << Introduced.getAsString()
491 << UseEnvironment << AttrEnvironment << TargetEnvironment;
498 if (
const auto *TD = dyn_cast<TagDecl>(Enclosing))
499 if (TD->getDeclName().isEmpty()) {
500 S.
Diag(TD->getLocation(),
501 diag::note_decl_unguarded_availability_silence)
502 << 1 << TD->getKindName();
506 S.
Diag(Enclosing->getLocation(),
507 diag::note_decl_unguarded_availability_silence)
510 if (Enclosing->hasAttr<AvailabilityAttr>())
519 StringRef PlatformName =
532 std::vector<StringRef> EquivalentPlatforms =
533 AvailabilityAttr::equivalentPlatformNames(PlatformName);
534 llvm::Twine MacroPrefix =
"__API_AVAILABLE_PLATFORM_";
535 auto AvailablePlatform =
536 llvm::find_if(EquivalentPlatforms, [&](StringRef EquivalentPlatform) {
537 return PP.
isMacroDefined((MacroPrefix + EquivalentPlatform).str());
539 if (AvailablePlatform == EquivalentPlatforms.end())
541 std::string Introduced =
545 (llvm::Twine(Insertion->Prefix) +
"API_AVAILABLE(" +
546 *AvailablePlatform +
"(" + Introduced +
"))" + Insertion->Suffix)
555 FD && FD->isImplicit())
558 if (ObjCPropertyAccess)
559 diag = diag::warn_property_method_deprecated;
561 diag = diag::warn_deprecated_switch_case;
563 diag = diag::warn_deprecated;
565 diag_message = diag::warn_deprecated_message;
566 diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
567 property_note_select = 0;
568 available_here_select_kind = 2;
569 if (
const auto *AL = OffendingDecl->
getAttr<DeprecatedAttr>())
570 NoteLocation = AL->getLocation();
574 diag = !ObjCPropertyAccess ? diag::err_unavailable
575 : diag::err_property_method_unavailable;
576 diag_message = diag::err_unavailable_message;
577 diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
578 property_note_select = 1;
579 available_here_select_kind = 0;
581 if (
auto AL = OffendingDecl->
getAttr<UnavailableAttr>()) {
582 if (AL->isImplicit() && AL->getImplicitReason()) {
585 auto flagARCError = [&] {
589 diag = diag::err_unavailable_in_arc;
592 switch (AL->getImplicitReason()) {
593 case UnavailableAttr::IR_None:
break;
595 case UnavailableAttr::IR_ARCForbiddenType:
597 diag_available_here = diag::note_arc_forbidden_type;
600 case UnavailableAttr::IR_ForbiddenWeak:
602 diag_available_here = diag::note_arc_weak_disabled;
604 diag_available_here = diag::note_arc_weak_no_runtime;
607 case UnavailableAttr::IR_ARCForbiddenConversion:
609 diag_available_here = diag::note_performs_forbidden_arc_conversion;
612 case UnavailableAttr::IR_ARCInitReturnsUnrelated:
614 diag_available_here = diag::note_arc_init_returns_unrelated;
617 case UnavailableAttr::IR_ARCFieldWithOwnership:
619 diag_available_here = diag::note_arc_field_with_ownership;
627 llvm_unreachable(
"Warning for availability of available declaration?");
632 StringRef Replacement;
633 if (
auto AL = OffendingDecl->
getAttr<DeprecatedAttr>())
634 Replacement = AL->getReplacement();
636 Replacement = AL->getReplacement();
639 if (!Replacement.empty())
643 if (
const auto *MethodDecl = dyn_cast<ObjCMethodDecl>(ReferringDecl)) {
644 Selector Sel = MethodDecl->getSelector();
648 if (NumParams && *NumParams == Sel.
getNumArgs()) {
649 assert(SelectorSlotNames.size() == Locs.size());
650 for (
unsigned I = 0; I < Locs.size(); ++I) {
655 NameRange, SelectorSlotNames[I]));
673 bool ShouldAllowWarningInSystemHeader =
674 InstantiationLoc != Loc &&
676 struct AllowWarningInSystemHeaders {
678 bool AllowWarningInSystemHeaders)
680 if (AllowWarningInSystemHeaders)
681 Engine.setForceSystemWarnings(
true);
683 ~AllowWarningInSystemHeaders() { Engine.setForceSystemWarnings(Prev); }
689 ShouldAllowWarningInSystemHeader);
691 if (!Message.empty()) {
692 S.
Diag(Loc, diag_message) << ReferringDecl << Message << FixIts;
695 << ObjCProperty->
getDeclName() << property_note_select;
696 }
else if (!UnknownObjCClass) {
697 S.
Diag(Loc,
diag) << ReferringDecl << FixIts;
700 << ObjCProperty->
getDeclName() << property_note_select;
702 S.
Diag(Loc, diag_fwdclass_message) << ReferringDecl << FixIts;
706 S.
Diag(NoteLocation, diag_available_here)
707 << OffendingDecl << available_here_select_kind;
712 "Expected an availability diagnostic here");
729 bool ObjCPropertyAccess) {
734 AR, Locs, ReferringDecl, OffendingDecl, UnknownObjCClass,
735 ObjCProperty, Message, ObjCPropertyAccess));
741 Message, Locs, UnknownObjCClass, ObjCProperty,
748bool isBodyLikeChildStmt(
const Stmt *S,
const Stmt *Parent) {
750 case Stmt::IfStmtClass:
753 case Stmt::WhileStmtClass:
755 case Stmt::DoStmtClass:
757 case Stmt::ForStmtClass:
759 case Stmt::CXXForRangeStmtClass:
761 case Stmt::ObjCForCollectionStmtClass:
763 case Stmt::CaseStmtClass:
764 case Stmt::DefaultStmtClass:
775 bool VisitStmt(Stmt *S)
override {
return S !=
Target; }
778 static bool isContained(
const Stmt *
Target,
const Decl *D) {
779 StmtUSEFinder Visitor;
781 return !Visitor.TraverseDecl(
const_cast<Decl *
>(D));
791 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
797 static const Stmt *findLastStmtThatUsesDecl(
const Decl *D,
799 LastDeclUSEFinder Visitor;
801 for (
const Stmt *S : llvm::reverse(Scope->
body())) {
802 if (!Visitor.TraverseStmt(
const_cast<Stmt *
>(S)))
820 SmallVector<VersionTuple, 8> AvailabilityStack;
821 SmallVector<const Stmt *, 16> StmtStack;
823 void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range,
824 ObjCInterfaceDecl *ClassReceiver =
nullptr);
827 DiagnoseUnguardedAvailability(Sema &SemaRef, Decl *Ctx)
828 : SemaRef(SemaRef), Ctx(Ctx) {
829 AvailabilityStack.push_back(
833 bool TraverseStmt(Stmt *S)
override {
836 StmtStack.push_back(S);
838 StmtStack.pop_back();
842 void IssueDiagnostics(Stmt *S) { TraverseStmt(S); }
844 bool TraverseIfStmt(IfStmt *
If)
override;
848 bool TraverseCaseStmt(CaseStmt *CS)
override {
852 bool VisitObjCMessageExpr(ObjCMessageExpr *Msg)
override {
854 ObjCInterfaceDecl *
ID =
nullptr;
859 DiagnoseDeclAvailability(
865 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
866 DiagnoseDeclAvailability(DRE->
getDecl(),
871 bool VisitMemberExpr(MemberExpr *ME)
override {
877 bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E)
override {
883 bool VisitTypeLoc(TypeLoc Ty)
override;
886void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
890 std::tie(
Result, OffendingDecl) =
898 const AvailabilityAttr *AA =
900 assert(AA !=
nullptr &&
"expecting valid availability attribute");
901 bool EnvironmentMatchesOrNone =
903 VersionTuple Introduced = AA->getIntroduced();
905 if (EnvironmentMatchesOrNone && AvailabilityStack.back() >= Introduced)
911 AA->getEnvironment(), Ctx,
916 std::string PlatformName(
918 llvm::StringRef TargetEnvironment(TI.
getTriple().getEnvironmentName());
919 llvm::StringRef AttrEnvironment =
920 AA->getEnvironment() ? AA->getEnvironment()->getName() :
"";
921 bool UseEnvironment =
922 (!AttrEnvironment.empty() && !TargetEnvironment.empty());
927 EnvironmentMatchesOrNone);
930 <<
Range << D << PlatformName << Introduced.getAsString()
931 << UseEnvironment << TargetEnvironment;
934 diag::note_partial_availability_specified_here)
935 << OffendingDecl << PlatformName << Introduced.getAsString()
937 << UseEnvironment << AttrEnvironment << TargetEnvironment;
944 SemaRef.
Diag(
Range.getBegin(), diag::note_unguarded_available_silence)
950 if (StmtStack.empty())
952 const Stmt *StmtOfUse = StmtStack.back();
954 for (
const Stmt *S : llvm::reverse(StmtStack)) {
955 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
959 if (isBodyLikeChildStmt(StmtOfUse, S)) {
967 const Stmt *LastStmtOfUse =
nullptr;
970 if (StmtUSEFinder::isContained(StmtStack.back(), D)) {
971 LastStmtOfUse = LastDeclUSEFinder::findLastStmtThatUsesDecl(D,
Scope);
981 SM.getExpansionRange(
982 (LastStmtOfUse ? LastStmtOfUse : StmtOfUse)->getEndLoc())
984 if (
SM.getFileID(IfInsertionLoc) !=
SM.getFileID(StmtEndLoc))
988 const char *ExtraIndentation =
" ";
989 std::string FixItString;
990 llvm::raw_string_ostream FixItOS(FixItString);
992 :
"__builtin_available")
994 << AvailabilityAttr::getPlatformNameSourceSpelling(
996 <<
" " << Introduced.getAsString() <<
", *)) {\n"
997 << Indentation << ExtraIndentation;
1005 FixItOS.str().clear();
1007 << Indentation <<
"} else {\n"
1008 << Indentation << ExtraIndentation
1009 <<
"// Fallback on earlier versions\n"
1010 << Indentation <<
"}";
1015bool DiagnoseUnguardedAvailability::VisitTypeLoc(
TypeLoc Ty) {
1019 if (
Range.isInvalid())
1022 if (
const auto *TT = dyn_cast<TagType>(TyPtr)) {
1024 DiagnoseDeclAvailability(TD, Range);
1026 }
else if (
const auto *TD = dyn_cast<TypedefType>(TyPtr)) {
1028 DiagnoseDeclAvailability(D, Range);
1030 }
else if (
const auto *ObjCO = dyn_cast<ObjCObjectType>(TyPtr)) {
1031 if (
NamedDecl *D = ObjCO->getInterface())
1032 DiagnoseDeclAvailability(D, Range);
1038struct ExtractedAvailabilityExpr {
1039 const ObjCAvailabilityCheckExpr *E =
nullptr;
1040 bool isNegated =
false;
1043ExtractedAvailabilityExpr extractAvailabilityExpr(
const Expr *IfCond) {
1044 const auto *E = IfCond;
1045 bool IsNegated =
false;
1048 if (
const auto *AE = dyn_cast<ObjCAvailabilityCheckExpr>(E)) {
1049 return ExtractedAvailabilityExpr{AE, IsNegated};
1052 const auto *UO = dyn_cast<UnaryOperator>(E);
1053 if (!UO || UO->getOpcode() != UO_LNot) {
1054 return ExtractedAvailabilityExpr{};
1056 E = UO->getSubExpr();
1057 IsNegated = !IsNegated;
1061bool DiagnoseUnguardedAvailability::TraverseIfStmt(
IfStmt *
If) {
1062 ExtractedAvailabilityExpr IfCond = extractAvailabilityExpr(
If->getCond());
1065 return DynamicRecursiveASTVisitor::TraverseIfStmt(
If);
1068 VersionTuple CondVersion = IfCond.E->
getVersion();
1071 if (CondVersion.empty() || CondVersion <= AvailabilityStack.back()) {
1072 return TraverseStmt(
If->getThen()) && TraverseStmt(
If->getElse());
1075 auto *Guarded =
If->getThen();
1076 auto *Unguarded =
If->getElse();
1077 if (IfCond.isNegated) {
1078 std::swap(Guarded, Unguarded);
1081 AvailabilityStack.push_back(CondVersion);
1082 bool ShouldContinue = TraverseStmt(Guarded);
1083 AvailabilityStack.pop_back();
1085 return ShouldContinue && TraverseStmt(Unguarded);
1091 Stmt *Body =
nullptr;
1094 Body = FD->getBody();
1096 if (
auto *CD = dyn_cast<CXXConstructorDecl>(FD))
1098 DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(CI->getInit());
1100 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
1101 Body = MD->getBody();
1102 else if (
auto *BD = dyn_cast<BlockDecl>(D))
1103 Body = BD->getBody();
1105 assert(Body &&
"Need a body here!");
1107 DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(Body);
1124 bool ObjCPropertyAccess,
1125 bool AvoidPartialAvailabilityChecks,
1128 std::string Message;
1132 std::tie(
Result, OffendingDecl) =
1138 if (AvoidPartialAvailabilityChecks)
1145 Context->HasPotentialAvailabilityViolations =
true;
1151 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
1154 if (PDeclResult ==
Result)
1160 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.