[cfe-commits] r91676 - in /cfe/trunk: lib/Sema/Lookup.h lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaLookup.cpp test/SemaCXX/nested-name-spec.cpp

John McCall rjmccall at apple.com
Fri Dec 18 02:40:04 PST 2009


Author: rjmccall
Date: Fri Dec 18 04:40:03 2009
New Revision: 91676

URL: http://llvm.org/viewvc/llvm-project?rev=91676&view=rev
Log:
Pull Sema::isAcceptableLookupResult into SemaLookup.  Extract the criteria into
different functions and pick the function at lookup initialization time.
In theory we could actually divide the criteria functions into N different
functions for the N cases, but it's so not worth it.

Among other things, lets us invoke LookupQualifiedName without recomputing
IDNS info every time.

Do some refactoring in SemaDecl to avoid an awkward special case in LQN
that was only necessary for redeclaration testing for anonymous structs/unions ---
which could be done more efficiently with a scoped lookup anyway.


Modified:
    cfe/trunk/lib/Sema/Lookup.h
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/SemaCXX/nested-name-spec.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/Lookup.h (original)
+++ cfe/trunk/lib/Sema/Lookup.h Fri Dec 18 04:40:03 2009
@@ -121,6 +121,8 @@
   typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
   typedef DeclsTy::const_iterator iterator;
 
+  typedef bool (*ResultFilter)(NamedDecl*, unsigned IDNS);
+
   LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
                Sema::LookupNameKind LookupKind,
                Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
@@ -130,11 +132,14 @@
       Name(Name),
       NameLoc(NameLoc),
       LookupKind(LookupKind),
+      IsAcceptableFn(0),
       IDNS(0),
       Redecl(Redecl != Sema::NotForRedeclaration),
       HideTags(true),
       Diagnose(Redecl == Sema::NotForRedeclaration)
-  {}
+  {
+    configure();
+  }
 
   /// Creates a temporary lookup result, initializing its core data
   /// using the information from another result.  Diagnostics are always
@@ -146,6 +151,7 @@
       Name(Other.Name),
       NameLoc(Other.NameLoc),
       LookupKind(Other.LookupKind),
+      IsAcceptableFn(Other.IsAcceptableFn),
       IDNS(Other.IDNS),
       Redecl(Other.Redecl),
       HideTags(Other.HideTags),
@@ -178,17 +184,6 @@
     HideTags = Hide;
   }
 
-  /// The identifier namespace of this lookup.  This information is
-  /// private to the lookup routines.
-  unsigned getIdentifierNamespace() const {
-    assert(IDNS);
-    return IDNS;
-  }
-
-  void setIdentifierNamespace(unsigned NS) {
-    IDNS = NS;
-  }
-
   bool isAmbiguous() const {
     return getResultKind() == Ambiguous;
   }
@@ -231,7 +226,19 @@
     return Paths;
   }
 
-  /// \brief Add a declaration to these results.
+  /// \brief Tests whether the given declaration is acceptable.
+  bool isAcceptableDecl(NamedDecl *D) const {
+    assert(IsAcceptableFn);
+    return IsAcceptableFn(D, IDNS);
+  }
+
+  /// \brief Returns the identifier namespace mask for this lookup.
+  unsigned getIdentifierNamespace() const {
+    return IDNS;
+  }
+
+  /// \brief Add a declaration to these results.  Does not test the
+  /// acceptance criteria.
   void addDecl(NamedDecl *D) {
     Decls.push_back(D);
     ResultKind = Found;
@@ -334,6 +341,7 @@
   void clear(Sema::LookupNameKind Kind) {
     clear();
     LookupKind = Kind;
+    configure();
   }
 
   void print(llvm::raw_ostream &);
@@ -438,6 +446,7 @@
   }
 
   void addDeclsFromBasePaths(const CXXBasePaths &P);
+  void configure();
 
   // Sanity checks.
   void sanity() const {
@@ -476,7 +485,9 @@
   SourceLocation NameLoc;
   SourceRange NameContextRange;
   Sema::LookupNameKind LookupKind;
-  unsigned IDNS; // ill-defined until set by lookup
+  ResultFilter IsAcceptableFn; // set by configure()
+  unsigned IDNS; // set by configure()
+
   bool Redecl;
 
   /// \brief True if tag declarations should be hidden if non-tags

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Dec 18 04:40:03 2009
@@ -613,10 +613,6 @@
                                         const LookupResult &Previous,
                                         Scope *S);
   void DiagnoseFunctionSpecifiers(Declarator& D);
