forked from OSchip/llvm-project
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:
parent
ccb8f16891
commit
17046b8506
|
@ -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">];
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue