[cfe-commits] r90367 - in /cfe/trunk: include/clang/AST/DeclContextInternals.h lib/Sema/SemaLookup.cpp test/SemaTemplate/instantiate-using-decl.cpp

John McCall rjmccall at apple.com
Wed Dec 2 16:58:24 PST 2009


Author: rjmccall
Date: Wed Dec  2 18:58:24 2009
New Revision: 90367

URL: http://llvm.org/viewvc/llvm-project?rev=90367&view=rev
Log:
Stop stripping UnresolvedUsingDecls out of LookupResults that have other
results in them (which we were doing intentionally as a stopgap).  Fix
an DeclContext lookup-table ordering problem which was causing UsingDecls to
show up incorrectly when looking for ordinary results.  And oh hey
Clang-Code-Syntax passes now.


Modified:
    cfe/trunk/include/clang/AST/DeclContextInternals.h
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclContextInternals.h (original)
+++ cfe/trunk/include/clang/AST/DeclContextInternals.h Wed Dec  2 18:58:24 2009
@@ -200,11 +200,37 @@
     }
 
     VectorTy &Vec = *getAsVector();
-    if (isa<UsingDirectiveDecl>(D) ||
-        D->getIdentifierNamespace() == Decl::IDNS_Tag)
+
+    // Using directives end up in a special entry which contains only
+    // other using directives, so all this logic is wasted for them.
+    // But avoiding the logic wastes time in the far-more-common case
+    // that we're *not* adding a new using directive.
+
+    // Tag declarations always go at the end of the list so that an
+    // iterator which points at the first tag will start a span of
+    // decls that only contains tags.
+    if (D->getIdentifierNamespace() == Decl::IDNS_Tag)
       Vec.push_back(reinterpret_cast<uintptr_t>(D));
-    else if (reinterpret_cast<NamedDecl *>(Vec.back())
-               ->getIdentifierNamespace() == Decl::IDNS_Tag) {
+
+    // Resolved using declarations go at the front of the list so that
+    // they won't show up in other lookup results.  Unresolved using
+    // declarations (which are always in IDNS_Using | IDNS_Ordinary)
+    // follow that so that the using declarations will be contiguous.
+    else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
+      VectorTy::iterator I = Vec.begin();
+      if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
+        while (I != Vec.end() &&
+               reinterpret_cast<NamedDecl *>(*I)
+                 ->getIdentifierNamespace() == Decl::IDNS_Using)
+          ++I;
+      }
+      Vec.insert(I, reinterpret_cast<uintptr_t>(D));
+
+    // All other declarations go at the end of the list, but before any
+    // tag declarations.  But we can be clever about tag declarations
+    // because there can only ever be one in a scope.
+    } else if (reinterpret_cast<NamedDecl *>(Vec.back())
+                 ->getIdentifierNamespace() == Decl::IDNS_Tag) {
       uintptr_t TagD = Vec.back();
       Vec.back() = reinterpret_cast<uintptr_t>(D);
       Vec.push_back(TagD);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Dec  2 18:58:24 2009
@@ -282,9 +282,6 @@
       // If it's not unique, pull something off the back (and
       // continue at this index).
       Decls[I] = Decls[--N];
-    } else if (isa<UnresolvedUsingValueDecl>(D)) {
-      // FIXME: support unresolved using value declarations
-      Decls[I] = Decls[--N];
     } else {
       // Otherwise, do some decl type analysis and then continue.
 
@@ -318,13 +315,13 @@
   //   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 (HideTags && HasTag && !Ambiguous && !HasUnresolved &&
-      (HasFunction || HasNonFunction))
+  if (HideTags && HasTag && !Ambiguous &&
+      (HasFunction || HasNonFunction || HasUnresolved))
     Decls[UniqueTagIndex] = Decls[--N];
 
   Decls.set_size(N);
 
-  if (HasFunction && HasNonFunction)
+  if (HasNonFunction && (HasFunction || HasUnresolved))
     Ambiguous = true;
 
   if (Ambiguous)

Modified: cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp?rev=90367&r1=90366&r2=90367&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp Wed Dec  2 18:58:24 2009
@@ -1,20 +1,49 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
-namespace N { }
+namespace test0 {
+  namespace N { }
 
-template<typename T>
-struct A {
-  void f();
-};
-
-template<typename T>
-struct B : A<T> {
-  using A<T>::f;
-  
-  void g() {
-    using namespace N;
-    f();
-  }
-};
+  template<typename T>
+  struct A {
+    void f();
+  };
+
+  template<typename T>
+  struct B : A<T> {
+    using A<T>::f;
+
+    void g() {
+      using namespace N;
+      f();
+    }
+  };
+
+  template struct B<int>;
+}
+
+namespace test1 {
+  template <class Derived> struct Visitor1 {
+    void Visit(struct Object1*);
+  };
+  template <class Derived> struct Visitor2 {
+    void Visit(struct Object2*); // expected-note {{candidate function}}
+  };
 
-template struct B<int>;
+  template <class Derived> struct JoinVisitor
+      : Visitor1<Derived>, Visitor2<Derived> {
+    typedef Visitor1<Derived> Base1;
+    typedef Visitor2<Derived> Base2;
+
+    void Visit(struct Object1*);  // expected-note {{candidate function}}
+    using Base2::Visit;
+  };
+
+  class Knot : JoinVisitor<Knot> {
+  };
+
+  void test() {
+    Knot().Visit((struct Object1*) 0);
+    Knot().Visit((struct Object2*) 0);
+    Knot().Visit((struct Object3*) 0); // expected-error {{no matching member function for call}}
+  }
+}





More information about the cfe-commits mailing list