[cfe-commits] r93428 - in /cfe/trunk/lib/Sema: Lookup.h SemaCodeComplete.cpp SemaLookup.cpp

Douglas Gregor dgregor at apple.com
Thu Jan 14 07:47:36 PST 2010


Author: dgregor
Date: Thu Jan 14 09:47:35 2010
New Revision: 93428

URL: http://llvm.org/viewvc/llvm-project?rev=93428&view=rev
Log:
Switch the remaining code completions over to LookupVisibleDecls,
after adding the ability to determine whether our lookup is a
base-class lookup. Eliminate CollectMemberLookupResults, since it is
no longer used (yay).

Modified:
    cfe/trunk/lib/Sema/Lookup.h
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/Lookup.h (original)
+++ cfe/trunk/lib/Sema/Lookup.h Thu Jan 14 09:47:35 2010
@@ -524,7 +524,11 @@
     ///
     /// \param Hiding a declaration that hides the declaration \p ND,
     /// or NULL if no such declaration exists.
-    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding) = 0;
+    ///
+    /// \param InBaseClass whether this declaration was found in base
+    /// class of the context we searched.
+    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, 
+                           bool InBaseClass) = 0;
   };
 }
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Jan 14 09:47:35 2010
@@ -178,7 +178,11 @@
     /// \param CurContext the context in which this result will be named.
     ///
     /// \param Hiding the declaration that hides the result.
-    void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding);
+    ///
+    /// \param InBaseClass whether the result was found in a base
+    /// class of the searched context.
+    void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
+                   bool InBaseClass);
     
     /// \brief Enter into a new scope.
     void EnterNewScope();
@@ -543,7 +547,7 @@
 }
 
 void ResultBuilder::AddResult(Result R, DeclContext *CurContext, 
-                              NamedDecl *Hiding) {
+                              NamedDecl *Hiding, bool InBaseClass = false) {
   assert(R.Kind == Result::RK_Declaration &&
          "Only declaration results are supported");
   
@@ -568,7 +572,11 @@
   // nested-name-specifier.
   if (AsNestedNameSpecifier)
     R.StartsNestedNameSpecifier = true;
-  
+  else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
+           isa<CXXRecordDecl>(R.Declaration->getDeclContext()
+                                                  ->getLookupContext()))
+    R.QualifierIsInformative = true;
+
   // If this result is supposed to have an informative qualifier, add one.
   if (R.QualifierIsInformative && !R.Qualifier &&
       !R.StartsNestedNameSpecifier) {
@@ -703,112 +711,12 @@
     CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
       : Results(Results), CurContext(CurContext) { }
     
-    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding) {
-      Results.AddResult(ND, CurContext, Hiding);
+    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
+      Results.AddResult(ND, CurContext, Hiding, InBaseClass);
     }
   };
 }
 
