aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp73
1 files changed, 53 insertions, 20 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 80dcfd4e6d..07e97117cb 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -708,7 +708,8 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
Previous.clear();
}
- SemaRef.CheckFunctionDeclaration(Function, Previous, false, Redeclaration,
+ SemaRef.CheckFunctionDeclaration(/*Scope*/ 0, Function, Previous,
+ false, Redeclaration,
/*FIXME:*/OverloadableAttrRequired);
// If the original function was part of a friend declaration,
@@ -868,7 +869,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
bool Redeclaration = false;
bool OverloadableAttrRequired = false;
- SemaRef.CheckFunctionDeclaration(Method, Previous, false, Redeclaration,
+ SemaRef.CheckFunctionDeclaration(0, Method, Previous, false, Redeclaration,
/*FIXME:*/OverloadableAttrRequired);
if (D->isPure())
@@ -1040,6 +1041,14 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
// The nested name specifier is non-dependent, so no transformation
// is required.
+ // We only need to do redeclaration lookups if we're in a class
+ // scope (in fact, it's not really even possible in non-class
+ // scopes).
+ bool CheckRedeclaration = Owner->isRecord();
+
+ LookupResult Prev(SemaRef, D->getDeclName(), D->getLocation(),
+ Sema::LookupUsingDeclName, Sema::ForRedeclaration);
+
UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
D->getLocation(),
D->getNestedNameRange(),
@@ -1051,34 +1060,55 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
CXXScopeSpec SS;
SS.setScopeRep(D->getTargetNestedNameDecl());
SS.setRange(D->getNestedNameRange());
- if (SemaRef.CheckUsingDeclQualifier(D->getUsingLocation(), SS,
+
+ if (CheckRedeclaration) {
+ Prev.setHideTags(false);
+ SemaRef.LookupQualifiedName(Prev, Owner);
+
+ // Check for invalid redeclarations.
+ if (SemaRef.CheckUsingDeclRedeclaration(D->getUsingLocation(),
+ D->isTypeName(), SS,
+ D->getLocation(), Prev))
+ NewUD->setInvalidDecl();
+
+ }
+
+ if (!NewUD->isInvalidDecl() &&
+ SemaRef.CheckUsingDeclQualifier(D->getUsingLocation(), SS,
D->getLocation()))
NewUD->setInvalidDecl();
+
SemaRef.Context.setInstantiatedFromUsingDecl(NewUD, D);
NewUD->setAccess(D->getAccess());
Owner->addDecl(NewUD);
- // We'll transform the UsingShadowDecls as we reach them.
+ // Don't process the shadow decls for an invalid decl.
+ if (NewUD->isInvalidDecl())
+ return NewUD;
- return NewUD;
-}
+ // Process the shadow decls.
+ for (UsingDecl::shadow_iterator I = D->shadow_begin(), E = D->shadow_end();
+ I != E; ++I) {
+ UsingShadowDecl *Shadow = *I;
+ NamedDecl *InstTarget =
+ cast<NamedDecl>(SemaRef.FindInstantiatedDecl(Shadow->getTargetDecl(),
+ TemplateArgs));
-Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) {
- UsingDecl *InstUsing =
- cast<UsingDecl>(SemaRef.FindInstantiatedDecl(D->getUsingDecl(),
- TemplateArgs));
- NamedDecl *InstTarget =
- cast<NamedDecl>(SemaRef.FindInstantiatedDecl(D->getTargetDecl(),
- TemplateArgs));
+ if (CheckRedeclaration &&
+ SemaRef.CheckUsingShadowDecl(NewUD, InstTarget, Prev))
+ continue;
- UsingShadowDecl *InstD = SemaRef.BuildUsingShadowDecl(/*Scope*/ 0,
- D->getAccess(),
- InstUsing,
- InstTarget);
+ UsingShadowDecl *InstShadow
+ = SemaRef.BuildUsingShadowDecl(/*Scope*/ 0, NewUD, InstTarget);
+ SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstShadow, Shadow);
+ }
- SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstD, D);
+ return NewUD;
+}
- return InstD;
+Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) {
+ // Ignore these; we handle them in bulk when processing the UsingDecl.
+ return 0;
}
Decl * TemplateDeclInstantiator
@@ -2087,7 +2117,10 @@ NamedDecl *Sema::FindInstantiatedDecl(NamedDecl *D,
ParentDC->decls_end());
}
- assert(Result && "Unable to find instantiation of declaration!");
+ // UsingShadowDecls can instantiate to nothing because of using hiding.
+ assert((Result || isa<UsingShadowDecl>(D))
+ && "Unable to find instantiation of declaration!");
+
D = Result;
}