Automated checking for C++ when determining what argument to send to the diagnostic for attribute subjects. In turn, this allows the Subjects to be enabled for some more attributes and improves diagnostics. Updated a test case based on the improved diagnostic.

llvm-svn: 195864
This commit is contained in:
Aaron Ballman 2013-11-27 19:16:55 +00:00
parent ccb8f16891
commit 17046b8506
4 changed files with 10 additions and 22 deletions

View File

@ -576,13 +576,13 @@ def NSBridged : InheritableAttr {
def ObjCBridge : InheritableAttr {
let Spellings = [GNU<"objc_bridge">];
// let Subjects = SubjectList<[Record], ErrorDiag>;
let Subjects = SubjectList<[Record], ErrorDiag>;
let Args = [IdentifierArgument<"BridgedType">];
}
def ObjCBridgeMutable : InheritableAttr {
let Spellings = [GNU<"objc_bridge_mutable">];
// let Subjects = SubjectList<[Record], ErrorDiag>;
let Subjects = SubjectList<[Record], ErrorDiag>;
let Args = [IdentifierArgument<"BridgedType">];
}

View File

@ -3891,14 +3891,6 @@ static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D,
const AttributeList &Attr) {
if (!isa<RecordDecl>(D)) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< Attr.getName()
<< (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass
: ExpectedStructOrUnion);
return;
}
IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
if (!Parm) {
@ -3913,14 +3905,6 @@ static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D,
static void handleObjCBridgeMutableAttr(Sema &S, Scope *Sc, Decl *D,
const AttributeList &Attr) {
if (!isa<RecordDecl>(D)) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< Attr.getName()
<< (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass
: ExpectedStructOrUnion);
return;
}
IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
if (!Parm) {

View File

@ -25,7 +25,7 @@ struct {
} __attribute__((__ms_struct__)) t1;
struct S {
double __attribute__((ms_struct)) d; // expected-warning {{'ms_struct' attribute only applies to struct, union or class}}
double __attribute__((ms_struct)) d; // expected-warning {{'ms_struct' attribute only applies to struct or union}}
unsigned long bf_1 : 12;
unsigned long : 0;
unsigned long bf_2 : 12;
@ -36,7 +36,7 @@ enum
A = 0,
B,
C
} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute only applies to struct, union or class}}
} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute only applies to struct or union}}
// rdar://10513599
#pragma ms_struct on

View File

@ -1771,8 +1771,12 @@ static std::string CalculateDiagnostic(const Record &S) {
case Type: return "ExpectedType";
case ObjCInterface: return "ExpectedObjectiveCInterface";
// FIXME: This could be checking lang opts to remove class.
case Struct: return "ExpectedStructOrUnionOrClass";
// "Struct" means struct, union or class; check the language options and if
// not compiling for C++, strip off the class part. Note that this relies
// on the fact that the context for this declares "Sema &S".
case Struct:
return "(S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : "
"ExpectedStructOrUnion)";
case Func | ObjCMethod | Block: return "ExpectedFunctionMethodOrBlock";
case Func | ObjCMethod | Class: return "ExpectedFunctionMethodOrClass";
case Func | Param: