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();
118 T->getLocallyUnqualifiedSingleStepDesugaredType().getTypePtr();
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())
216 if (
const auto *FD = dyn_cast<FunctionDecl>(
C); FD && FD->isDefaulted())
222 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) {
223 if (
const auto *Impl = dyn_cast<ObjCImplDecl>(
C)) {
224 if (MD->getClassInterface() == Impl->getClassInterface())
230 if (
C->isUnavailable())
236 if (CheckContext(Ctx))
241 if (
const auto *MethodD = dyn_cast<ObjCMethodDecl>(Ctx))
242 if (MethodD->isClassMethod() &&
243 MethodD->getSelector().getAsString() ==
"load")
246 if (
const auto *CatOrImpl = dyn_cast<ObjCImplDecl>(Ctx)) {
252 else if (
const auto *CatD = dyn_cast<ObjCCategoryDecl>(Ctx))
262 const ASTContext &Context,
const VersionTuple &DeploymentVersion,
263 const VersionTuple &DeclVersion,
bool HasMatchingEnv) {
264 const auto &Triple = Context.getTargetInfo().getTriple();
265 VersionTuple ForceAvailabilityFromVersion;
266 switch (Triple.getOS()) {
271 case llvm::Triple::IOS:
272 case llvm::Triple::TvOS:
273 ForceAvailabilityFromVersion = VersionTuple(11);
275 case llvm::Triple::WatchOS:
276 ForceAvailabilityFromVersion = VersionTuple(4);
278 case llvm::Triple::Darwin:
279 case llvm::Triple::MacOSX:
280 ForceAvailabilityFromVersion = VersionTuple(10, 13);
286 case llvm::Triple::ShaderModel:
287 return HasMatchingEnv ? diag::warn_hlsl_availability
288 : diag::warn_hlsl_availability_unavailable;
291 ForceAvailabilityFromVersion =
292 (Triple.getVendor() == llvm::Triple::Apple)
294 : VersionTuple((
unsigned)-1, (
unsigned)-1);
296 if (DeploymentVersion >= ForceAvailabilityFromVersion ||
297 DeclVersion >= ForceAvailabilityFromVersion)
298 return HasMatchingEnv ? diag::warn_unguarded_availability_new
299 : diag::warn_unguarded_availability_unavailable_new;
300 return HasMatchingEnv ? diag::warn_unguarded_availability
301 : diag::warn_unguarded_availability_unavailable;
305 for (
Decl *Ctx = OrigCtx; Ctx;
306 Ctx = cast_or_null<Decl>(Ctx->getDeclContext())) {
309 if (
auto *CD = dyn_cast<ObjCContainerDecl>(Ctx)) {
310 if (
auto *Imp = dyn_cast<ObjCImplDecl>(Ctx))
311 return Imp->getClassInterface();
316 return dyn_cast<NamedDecl>(OrigCtx);
321struct AttributeInsertion {
326 static AttributeInsertion createInsertionAfter(
const NamedDecl *D) {
329 static AttributeInsertion createInsertionAfter(SourceLocation Loc) {
330 return {
" ", Loc,
""};
332 static AttributeInsertion createInsertionBefore(
const NamedDecl *D) {
347static std::optional<unsigned>
351 if (!Name.empty() && (Name.front() ==
'-' || Name.front() ==
'+'))
352 Name = Name.drop_front(1);
355 Name.split(SlotNames,
':');
357 if (Name.back() ==
':') {
359 SlotNames.pop_back();
360 NumParams = SlotNames.size();
362 if (SlotNames.size() != 1)
368 bool AllowDollar = LangOpts.DollarIdents;
369 for (StringRef S : SlotNames) {
380static std::optional<AttributeInsertion>
384 return AttributeInsertion::createInsertionAfter(D);
385 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
388 return AttributeInsertion::createInsertionAfter(D);
390 if (
const auto *TD = dyn_cast<TagDecl>(D)) {
396 return AttributeInsertion::createInsertionAfter(Loc);
398 return AttributeInsertion::createInsertionBefore(D);
418 bool ObjCPropertyAccess) {
420 unsigned diag, diag_message, diag_fwdclass_message;
421 unsigned diag_available_here = diag::note_availability_specified_here;
425 unsigned property_note_select;
428 unsigned available_here_select_kind;
430 VersionTuple DeclVersion;
434 DeclVersion = AA->getEffectiveIntroduced();
435 IIEnv = AA->getEffectiveEnvironment();
446 if (AA && AA->isInherited()) {
449 const AvailabilityAttr *AForRedecl =
451 if (AForRedecl && !AForRedecl->isInherited()) {
454 NoteLocation = Redecl->getLocation();
466 assert(AA !=
nullptr &&
"expecting valid availability attribute");
467 VersionTuple Introduced = AA->getEffectiveIntroduced();
468 bool EnvironmentMatchesOrNone =
472 std::string PlatformName(
474 llvm::StringRef TargetEnvironment(
475 llvm::Triple::getEnvironmentTypeName(TI.
getTriple().getEnvironment()));
476 llvm::StringRef AttrEnvironment =
477 AA->getEnvironment() ? AA->getEnvironment()->getName() :
"";
478 bool UseEnvironment =
479 (!AttrEnvironment.empty() && !TargetEnvironment.empty());
483 Introduced, EnvironmentMatchesOrNone);
485 S.
Diag(Loc, DiagKind) << OffendingDecl << PlatformName
486 << Introduced.getAsString() << UseEnvironment
487 << TargetEnvironment;
490 diag::note_partial_availability_specified_here)
491 << OffendingDecl << PlatformName << Introduced.getAsString()
493 << UseEnvironment << AttrEnvironment << TargetEnvironment;
500 if (
const auto *TD = dyn_cast<TagDecl>(Enclosing))
501 if (TD->getDeclName().isEmpty()) {
502 S.
Diag(TD->getLocation(),
503 diag::note_decl_unguarded_availability_silence)
504 << 1 << TD->getKindName();
508 S.
Diag(Enclosing->getLocation(),
509 diag::note_decl_unguarded_availability_silence)
512 if (Enclosing->hasAttr<AvailabilityAttr>())
521 StringRef PlatformName =
534 std::vector<StringRef> EquivalentPlatforms =
535 AvailabilityAttr::equivalentPlatformNames(PlatformName);
536 llvm::Twine MacroPrefix =
"__API_AVAILABLE_PLATFORM_";
537 auto AvailablePlatform =
538 llvm::find_if(EquivalentPlatforms, [&](StringRef EquivalentPlatform) {
539 return PP.
isMacroDefined((MacroPrefix + EquivalentPlatform).str());
541 if (AvailablePlatform == EquivalentPlatforms.end())
543 std::string Introduced =
547 (llvm::Twine(Insertion->Prefix) +
"API_AVAILABLE(" +
548 *AvailablePlatform +
"(" + Introduced +
"))" + Insertion->Suffix)
554 if (ObjCPropertyAccess)
555 diag = diag::warn_property_method_deprecated;
557 diag = diag::warn_deprecated_switch_case;
559 diag = diag::warn_deprecated;
561 diag_message = diag::warn_deprecated_message;
562 diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
563 property_note_select = 0;
564 available_here_select_kind = 2;
565 if (
const auto *AL = OffendingDecl->
getAttr<DeprecatedAttr>())
566 NoteLocation = AL->getLocation();
570 diag = !ObjCPropertyAccess ? diag::err_unavailable
571 : diag::err_property_method_unavailable;
572 diag_message = diag::err_unavailable_message;
573 diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
574 property_note_select = 1;
575 available_here_select_kind = 0;
577 if (
auto AL = OffendingDecl->
getAttr<UnavailableAttr>()) {
578 if (AL->isImplicit() && AL->getImplicitReason()) {
581 auto flagARCError = [&] {
585 diag = diag::err_unavailable_in_arc;
588 switch (AL->getImplicitReason()) {
589 case UnavailableAttr::IR_None:
break;
591 case UnavailableAttr::IR_ARCForbiddenType:
593 diag_available_here = diag::note_arc_forbidden_type;
596 case UnavailableAttr::IR_ForbiddenWeak:
598 diag_available_here = diag::note_arc_weak_disabled;
600 diag_available_here = diag::note_arc_weak_no_runtime;
603 case UnavailableAttr::IR_ARCForbiddenConversion:
605 diag_available_here = diag::note_performs_forbidden_arc_conversion;
608 case UnavailableAttr::IR_ARCInitReturnsUnrelated:
610 diag_available_here = diag::note_arc_init_returns_unrelated;
613 case UnavailableAttr::IR_ARCFieldWithOwnership:
615 diag_available_here = diag::note_arc_field_with_ownership;
623 llvm_unreachable(
"Warning for availability of available declaration?");
628 StringRef Replacement;
629 if (
auto AL = OffendingDecl->
getAttr<DeprecatedAttr>())
630 Replacement = AL->getReplacement();
632 Replacement = AL->getReplacement();
635 if (!Replacement.empty())
639 if (
const auto *MethodDecl = dyn_cast<ObjCMethodDecl>(ReferringDecl)) {
640 Selector Sel = MethodDecl->getSelector();
644 if (NumParams && *NumParams == Sel.
getNumArgs()) {
645 assert(SelectorSlotNames.size() == Locs.size());
646 for (
unsigned I = 0; I < Locs.size(); ++I) {
651 NameRange, SelectorSlotNames[I]));
669 bool ShouldAllowWarningInSystemHeader =
670 InstantiationLoc != Loc &&
672 struct AllowWarningInSystemHeaders {
674 bool AllowWarningInSystemHeaders)
676 if (AllowWarningInSystemHeaders)
677 Engine.setForceSystemWarnings(
true);
679 ~AllowWarningInSystemHeaders() { Engine.setForceSystemWarnings(Prev); }
685 ShouldAllowWarningInSystemHeader);
687 if (!Message.empty()) {
688 S.
Diag(Loc, diag_message) << ReferringDecl << Message << FixIts;
691 << ObjCProperty->
getDeclName() << property_note_select;
692 }
else if (!UnknownObjCClass) {
693 S.
Diag(Loc,
diag) << ReferringDecl << FixIts;
696 << ObjCProperty->
getDeclName() << property_note_select;
698 S.
Diag(Loc, diag_fwdclass_message) << ReferringDecl << FixIts;
702 S.
Diag(NoteLocation, diag_available_here)
703 << OffendingDecl << available_here_select_kind;
708 "Expected an availability diagnostic here");
725 bool ObjCPropertyAccess) {
730 AR, Locs, ReferringDecl, OffendingDecl, UnknownObjCClass,
731 ObjCProperty, Message, ObjCPropertyAccess));
737 Message, Locs, UnknownObjCClass, ObjCProperty,
744bool isBodyLikeChildStmt(
const Stmt *S,
const Stmt *Parent) {
746 case Stmt::IfStmtClass:
749 case Stmt::WhileStmtClass:
751 case Stmt::DoStmtClass:
753 case Stmt::ForStmtClass:
755 case Stmt::CXXForRangeStmtClass:
757 case Stmt::ObjCForCollectionStmtClass:
759 case Stmt::CaseStmtClass:
760 case Stmt::DefaultStmtClass:
771 bool VisitStmt(Stmt *S)
override {
return S !=
Target; }
774 static bool isContained(
const Stmt *
Target,
const Decl *D) {
775 StmtUSEFinder Visitor;
777 return !Visitor.TraverseDecl(
const_cast<Decl *
>(D));
787 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
793 static const Stmt *findLastStmtThatUsesDecl(
const Decl *D,
795 LastDeclUSEFinder Visitor;
797 for (
const Stmt *S : llvm::reverse(Scope->
body())) {
798 if (!Visitor.TraverseStmt(
const_cast<Stmt *
>(S)))
816 SmallVector<VersionTuple, 8> AvailabilityStack;
817 SmallVector<const Stmt *, 16> StmtStack;
819 void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range,
820 ObjCInterfaceDecl *ClassReceiver =
nullptr);
823 DiagnoseUnguardedAvailability(Sema &SemaRef, Decl *Ctx)
824 : SemaRef(SemaRef), Ctx(Ctx) {
825 AvailabilityStack.push_back(
829 bool TraverseStmt(Stmt *S)
override {
832 StmtStack.push_back(S);
834 StmtStack.pop_back();
838 void IssueDiagnostics(Stmt *S) { TraverseStmt(S); }
840 bool TraverseIfStmt(IfStmt *
If)
override;
844 bool TraverseCaseStmt(CaseStmt *CS)
override {
848 bool VisitObjCMessageExpr(ObjCMessageExpr *Msg)
override {
850 ObjCInterfaceDecl *
ID =
nullptr;
855 DiagnoseDeclAvailability(
861 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
862 DiagnoseDeclAvailability(DRE->
getDecl(),
867 bool VisitMemberExpr(MemberExpr *ME)
override {
873 bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E)
override {
879 bool VisitTypeLoc(TypeLoc Ty)
override;
882void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
886 std::tie(
Result, OffendingDecl) =
894 const AvailabilityAttr *AA =
896 assert(AA !=
nullptr &&
"expecting valid availability attribute");
899 VersionTuple Introduced = AA->getEffectiveIntroduced();
901 if (EnvironmentMatchesOrNone && AvailabilityStack.back() >= Introduced)
907 AA->getEffectiveEnvironment(), Ctx,
912 std::string PlatformName(
914 llvm::StringRef TargetEnvironment(TI.
getTriple().getEnvironmentName());
915 llvm::StringRef AttrEnvironment =
916 AA->getEnvironment() ? AA->getEnvironment()->getName() :
"";
917 bool UseEnvironment =
918 (!AttrEnvironment.empty() && !TargetEnvironment.empty());
923 EnvironmentMatchesOrNone);
926 <<
Range << D << PlatformName << Introduced.getAsString()
927 << UseEnvironment << TargetEnvironment;
930 diag::note_partial_availability_specified_here)
931 << OffendingDecl << PlatformName << Introduced.getAsString()
933 << UseEnvironment << AttrEnvironment << TargetEnvironment;
940 SemaRef.
Diag(
Range.getBegin(), diag::note_unguarded_available_silence)
946 if (StmtStack.empty())
948 const Stmt *StmtOfUse = StmtStack.back();
950 for (
const Stmt *S : llvm::reverse(StmtStack)) {
951 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
955 if (isBodyLikeChildStmt(StmtOfUse, S)) {
963 const Stmt *LastStmtOfUse =
nullptr;
966 if (StmtUSEFinder::isContained(StmtStack.back(), D)) {
967 LastStmtOfUse = LastDeclUSEFinder::findLastStmtThatUsesDecl(D,
Scope);
978 (LastStmtOfUse ? LastStmtOfUse : StmtOfUse)->getEndLoc())
984 const char *ExtraIndentation =
" ";
985 std::string FixItString;
986 llvm::raw_string_ostream FixItOS(FixItString);
987 StringRef FixItPlatformName;
988 VersionTuple FixItVersion;
990 if (AA->getInferredAttr()) {
991 FixItPlatformName =
"anyAppleOS";
992 FixItVersion = AA->getIntroduced();
994 FixItPlatformName = AvailabilityAttr::getPlatformNameSourceSpelling(
996 FixItVersion = AA->getEffectiveIntroduced();
1000 :
"__builtin_available")
1001 <<
"(" << FixItPlatformName <<
" " << FixItVersion.getAsString()
1003 << Indentation << ExtraIndentation;
1011 FixItOS.str().clear();
1013 << Indentation <<
"} else {\n"
1014 << Indentation << ExtraIndentation
1015 <<
"// Fallback on earlier versions\n"
1016 << Indentation <<
"}";
1021bool DiagnoseUnguardedAvailability::VisitTypeLoc(
TypeLoc Ty) {
1025 if (
Range.isInvalid())
1028 if (
const auto *TT = dyn_cast<TagType>(TyPtr)) {
1030 DiagnoseDeclAvailability(TD, Range);
1032 }
else if (
const auto *TD = dyn_cast<TypedefType>(TyPtr)) {
1034 DiagnoseDeclAvailability(D, Range);
1036 }
else if (
const auto *ObjCO = dyn_cast<ObjCObjectType>(TyPtr)) {
1037 if (
NamedDecl *D = ObjCO->getInterface())
1038 DiagnoseDeclAvailability(D, Range);
1044struct ExtractedAvailabilityExpr {
1045 const ObjCAvailabilityCheckExpr *E =
nullptr;
1046 bool isNegated =
false;
1049ExtractedAvailabilityExpr extractAvailabilityExpr(
const Expr *IfCond) {
1050 const auto *E = IfCond;
1051 bool IsNegated =
false;
1054 if (
const auto *AE = dyn_cast<ObjCAvailabilityCheckExpr>(E)) {
1055 return ExtractedAvailabilityExpr{AE, IsNegated};
1058 const auto *UO = dyn_cast<UnaryOperator>(E);
1059 if (!UO || UO->getOpcode() != UO_LNot) {
1060 return ExtractedAvailabilityExpr{};
1062 E = UO->getSubExpr();
1063 IsNegated = !IsNegated;
1067bool DiagnoseUnguardedAvailability::TraverseIfStmt(
IfStmt *
If) {
1068 ExtractedAvailabilityExpr IfCond = extractAvailabilityExpr(
If->getCond());
1071 return DynamicRecursiveASTVisitor::TraverseIfStmt(
If);
1074 VersionTuple CondVersion = IfCond.E->
getVersion();
1077 if (CondVersion.empty() || CondVersion <= AvailabilityStack.back()) {
1078 return TraverseStmt(
If->getThen()) && TraverseStmt(
If->getElse());
1081 auto *Guarded =
If->getThen();
1082 auto *Unguarded =
If->getElse();
1083 if (IfCond.isNegated) {
1084 std::swap(Guarded, Unguarded);
1087 AvailabilityStack.push_back(CondVersion);
1088 bool ShouldContinue = TraverseStmt(Guarded);
1089 AvailabilityStack.pop_back();
1091 return ShouldContinue && TraverseStmt(Unguarded);
1097 Stmt *Body =
nullptr;
1100 Body = FD->getBody();
1102 if (
auto *CD = dyn_cast<CXXConstructorDecl>(FD))
1104 DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(CI->getInit());
1106 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
1107 Body = MD->getBody();
1108 else if (
auto *BD = dyn_cast<BlockDecl>(D))
1109 Body = BD->getBody();
1111 assert(Body &&
"Need a body here!");
1113 DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(Body);
1130 bool ObjCPropertyAccess,
1131 bool AvoidPartialAvailabilityChecks,
1134 std::string Message;
1138 std::tie(
Result, OffendingDecl) =
1144 if (AvoidPartialAvailabilityChecks)
1151 Context->HasPotentialAvailabilityViolations =
true;
1157 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
1160 if (PDeclResult ==
Result)
1166 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.
Result
Implement __builtin_bit_cast and related operations.
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)
SourceLocation getEnd() const
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.
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
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.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
CharSourceRange getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
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.
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.
Top level wrappers for InstallAPI frontend operations.
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.
const FunctionProtoType * T
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.