diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-26 04:08:46 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-26 04:08:46 +0000 |
commit | 4ca93d9978aac02b01814b4f749d6903a1f87ee5 (patch) | |
tree | 567afc5124dbf52e1714409bb2b19751ad52a874 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | b3dcbbda59a24a5c72483d00f16c5e3f2b328495 (diff) |
Delay checking of dependent underlying types for redeclarations of member
enumerations in templates until the template is instantiated.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153426 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index ebc43d443d..caf134e025 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -588,9 +588,20 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { if (SubstQualifier(D, Enum)) return 0; Owner->addDecl(Enum); - // FIXME: If this is a redeclaration: - // CheckEnumRedeclaration(Enum->getLocation(), Enum->isScoped(), - // Enum->getIntegerType(), Prev); + EnumDecl *Def = D->getDefinition(); + if (Def && Def != D) { + // If this is an out-of-line definition of an enum member template, check + // that the underlying types match in the instantiation of both + // declarations. + if (TypeSourceInfo *TI = Def->getIntegerTypeSourceInfo()) { + SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc(); + QualType DefnUnderlying = + SemaRef.SubstType(TI->getType(), TemplateArgs, + UnderlyingLoc, DeclarationName()); + SemaRef.CheckEnumRedeclaration(Def->getLocation(), Def->isScoped(), + DefnUnderlying, Enum); + } + } if (D->getDeclContext()->isFunctionOrMethod()) SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum); @@ -600,8 +611,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { // not the definitions of scoped member enumerations. // FIXME: There appears to be no wording for what happens for an enum defined // within a block scope, but we treat that like a member of a class template. - if (!Enum->isScoped() && D->getDefinition()) - InstantiateEnumDefinition(Enum, D); + if (!Enum->isScoped() && Def) + InstantiateEnumDefinition(Enum, Def); return Enum; } |