-  bool CheckRedeclaration(DeclContext *DC,
-                          DeclarationName Name,
-                          SourceLocation NameLoc,
-                          unsigned Diagnostic);
   NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                                     QualType R, TypeSourceInfo *TInfo,
                                     LookupResult &Previous, bool &Redeclaration);
@@ -1176,36 +1172,6 @@
   bool CppLookupName(LookupResult &R, Scope *S);
 
 public:
-  /// Determines whether D is a suitable lookup result according to the
-  /// lookup criteria.
-  static bool isAcceptableLookupResult(NamedDecl *D, LookupNameKind NameKind,
-                                       unsigned IDNS) {
-    switch (NameKind) {
-    case Sema::LookupOrdinaryName:
-    case Sema::LookupTagName:
-    case Sema::LookupMemberName:
-    case Sema::LookupRedeclarationWithLinkage: // FIXME: check linkage, scoping
-    case Sema::LookupUsingDeclName:
-    case Sema::LookupObjCProtocolName:
-    case Sema::LookupObjCImplementationName:
-      return D->isInIdentifierNamespace(IDNS);
-
-    case Sema::LookupOperatorName:
-      return D->isInIdentifierNamespace(IDNS) &&
-             !D->getDeclContext()->isRecord();
-
-    case Sema::LookupNestedNameSpecifierName:
-      return isa<TypedefDecl>(D) || D->isInIdentifierNamespace(Decl::IDNS_Tag);
-
-    case Sema::LookupNamespaceName:
-      return isa<NamespaceDecl>(D) || isa<NamespaceAliasDecl>(D);
-    }
-
-    assert(false &&
-           "isAcceptableLookupResult always returns before this point");
-    return false;
-  }
-
   /// \brief Look up a name, looking for a single declaration.  Return
   /// null if the results were absent, ambiguous, or overloaded.
   ///

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Dec 18 04:40:03 2009
@@ -1519,29 +1519,27 @@
   return DeclPtrTy::make(Tag);
 }
 
-/// We are trying to introduce the given name into the given context;
+/// We are trying to inject an anonymous member into the given scope;
 /// check if there's an existing declaration that can't be overloaded.
 ///
 /// \return true if this is a forbidden redeclaration
-bool Sema::CheckRedeclaration(DeclContext *DC,
-                              DeclarationName Name,
-                              SourceLocation NameLoc,
-                              unsigned diagnostic) {
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName,
-                 ForRedeclaration);
-  LookupQualifiedName(R, DC);
+static bool CheckAnonMemberRedeclaration(Sema &SemaRef,
+                                         Scope *S,
+                                         DeclarationName Name,
+                                         SourceLocation NameLoc,
+                                         unsigned diagnostic) {
+  LookupResult R(SemaRef, Name, NameLoc, Sema::LookupMemberName,
+                 Sema::ForRedeclaration);
+  if (!SemaRef.LookupName(R, S)) return false;
 
-  if (R.empty()) return false;
-
-  if (R.getResultKind() == LookupResult::Found &&
-      isa<TagDecl>(R.getFoundDecl()))
+  if (R.getAsSingle<TagDecl>())
     return false;
 
   // Pick a representative declaration.
-  NamedDecl *PrevDecl = (*R.begin())->getUnderlyingDecl();
+  NamedDecl *PrevDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
 
-  Diag(NameLoc, diagnostic) << Name;
-  Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
+  SemaRef.Diag(NameLoc, diagnostic) << Name;
+  SemaRef.Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
 
   return true;
 }