-/// \brief Collect the results of searching for members within the given
-/// declaration context.
-///
-/// \param Ctx the declaration context from which we will gather results.
-///
-/// \param Visited the set of declaration contexts that have already been
-/// visited. Declaration contexts will only be visited once.
-///
-/// \param Results the result set that will be extended with any results
-/// found within this declaration context (and, for a C++ class, its bases).
-///
-/// \param InBaseClass whether we are in a base class.
-static void CollectMemberLookupResults(DeclContext *Ctx, 
-                                       DeclContext *CurContext,
-                                 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
-                                       ResultBuilder &Results,
-                                       bool InBaseClass = false) {
-  // Make sure we don't visit the same context twice.
-  if (!Visited.insert(Ctx->getPrimaryContext()))
-    return;
-  
-  // Enumerate all of the results in this context.
-  typedef CodeCompleteConsumer::Result Result;
-  Results.EnterNewScope();
-  for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx; 
-       CurCtx = CurCtx->getNextContext()) {
-    for (DeclContext::decl_iterator D = CurCtx->decls_begin(), 
-                                 DEnd = CurCtx->decls_end();
-         D != DEnd; ++D) {
-      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
-        Results.MaybeAddResult(Result(ND, 0, InBaseClass), CurContext);
-      
-      // Visit transparent contexts inside this context.
-      if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
-        if (InnerCtx->isTransparentContext())
-          CollectMemberLookupResults(InnerCtx, CurContext, Visited,
-                                     Results, InBaseClass);
-      }
-    }
-  }
-  
-  // Traverse the contexts of inherited classes.
-  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
-    for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
-                                         BEnd = Record->bases_end();
-         B != BEnd; ++B) {
-      QualType BaseType = B->getType();
-      
-      // Don't look into dependent bases, because name lookup can't look
-      // there anyway.
-      if (BaseType->isDependentType())
-        continue;
-      
-      const RecordType *Record = BaseType->getAs<RecordType>();
-      if (!Record)
-        continue;
-      
-      // FIXME: It would be nice to be able to determine whether referencing
-      // a particular member would be ambiguous. For example, given
-      //
-      //   struct A { int member; };
-      //   struct B { int member; };
-      //   struct C : A, B { };
-      //
-      //   void f(C *c) { c->### }
-      // accessing 'member' would result in an ambiguity. However, code
-      // completion could be smart enough to qualify the member with the
-      // base class, e.g.,
-      //
-      //   c->B::member
-      //
-      // or
-      //
-      //   c->A::member
-      
-      // Collect results from this base class (and its bases).
-      CollectMemberLookupResults(Record->getDecl(), CurContext, Visited,
-                                 Results, /*InBaseClass=*/true);
-    }
-  }
-  
-  // FIXME: Look into base classes in Objective-C!
-  
-  Results.ExitScope();
-}
-
-/// \brief Collect the results of searching for members within the given
-/// declaration context.
-///
-/// \param Ctx the declaration context from which we will gather results.
-///
-/// \param Results the result set that will be extended with any results
-/// found within this declaration context (and, for a C++ class, its bases).
-static void CollectMemberLookupResults(DeclContext *Ctx, 
-                                       DeclContext *CurContext,
-                                       ResultBuilder &Results) {
-  llvm::SmallPtrSet<DeclContext *, 16> Visited;
-  CollectMemberLookupResults(Ctx, CurContext, Visited, Results);
-}
-
 /// \brief Add type specifiers for the current language as keyword results.
 static void AddTypeSpecifierResults(const LangOptions &LangOpts,
                                     ResultBuilder &Results) {
@@ -2086,7 +1994,8 @@
   if (const RecordType *Record = BaseType->getAs<RecordType>()) {
     // Access to a C/C++ class, struct, or union.
     Results.allowNestedNameSpecifiers();
-    CollectMemberLookupResults(Record->getDecl(), Record->getDecl(), Results);
+    CodeCompletionDeclConsumer Consumer(Results, CurContext);
+    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
 
     if (getLangOptions().CPlusPlus) {
       if (!Results.empty()) {

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Jan 14 09:47:35 2010
@@ -1942,10 +1942,12 @@
           (*I)->getIdentifierNamespace() != IDNS)
         continue;
 
-      // Functions and function templates overload rather than hide.
-      // FIXME: Look for hiding based on function signatures!
+      // Functions and function templates in the same scope overload
+      // rather than hide.  FIXME: Look for hiding based on function
+      // signatures!
       if ((*I)->isFunctionOrFunctionTemplate() &&
-          ND->isFunctionOrFunctionTemplate())
+          ND->isFunctionOrFunctionTemplate() &&
+          SM == ShadowMaps.rbegin())
         continue;
           
       // We've found a declaration that hides this one.
@@ -1958,6 +1960,7 @@
 
 static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
                                bool QualifiedNameLookup,
+                               bool InBaseClass,
                                VisibleDeclConsumer &Consumer,
                                VisibleDeclsRecord &Visited) {
   // Make sure we don't visit the same context twice.
@@ -1972,14 +1975,14 @@
          D != DEnd; ++D) {
       if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
         if (Result.isAcceptableDecl(ND)) {
-          Consumer.FoundDecl(ND, Visited.checkHidden(ND));
+          Consumer.FoundDecl(ND, Visited.checkHidden(ND), InBaseClass);
           Visited.add(ND);
         }
 
       // Visit transparent contexts inside this context.
       if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
         if (InnerCtx->isTransparentContext())
-          LookupVisibleDecls(InnerCtx, Result, QualifiedNameLookup, 
+          LookupVisibleDecls(InnerCtx, Result, QualifiedNameLookup, InBaseClass,
                              Consumer, Visited);
       }
     }
@@ -1991,7 +1994,7 @@
     DeclContext::udir_iterator I, E;
     for (llvm::tie(I, E) = Ctx->getUsingDirectives(); I != E; ++I) {
       LookupVisibleDecls((*I)->getNominatedNamespace(), Result, 
-                         QualifiedNameLookup, Consumer, Visited);
+                         QualifiedNameLookup, InBaseClass, Consumer, Visited);
     }
   }
 
@@ -2033,7 +2036,7 @@
       // Find results in this base class (and its bases).
       ShadowContextRAII Shadow(Visited);
       LookupVisibleDecls(Record->getDecl(), Result, QualifiedNameLookup,
-                         Consumer, Visited);
+                         true, Consumer, Visited);
     }
   }
   
