summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-08-13 18:18:50 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-08-13 18:18:50 +0000
commit1c34fb78e7ebb9956c4282a5247a949869e6c09c (patch)
treee0bbcc06c58ed3c975834e73b00bb4b053f80f94 /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
parentc8d710cc82ee56cc59fb9b378b44623dcc53fd15 (diff)
downloadbcm5719-llvm-1c34fb78e7ebb9956c4282a5247a949869e6c09c.tar.gz
bcm5719-llvm-1c34fb78e7ebb9956c4282a5247a949869e6c09c.zip
Fix implementation of C11 6.2.7/4 and C++11 [dcl.array]p3:
When a local extern declaration redeclares some other entity, the type of that entity is merged with the prior type if the prior declaration is visible (in C) or is declared in the same scope (in C++). - Make LookupRedeclarationWithLinkage actually work in C++, use it in the right set of cases, and make it track whether it found a shadowed declaration. - Track whether we found a declaration in the same scope (for C++) including across serialization and template instantiation. llvm-svn: 188307
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp18
1 files changed, 13 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 5766afa1011..c7242aa5f99 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -973,7 +973,8 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) {
// FIXME: This, and ForVarTemplate, is a hack that is probably unnecessary.
// We should use a simplified version of VisitVarDecl.
- VarDecl *VarInst = cast_or_null<VarDecl>(VisitVarDecl(Pattern, /*ForVarTemplate=*/true));
+ VarDecl *VarInst =
+ cast_or_null<VarDecl>(VisitVarDecl(Pattern, /*ForVarTemplate=*/ true));
DeclContext *DC = Owner;
@@ -3336,6 +3337,8 @@ void Sema::BuildVariableInstantiation(
NewVar->setInitStyle(OldVar->getInitStyle());
NewVar->setCXXForRangeDecl(OldVar->isCXXForRangeDecl());
NewVar->setConstexpr(OldVar->isConstexpr());
+ NewVar->setPreviousDeclInSameBlockScope(
+ OldVar->isPreviousDeclInSameBlockScope());
NewVar->setAccess(OldVar->getAccess());
if (!OldVar->isStaticDataMember()) {
@@ -3348,13 +3351,18 @@ void Sema::BuildVariableInstantiation(
if (NewVar->hasAttrs())
CheckAlignasUnderalignment(NewVar);
- // FIXME: In theory, we could have a previous declaration for variables that
- // are not static data members.
- // FIXME: having to fake up a LookupResult is dumb.
LookupResult Previous(*this, NewVar->getDeclName(), NewVar->getLocation(),
Sema::LookupOrdinaryName, Sema::ForRedeclaration);
- if (!isa<VarTemplateSpecializationDecl>(NewVar))
+ if (NewVar->getLexicalDeclContext()->isFunctionOrMethod() &&
+ OldVar->getPreviousDecl()) {
+ // We have a previous declaration. Use that one, so we merge with the
+ // right type.
+ if (NamedDecl *NewPrev = FindInstantiatedDecl(
+ NewVar->getLocation(), OldVar->getPreviousDecl(), TemplateArgs))
+ Previous.addDecl(NewPrev);
+ } else if (!isa<VarTemplateSpecializationDecl>(NewVar) &&
+ OldVar->hasLinkage())
LookupQualifiedName(Previous, NewVar->getDeclContext(), false);
CheckVariableDeclaration(NewVar, Previous);
OpenPOWER on IntegriCloud