diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-23 03:33:32 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-23 03:33:32 +0000 |
commit | 1af83c444e5a2f6f50a6e1c15e6ebc618ae18a5f (patch) | |
tree | 8a325a6f98d042574b75774b359263f77a7d32e8 /lib/Sema/SemaTemplate.cpp | |
parent | ccc6f36e53274fccae024f30ac5adb6be6f815d3 (diff) |
Support for definitions of member enumerations of class templates outside the
class template's definition, and for explicit specializations of such enum
members.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153304 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 680e6eaf2e..3a4a6f5312 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4699,8 +4699,11 @@ static bool CheckTemplateSpecializationScope(Sema &S, EntityKind = 4; else if (isa<RecordDecl>(Specialized)) EntityKind = 5; + else if (isa<EnumDecl>(Specialized) && S.getLangOpts().CPlusPlus0x) + EntityKind = 6; else { - S.Diag(Loc, diag::err_template_spec_unknown_kind); + S.Diag(Loc, diag::err_template_spec_unknown_kind) + << S.getLangOpts().CPlusPlus0x; S.Diag(Specialized->getLocation(), diag::note_specialized_entity); return true; } @@ -5816,6 +5819,14 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { InstantiatedFrom = PrevRecord->getInstantiatedFromMemberClass(); MSInfo = PrevRecord->getMemberSpecializationInfo(); } + } else if (isa<EnumDecl>(Member)) { + EnumDecl *PrevEnum; + if (Previous.isSingleResult() && + (PrevEnum = dyn_cast<EnumDecl>(Previous.getFoundDecl()))) { + Instantiation = PrevEnum; + InstantiatedFrom = PrevEnum->getInstantiatedFromMemberEnum(); + MSInfo = PrevEnum->getMemberSpecializationInfo(); + } } if (!Instantiation) { @@ -5906,8 +5917,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { cast<VarDecl>(InstantiatedFrom), TSK_ExplicitSpecialization); MarkUnusedFileScopedDecl(InstantiationVar); - } else { - assert(isa<CXXRecordDecl>(Member) && "Only member classes remain"); + } else if (isa<CXXRecordDecl>(Member)) { CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation); if (InstantiationClass->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) { @@ -5919,6 +5929,18 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass( cast<CXXRecordDecl>(InstantiatedFrom), TSK_ExplicitSpecialization); + } else { + assert(isa<EnumDecl>(Member) && "Only member enums remain"); + EnumDecl *InstantiationEnum = cast<EnumDecl>(Instantiation); + if (InstantiationEnum->getTemplateSpecializationKind() == + TSK_ImplicitInstantiation) { + InstantiationEnum->setTemplateSpecializationKind( + TSK_ExplicitSpecialization); + InstantiationEnum->setLocation(Member->getLocation()); + } + + cast<EnumDecl>(Member)->setInstantiationOfMemberEnum( + cast<EnumDecl>(InstantiatedFrom), TSK_ExplicitSpecialization); } // Save the caller the trouble of having to figure out which declaration @@ -6219,11 +6241,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, return true; TagDecl *Tag = cast<TagDecl>(TagD); - if (Tag->isEnum()) { - Diag(TemplateLoc, diag::err_explicit_instantiation_enum) - << Context.getTypeDeclType(Tag); - return true; - } + assert(!Tag->isEnum() && "shouldn't see enumerations here"); if (Tag->isInvalidDecl()) return true; |