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 | 258a744bbd6dbfb675d3c39da021321f2b317dae (patch) | |
tree | 08bd61324793a416d0b0e8f04650ea5d8f96bc0c /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | eb75cc26af4ca8f5cba1b52f42809329ba48c583 (diff) | |
download | bcm5719-llvm-258a744bbd6dbfb675d3c39da021321f2b317dae.tar.gz bcm5719-llvm-258a744bbd6dbfb675d3c39da021321f2b317dae.zip |
Delay checking of dependent underlying types for redeclarations of member
enumerations in templates until the template is instantiated.
llvm-svn: 153426
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index ebc43d443db..caf134e0259 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/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; } |