Add message to attribute(deprecated).

attribute(unavailable) to do next.
// rdar:// 6734520.

llvm-svn: 115842
This commit is contained in:
Fariborz Jahanian 2010-10-06 21:18:44 +00:00
parent b270f28c1a
commit 55106310ae
8 changed files with 86 additions and 17 deletions

View File

@ -172,6 +172,7 @@ def Constructor : Attr {
def Deprecated : Attr {
let Spellings = ["deprecated"];
let Args = [StringArgument<"Message">];
}
def Destructor : Attr {

View File

@ -1745,6 +1745,8 @@ def note_dependent_var_use : Note<"must qualify identifier to find this "
def err_undeclared_use : Error<"use of undeclared %0">;
def warn_deprecated : Warning<"%0 is deprecated">,
InGroup<DeprecatedDeclarations>;
def warn_deprecated_message : Warning<"%0 is deprecated: %1">,
InGroup<DeprecatedDeclarations>;
def err_unavailable : Error<"%0 is unavailable">;
def note_unavailable_here : Note<
"function has been explicitly marked %select{unavailable|deleted}0 here">;

View File

@ -121,7 +121,7 @@ public:
union {
/// Deprecation.
struct { NamedDecl *Decl; } DeprecationData;
struct { NamedDecl *Decl; const char* Message; } DeprecationData;
/// Access control.
char AccessData[sizeof(AccessedEntity)];
@ -135,12 +135,14 @@ public:
}
static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
NamedDecl *D) {
NamedDecl *D,
const char *Msg) {
DelayedDiagnostic DD;
DD.Kind = Deprecation;
DD.Triggered = false;
DD.Loc = Loc;
DD.DeprecationData.Decl = D;
DD.DeprecationData.Message = Msg;
return DD;
}

View File

@ -1649,7 +1649,8 @@ public:
ParsingDeclStackState PushParsingDeclaration();
void PopParsingDeclaration(ParsingDeclStackState S, Decl *D);
void EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc);
void EmitDeprecationWarning(NamedDecl *D, const char *Message,
SourceLocation Loc);
void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);

View File

@ -903,12 +903,28 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
int noArgs = Attr.getNumArgs();
if (noArgs > 1) {
S.Diag(Attr.getLoc(),
diag::err_attribute_wrong_number_arguments) << "0 or 1";
return;
}
// Handle the case where deprecated attribute has a text message.
StringLiteral *SE;
if (noArgs == 1) {
Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
SE = dyn_cast<StringLiteral>(ArgExpr);
if (!SE) {
S.Diag(ArgExpr->getLocStart(),
diag::err_attribute_not_string) << "deprecated";
return;
}
}
else
SE = StringLiteral::CreateEmpty(S.Context, 1);
d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context));
d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context,
SE->getString()));
}
static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@ -2536,20 +2552,30 @@ void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
return;
DD.Triggered = true;
Diag(DD.Loc, diag::warn_deprecated)
<< DD.DeprecationData.Decl->getDeclName();
if (strlen(DD.DeprecationData.Message))
Diag(DD.Loc, diag::warn_deprecated_message)
<< DD.DeprecationData.Decl->getDeclName()
<< DD.DeprecationData.Message;
else
Diag(DD.Loc, diag::warn_deprecated)
<< DD.DeprecationData.Decl->getDeclName();
}
void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) {
void Sema::EmitDeprecationWarning(NamedDecl *D, const char * Message,
SourceLocation Loc) {
// Delay if we're currently parsing a declaration.
if (ParsingDeclDepth) {
DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D));
DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D,
Message));
return;
}
// Otherwise, don't warn if our current context is deprecated.
if (isDeclDeprecated(cast<Decl>(CurContext)))
return;
Diag(Loc, diag::warn_deprecated) << D->getDeclName();
if (strlen(Message))
Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
<< Message;
else
Diag(Loc, diag::warn_deprecated) << D->getDeclName();
}

View File

@ -1622,9 +1622,13 @@ Decl *Sema::ActOnMethodDeclaration(
// If the interface declared this method, and it was deprecated there,
// mark it deprecated here.
if (InterfaceMD)
if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>())
ObjCMethod->addAttr(::new (Context) DeprecatedAttr(DA->getLocation(),
Context));
if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>()) {
StringLiteral *SE = StringLiteral::CreateEmpty(Context, 1);
ObjCMethod->addAttr(::new (Context)
DeprecatedAttr(DA->getLocation(),
Context,
SE->getString()));
}
return ObjCMethod;
}

View File

@ -57,8 +57,10 @@ using namespace sema;
///
bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
// See if the decl is deprecated.
if (D->getAttr<DeprecatedAttr>()) {
EmitDeprecationWarning(D, Loc);
if (const DeprecatedAttr *DA = D->getAttr<DeprecatedAttr>()) {
const char *Message =
DA->getMessage().empty() ? "" : DA->getMessage().data();
EmitDeprecationWarning(D, Message, Loc);
}
// See if the decl is unavailable

View File

@ -0,0 +1,31 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only
// rdar: // 6734520
typedef int INT1 __attribute__((deprecated("Please avoid INT1")));
typedef INT1 INT2 __attribute__ ((__deprecated__("Please avoid INT2")));
typedef INT1 INT1a; // expected-warning {{'INT1' is deprecated: Please avoid INT1}}
typedef INT1 INT1b __attribute__ ((deprecated("Please avoid INT1b")));
INT1 should_be_unavailable; // expected-warning {{'INT1' is deprecated: Please avoid INT1}}
INT1a should_not_be_deprecated;
INT1 f1(void) __attribute__ ((deprecated("Please avoid f1")));
INT1 f2(void); // expected-warning {{'INT1' is deprecated: Please avoid INT1}}
typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color")));
Color c1; // expected-warning {{'Color' is deprecated: Please avoid Color}}
int g1;
int g2 __attribute__ ((deprecated("Please avoid g2")));
int func1()
{
int (*pf)() = f1; // expected-warning {{'f1' is deprecated: Please avoid f1}}
int i = f2();
return g1 + g2; // expected-warning {{'g2' is deprecated: Please avoid g2}}
}