r277887 - [NFC][ObjC Availability] Refactor DiagnoseAvailabilityOfDecl
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 5 15:59:03 PDT 2016
Author: epilk
Date: Fri Aug 5 17:59:03 2016
New Revision: 277887
URL: http://llvm.org/viewvc/llvm-project?rev=277887&view=rev
Log:
[NFC][ObjC Availability] Refactor DiagnoseAvailabilityOfDecl
Differential revision: https://reviews.llvm.org/D23221
Modified:
cfe/trunk/include/clang/Sema/DelayedDiagnostic.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/DelayedDiagnostic.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/include/clang/Sema/DelayedDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DelayedDiagnostic.h?rev=277887&r1=277886&r2=277887&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DelayedDiagnostic.h (original)
+++ cfe/trunk/include/clang/Sema/DelayedDiagnostic.h Fri Aug 5 17:59:03 2016
@@ -122,7 +122,7 @@ public:
void Destroy();
- static DelayedDiagnostic makeAvailability(Sema::AvailabilityDiagnostic AD,
+ static DelayedDiagnostic makeAvailability(AvailabilityResult AR,
SourceLocation Loc,
const NamedDecl *D,
const ObjCInterfaceDecl *UnknownObjCClass,
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=277887&r1=277886&r2=277887&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Aug 5 17:59:03 2016
@@ -3629,13 +3629,10 @@ public:
void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
- enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial };
-
- void EmitAvailabilityWarning(AvailabilityDiagnostic AD,
- NamedDecl *D, StringRef Message,
- SourceLocation Loc,
+ void EmitAvailabilityWarning(AvailabilityResult AR, NamedDecl *D,
+ StringRef Message, SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
+ const ObjCPropertyDecl *ObjCProperty,
bool ObjCPropertyAccess);
bool makeUnavailableInSystemHeader(SourceLocation loc,
@@ -9608,6 +9605,17 @@ public:
/// availability attribuite effectively has the availability of the interface.
VersionTuple getVersionForDecl(const Decl *Ctx) const;
+ /// \brief The diagnostic we should emit for \c D, or \c AR_Available.
+ ///
+ /// \param D The declaration to check. Note that this may be altered to point
+ /// to another declaration that \c D gets it's availability from. i.e., we
+ /// walk the list of typedefs to find an availability attribute.
+ ///
+ /// \param ContextVersion The version to compare availability against.
+ AvailabilityResult
+ ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D, VersionTuple ContextVersion,
+ std::string *Message);
+
const DeclContext *getCurObjCLexicalContext() const {
const DeclContext *DC = getCurLexicalContext();
// A category implicitly has the attribute of the interface.
Modified: cfe/trunk/lib/Sema/DelayedDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DelayedDiagnostic.cpp?rev=277887&r1=277886&r2=277887&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DelayedDiagnostic.cpp (original)
+++ cfe/trunk/lib/Sema/DelayedDiagnostic.cpp Fri Aug 5 17:59:03 2016
@@ -20,7 +20,7 @@ using namespace clang;
using namespace sema;
DelayedDiagnostic
-DelayedDiagnostic::makeAvailability(Sema::AvailabilityDiagnostic AD,
+DelayedDiagnostic::makeAvailability(AvailabilityResult AD,
SourceLocation Loc,
const NamedDecl *D,
const ObjCInterfaceDecl *UnknownObjCClass,
@@ -29,14 +29,14 @@ DelayedDiagnostic::makeAvailability(Sema
bool ObjCPropertyAccess) {
DelayedDiagnostic DD;
switch (AD) {
- case Sema::AD_Deprecation:
- DD.Kind = Deprecation;
- break;
- case Sema::AD_Unavailable:
- DD.Kind = Unavailable;
- break;
- case Sema::AD_Partial:
- llvm_unreachable("AD_Partial diags should not be delayed");
+ case AR_Deprecated:
+ DD.Kind = Deprecation;
+ break;
+ case AR_Unavailable:
+ DD.Kind = Unavailable;
+ break;
+ default:
+ llvm_unreachable("partial diags should not be delayed");
}
DD.Triggered = false;
DD.Loc = Loc;
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=277887&r1=277886&r2=277887&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Aug 5 17:59:03 2016
@@ -6246,7 +6246,7 @@ static const AvailabilityAttr *getAttrFo
return nullptr;
}
-static void DoEmitAvailabilityWarning(Sema &S, Sema::AvailabilityDiagnostic K,
+static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
Decl *Ctx, const NamedDecl *D,
StringRef Message, SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass,
@@ -6264,7 +6264,7 @@ static void DoEmitAvailabilityWarning(Se
// Don't warn if our current context is deprecated or unavailable.
switch (K) {
- case Sema::AD_Deprecation:
+ case AR_Deprecated:
if (isDeclDeprecated(Ctx) || isDeclUnavailable(Ctx))
return;
diag = !ObjCPropertyAccess ? diag::warn_deprecated
@@ -6275,7 +6275,7 @@ static void DoEmitAvailabilityWarning(Se
available_here_select_kind = /* deprecated */ 2;
break;
- case Sema::AD_Unavailable:
+ case AR_Unavailable:
if (isDeclUnavailable(Ctx))
return;
diag = !ObjCPropertyAccess ? diag::err_unavailable
@@ -6329,18 +6329,21 @@ static void DoEmitAvailabilityWarning(Se
}
break;
- case Sema::AD_Partial:
+ case AR_NotYetIntroduced:
diag = diag::warn_partial_availability;
diag_message = diag::warn_partial_message;
diag_fwdclass_message = diag::warn_partial_fwdclass_message;
property_note_select = /* partial */ 2;
available_here_select_kind = /* partial */ 3;
break;
+
+ case AR_Available:
+ llvm_unreachable("Warning for availability of available declaration?");
}
CharSourceRange UseRange;
StringRef Replacement;
- if (K == Sema::AD_Deprecation) {
+ if (K == AR_Deprecated) {
if (auto attr = D->getAttr<DeprecatedAttr>())
Replacement = attr->getReplacement();
if (auto attr = getAttrForPlatform(S.Context, D))
@@ -6393,7 +6396,7 @@ static void DoEmitAvailabilityWarning(Se
S.Diag(D->getLocation(), diag_available_here)
<< D << available_here_select_kind;
- if (K == Sema::AD_Partial)
+ if (K == AR_NotYetIntroduced)
S.Diag(Loc, diag::note_partial_availability_silence) << D;
}
@@ -6401,12 +6404,12 @@ static void handleDelayedAvailabilityChe
Decl *Ctx) {
assert(DD.Kind == DelayedDiagnostic::Deprecation ||
DD.Kind == DelayedDiagnostic::Unavailable);
- Sema::AvailabilityDiagnostic AD = DD.Kind == DelayedDiagnostic::Deprecation
- ? Sema::AD_Deprecation
- : Sema::AD_Unavailable;
+ AvailabilityResult AR = DD.Kind == DelayedDiagnostic::Deprecation
+ ? AR_Deprecated
+ : AR_Unavailable;
DD.Triggered = true;
DoEmitAvailabilityWarning(
- S, AD, Ctx, DD.getDeprecationDecl(), DD.getDeprecationMessage(), DD.Loc,
+ S, AR, Ctx, DD.getDeprecationDecl(), DD.getDeprecationMessage(), DD.Loc,
DD.getUnknownObjCClass(), DD.getObjCProperty(), false);
}
@@ -6466,22 +6469,23 @@ void Sema::redelayDiagnostics(DelayedDia
curPool->steal(pool);
}
-void Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD,
+void Sema::EmitAvailabilityWarning(AvailabilityResult AR,
NamedDecl *D, StringRef Message,
SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass,
const ObjCPropertyDecl *ObjCProperty,
bool ObjCPropertyAccess) {
// Delay if we're currently parsing a declaration.
- if (DelayedDiagnostics.shouldDelayDiagnostics() && AD != AD_Partial) {
+ if (DelayedDiagnostics.shouldDelayDiagnostics() &&
+ AR != AR_NotYetIntroduced) {
DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(
- AD, Loc, D, UnknownObjCClass, ObjCProperty, Message,
+ AR, Loc, D, UnknownObjCClass, ObjCProperty, Message,
ObjCPropertyAccess));
return;
}
Decl *Ctx = cast<Decl>(getCurLexicalContext());
- DoEmitAvailabilityWarning(*this, AD, Ctx, D, Message, Loc, UnknownObjCClass,
+ DoEmitAvailabilityWarning(*this, AR, Ctx, D, Message, Loc, UnknownObjCClass,
ObjCProperty, ObjCPropertyAccess);
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=277887&r1=277886&r2=277887&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Aug 5 17:59:03 2016
@@ -103,18 +103,9 @@ static bool HasRedeclarationWithoutAvail
return false;
}
-static AvailabilityResult
-DiagnoseAvailabilityOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass,
- bool ObjCPropertyAccess) {
- VersionTuple ContextVersion;
- if (const DeclContext *DC = S.getCurObjCLexicalContext())
- ContextVersion = S.getVersionForDecl(cast<Decl>(DC));
-
- // See if this declaration is unavailable, deprecated, or partial in the
- // current context.
- std::string Message;
- AvailabilityResult Result = D->getAvailability(&Message, ContextVersion);
+AvailabilityResult Sema::ShouldDiagnoseAvailabilityOfDecl(
+ NamedDecl *&D, VersionTuple ContextVersion, std::string *Message) {
+ AvailabilityResult Result = D->getAvailability(Message, ContextVersion);
// For typedefs, if the typedef declaration appears available look
// to the underlying type to see if it is more restrictive.
@@ -122,18 +113,18 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name
if (Result == AR_Available) {
if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
D = TT->getDecl();
- Result = D->getAvailability(&Message, ContextVersion);
+ Result = D->getAvailability(Message, ContextVersion);
continue;
}
}
break;
}
-
+
// Forward class declarations get their attributes from their definition.
if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
if (IDecl->getDefinition()) {
D = IDecl->getDefinition();
- Result = D->getAvailability(&Message, ContextVersion);
+ Result = D->getAvailability(Message, ContextVersion);
}
}
@@ -141,12 +132,58 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name
if (Result == AR_Available) {
const DeclContext *DC = ECD->getDeclContext();
if (const EnumDecl *TheEnumDecl = dyn_cast<EnumDecl>(DC))
- Result = TheEnumDecl->getAvailability(&Message, ContextVersion);
+ Result = TheEnumDecl->getAvailability(Message, ContextVersion);
}
- const ObjCPropertyDecl *ObjCPDecl = nullptr;
- if (Result == AR_Deprecated || Result == AR_Unavailable ||
- Result == AR_NotYetIntroduced) {
+ switch (Result) {
+ case AR_Available:
+ return Result;
+
+ case AR_Unavailable:
+ case AR_Deprecated:
+ return getCurContextAvailability() != Result ? Result : AR_Available;
+
+ case AR_NotYetIntroduced: {
+ // Don't do this for enums, they can't be redeclared.
+ if (isa<EnumConstantDecl>(D) || isa<EnumDecl>(D))
+ return AR_Available;
+
+ bool Warn = !D->getAttr<AvailabilityAttr>()->isInherited();
+ // Objective-C method declarations in categories are not modelled as
+ // redeclarations, so manually look for a redeclaration in a category
+ // if necessary.
+ if (Warn && HasRedeclarationWithoutAvailabilityInCategory(D))
+ Warn = false;
+ // In general, D will point to the most recent redeclaration. However,
+ // for `@class A;` decls, this isn't true -- manually go through the
+ // redecl chain in that case.
+ if (Warn && isa<ObjCInterfaceDecl>(D))
+ for (Decl *Redecl = D->getMostRecentDecl(); Redecl && Warn;
+ Redecl = Redecl->getPreviousDecl())
+ if (!Redecl->hasAttr<AvailabilityAttr>() ||
+ Redecl->getAttr<AvailabilityAttr>()->isInherited())
+ Warn = false;
+
+ return Warn ? AR_NotYetIntroduced : AR_Available;
+ }
+ }
+}
+
+static void
+DiagnoseAvailabilityOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc,
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ bool ObjCPropertyAccess) {
+ VersionTuple ContextVersion;
+ if (const DeclContext *DC = S.getCurObjCLexicalContext())
+ ContextVersion = S.getVersionForDecl(cast<Decl>(DC));
+
+ std::string Message;
+ // See if this declaration is unavailable, deprecated, or partial in the
+ // current context.
+ if (AvailabilityResult Result =
+ S.ShouldDiagnoseAvailabilityOfDecl(D, ContextVersion, &Message)) {
+
+ const ObjCPropertyDecl *ObjCPDecl = nullptr;
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {
AvailabilityResult PDeclResult =
@@ -155,56 +192,10 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name
ObjCPDecl = PD;
}
}
- }
-
- switch (Result) {
- case AR_Available:
- break;
- case AR_Deprecated:
- if (S.getCurContextAvailability() != AR_Deprecated)
- S.EmitAvailabilityWarning(Sema::AD_Deprecation,
- D, Message, Loc, UnknownObjCClass, ObjCPDecl,
- ObjCPropertyAccess);
- break;
-
- case AR_NotYetIntroduced: {
- // Don't do this for enums, they can't be redeclared.
- if (isa<EnumConstantDecl>(D) || isa<EnumDecl>(D))
- break;
-
- bool Warn = !D->getAttr<AvailabilityAttr>()->isInherited();
- // Objective-C method declarations in categories are not modelled as
- // redeclarations, so manually look for a redeclaration in a category
- // if necessary.
- if (Warn && HasRedeclarationWithoutAvailabilityInCategory(D))
- Warn = false;
- // In general, D will point to the most recent redeclaration. However,
- // for `@class A;` decls, this isn't true -- manually go through the
- // redecl chain in that case.
- if (Warn && isa<ObjCInterfaceDecl>(D))
- for (Decl *Redecl = D->getMostRecentDecl(); Redecl && Warn;
- Redecl = Redecl->getPreviousDecl())
- if (!Redecl->hasAttr<AvailabilityAttr>() ||
- Redecl->getAttr<AvailabilityAttr>()->isInherited())
- Warn = false;
-
- if (Warn)
- S.EmitAvailabilityWarning(Sema::AD_Partial, D, Message, Loc,
- UnknownObjCClass, ObjCPDecl,
- ObjCPropertyAccess);
- break;
- }
-
- case AR_Unavailable:
- if (S.getCurContextAvailability() != AR_Unavailable)
- S.EmitAvailabilityWarning(Sema::AD_Unavailable,
- D, Message, Loc, UnknownObjCClass, ObjCPDecl,
- ObjCPropertyAccess);
- break;
-
- }
- return Result;
+ S.EmitAvailabilityWarning(Result, D, Message, Loc, UnknownObjCClass,
+ ObjCPDecl, ObjCPropertyAccess);
+ }
}
/// \brief Emit a note explaining that this function is deleted.
More information about the cfe-commits
mailing list