[cfe-commits] r89048 - in /cfe/trunk: 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

John McCall rjmccall at apple.com
Mon Nov 16 21:59:44 PST 2009


Author: rjmccall
Date: Mon Nov 16 23:59:44 2009
New Revision: 89048

URL: http://llvm.org/viewvc/llvm-project?rev=89048&view=rev
Log:
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.


Modified:
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/AST/DeclNodes.def
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Mon Nov 16 23:59:44 2009
@@ -79,9 +79,11 @@
   /// 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 @@
     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

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Nov 16 23:59:44 2009
@@ -1644,6 +1644,56 @@
   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 @@
   /// 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 @@
   /// 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;

Modified: cfe/trunk/include/clang/AST/DeclNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclNodes.def?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclNodes.def (original)
+++ cfe/trunk/include/clang/AST/DeclNodes.def Mon Nov 16 23:59:44 2009
@@ -110,6 +110,7 @@
     DECL(TemplateTemplateParm, TemplateDecl)
   DECL(Using, NamedDecl)
   DECL(UnresolvedUsing, NamedDecl)
+  DECL(UsingShadow, NamedDecl)
   DECL(ObjCMethod, NamedDecl)
   DECL(ObjCContainer, NamedDecl)
     DECL(ObjCCategory, ObjCContainerDecl)

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Nov 16 23:59:44 2009
@@ -289,6 +289,10 @@
   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 @@
 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))

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Mon Nov 16 23:59:44 2009
@@ -97,7 +97,7 @@
 }
 
 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 @@
 
 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 @@
     case ImplicitParam:
     case ParmVar:
     case NonTypeTemplateParm:
-    case Using:
-    case UnresolvedUsing:
     case ObjCMethod:
     case ObjCContainer:
     case ObjCCategory:
@@ -210,6 +209,15 @@
     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 @@
     case ClassTemplatePartialSpecialization:
       return 0;
   }
+
+  return 0;
 }
 
 void Decl::addAttr(Attr *NewAttr) {

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Nov 16 23:59:44 2009
@@ -914,11 +914,10 @@
 }
 
 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,

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Mon Nov 16 23:59:44 2009
@@ -73,6 +73,7 @@
     void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
     void VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D);
     void VisitUsingDecl(UsingDecl *D);
+    void VisitUsingShadowDecl(UsingShadowDecl *D);
   };
 }
 
@@ -825,7 +826,7 @@
 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 @@
   D->getTargetNestedNameSpecifier()->print(Out, Policy);
   Out << D->getTargetName().getAsString();
 }
+
+void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
+  // ignore
+}

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Nov 16 23:59:44 2009
@@ -1197,6 +1197,7 @@
         LookupKind(LookupKind),
         IDNS(0),
         Redecl(Redecl != NotForRedeclaration),
+        HideTags(true),
         Diagnose(Redecl == NotForRedeclaration)
     {}
 
@@ -1212,6 +1213,7 @@
         LookupKind(Other.LookupKind),
         IDNS(Other.IDNS),
         Redecl(Other.Redecl),
+        HideTags(Other.HideTags),
         Diagnose(false)
     {}
 
@@ -1235,6 +1237,12 @@
       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 @@
     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 @@
                                            SourceLocation IdentLoc,
                                            IdentifierInfo *Ident);
 
-  NamedDecl *BuildUsingDeclaration(SourceLocation UsingLoc,
+  NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
+                                   SourceLocation UsingLoc,
                                    const CXXScopeSpec &SS,
                                    SourceLocation IdentLoc,
                                    DeclarationName Name,

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Mon Nov 16 23:59:44 2009
@@ -198,7 +198,7 @@
     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);
   

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Nov 16 23:59:44 2009
@@ -2835,7 +2835,7 @@
   }
   
   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 @@
   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 @@
     // 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 @@
     }
   }
 
-  // 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 @@
     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

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Nov 16 23:59:44 2009
@@ -297,7 +297,7 @@
   //   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);

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Nov 16 23:59:44 2009
@@ -788,10 +788,46 @@
   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;

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=89048&r1=89047&r2=89048&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Nov 16 23:59:44 2009
@@ -1019,9 +1019,9 @@
   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);





More information about the cfe-commits mailing list