diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 28 |
3 files changed, 48 insertions, 5 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f527657626..eebb11da99 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -242,6 +242,24 @@ ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl) { InstantiatedFromStaticDataMember[Inst] = Tmpl; } +UnresolvedUsingDecl * +ASTContext::getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD) { + llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>::iterator Pos + = InstantiatedFromUnresolvedUsingDecl.find(UUD); + if (Pos == InstantiatedFromUnresolvedUsingDecl.end()) + return 0; + + return Pos->second; +} + +void +ASTContext::setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD, + UnresolvedUsingDecl *UUD) { + assert(!InstantiatedFromUnresolvedUsingDecl[UD] && + "Already noted what using decl what instantiated from"); + InstantiatedFromUnresolvedUsingDecl[UD] = UUD; +} + namespace { class BeforeInTranslationUnit : std::binary_function<SourceRange, SourceRange, bool> { diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 521394b978..b1cc328a2d 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -477,6 +477,11 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) { if (!InstD) return SemaRef.ExprError(); + // If we instantiated an UnresolvedUsingDecl and got back an UsingDecl, + // we need to get the underlying decl. + // FIXME: Is this correct? Maybe FindInstantiatedDecl should do this? + InstD = InstD->getUnderlyingDecl(); + // FIXME: nested-name-specifier for QualifiedDeclRefExpr return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD, /*FIXME:*/false, @@ -685,6 +690,8 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, Invalid = true; else if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) Fields.push_back(DeclPtrTy::make(Field)); + else if (UsingDecl *UD = dyn_cast<UsingDecl>(NewMember)) + Instantiation->addDecl(UD); } else { // FIXME: Eventually, a NULL return will mean that one of the // instantiations was a semantic disaster, and we'll want to set Invalid = diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 6c1f0115b6..5978dae311 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -757,9 +757,14 @@ TemplateDeclInstantiator::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) { SS.setRange(D->getTargetNestedNameRange()); SS.setScopeRep(NNS); - return SemaRef.BuildUsingDeclaration(D->getLocation(), SS, - D->getTargetNameLocation(), - D->getTargetName(), 0, D->isTypeName()); + NamedDecl *UD = + SemaRef.BuildUsingDeclaration(D->getLocation(), SS, + D->getTargetNameLocation(), + D->getTargetName(), 0, D->isTypeName()); + if (UD) + SemaRef.Context.setInstantiatedFromUnresolvedUsingDecl(cast<UsingDecl>(UD), + D); + return UD; } Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner, @@ -1220,6 +1225,12 @@ static bool isInstantiationOf(EnumDecl *Pattern, return false; } +static bool isInstantiationOf(UnresolvedUsingDecl *Pattern, + UsingDecl *Instance, + ASTContext &C) { + return C.getInstantiatedFromUnresolvedUsingDecl(Instance) == Pattern; +} + static bool isInstantiationOfStaticDataMember(VarDecl *Pattern, VarDecl *Instance) { assert(Instance->isStaticDataMember()); @@ -1236,9 +1247,16 @@ static bool isInstantiationOfStaticDataMember(VarDecl *Pattern, } static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) { - if (D->getKind() != Other->getKind()) - return false; + if (D->getKind() != Other->getKind()) { + if (UnresolvedUsingDecl *UUD = dyn_cast<UnresolvedUsingDecl>(D)) { + if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) { + return isInstantiationOf(UUD, UD, Ctx); + } + } + return false; + } + if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other)) return isInstantiationOf(cast<CXXRecordDecl>(D), Record); |