Skip to content

Commit 0e05e24

Browse files
committed
Added struct/class syntactic info for c++0x scoped enum.
llvm-svn: 120828
1 parent 376d387 commit 0e05e24

12 files changed

+47
-22
lines changed

clang/include/clang/AST/Decl.h

+16-3
Original file line numberDiff line numberDiff line change
@@ -1964,9 +1964,14 @@ class TagDecl
19641964
unsigned NumPositiveBits : 8;
19651965
unsigned NumNegativeBits : 8;
19661966

1967-
/// IsScoped - True if this is tag declaration is a scoped enumeration. Only
1967+
/// IsScoped - True if this tag declaration is a scoped enumeration. Only
19681968
/// possible in C++0x mode.
19691969
bool IsScoped : 1;
1970+
/// IsScopedUsingClassTag - If this tag declaration is a scoped enum,
1971+
/// then this is true if the scoped enum was declared using the class
1972+
/// tag, false if it was declared with the struct tag. No meaning is
1973+
/// associated if this tag declaration is not a scoped enum.
1974+
bool IsScopedUsingClassTag : 1;
19701975

19711976
/// IsFixed - True if this is an enumeration with fixed underlying type. Only
19721977
/// possible in C++0x mode.
@@ -2189,12 +2194,14 @@ class EnumDecl : public TagDecl {
21892194

21902195
EnumDecl(DeclContext *DC, SourceLocation L,
21912196
IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL,
2192-
bool Scoped, bool Fixed)
2197+
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
21932198
: TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
2199+
assert(Scoped || !ScopedUsingClassTag);
21942200
IntegerType = (const Type*)0;
21952201
NumNegativeBits = 0;
21962202
NumPositiveBits = 0;
21972203
IsScoped = Scoped;
2204+
IsScopedUsingClassTag = ScopedUsingClassTag;
21982205
IsFixed = Fixed;
21992206
}
22002207
public:
@@ -2215,7 +2222,8 @@ class EnumDecl : public TagDecl {
22152222
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
22162223
SourceLocation L, IdentifierInfo *Id,
22172224
SourceLocation TKL, EnumDecl *PrevDecl,
2218-
bool IsScoped, bool IsFixed);
2225+
bool IsScoped, bool IsScopedUsingClassTag,
2226+
bool IsFixed);
22192227
static EnumDecl *Create(ASTContext &C, EmptyShell Empty);
22202228

22212229
/// completeDefinition - When created, the EnumDecl corresponds to a
@@ -2306,6 +2314,11 @@ class EnumDecl : public TagDecl {
23062314
return IsScoped;
23072315
}
23082316

2317+
/// \brief Returns true if this is a C++0x scoped enumeration.
2318+
bool isScopedUsingClassTag() const {
2319+
return IsScopedUsingClassTag;
2320+
}
2321+
23092322
/// \brief Returns true if this is a C++0x enumeration with fixed underlying
23102323
/// type.
23112324
bool isFixed() const {

clang/include/clang/Sema/Sema.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ class Sema {
808808
AttributeList *Attr, AccessSpecifier AS,
809809
MultiTemplateParamsArg TemplateParameterLists,
810810
bool &OwnedDecl, bool &IsDependent, bool ScopedEnum,
811-
TypeResult UnderlyingType);
811+
bool ScopedEnumUsesClassTag, TypeResult UnderlyingType);
812812

813813
Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
814814
unsigned TagSpec, SourceLocation TagLoc,

clang/lib/AST/ASTImporter.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -2001,9 +2001,10 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
20012001

20022002
// Create the enum declaration.
20032003
EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC, Loc,
2004-
Name.getAsIdentifierInfo(),
2005-
Importer.Import(D->getTagKeywordLoc()),
2006-
0, D->isScoped(), D->isFixed());
2004+
Name.getAsIdentifierInfo(),
2005+
Importer.Import(D->getTagKeywordLoc()), 0,
2006+
D->isScoped(), D->isScopedUsingClassTag(),
2007+
D->isFixed());
20072008
// Import the qualifier, if any.
20082009
if (D->getQualifier()) {
20092010
NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());

clang/lib/AST/Decl.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -1925,16 +1925,17 @@ void TagDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
19251925

19261926
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
19271927
IdentifierInfo *Id, SourceLocation TKL,
1928-
EnumDecl *PrevDecl, bool IsScoped, bool IsFixed) {
1928+
EnumDecl *PrevDecl, bool IsScoped,
1929+
bool IsScopedUsingClassTag, bool IsFixed) {
19291930
EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, PrevDecl, TKL,
1930-
IsScoped, IsFixed);
1931+
IsScoped, IsScopedUsingClassTag, IsFixed);
19311932
C.getTypeDeclType(Enum, PrevDecl);
19321933
return Enum;
19331934
}
19341935

19351936
EnumDecl *EnumDecl::Create(ASTContext &C, EmptyShell Empty) {
19361937
return new (C) EnumDecl(0, SourceLocation(), 0, 0, SourceLocation(),
1937-
false, false);
1938+
false, false, false);
19381939
}
19391940

