[cfe-commits] r93397 - in /cfe/trunk: lib/Sema/SemaCodeComplete.cpp test/Index/complete-at-exprstmt.m

Douglas Gregor dgregor at apple.com
Wed Jan 13 17:09:38 PST 2010


Author: dgregor
Date: Wed Jan 13 19:09:38 2010
New Revision: 93397

URL: http://llvm.org/viewvc/llvm-project?rev=93397&view=rev
Log:
Switch code-completion for ordinary names over to the new(ish)
LookupVisibleDecls, unifying the name lookup mechanisms used by code
completion and typo correction. Aside from the software-engineering
improvements, this makes code-completion see through using directives
and see ivars when performing unqualified name lookup in an
Objective-C instance method.


Modified:
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/test/Index/complete-at-exprstmt.m

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Jan 13 19:09:38 2010
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 #include "Sema.h"
+#include "Lookup.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -150,11 +151,21 @@
     /// of the shadow maps), or replace an existing result (for, e.g., a 
     /// redeclaration).
     ///
-    /// \param R the result to add (if it is unique).
+    /// \param CurContext the result to add (if it is unique).
     ///
     /// \param R the context in which this result will be named.
     void MaybeAddResult(Result R, DeclContext *CurContext = 0);
     
+    /// \brief Add a new result to this result set, where we already know
+    /// the hiding declation (if any).
+    ///
+    /// \param R the result to add (if it is unique).
+    ///
+    /// \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);
+    
     /// \brief Enter into a new scope.
     void EnterNewScope();
     
@@ -505,6 +516,52 @@
   Results.push_back(R);
 }
 
+void ResultBuilder::AddResult(Result R, DeclContext *CurContext, 
+                              NamedDecl *Hiding) {
+  assert(R.Kind == Result::RK_Declaration &&
+         "Only declaration results are supported");
+  
+  // Look through using declarations.
+  if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
+    AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
+    return;
+  }
+  
+  if (!isInterestingDecl(R.Declaration))
+    return;
+  
+  if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
+    return;
+      
+  // Make sure that any given declaration only shows up in the result set once.
+  if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
+    return;
+  
+  // If the filter is for nested-name-specifiers, then this result starts a
+  // nested-name-specifier.
+  if ((Filter == &ResultBuilder::IsNestedNameSpecifier) ||
+      (Filter == &ResultBuilder::IsMember &&
+       isa<CXXRecordDecl>(R.Declaration) &&
+       cast<CXXRecordDecl>(R.Declaration)->isInjectedClassName()))
+    R.StartsNestedNameSpecifier = true;
+  
+  // If this result is supposed to have an informative qualifier, add one.
+  if (R.QualifierIsInformative && !R.Qualifier &&
+      !R.StartsNestedNameSpecifier) {
+    DeclContext *Ctx = R.Declaration->getDeclContext();
+    if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
+    else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false, 
+                                                SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
+    else
+      R.QualifierIsInformative = false;
+  }
+  
+  // Insert this result into the set of results.
+  Results.push_back(R);
+}
+
 /// \brief Enter into a new scope.
 void ResultBuilder::EnterNewScope() {
   ShadowMaps.push_back(ShadowMap());
@@ -527,7 +584,9 @@
   unsigned IDNS = Decl::IDNS_Ordinary;
   if (SemaRef.getLangOptions().CPlusPlus)
     IDNS |= Decl::IDNS_Tag;
-  
+  else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
+    return true;
+
   return ND->getIdentifierNamespace() & IDNS;
 }
 
@@ -609,6 +668,23 @@
     isa<ObjCPropertyDecl>(ND);
 }
 
+namespace {
+  /// \brief Visible declaration consumer that adds a code-completion result
+  /// for each visible declaration.
+  class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
+    ResultBuilder &Results;
+    DeclContext *CurContext;
+    
+  public:
+    CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
+      : Results(Results), CurContext(CurContext) { }
+    
+    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding) {
+      Results.AddResult(ND, CurContext, Hiding);
+    }
+  };
+}
+
 // Find the next outer declaration context corresponding to this scope.
 static DeclContext *findOuterContext(Scope *S) {
   for (S = S->getParent(); S; S = S->getParent())
@@ -1970,8 +2046,8 @@
     break;
   }
 
-  CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext, 
-                       Results);
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
 
   Results.EnterNewScope();
   AddOrdinaryNameResults(CompletionContext, S, *this, Results);

Modified: cfe/trunk/test/Index/complete-at-exprstmt.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-at-exprstmt.m?rev=93397&r1=93396&r2=93397&view=diff

==============================================================================
--- cfe/trunk/test/Index/complete-at-exprstmt.m (original)
+++ cfe/trunk/test/Index/complete-at-exprstmt.m Wed Jan 13 19:09:38 2010
@@ -1,6 +1,6 @@
 /* The run lines are below, because this test is line- and
    column-number sensitive. */
- at interface MyClass { }
+ at interface MyClass { int ivar; }
 - (int)myMethod:(int)arg;
 @end
 
@@ -31,6 +31,7 @@
 // CHECK-CC3: ParmDecl:{ResultType int}{TypedText arg}
 // CHECK-CC3: TypedefDecl:{TypedText Class}
 // CHECK-CC3: TypedefDecl:{TypedText id}
+// CHECK-CC3: ObjCIvarDecl:{ResultType int}{TypedText ivar}
 // CHECK-CC3: ObjCInterfaceDecl:{TypedText MyClass}
 // CHECK-CC3: TypedefDecl:{TypedText SEL}
 // CHECK-CC3: NotImplemented:{ResultType MyClass *}{TypedText self}





More information about the cfe-commits mailing list