forked from OSchip/llvm-project
Parse attributes on enumerators and instantiate attributes on enum decls.
llvm-svn: 117182
This commit is contained in:
parent
21836f726b
commit
811a0f5578
|
@ -882,6 +882,7 @@ public:
|
|||
|
||||
Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant,
|
||||
SourceLocation IdLoc, IdentifierInfo *Id,
|
||||
AttributeList *Attrs,
|
||||
SourceLocation EqualLoc, Expr *Val);
|
||||
void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
|
||||
SourceLocation RBraceLoc, Decl *EnumDecl,
|
||||
|
|
|
@ -2124,6 +2124,11 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
|
|||
IdentifierInfo *Ident = Tok.getIdentifierInfo();
|
||||
SourceLocation IdentLoc = ConsumeToken();
|
||||
|
||||
// If attributes exist after the enumerator, parse them.
|
||||
llvm::OwningPtr<AttributeList> Attr;
|
||||
if (Tok.is(tok::kw___attribute))
|
||||
Attr.reset(ParseGNUAttributes());
|
||||
|
||||
SourceLocation EqualLoc;
|
||||
ExprResult AssignedVal;
|
||||
if (Tok.is(tok::equal)) {
|
||||
|
@ -2137,7 +2142,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
|
|||
Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
|
||||
LastEnumConstDecl,
|
||||
IdentLoc, Ident,
|
||||
EqualLoc,
|
||||
Attr.get(), EqualLoc,
|
||||
AssignedVal.release());
|
||||
EnumConstantDecls.push_back(EnumConstDecl);
|
||||
LastEnumConstDecl = EnumConstDecl;
|
||||
|
|
|
@ -7229,10 +7229,9 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
|
|||
}
|
||||
|
||||
|
||||
Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl,
|
||||
Decl *lastEnumConst,
|
||||
SourceLocation IdLoc,
|
||||
IdentifierInfo *Id,
|
||||
Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
|
||||
SourceLocation IdLoc, IdentifierInfo *Id,
|
||||
AttributeList *Attr,
|
||||
SourceLocation EqualLoc, ExprTy *val) {
|
||||
EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl);
|
||||
EnumConstantDecl *LastEnumConst =
|
||||
|
@ -7280,11 +7279,14 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl,
|
|||
if (Record->getIdentifier() && Record->getIdentifier() == Id)
|
||||
Diag(IdLoc, diag::err_member_name_of_class) << Id;
|
||||
|
||||
EnumConstantDecl *New = CheckEnumConstant(TheEnumDecl, LastEnumConst,
|
||||
IdLoc, Id, Val);
|
||||
EnumConstantDecl *New =
|
||||
CheckEnumConstant(TheEnumDecl, LastEnumConst, IdLoc, Id, Val);
|
||||
|
||||
if (New) {
|
||||
// Process attributes.
|
||||
if (Attr) ProcessDeclAttributeList(S, New, Attr);
|
||||
|
||||
// Register this decl in the current scope stack.
|
||||
if (New) {
|
||||
New->setAccess(TheEnumDecl->getAccess());
|
||||
PushOnScopeChains(New, S);
|
||||
}
|
||||
|
|
|
@ -619,6 +619,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
|
|||
}
|
||||
}
|
||||
|
||||
SemaRef.InstantiateAttrs(TemplateArgs, D, Enum);
|
||||
|
||||
Enum->setInstantiationOfMemberEnum(D);
|
||||
Enum->setAccess(D->getAccess());
|
||||
if (SubstQualifier(D, Enum)) return 0;
|
||||
|
@ -663,6 +665,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
|
|||
}
|
||||
|
||||
if (EnumConst) {
|
||||
SemaRef.InstantiateAttrs(TemplateArgs, *EC, EnumConst);
|
||||
|
||||
EnumConst->setAccess(Enum->getAccess());
|
||||
Enum->addDecl(EnumConst);
|
||||
Enumerators.push_back(EnumConst);
|
||||
|
|
|
@ -98,3 +98,14 @@ unsigned long test16 __attribute__((deprecated))
|
|||
foo_dep test17, // expected-warning {{'foo_dep' is deprecated}}
|
||||
test18 __attribute__((deprecated)),
|
||||
test19;
|
||||
|
||||
// rdar://problem/8518751
|
||||
enum __attribute__((deprecated)) Test20 {
|
||||
test20_a __attribute__((deprecated)),
|
||||
test20_b
|
||||
};
|
||||
void test20() {
|
||||
enum Test20 f; // expected-warning {{'Test20' is deprecated}}
|
||||
f = test20_a; // expected-warning {{'test20_a' is deprecated}}
|
||||
f = test20_b;
|
||||
}
|
||||
|
|
|
@ -190,3 +190,46 @@ namespace test5 {
|
|||
{}
|
||||
};
|
||||
}
|
||||
|
||||
// rdar://problem/8518751
|
||||
namespace test6 {
|
||||
enum __attribute__((deprecated)) A {
|
||||
a0
|
||||
};
|
||||
void testA() {
|
||||
A x; // expected-warning {{'A' is deprecated}}
|
||||
x = a0;
|
||||
}
|
||||
|
||||
enum B {
|
||||
b0 __attribute__((deprecated)),
|
||||
b1
|
||||
};
|
||||
void testB() {
|
||||
B x;
|
||||
x = b0; // expected-warning {{'b0' is deprecated}}
|
||||
x = b1;
|
||||
}
|
||||
|
||||
template <class T> struct C {
|
||||
enum __attribute__((deprecated)) Enum {
|
||||
c0
|
||||
};
|
||||
};
|
||||
void testC() {
|
||||
C<int>::Enum x; // expected-warning {{'Enum' is deprecated}}
|
||||
x = C<int>::c0;
|
||||
}
|
||||
|
||||
template <class T> struct D {
|
||||
enum Enum {
|
||||
d0,
|
||||
d1 __attribute__((deprecated)),
|
||||
};
|
||||
};
|
||||
void testD() {
|
||||
D<int>::Enum x;
|
||||
x = D<int>::d0;
|
||||
x = D<int>::d1; // expected-warning {{'d1' is deprecated}}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue