From 3f746828d70bda31d6b19c07d430a569ad0e6048 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 17 Nov 2009 05:59:44 +0000 Subject: [PATCH] Instead of hanging a using declaration's target decls directly off the using decl, create shadow declarations and put them in scope like normal. Work in progress. llvm-svn: 89048 --- clang/include/clang/AST/DeclBase.h | 11 +- clang/include/clang/AST/DeclCXX.h | 106 +++++++++++++----- clang/include/clang/AST/DeclNodes.def | 1 + clang/lib/AST/Decl.cpp | 6 +- clang/lib/AST/DeclBase.cpp | 24 ++-- clang/lib/AST/DeclCXX.cpp | 9 +- clang/lib/AST/DeclPrinter.cpp | 7 +- clang/lib/Sema/Sema.h | 15 ++- clang/lib/Sema/SemaCodeComplete.cpp | 2 +- clang/lib/Sema/SemaDeclCXX.cpp | 60 ++++++++-- clang/lib/Sema/SemaLookup.cpp | 2 +- clang/lib/Sema/SemaTemplateInstantiate.cpp | 44 +++++++- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 6 +- 13 files changed, 230 insertions(+), 63 deletions(-) diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 10db7030db18..79f766356138 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -79,9 +79,11 @@ public: /// namespaces, labels, tags, members and ordinary /// identifiers. These are meant as bitmasks, so that searches in /// C++ can look into the "tag" namespace during ordinary lookup. We - /// use additional namespaces for Objective-C entities. We also - /// put C++ friend declarations (of previously-undeclared entities) in - /// shadow namespaces. + /// use additional namespaces for Objective-C entities. We also put + /// C++ friend declarations (of previously-undeclared entities) in + /// shadow namespaces, and 'using' declarations (as opposed to their + /// implicit shadow declarations) can be found in their own + /// namespace. enum IdentifierNamespace { IDNS_Label = 0x1, IDNS_Tag = 0x2, @@ -91,7 +93,8 @@ public: IDNS_ObjCImplementation = 0x20, IDNS_ObjCCategoryImpl = 0x40, IDNS_OrdinaryFriend = 0x80, - IDNS_TagFriend = 0x100 + IDNS_TagFriend = 0x100, + IDNS_Using = 0x200 }; /// ObjCDeclQualifier - Qualifier used on types in method declarations diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 17dbd61aecf4..4d8991a46ffa 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1644,6 +1644,56 @@ public: static bool classof(const NamespaceAliasDecl *D) { return true; } }; +/// UsingShadowDecl - Represents a shadow declaration introduced into +/// a scope by a (resolved) using declaration. For example, +/// +/// namespace A { +/// void foo(); +/// } +/// namespace B { +/// using A::foo(); // <- a UsingDecl +/// // Also creates a UsingShadowDecl for A::foo in B +/// } +/// +class UsingShadowDecl : public NamedDecl { + /// The referenced declaration. + NamedDecl *Underlying; + + /// The using declaration which introduced this decl. + UsingDecl *Using; + + UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using, + NamedDecl *Target) + : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()), + Underlying(Target), Using(Using) { + IdentifierNamespace = Target->getIdentifierNamespace(); + setImplicit(); + } + +public: + static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation Loc, UsingDecl *Using, + NamedDecl *Target) { + return new (C) UsingShadowDecl(DC, Loc, Using, Target); + } + + /// Gets the underlying declaration which has been brought into the + /// local scope. + NamedDecl *getTargetDecl() const { + return Underlying; + } + + /// Gets the using declaration to which this declaration is tied. + UsingDecl *getUsingDecl() const { + return Using; + } + + static bool classof(const Decl *D) { + return D->getKind() == Decl::UsingShadow; + } + static bool classof(const UsingShadowDecl *D) { return true; } +}; + /// UsingDecl - Represents a C++ using-declaration. For example: /// using someNameSpace::someIdentifier; class UsingDecl : public NamedDecl { @@ -1651,29 +1701,26 @@ class UsingDecl : public NamedDecl { /// preceding the declaration name. SourceRange NestedNameRange; - /// \brief The source location of the target declaration name. - SourceLocation TargetNameLocation; - /// \brief The source location of the "using" location itself. SourceLocation UsingLocation; - /// \brief Target declaration. - NamedDecl* TargetDecl; - /// \brief Target nested name specifier. - NestedNameSpecifier* TargetNestedNameDecl; + NestedNameSpecifier* TargetNestedName; + + /// \brief The collection of shadow declarations associated with + /// this using declaration. This set can change as a class is + /// processed. + llvm::SmallPtrSet Shadows; // \brief Has 'typename' keyword. bool IsTypeName; UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR, - SourceLocation TargetNL, SourceLocation UL, NamedDecl* Target, - NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) - : NamedDecl(Decl::Using, DC, L, Target->getDeclName()), - NestedNameRange(NNR), TargetNameLocation(TargetNL), - UsingLocation(UL), TargetDecl(Target), - TargetNestedNameDecl(TargetNNS), IsTypeName(IsTypeNameArg) { - this->IdentifierNamespace = TargetDecl->getIdentifierNamespace(); + SourceLocation UL, NestedNameSpecifier* TargetNNS, + DeclarationName Name, bool IsTypeNameArg) + : NamedDecl(Decl::Using, DC, L, Name), + NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS), + IsTypeName(IsTypeNameArg) { } public: @@ -1681,28 +1728,37 @@ public: /// preceding the namespace name. SourceRange getNestedNameRange() { return NestedNameRange; } - /// \brief Returns the source location of the target declaration name. - SourceLocation getTargetNameLocation() { return TargetNameLocation; } - /// \brief Returns the source location of the "using" location itself. SourceLocation getUsingLocation() { return UsingLocation; } - /// \brief getTargetDecl - Returns target specified by using-decl. - NamedDecl *getTargetDecl() { return TargetDecl; } - const NamedDecl *getTargetDecl() const { return TargetDecl; } - /// \brief Get target nested name declaration. NestedNameSpecifier* getTargetNestedNameDecl() { - return TargetNestedNameDecl; + return TargetNestedName; } /// isTypeName - Return true if using decl has 'typename'. bool isTypeName() const { return IsTypeName; } + typedef llvm::SmallPtrSet::const_iterator shadow_iterator; + shadow_iterator shadow_begin() const { return Shadows.begin(); } + shadow_iterator shadow_end() const { return Shadows.end(); } + + void addShadowDecl(UsingShadowDecl *S) { + assert(S->getUsingDecl() == this); + if (!Shadows.insert(S)) { + assert(false && "declaration already in set"); + } + } + void removeShadowDecl(UsingShadowDecl *S) { + assert(S->getUsingDecl() == this); + if (!Shadows.erase(S)) { + assert(false && "declaration not in set"); + } + } + static UsingDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, SourceRange NNR, SourceLocation TargetNL, - SourceLocation UL, NamedDecl* Target, - NestedNameSpecifier* TargetNNS, bool IsTypeNameArg); + SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL, + NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg); static bool classof(const Decl *D) { return D->getKind() == Decl::Using; diff --git a/clang/include/clang/AST/DeclNodes.def b/clang/include/clang/AST/DeclNodes.def index 3ef3cc3f0975..f0238375cc22 100644 --- a/clang/include/clang/AST/DeclNodes.def +++ b/clang/include/clang/AST/DeclNodes.def @@ -110,6 +110,7 @@ ABSTRACT_DECL(Named, Decl) DECL(TemplateTemplateParm, TemplateDecl) DECL(Using, NamedDecl) DECL(UnresolvedUsing, NamedDecl) + DECL(UsingShadow, NamedDecl) DECL(ObjCMethod, NamedDecl) DECL(ObjCContainer, NamedDecl) DECL(ObjCCategory, ObjCContainerDecl) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index a6996a4bfe5c..bdc804722c41 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -289,6 +289,10 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { if (isa(this) && isa(OldD)) return true; + if (isa(this) && isa(OldD)) + return cast(this)->getTargetDecl() == + cast(OldD)->getTargetDecl(); + // For non-function declarations, if the declarations are of the // same kind then this must be a redeclaration, or semantic analysis // would not have given us the new declaration. @@ -308,7 +312,7 @@ bool NamedDecl::hasLinkage() const { NamedDecl *NamedDecl::getUnderlyingDecl() { NamedDecl *ND = this; while (true) { - if (UsingDecl *UD = dyn_cast(ND)) + if (UsingShadowDecl *UD = dyn_cast(ND)) ND = UD->getTargetDecl(); else if (ObjCCompatibleAliasDecl *AD = dyn_cast(ND)) diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 6cfdcdd3e50e..da3b19df5b60 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -97,7 +97,7 @@ bool Decl::isTemplateParameterPack() const { } bool Decl::isFunctionOrFunctionTemplate() const { - if (const UsingDecl *UD = dyn_cast(this)) + if (const UsingShadowDecl *UD = dyn_cast(this)) return UD->getTargetDecl()->isFunctionOrFunctionTemplate(); return isa(this) || isa(this); @@ -189,10 +189,11 @@ ASTContext &Decl::getASTContext() const { unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { switch (DeclKind) { - default: - if (DeclKind >= FunctionFirst && DeclKind <= FunctionLast) - return IDNS_Ordinary; - assert(0 && "Unknown decl kind!"); + case Function: + case CXXMethod: + case CXXConstructor: + case CXXDestructor: + case CXXConversion: case OverloadedFunction: case Typedef: case EnumConstant: @@ -200,8 +201,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ImplicitParam: case ParmVar: case NonTypeTemplateParm: - case Using: - case UnresolvedUsing: case ObjCMethod: case ObjCContainer: case ObjCCategory: @@ -210,6 +209,15 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCCompatibleAlias: return IDNS_Ordinary; + case UsingShadow: + return 0; // we'll actually overwrite this later + + case UnresolvedUsing: + return IDNS_Tag | IDNS_Ordinary | IDNS_Using; + + case Using: + return IDNS_Using; + case ObjCProtocol: return IDNS_ObjCProtocol; @@ -256,6 +264,8 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ClassTemplatePartialSpecialization: return 0; } + + return 0; } void Decl::addAttr(Attr *NewAttr) { diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 3768796627dd..520206d24819 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -914,11 +914,10 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, } UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, SourceRange NNR, SourceLocation TargetNL, - SourceLocation UL, NamedDecl* Target, - NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) { - return new (C) UsingDecl(DC, L, NNR, TargetNL, UL, Target, - TargetNNS, IsTypeNameArg); + SourceLocation L, SourceRange NNR, SourceLocation UL, + NestedNameSpecifier* TargetNNS, DeclarationName Name, + bool IsTypeNameArg) { + return new (C) UsingDecl(DC, L, NNR, UL, TargetNNS, Name, IsTypeNameArg); } UnresolvedUsingDecl *UnresolvedUsingDecl::Create(ASTContext &C, DeclContext *DC, diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index b88a971f1ec6..199ed356d6d3 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -73,6 +73,7 @@ namespace { void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); void VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D); void VisitUsingDecl(UsingDecl *D); + void VisitUsingShadowDecl(UsingShadowDecl *D); }; } @@ -825,7 +826,7 @@ void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) { void DeclPrinter::VisitUsingDecl(UsingDecl *D) { Out << "using "; D->getTargetNestedNameDecl()->print(Out, Policy); - Out << D->getTargetDecl()->getNameAsString(); + Out << D->getNameAsString(); } void DeclPrinter::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) { @@ -833,3 +834,7 @@ void DeclPrinter::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) { D->getTargetNestedNameSpecifier()->print(Out, Policy); Out << D->getTargetName().getAsString(); } + +void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) { + // ignore +} diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index acf52c97fde7..fea6f80e545f 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1197,6 +1197,7 @@ public: LookupKind(LookupKind), IDNS(0), Redecl(Redecl != NotForRedeclaration), + HideTags(true), Diagnose(Redecl == NotForRedeclaration) {} @@ -1212,6 +1213,7 @@ public: LookupKind(Other.LookupKind), IDNS(Other.IDNS), Redecl(Other.Redecl), + HideTags(Other.HideTags), Diagnose(false) {} @@ -1235,6 +1237,12 @@ public: return Redecl; } + /// Sets whether tag declarations should be hidden by non-tag + /// declarations during resolution. The default is true. + void setHideTags(bool Hide) { + HideTags = Hide; + } + /// The identifier namespace of this lookup. This information is /// private to the lookup routines. unsigned getIdentifierNamespace() const { @@ -1441,6 +1449,10 @@ public: unsigned IDNS; // ill-defined until set by lookup bool Redecl; + /// \brief True if tag declarations should be hidden if non-tags + /// are present + bool HideTags; + bool Diagnose; }; @@ -2007,7 +2019,8 @@ public: SourceLocation IdentLoc, IdentifierInfo *Ident); - NamedDecl *BuildUsingDeclaration(SourceLocation UsingLoc, + NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS, + SourceLocation UsingLoc, const CXXScopeSpec &SS, SourceLocation IdentLoc, DeclarationName Name, diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 84262a4c8f06..de30441c5312 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -198,7 +198,7 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) { return; // Look through using declarations. - if (UsingDecl *Using = dyn_cast(R.Declaration)) + if (UsingShadowDecl *Using = dyn_cast(R.Declaration)) MaybeAddResult(Result(Using->getTargetDecl(), R.Rank, R.Qualifier), CurContext); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 9ba03a90fc03..698d81e30f3d 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2835,7 +2835,7 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S, } DeclarationName TargetName = GetNameFromUnqualifiedId(Name); - NamedDecl *UD = BuildUsingDeclaration(UsingLoc, SS, + NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS, Name.getSourceRange().getBegin(), TargetName, AttrList, IsTypeName); if (UD) { @@ -2846,7 +2846,34 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S, return DeclPtrTy::make(UD); } -NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc, +/// Builds a shadow declaration corresponding to a 'using' declaration. +static UsingShadowDecl *BuildUsingShadowDecl(Sema &SemaRef, Scope *S, + AccessSpecifier AS, + UsingDecl *UD, NamedDecl *Orig) { + // FIXME: diagnose hiding, collisions + + // If we resolved to another shadow declaration, just coalesce them. + if (isa(Orig)) { + Orig = cast(Orig)->getTargetDecl(); + assert(!isa(Orig) && "nested shadow declaration"); + } + + UsingShadowDecl *Shadow + = UsingShadowDecl::Create(SemaRef.Context, SemaRef.CurContext, + UD->getLocation(), UD, Orig); + UD->addShadowDecl(Shadow); + + if (S) + SemaRef.PushOnScopeChains(Shadow, S); + else + SemaRef.CurContext->addDecl(Shadow); + Shadow->setAccess(AS); + + return Shadow; +} + +NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, + SourceLocation UsingLoc, const CXXScopeSpec &SS, SourceLocation IdentLoc, DeclarationName Name, @@ -2880,7 +2907,7 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc, // anonymous union that is a member of a base class of the class being // defined, or shall refer to an enumerator for an enumeration type that is // a member of a base class of the class being defined. - + CXXRecordDecl *LookupRD = dyn_cast(LookupContext); if (!LookupRD || !RD->isDerivedFrom(LookupRD)) { Diag(SS.getRange().getBegin(), @@ -2898,8 +2925,12 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc, } } - // Lookup target name. + // Look up the target name. Unlike most lookups, we do not want to + // hide tag declarations: tag names are visible through the using + // declaration even if hidden by ordinary names. LookupResult R(*this, Name, IdentLoc, LookupOrdinaryName); + R.setHideTags(false); + LookupQualifiedName(R, LookupContext); if (R.empty()) { @@ -2908,24 +2939,33 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc, return 0; } - // FIXME: handle ambiguity? - NamedDecl *ND = R.getAsSingleDecl(Context); + if (R.isAmbiguous()) + return 0; - if (IsTypeName && !isa(ND)) { + if (IsTypeName && + (R.getResultKind() != LookupResult::Found + || !isa(R.getFoundDecl()))) { Diag(IdentLoc, diag::err_using_typename_non_type); return 0; } // C++0x N2914 [namespace.udecl]p6: // A using-declaration shall not name a namespace. - if (isa(ND)) { + if (R.getResultKind() == LookupResult::Found + && isa(R.getFoundDecl())) { Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace) << SS.getRange(); return 0; } - return UsingDecl::Create(Context, CurContext, IdentLoc, SS.getRange(), - ND->getLocation(), UsingLoc, ND, NNS, IsTypeName); + UsingDecl *UD = UsingDecl::Create(Context, CurContext, IdentLoc, + SS.getRange(), UsingLoc, NNS, Name, + IsTypeName); + + for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) + BuildUsingShadowDecl(*this, S, AS, UD, *I); + + return UD; } /// getNamespaceDecl - Returns the namespace a decl represents. If the decl diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 1c7dce0def15..58b95fc67902 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -297,7 +297,7 @@ void Sema::LookupResult::resolveKind() { // wherever the object, function, or enumerator name is visible. // But it's still an error if there are distinct tag types found, // even if they're not visible. (ref?) - if (HasTag && !Ambiguous && (HasFunction || HasNonFunction)) + if (HideTags && HasTag && !Ambiguous && (HasFunction || HasNonFunction)) Decls[UniqueTagIndex] = Decls[--N]; Decls.set_size(N); diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 721bfb9004ce..58fe59e321cf 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -788,10 +788,46 @@ 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(); + // Flatten using declarations into their shadow declarations. + if (isa(InstD)) { + UsingDecl *UD = cast(InstD); + + bool HasNonFunction = false; + + llvm::SmallVector Decls; + for (UsingDecl::shadow_iterator I = UD->shadow_begin(), + E = UD->shadow_end(); I != E; ++I) { + NamedDecl *TD = (*I)->getTargetDecl(); + if (!TD->isFunctionOrFunctionTemplate()) + HasNonFunction = true; + + Decls.push_back(TD); + } + + if (Decls.empty()) + return SemaRef.ExprError(); + + if (Decls.size() == 1) + InstD = Decls[0]; + else if (!HasNonFunction) { + OverloadedFunctionDecl *OFD + = OverloadedFunctionDecl::Create(SemaRef.Context, + UD->getDeclContext(), + UD->getDeclName()); + for (llvm::SmallVectorImpl::iterator I = Decls.begin(), + E = Decls.end(); I != E; ++I) + if (isa(*I)) + OFD->addOverload(cast(*I)); + else + OFD->addOverload(cast(*I)); + + InstD = OFD; + } else { + // FIXME + assert(false && "using declaration resolved to mixed set"); + return SemaRef.ExprError(); + } + } CXXScopeSpec SS; NestedNameSpecifier *Qualifier = 0; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index a37f3a2b99d1..208352fb5322 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1019,9 +1019,9 @@ TemplateDeclInstantiator::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) { SS.setScopeRep(NNS); NamedDecl *UD = - SemaRef.BuildUsingDeclaration(D->getLocation(), SS, - D->getTargetNameLocation(), - D->getTargetName(), 0, D->isTypeName()); + SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(), + D->getLocation(), SS, D->getTargetNameLocation(), + D->getDeclName(), 0, D->isTypeName()); if (UD) SemaRef.Context.setInstantiatedFromUnresolvedUsingDecl(cast(UD), D);