@@ -1573,8 +1571,8 @@
                                FEnd = AnonRecord->field_end();
        F != FEnd; ++F) {
     if ((*F)->getDeclName()) {
-      if (CheckRedeclaration(Owner, (*F)->getDeclName(),
-                             (*F)->getLocation(), diagKind)) {
+      if (CheckAnonMemberRedeclaration(*this, S, (*F)->getDeclName(),
+                                       (*F)->getLocation(), diagKind)) {
         // C++ [class.union]p2:
         //   The names of the members of an anonymous union shall be
         //   distinct from the names of any other entity in the

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Dec 18 04:40:03 2009
@@ -192,23 +192,71 @@
   };
 }
 
+static bool IsAcceptableIDNS(NamedDecl *D, unsigned IDNS) {
+  return D->isInIdentifierNamespace(IDNS);
+}
+
+static bool IsAcceptableOperatorName(NamedDecl *D, unsigned IDNS) {
+  return D->isInIdentifierNamespace(IDNS) &&
+    !D->getDeclContext()->isRecord();
+}
+
+static bool IsAcceptableNestedNameSpecifierName(NamedDecl *D, unsigned IDNS) {
+  return isa<TypedefDecl>(D) || D->isInIdentifierNamespace(Decl::IDNS_Tag);
+}
+
+static bool IsAcceptableNamespaceName(NamedDecl *D, unsigned IDNS) {
+  return isa<NamespaceDecl>(D) || isa<NamespaceAliasDecl>(D);
+}
+
+/// Gets the default result filter for the given lookup.
+static inline
+LookupResult::ResultFilter getResultFilter(Sema::LookupNameKind NameKind) {
+  switch (NameKind) {
+  case Sema::LookupOrdinaryName:
+  case Sema::LookupTagName:
+  case Sema::LookupMemberName:
+  case Sema::LookupRedeclarationWithLinkage: // FIXME: check linkage, scoping
+  case Sema::LookupUsingDeclName:
+  case Sema::LookupObjCProtocolName:
+  case Sema::LookupObjCImplementationName:
+    return &IsAcceptableIDNS;
+
+  case Sema::LookupOperatorName:
+    return &IsAcceptableOperatorName;
+
+  case Sema::LookupNestedNameSpecifierName:
+    return &IsAcceptableNestedNameSpecifierName;
+
+  case Sema::LookupNamespaceName:
+    return &IsAcceptableNamespaceName;
+  }
+
+  llvm_unreachable("unkknown lookup kind");
+  return 0;
+}
+
 // Retrieve the set of identifier namespaces that correspond to a
 // specific kind of name lookup.
-inline unsigned
-getIdentifierNamespacesFromLookupNameKind(Sema::LookupNameKind NameKind,
-                                          bool CPlusPlus) {
+static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
+                               bool CPlusPlus,
+                               bool Redeclaration) {
   unsigned IDNS = 0;
   switch (NameKind) {
   case Sema::LookupOrdinaryName:
   case Sema::LookupOperatorName:
   case Sema::LookupRedeclarationWithLinkage:
     IDNS = Decl::IDNS_Ordinary;
-    if (CPlusPlus)
+    if (CPlusPlus) {
       IDNS |= Decl::IDNS_Tag | Decl::IDNS_Member;
+      if (Redeclaration) IDNS |= Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend;
+    }
     break;
 
   case Sema::LookupTagName:
     IDNS = Decl::IDNS_Tag;
+    if (CPlusPlus && Redeclaration)
+      IDNS |= Decl::IDNS_TagFriend;
     break;
 
   case Sema::LookupMemberName:
@@ -238,6 +286,13 @@
   return IDNS;
 }
 
+void LookupResult::configure() {
+  IDNS = getIDNS(LookupKind,
+                 SemaRef.getLangOptions().CPlusPlus,
+                 isForRedeclaration());
+  IsAcceptableFn = getResultFilter(LookupKind);
+}
+
 // Necessary because CXXBasePaths is not complete in Sema.h
 void LookupResult::deletePaths(CXXBasePaths *Paths) {
   delete Paths;
@@ -377,8 +432,7 @@
 
   DeclContext::lookup_const_iterator I, E;
   for (llvm::tie(I, E) = DC->lookup(R.getLookupName()); I != E; ++I)
-    if (Sema::isAcceptableLookupResult(*I, R.getLookupKind(),
-                                       R.getIdentifierNamespace()))
+    if (R.isAcceptableDecl(*I))
       R.addDecl(*I), Found = true;
 
   return Found;
@@ -424,19 +478,7 @@
 }
 
 bool Sema::CppLookupName(LookupResult &R, Scope *S) {
-  assert(getLangOptions().CPlusPlus &&
-         "Can perform only C++ lookup");
-  LookupNameKind NameKind = R.getLookupKind();
-  unsigned IDNS
-    = getIdentifierNamespacesFromLookupNameKind(NameKind, /*CPlusPlus*/ true);
-
-  // If we're testing for redeclarations, also look in the friend namespaces.
-  if (R.isForRedeclaration()) {
-    if (IDNS & Decl::IDNS_Tag) IDNS |= Decl::IDNS_TagFriend;
-    if (IDNS & Decl::IDNS_Ordinary) IDNS |= Decl::IDNS_OrdinaryFriend;
-  }
-
-  R.setIdentifierNamespace(IDNS);
+  assert(getLangOptions().CPlusPlus && "Can perform only C++ lookup");
 
   DeclarationName Name = R.getLookupName();
 
@@ -467,7 +509,7 @@
     // Check whether the IdResolver has anything in this scope.
     bool Found = false;
     for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
-      if (isAcceptableLookupResult(*I, NameKind, IDNS)) {
+      if (R.isAcceptableDecl(*I)) {
         Found = true;
         R.addDecl(*I);
       }
@@ -531,7 +573,7 @@
     // Check whether the IdResolver has anything in this scope.
     bool Found = false;
     for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
-      if (isAcceptableLookupResult(*I, NameKind, IDNS)) {
+      if (R.isAcceptableDecl(*I)) {
         // We found something.  Look for anything else in our scope
         // with this same name and in an acceptable identifier
         // namespace, so that we can construct an overload set if we
@@ -597,47 +639,18 @@
   if (!getLangOptions().CPlusPlus) {
     // Unqualified name lookup in C/Objective-C is purely lexical, so
     // search in the declarations attached to the name.
-    unsigned IDNS = 0;
-    switch (NameKind) {
-    case Sema::LookupOrdinaryName:
-      IDNS = Decl::IDNS_Ordinary;
-      break;
-
-    case Sema::LookupTagName:
-      IDNS = Decl::IDNS_Tag;
-      break;
-
-    case Sema::LookupMemberName:
-      IDNS = Decl::IDNS_Member;
-      break;
 
-    case Sema::LookupOperatorName:
-    case Sema::LookupNestedNameSpecifierName:
-    case Sema::LookupNamespaceName:
-    case Sema::LookupUsingDeclName:
-      assert(false && "C does not perform these kinds of name lookup");
-      break;
-
-    case Sema::LookupRedeclarationWithLinkage:
+    if (NameKind == Sema::LookupRedeclarationWithLinkage) {
       // Find the nearest non-transparent declaration scope.
       while (!(S->getFlags() & Scope::DeclScope) ||
              (S->getEntity() &&
               static_cast<DeclContext *>(S->getEntity())
                 ->isTransparentContext()))
         S = S->getParent();
-      IDNS = Decl::IDNS_Ordinary;
-      break;
-
-    case Sema::LookupObjCProtocolName:
-      IDNS = Decl::IDNS_ObjCProtocol;
-      break;
-
-    case Sema::LookupObjCImplementationName:
-      IDNS = Decl::IDNS_ObjCImplementation;
-      break;
-
     }
 
+    unsigned IDNS = R.getIdentifierNamespace();
+
     // Scan up the scope chain looking for a decl that matches this
     // identifier that is in the appropriate namespace.  This search
     // should not take long, as shadowing of names is uncommon, and
@@ -864,17 +877,6 @@
   if (!R.getLookupName())
     return false;
 
-  // If we're performing qualified name lookup (e.g., lookup into a
-  // struct), find fields as part of ordinary name lookup.
-  LookupNameKind NameKind = R.getLookupKind();
-  unsigned IDNS
-    = getIdentifierNamespacesFromLookupNameKind(NameKind,
-                                                getLangOptions().CPlusPlus);
-  if (NameKind == LookupOrdinaryName)
-    IDNS |= Decl::IDNS_Member;
-
-  R.setIdentifierNamespace(IDNS);
-
   // Make sure that the declaration context is complete.
   assert((!isa<TagDecl>(LookupCtx) ||
           LookupCtx->isDependentContext() ||

Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=91676&r1=91675&r2=91676&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Fri Dec 18 04:40:03 2009
@@ -191,6 +191,19 @@
 
 somens::a a3 = a2; // expected-error {{cannot initialize 'a3' with an lvalue of type 'foo<somens::a>'}}
 
+// typedefs and using declarations.
+namespace test1 {
+  namespace ns {
+    class Counter { static int count; };
+    typedef Counter counter;
+  }
+  using ns::counter;
 
-
-
+  class Test {
+    void test1() {
+      counter c;
+      c.count++;
+      counter::count++;
+    }
+  };
+}





More information about the cfe-commits mailing list