@@ -2043,34 +2046,37 @@
     for (ObjCCategoryDecl *Category = IFace->getCategoryList();
          Category; Category = Category->getNextClassCategory()) {
       ShadowContextRAII Shadow(Visited);
-      LookupVisibleDecls(Category, Result, QualifiedNameLookup, Consumer, 
-                         Visited);
+      LookupVisibleDecls(Category, Result, QualifiedNameLookup, false, 
+                         Consumer, Visited);
     }
 
     // Traverse protocols.
     for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
          E = IFace->protocol_end(); I != E; ++I) {
       ShadowContextRAII Shadow(Visited);
-      LookupVisibleDecls(*I, Result, QualifiedNameLookup, Consumer, Visited);
+      LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer, 
+                         Visited);
     }
 
     // Traverse the superclass.
     if (IFace->getSuperClass()) {
       ShadowContextRAII Shadow(Visited);
       LookupVisibleDecls(IFace->getSuperClass(), Result, QualifiedNameLookup,
-                         Consumer, Visited);
+                         true, Consumer, Visited);
     }
   } else if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Ctx)) {
     for (ObjCProtocolDecl::protocol_iterator I = Protocol->protocol_begin(),
            E = Protocol->protocol_end(); I != E; ++I) {
       ShadowContextRAII Shadow(Visited);
-      LookupVisibleDecls(*I, Result, QualifiedNameLookup, Consumer, Visited);
+      LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer, 
+                         Visited);
     }
   } else if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Ctx)) {
     for (ObjCCategoryDecl::protocol_iterator I = Category->protocol_begin(),
            E = Category->protocol_end(); I != E; ++I) {
       ShadowContextRAII Shadow(Visited);
-      LookupVisibleDecls(*I, Result, QualifiedNameLookup, Consumer, Visited);
+      LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer, 
+                         Visited);
     }
   }
 }
@@ -2089,7 +2095,7 @@
          D != DEnd; ++D) {
       if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
         if (Result.isAcceptableDecl(ND)) {
-          Consumer.FoundDecl(ND, Visited.checkHidden(ND));
+          Consumer.FoundDecl(ND, Visited.checkHidden(ND), false);
           Visited.add(ND);
         }
     }
@@ -2112,7 +2118,7 @@
                                   Result.getNameLoc(), Sema::LookupMemberName);
           ObjCInterfaceDecl *IFace = Method->getClassInterface();
           LookupVisibleDecls(IFace, IvarResult, /*QualifiedNameLookup=*/false, 
-                             Consumer, Visited);
+                             /*InBaseClass=*/false, Consumer, Visited);
         }
 
         // We've already performed all of the name lookup that we need
@@ -2125,7 +2131,7 @@
         continue;
       
       LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/false, 
-                         Consumer, Visited);
+                         /*InBaseClass=*/false, Consumer, Visited);
     }
   } else if (!S->getParent()) {
     // Look into the translation unit scope. We walk through the translation
@@ -2139,7 +2145,7 @@
     // in DeclContexts unless we have to" optimization), we can eliminate this.
     Entity = Result.getSema().Context.getTranslationUnitDecl();
     LookupVisibleDecls(Entity, Result, /*QualifiedNameLookup=*/false, 
-                       Consumer, Visited);
+                       /*InBaseClass=*/false, Consumer, Visited);
   } 
   
   if (Entity) {
@@ -2149,8 +2155,8 @@
     llvm::tie(UI, UEnd) = UDirs.getNamespacesFor(Entity);
     for (; UI != UEnd; ++UI)
       LookupVisibleDecls(const_cast<DeclContext *>(UI->getNominatedNamespace()),
-                         Result, /*QualifiedNameLookup=*/false, Consumer, 
-                         Visited);
+                         Result, /*QualifiedNameLookup=*/false, 
+                         /*InBaseClass=*/false, Consumer, Visited);
   }
 
   // Lookup names in the parent scope.
@@ -2185,8 +2191,8 @@
   LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
   VisibleDeclsRecord Visited;
   ShadowContextRAII Shadow(Visited);
-  ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true, Consumer, 
-                       Visited);
+  ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true, 
+                       /*InBaseClass=*/false, Consumer, Visited);
 }
 
 //----------------------------------------------------------------------------
@@ -2209,7 +2215,7 @@
   explicit TypoCorrectionConsumer(IdentifierInfo *Typo)
     : Typo(Typo->getName()) { }
 
-  virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding);
+  virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass);
 
   typedef llvm::SmallVector<NamedDecl *, 4>::const_iterator iterator;
   iterator begin() const { return BestResults.begin(); }
@@ -2221,7 +2227,8 @@
 
 }
 
-void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding) {
+void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding, 
+                                       bool InBaseClass) {
   // Don't consider hidden names for typo correction.
   if (Hiding)
     return;





More information about the cfe-commits mailing list