]> granicus.if.org Git - clang/commitdiff
Instead of hanging a using declaration's target decls directly off the using
authorJohn McCall <rjmccall@apple.com>
Tue, 17 Nov 2009 05:59:44 +0000 (05:59 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 17 Nov 2009 05:59:44 +0000 (05:59 +0000)
decl, create shadow declarations and put them in scope like normal.
Work in progress.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89048 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/clang/AST/DeclBase.h
include/clang/AST/DeclCXX.h
include/clang/AST/DeclNodes.def
lib/AST/Decl.cpp
lib/AST/DeclBase.cpp
lib/AST/DeclCXX.cpp
lib/AST/DeclPrinter.cpp
lib/Sema/Sema.h
lib/Sema/SemaCodeComplete.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaLookup.cpp
lib/Sema/SemaTemplateInstantiate.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp

index 10db7030db18e1e06187aca81d691c1f0ce5b1e7..79f76635613830cbca777641dfbc28def6b5911a 100644 (file)
@@ -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
index 17dbd61aecf421c2af613c4032e971765e942d04..4d8991a46ffa103cd403fafc6eee41047bfb3567 100644 (file)
@@ -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<UsingShadowDecl*, 8> 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<UsingShadowDecl*,8>::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;
index 3ef3cc3f09753f3c93e15b94792ae5747e13182f..f0238375cc22b110e1a97450e9f2211ea29b28a6 100644 (file)
@@ -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)
index a6996a4bfe5cc2cb69960a721439eb0da10e873f..bdc804722c4177e1d64aac9031fc453e24ff1703 100644 (file)
@@ -289,6 +289,10 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
   if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
     return true;
 
+  if (isa<UsingShadowDecl>(this) && isa<UsingShadowDecl>(OldD))
+    return cast<UsingShadowDecl>(this)->getTargetDecl() ==
+           cast<UsingShadowDecl>(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<UsingDecl>(ND))
+    if (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND))
       ND = UD->getTargetDecl();
     else if (ObjCCompatibleAliasDecl *AD
               = dyn_cast<ObjCCompatibleAliasDecl>(ND))
index 6cfdcdd3e50e1f31937ba5a00017b3dddf5be5ba..da3b19df5b60784d9e56f1da5c263a8c95ad4c0a 100644 (file)
@@ -97,7 +97,7 @@ bool Decl::isTemplateParameterPack() const {
 }
 
 bool Decl::isFunctionOrFunctionTemplate() const {
-  if (const UsingDecl *UD = dyn_cast<UsingDecl>(this))
+  if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
     return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
 
   return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(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) {
index 3768796627ddb497a3c0fed2f62bff11d181d508..520206d248192427034653a3d99b5d94eaaf0e7f 100644 (file)
@@ -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,
index b88a971f1ec6e89f56d89a90264167b3d7c839ef..199ed356d6d3838b73056f81ae4b7fcf88355b5b 100644 (file)
@@ -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
+}
index acf52c97fde701a57a7cdfdba33230cde575690f..fea6f80e545f3b1c54880754a8ccba88d001eea3 100644 (file)
@@ -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,
index 84262a4c8f06b11fa25f4a00a0c7fe0e5a070061..de30441c5312820de9fb83ea40f78570e9f6174f 100644 (file)
@@ -198,7 +198,7 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
     return;
       
   // Look through using declarations.
-  if (UsingDecl *Using = dyn_cast<UsingDecl>(R.Declaration))
+  if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration))
     MaybeAddResult(Result(Using->getTargetDecl(), R.Rank, R.Qualifier),
                    CurContext);
   
index 9ba03a90fc03595c3176a4cef6077643161f3a46..698d81e30f3d9cedf499a19aba6b1b8a1bc5ae25 100644 (file)
@@ -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<UsingShadowDecl>(Orig)) {
+    Orig = cast<UsingShadowDecl>(Orig)->getTargetDecl();
+    assert(!isa<UsingShadowDecl>(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<CXXRecordDecl>(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<TypeDecl>(ND)) {
+  if (IsTypeName &&
+      (R.getResultKind() != LookupResult::Found
+       || !isa<TypeDecl>(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<NamespaceDecl>(ND)) {
+  if (R.getResultKind() == LookupResult::Found
+      && isa<NamespaceDecl>(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
index 1c7dce0def1535378369565b70cd48ce35e6b2d6..58b95fc67902ffdeb3ae9215f95d243e78f0b0dd 100644 (file)
@@ -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);
index 721bfb9004ce2cb091cf19eabedb67dfa99c3fa8..58fe59e321cf96bf992192ff9c71d004435ee744 100644 (file)
@@ -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<UsingDecl>(InstD)) {
+    UsingDecl *UD = cast<UsingDecl>(InstD);
+
+    bool HasNonFunction = false;
+
+    llvm::SmallVector<NamedDecl*, 8> 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<NamedDecl*>::iterator I = Decls.begin(),
+                                                E = Decls.end(); I != E; ++I)
+        if (isa<FunctionDecl>(*I))
+          OFD->addOverload(cast<FunctionDecl>(*I));
+        else
+          OFD->addOverload(cast<FunctionTemplateDecl>(*I));
+
+      InstD = OFD;
+    } else {
+      // FIXME
+      assert(false && "using declaration resolved to mixed set");
+      return SemaRef.ExprError();
+    }
+  }
 
   CXXScopeSpec SS;
   NestedNameSpecifier *Qualifier = 0;
index a37f3a2b99d1cdf728563c598e40d14301657b30..208352fb5322beac01acecd515c93b02186946ba 100644 (file)
@@ -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<UsingDecl>(UD),
                                                            D);