24#include "llvm/ADT/StringRef.h"
31 const AvailabilityAttr *AA) {
34 if (!IIEnvironment || Environment == llvm::Triple::UnknownEnvironment)
37 llvm::Triple::EnvironmentType ET =
38 AvailabilityAttr::getEnvironmentType(IIEnvironment->
getName());
39 return Environment == ET;
44 AvailabilityAttr
const *PartialMatch =
nullptr;
48 for (
const auto *A : D->
attrs()) {
49 if (
const auto *Avail = dyn_cast<AvailabilityAttr>(A)) {
55 StringRef ActualPlatform = Avail->getPlatform()->getName();
56 StringRef RealizedPlatform = ActualPlatform;
58 size_t suffix = RealizedPlatform.rfind(
"_app_extension");
59 if (suffix != StringRef::npos)
60 RealizedPlatform = RealizedPlatform.slice(0, suffix);
66 if (RealizedPlatform == TargetPlatform) {
85static std::pair<AvailabilityResult, const NamedDecl *>
93 while (
const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
95 if (
const auto *TT = TD->getUnderlyingType()->getAs<
TagType>()) {
105 if (
const auto *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
106 if (IDecl->getDefinition()) {
107 D = IDecl->getDefinition();
112 if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D))
115 if (
const auto *TheEnumDecl = dyn_cast<EnumDecl>(DC)) {
122 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
127 MD->getSelector() == S.
ObjC().
NSAPIObj->getNewSelector() &&
129 Result =
Init->getAvailability(Message);
145 assert(K !=
AR_Available &&
"Expected an unavailable declaration here!");
150 if (DeclLoc.isMacroID() && S.
getLangOpts().CPlusPlus &&
151 isa<TypedefDecl>(OffendingDecl)) {
153 if (MacroName ==
"CF_OPTIONS" || MacroName ==
"OBJC_OPTIONS" ||
154 MacroName ==
"SWIFT_OPTIONS" || MacroName ==
"NS_OPTIONS") {
160 auto CheckContext = [&](
const Decl *
C) {
163 if (AA->getIntroduced() >= DeclVersion &&
164 AA->getEnvironment() == DeclEnv)
167 if (
C->isDeprecated())
173 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) {
174 if (
const auto *Impl = dyn_cast<ObjCImplDecl>(
C)) {
175 if (MD->getClassInterface() == Impl->getClassInterface())
181 if (
C->isUnavailable())
187 if (CheckContext(Ctx))
192 if (
const auto *MethodD = dyn_cast<ObjCMethodDecl>(Ctx))
193 if (MethodD->isClassMethod() &&
194 MethodD->getSelector().getAsString() ==
"load")
197 if (
const auto *CatOrImpl = dyn_cast<ObjCImplDecl>(Ctx)) {
203 else if (
const auto *CatD = dyn_cast<ObjCCategoryDecl>(Ctx))
214 const VersionTuple &DeploymentVersion,
215 const VersionTuple &DeclVersion) {
217 VersionTuple ForceAvailabilityFromVersion;
218 switch (Triple.getOS()) {
219 case llvm::Triple::IOS:
220 case llvm::Triple::TvOS:
221 ForceAvailabilityFromVersion = VersionTuple(11);
223 case llvm::Triple::WatchOS:
224 ForceAvailabilityFromVersion = VersionTuple(4);
226 case llvm::Triple::Darwin:
227 case llvm::Triple::MacOSX:
228 ForceAvailabilityFromVersion = VersionTuple(10, 13);
230 case llvm::Triple::ShaderModel:
235 return Triple.getVendor() == llvm::Triple::Apple;
237 return DeploymentVersion >= ForceAvailabilityFromVersion ||
238 DeclVersion >= ForceAvailabilityFromVersion;
242 for (
Decl *Ctx = OrigCtx; Ctx;
243 Ctx = cast_or_null<Decl>(Ctx->getDeclContext())) {
244 if (isa<TagDecl>(Ctx) || isa<FunctionDecl>(Ctx) || isa<ObjCMethodDecl>(Ctx))
245 return cast<NamedDecl>(Ctx);
246 if (
auto *CD = dyn_cast<ObjCContainerDecl>(Ctx)) {
247 if (
auto *Imp = dyn_cast<ObjCImplDecl>(Ctx))
248 return Imp->getClassInterface();
253 return dyn_cast<NamedDecl>(OrigCtx);
258struct AttributeInsertion {
263 static AttributeInsertion createInsertionAfter(
const NamedDecl *D) {
266 static AttributeInsertion createInsertionAfter(
SourceLocation Loc) {
267 return {
" ",
Loc,
""};
269 static AttributeInsertion createInsertionBefore(
const NamedDecl *D) {
284static std::optional<unsigned>
288 if (!Name.empty() && (Name.front() ==
'-' || Name.front() ==
'+'))
289 Name = Name.drop_front(1);
292 Name.split(SlotNames,
':');
294 if (Name.back() ==
':') {
296 SlotNames.pop_back();
297 NumParams = SlotNames.size();
299 if (SlotNames.size() != 1)
305 bool AllowDollar = LangOpts.DollarIdents;
306 for (StringRef S : SlotNames) {
317static std::optional<AttributeInsertion>
320 if (isa<ObjCPropertyDecl>(D))
321 return AttributeInsertion::createInsertionAfter(D);
322 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
325 return AttributeInsertion::createInsertionAfter(D);
327 if (
const auto *TD = dyn_cast<TagDecl>(D)) {
333 return AttributeInsertion::createInsertionAfter(
Loc);
335 return AttributeInsertion::createInsertionBefore(D);
355 bool ObjCPropertyAccess) {
357 unsigned diag, diag_message, diag_fwdclass_message;
358 unsigned diag_available_here = diag::note_availability_specified_here;
362 unsigned property_note_select;
365 unsigned available_here_select_kind;
367 VersionTuple DeclVersion;
371 DeclVersion = AA->getIntroduced();
372 IIEnv = AA->getEnvironment();
383 if (AA && AA->isInherited()) {
386 const AvailabilityAttr *AForRedecl =
388 if (AForRedecl && !AForRedecl->isInherited()) {
391 NoteLocation = Redecl->getLocation();
403 assert(AA !=
nullptr &&
"expecting valid availability attribute");
404 VersionTuple Introduced = AA->getIntroduced();
405 bool EnvironmentMatchesOrNone =
409 std::string PlatformName(
411 llvm::StringRef TargetEnvironment(AvailabilityAttr::getPrettyEnviromentName(
413 llvm::StringRef AttrEnvironment =
414 AA->getEnvironment() ? AvailabilityAttr::getPrettyEnviromentName(
415 AA->getEnvironment()->getName())
417 bool UseEnvironment =
418 (!AttrEnvironment.empty() && !TargetEnvironment.empty());
425 EnvironmentMatchesOrNone
426 ? (UseNewWarning ? diag::warn_unguarded_availability_new
427 : diag::warn_unguarded_availability)
428 : (UseNewWarning ? diag::warn_unguarded_availability_unavailable_new
429 : diag::warn_unguarded_availability_unavailable);
431 S.
Diag(
Loc, DiagKind) << OffendingDecl << PlatformName
432 << Introduced.getAsString() << UseEnvironment
433 << TargetEnvironment;
436 diag::note_partial_availability_specified_here)
437 << OffendingDecl << PlatformName << Introduced.getAsString()
439 << UseEnvironment << AttrEnvironment << TargetEnvironment;
442 if (
const auto *TD = dyn_cast<TagDecl>(Enclosing))
443 if (TD->getDeclName().isEmpty()) {
444 S.
Diag(TD->getLocation(),
445 diag::note_decl_unguarded_availability_silence)
446 << 1 << TD->getKindName();
450 S.
Diag(Enclosing->getLocation(),
451 diag::note_decl_unguarded_availability_silence)
454 if (Enclosing->hasAttr<AvailabilityAttr>())
462 std::string PlatformName =
463 AvailabilityAttr::getPlatformNameSourceSpelling(
466 std::string Introduced =
470 (llvm::Twine(Insertion->Prefix) +
"API_AVAILABLE(" + PlatformName +
471 "(" + Introduced +
"))" + Insertion->Suffix)
477 diag = !ObjCPropertyAccess ? diag::warn_deprecated
478 : diag::warn_property_method_deprecated;
479 diag_message = diag::warn_deprecated_message;
480 diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
481 property_note_select = 0;
482 available_here_select_kind = 2;
483 if (
const auto *AL = OffendingDecl->
getAttr<DeprecatedAttr>())
484 NoteLocation = AL->getLocation();
488 diag = !ObjCPropertyAccess ? diag::err_unavailable
489 : diag::err_property_method_unavailable;
490 diag_message = diag::err_unavailable_message;
491 diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
492 property_note_select = 1;
493 available_here_select_kind = 0;
495 if (
auto AL = OffendingDecl->
getAttr<UnavailableAttr>()) {
496 if (AL->isImplicit() && AL->getImplicitReason()) {
499 auto flagARCError = [&] {
503 diag = diag::err_unavailable_in_arc;
506 switch (AL->getImplicitReason()) {
507 case UnavailableAttr::IR_None:
break;
509 case UnavailableAttr::IR_ARCForbiddenType:
511 diag_available_here = diag::note_arc_forbidden_type;
514 case UnavailableAttr::IR_ForbiddenWeak:
516 diag_available_here = diag::note_arc_weak_disabled;
518 diag_available_here = diag::note_arc_weak_no_runtime;
521 case UnavailableAttr::IR_ARCForbiddenConversion:
523 diag_available_here = diag::note_performs_forbidden_arc_conversion;
526 case UnavailableAttr::IR_ARCInitReturnsUnrelated:
528 diag_available_here = diag::note_arc_init_returns_unrelated;
531 case UnavailableAttr::IR_ARCFieldWithOwnership:
533 diag_available_here = diag::note_arc_field_with_ownership;
541 llvm_unreachable(
"Warning for availability of available declaration?");
546 StringRef Replacement;
547 if (
auto AL = OffendingDecl->
getAttr<DeprecatedAttr>())
548 Replacement = AL->getReplacement();
550 Replacement = AL->getReplacement();
553 if (!Replacement.empty())
557 if (
const auto *MethodDecl = dyn_cast<ObjCMethodDecl>(ReferringDecl)) {
558 Selector Sel = MethodDecl->getSelector();
562 if (NumParams && *NumParams == Sel.
getNumArgs()) {
563 assert(SelectorSlotNames.size() == Locs.size());
564 for (
unsigned I = 0; I < Locs.size(); ++I) {
569 NameRange, SelectorSlotNames[I]));
587 bool ShouldAllowWarningInSystemHeader =
588 InstantiationLoc !=
Loc &&
590 struct AllowWarningInSystemHeaders {
592 bool AllowWarningInSystemHeaders)
596 ~AllowWarningInSystemHeaders() { Engine.setSuppressSystemWarnings(Prev); }
602 ShouldAllowWarningInSystemHeader);
604 if (!Message.empty()) {
605 S.
Diag(
Loc, diag_message) << ReferringDecl << Message << FixIts;
608 << ObjCProperty->
getDeclName() << property_note_select;
609 }
else if (!UnknownObjCClass) {
610 S.
Diag(
Loc, diag) << ReferringDecl << FixIts;
613 << ObjCProperty->
getDeclName() << property_note_select;
615 S.
Diag(
Loc, diag_fwdclass_message) << ReferringDecl << FixIts;
619 S.
Diag(NoteLocation, diag_available_here)
620 << OffendingDecl << available_here_select_kind;
625 "Expected an availability diagnostic here");
642 bool ObjCPropertyAccess) {
647 AR, Locs, ReferringDecl, OffendingDecl, UnknownObjCClass,
648 ObjCProperty, Message, ObjCPropertyAccess));
654 Message, Locs, UnknownObjCClass, ObjCProperty,
662 switch (
Parent->getStmtClass()) {
663 case Stmt::IfStmtClass:
664 return cast<IfStmt>(
Parent)->getThen() == S ||
665 cast<IfStmt>(
Parent)->getElse() == S;
666 case Stmt::WhileStmtClass:
667 return cast<WhileStmt>(
Parent)->getBody() == S;
668 case Stmt::DoStmtClass:
669 return cast<DoStmt>(
Parent)->getBody() == S;
670 case Stmt::ForStmtClass:
671 return cast<ForStmt>(
Parent)->getBody() == S;
672 case Stmt::CXXForRangeStmtClass:
673 return cast<CXXForRangeStmt>(
Parent)->getBody() == S;
674 case Stmt::ObjCForCollectionStmtClass:
675 return cast<ObjCForCollectionStmt>(
Parent)->getBody() == S;
676 case Stmt::CaseStmtClass:
677 case Stmt::DefaultStmtClass:
678 return cast<SwitchCase>(
Parent)->getSubStmt() == S;
688 bool VisitStmt(
Stmt *S) {
return S !=
Target; }
692 StmtUSEFinder Visitor;
694 return !Visitor.TraverseDecl(
const_cast<Decl *
>(D));
710 static const Stmt *findLastStmtThatUsesDecl(
const Decl *D,
712 LastDeclUSEFinder Visitor;
714 for (
const Stmt *S : llvm::reverse(
Scope->body())) {
715 if (!Visitor.TraverseStmt(
const_cast<Stmt *
>(S)))
728class DiagnoseUnguardedAvailability
743 DiagnoseUnguardedAvailability(
Sema &SemaRef,
Decl *Ctx)
744 : SemaRef(SemaRef), Ctx(Ctx) {
745 AvailabilityStack.push_back(
749 bool TraverseStmt(
Stmt *S) {
752 StmtStack.push_back(S);
753 bool Result = Base::TraverseStmt(S);
754 StmtStack.pop_back();
758 void IssueDiagnostics(
Stmt *S) { TraverseStmt(S); }
775 DiagnoseDeclAvailability(
782 DiagnoseDeclAvailability(DRE->
getDecl(),
802void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
806 std::tie(
Result, OffendingDecl) =
814 const AvailabilityAttr *AA =
816 bool EnvironmentMatchesOrNone =
818 VersionTuple Introduced = AA->getIntroduced();
820 if (EnvironmentMatchesOrNone && AvailabilityStack.back() >= Introduced)
826 AA->getEnvironment(), Ctx,
839 std::string PlatformName(
841 llvm::StringRef TargetEnvironment(AvailabilityAttr::getPrettyEnviromentName(
843 llvm::StringRef AttrEnvironment =
844 AA->getEnvironment() ? AvailabilityAttr::getPrettyEnviromentName(
845 AA->getEnvironment()->getName())
847 bool UseEnvironment =
848 (!AttrEnvironment.empty() && !TargetEnvironment.empty());
851 EnvironmentMatchesOrNone
852 ? (UseNewDiagKind ? diag::warn_unguarded_availability_new
853 : diag::warn_unguarded_availability)
855 ? diag::warn_unguarded_availability_unavailable_new
856 : diag::warn_unguarded_availability_unavailable);
859 <<
Range << D << PlatformName << Introduced.getAsString()
860 << UseEnvironment << TargetEnvironment;
863 diag::note_partial_availability_specified_here)
864 << OffendingDecl << PlatformName << Introduced.getAsString()
866 << UseEnvironment << AttrEnvironment << TargetEnvironment;
875 if (StmtStack.empty())
877 const Stmt *StmtOfUse = StmtStack.back();
879 for (
const Stmt *S : llvm::reverse(StmtStack)) {
880 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
884 if (isBodyLikeChildStmt(StmtOfUse, S)) {
892 const Stmt *LastStmtOfUse =
nullptr;
893 if (isa<DeclStmt>(StmtOfUse) &&
Scope) {
894 for (
const Decl *D : cast<DeclStmt>(StmtOfUse)->decls()) {
895 if (StmtUSEFinder::isContained(StmtStack.back(), D)) {
896 LastStmtOfUse = LastDeclUSEFinder::findLastStmtThatUsesDecl(D,
Scope);
906 SM.getExpansionRange(
907 (LastStmtOfUse ? LastStmtOfUse : StmtOfUse)->getEndLoc())
909 if (
SM.getFileID(IfInsertionLoc) !=
SM.getFileID(StmtEndLoc))
913 const char *ExtraIndentation =
" ";
914 std::string FixItString;
915 llvm::raw_string_ostream FixItOS(FixItString);
916 FixItOS <<
"if (" << (SemaRef.
getLangOpts().ObjC ?
"@available"
917 :
"__builtin_available")
919 << AvailabilityAttr::getPlatformNameSourceSpelling(
921 <<
" " << Introduced.getAsString() <<
", *)) {\n"
922 << Indentation << ExtraIndentation;
930 FixItOS.str().clear();
932 << Indentation <<
"} else {\n"
933 << Indentation << ExtraIndentation
934 <<
"// Fallback on earlier versions\n"
935 << Indentation <<
"}";
940bool DiagnoseUnguardedAvailability::VisitTypeLoc(
TypeLoc Ty) {
947 if (
const auto *TT = dyn_cast<TagType>(TyPtr)) {
949 DiagnoseDeclAvailability(TD,
Range);
951 }
else if (
const auto *TD = dyn_cast<TypedefType>(TyPtr)) {
953 DiagnoseDeclAvailability(D,
Range);
955 }
else if (
const auto *ObjCO = dyn_cast<ObjCObjectType>(TyPtr)) {
956 if (
NamedDecl *D = ObjCO->getInterface())
957 DiagnoseDeclAvailability(D,
Range);
963bool DiagnoseUnguardedAvailability::TraverseIfStmt(
IfStmt *
If) {
964 VersionTuple CondVersion;
965 if (
auto *E = dyn_cast<ObjCAvailabilityCheckExpr>(
If->getCond())) {
970 if (CondVersion.empty() || CondVersion <= AvailabilityStack.back())
971 return TraverseStmt(
If->getThen()) && TraverseStmt(
If->getElse());
974 return Base::TraverseIfStmt(
If);
977 AvailabilityStack.push_back(CondVersion);
978 bool ShouldContinue = TraverseStmt(
If->getThen());
979 AvailabilityStack.pop_back();
981 return ShouldContinue && TraverseStmt(
If->getElse());
987 Stmt *Body =
nullptr;
992 if (FD->isTemplateInstantiation())
995 Body = FD->getBody();
997 if (
auto *CD = dyn_cast<CXXConstructorDecl>(FD))
999 DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(CI->getInit());
1001 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
1002 Body = MD->getBody();
1003 else if (
auto *BD = dyn_cast<BlockDecl>(D))
1004 Body = BD->getBody();
1006 assert(Body &&
"Need a body here!");
1008 DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(Body);
1025 bool ObjCPropertyAccess,
1026 bool AvoidPartialAvailabilityChecks,
1028 std::string Message;
1032 std::tie(
Result, OffendingDecl) =
1038 if (AvoidPartialAvailabilityChecks)
1045 Context->HasPotentialAvailabilityViolations =
true;
1051 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
1054 if (PDeclResult ==
Result)
1060 UnknownObjCClass, ObjCPDecl, ObjCPropertyAccess);
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
llvm::MachO::Target Target
Defines the clang::Preprocessor interface.
static std::pair< AvailabilityResult, const NamedDecl * > ShouldDiagnoseAvailabilityOfDecl(Sema &S, const NamedDecl *D, std::string *Message, ObjCInterfaceDecl *ClassReceiver)
The diagnostic we should emit for D, and the declaration that originated it, or AR_Available.
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 bool shouldDiagnoseAvailabilityByDefault(const ASTContext &Context, const VersionTuple &DeploymentVersion, const VersionTuple &DeclVersion)
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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const LangOptions & getLangOpts() const
const TargetInfo & getTargetInfo() const
Represents a C++ base or member initializer.
CaseStmt - Represent a case statement.
Represents a character-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...
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
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.
void setSuppressSystemWarnings(bool Val)
When set to true mask warnings that come from system headers.
bool getSuppressSystemWarnings() const
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.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
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()
A runtime availability query.
SourceLocation getBeginLoc() const
VersionTuple getVersion() const
Represents an ObjC class declaration.
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
An expression that sends a message to the given Objective-C object or class.
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.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
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.
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
bool isMacroDefined(StringRef Id)
StringRef getImmediateMacroName(SourceLocation Loc)
Retrieve the name of the immediate macro expansion.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
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, bool DeferHint=false)
Emit a diagnostic.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
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
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
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 DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass, bool ObjCPropertyAccess, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReceiver=nullptr)
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.
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents the declaration of a struct/union/class/enum.
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.
The JSON file list parser is used to communicate input to InstallAPI.
@ 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.
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.