aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-01-10 01:33:14 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-01-10 01:33:14 +0000
commitbdad7a2e21686296b78dac6190b78d11c996f6d7 (patch)
treea2695b7ffdfd95acfa1966fc6fd43fa38b419a9a /lib/Sema/SemaDecl.cpp
parent8f0a403945b60a8a8a56a7721bb66f6b84ec129b (diff)
Update C++11 scoped enumeration support to match the final proposal:
- reject definitions of enums within friend declarations - require 'enum', not 'enum class', for non-declaring references to scoped enumerations git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147824 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 4a804bfcff..a2bf48e47a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -7580,7 +7580,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation ModulePrivateLoc,
MultiTemplateParamsArg TemplateParameterLists,
bool &OwnedDecl, bool &IsDependent,
- bool ScopedEnum, bool ScopedEnumUsesClassTag,
+ SourceLocation ScopedEnumKWLoc,
+ bool ScopedEnumUsesClassTag,
TypeResult UnderlyingType) {
// If this is not a definition, it must have a name.
assert((Name != 0 || TUK == TUK_Definition) &&
@@ -7589,6 +7590,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
OwnedDecl = false;
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
+ bool ScopedEnum = ScopedEnumKWLoc.isValid();
// FIXME: Check explicit specializations more carefully.
bool isExplicitSpecialization = false;
@@ -7919,6 +7921,16 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
if (Kind == TTK_Enum && PrevTagDecl->getTagKind() == TTK_Enum) {
const EnumDecl *PrevEnum = cast<EnumDecl>(PrevTagDecl);
+ // If this is an elaborated-type-specifier for a scoped enumeration,
+ // the 'class' keyword is not necessary and not permitted.
+ if (TUK == TUK_Reference || TUK == TUK_Friend) {
+ if (ScopedEnum)
+ Diag(ScopedEnumKWLoc, diag::err_enum_class_reference)
+ << PrevEnum->isScoped()
+ << FixItHint::CreateRemoval(ScopedEnumKWLoc);
+ return PrevTagDecl;
+ }
+
// All conflicts with previous declarations are recovered by
// returning the previous declaration.
if (ScopedEnum != PrevEnum->isScoped()) {