19401941
void EnumDecl::completeDefinition(QualType NewType,

clang/lib/AST/DeclPrinter.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,12 @@ void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
308308

309309
void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
310310
Out << "enum ";
311-
if (D->isScoped())
312-
Out << "class ";
311+
if (D->isScoped()) {
312+
if (D->isScopedUsingClassTag())
313+
Out << "class ";
314+
else
315+
Out << "struct ";
316+
}
313317
Out << D;
314318

315319
if (D->isFixed()) {

clang/lib/Parse/ParseDecl.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -1980,11 +1980,13 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
19801980
}
19811981

19821982
bool IsScopedEnum = false;
1983+
bool IsScopedUsingClassTag = false;
19831984

1984-
if (getLang().CPlusPlus0x && (Tok.is(tok::kw_class)
1985-
|| Tok.is(tok::kw_struct))) {
1986-
ConsumeToken();
1985+
if (getLang().CPlusPlus0x &&
1986+
(Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
19871987
IsScopedEnum = true;
1988+
IsScopedUsingClassTag = Tok.is(tok::kw_class);
1989+
ConsumeToken();
19881990
}
19891991

19901992
// Must have either 'enum name' or 'enum {...}'.
@@ -2009,6 +2011,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
20092011
// declaration of a scoped enumeration.
20102012
Diag(Tok, diag::err_scoped_enum_missing_identifier);
20112013
IsScopedEnum = false;
2014+
IsScopedUsingClassTag = false;
20122015
}
20132016

20142017
TypeResult BaseType;
@@ -2103,7 +2106,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
21032106
AS,
21042107
MultiTemplateParamsArg(Actions),
21052108
Owned, IsDependent, IsScopedEnum,
2106-
BaseType);
2109+
IsScopedUsingClassTag, BaseType);
21072110

21082111
if (IsDependent) {
21092112
// This enum has a dependent nested-name-specifier. Handle it as a

clang/lib/Parse/ParseDeclCXX.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
10021002
TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
10031003
SS, Name, NameLoc, AttrList, AS,
10041004
TParams, Owned, IsDependent, false,
1005-
clang::TypeResult());
1005+
false, clang::TypeResult());
10061006

10071007
// If ActOnTag said the type was dependent, try again with the
10081008
// less common call.

clang/lib/Sema/SemaDecl.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -5643,7 +5643,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
56435643
IdentifierInfo *Name, SourceLocation NameLoc,
56445644
AttributeList *Attr, AccessSpecifier AS,
56455645
MultiTemplateParamsArg TemplateParameterLists,
5646-
bool &OwnedDecl, bool &IsDependent, bool ScopedEnum,
5646+
bool &OwnedDecl, bool &IsDependent,
5647+
bool ScopedEnum, bool ScopedEnumUsesClassTag,
56475648
TypeResult UnderlyingType) {
56485649
// If this is not a definition, it must have a name.
56495650
assert((Name != 0 || TUK == TUK_Definition) &&
@@ -6139,7 +6140,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
61396140
// enum X { A, B, C } D; D should chain to X.
61406141
New = EnumDecl::Create(Context, SearchDC, Loc, Name, KWLoc,
61416142
cast_or_null<EnumDecl>(PrevDecl), ScopedEnum,
6142-
!EnumUnderlying.isNull());
6143+
ScopedEnumUsesClassTag, !EnumUnderlying.isNull());
61436144
// If this is an undefined enum, warn.
61446145
if (TUK != TUK_Definition && !Invalid) {
61456146
TagDecl *Def;

clang/lib/Sema/SemaTemplate.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -5172,7 +5172,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
51725172
Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference,
51735173
KWLoc, SS, Name, NameLoc, Attr, AS_none,
51745174
MultiTemplateParamsArg(*this, 0, 0),
5175-
Owned, IsDependent, false,
5175+
Owned, IsDependent, false, false,
51765176
TypeResult());
51775177
assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
51785178

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
540540
EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner,
541541
D->getLocation(), D->getIdentifier(),
542542
D->getTagKeywordLoc(),
543-
/*PrevDecl=*/0,
544-
D->isScoped(), D->isFixed());
543+
/*PrevDecl=*/0, D->isScoped(),
544+
D->isScopedUsingClassTag(), D->isFixed());
545545
if (D->isFixed()) {
546546
if (TypeSourceInfo* TI = D->getIntegerTypeSourceInfo()) {
547547
// If we have type source information for the underlying type, it means it

clang/lib/Serialization/ASTReaderDecl.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
242242
ED->setNumPositiveBits(Record[Idx++]);
243243
ED->setNumNegativeBits(Record[Idx++]);
244244
ED->IsScoped = Record[Idx++];
245+
ED->IsScopedUsingClassTag = Record[Idx++];
245246
ED->IsFixed = Record[Idx++];
246247
ED->setInstantiationOfMemberEnum(
247248
cast_or_null<EnumDecl>(Reader.GetDecl(Record[Idx++])));

clang/lib/Serialization/ASTWriterDecl.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
190190
Record.push_back(D->getNumPositiveBits());
191191
Record.push_back(D->getNumNegativeBits());
192192
Record.push_back(D->isScoped());
193+
Record.push_back(D->isScopedUsingClassTag());
193194
Record.push_back(D->isFixed());
194195
Writer.AddDeclRef(D->getInstantiatedFromMemberEnum(), Record);
195196
Code = serialization::DECL_ENUM;

0 commit comments

Comments
 (0)