[cfe-commits] r93418 - /cfe/trunk/lib/Sema/SemaCodeComplete.cpp

Douglas Gregor dgregor at apple.com
Wed Jan 13 19:21:49 PST 2010


Author: dgregor
Date: Wed Jan 13 21:21:49 2010
New Revision: 93418

URL: http://llvm.org/viewvc/llvm-project?rev=93418&view=rev
Log:
Simplify the code-completion logic for nested-name-specifiers: rather
than traversing visible declarations twice, only perform one traversal
and recognize nested-name-specifiers as special.

Modified:
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Jan 13 21:21:49 2010
@@ -112,14 +112,18 @@
     /// \brief If non-NULL, a filter function used to remove any code-completion
     /// results that are not desirable.
     LookupFilter Filter;
-    
+
+    /// \brief Whether we should allow declarations as
+    /// nested-name-specifiers that would otherwise be filtered out.
+    bool AllowNestedNameSpecifiers;
+
     /// \brief A list of shadow maps, which is used to model name hiding at
     /// different levels of, e.g., the inheritance hierarchy.
     std::list<ShadowMap> ShadowMaps;
     
   public:
     explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
-      : SemaRef(SemaRef), Filter(Filter) { }
+      : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
     
     /// \brief Set the filter used for code-completion results.
     void setFilter(LookupFilter Filter) {
@@ -134,9 +138,19 @@
     unsigned size() const { return Results.size(); }
     bool empty() const { return Results.empty(); }
     
+    /// \brief Specify whether nested-name-specifiers are allowed.
+    void allowNestedNameSpecifiers(bool Allow = true) {
+      AllowNestedNameSpecifiers = Allow;
+    }
+
     /// \brief Determine whether the given declaration is at all interesting
     /// as a code-completion result.
-    bool isInterestingDecl(NamedDecl *ND) const;
+    ///
+    /// \param ND the declaration that we are inspecting.
+    ///
+    /// \param AsNestedNameSpecifier will be set true if this declaration is
+    /// only interesting when it is a nested-name-specifier.
+    bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
     
     /// \brief Check whether the result is hidden by the Hiding declaration.
     ///
@@ -330,7 +344,10 @@
   return Result;
 }
 
-bool ResultBuilder::isInterestingDecl(NamedDecl *ND) const {
+bool ResultBuilder::isInterestingDecl(NamedDecl *ND, 
+                                      bool &AsNestedNameSpecifier) const {
+  AsNestedNameSpecifier = false;
+
   ND = ND->getUnderlyingDecl();
   unsigned IDNS = ND->getIdentifierNamespace();
 
@@ -376,8 +393,19 @@
     return false;
   
   // Filter out any unwanted results.
-  if (Filter && !(this->*Filter)(ND))
+  if (Filter && !(this->*Filter)(ND)) {
+    // Check whether it is interesting as a nested-name-specifier.
+    if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus && 
+        IsNestedNameSpecifier(ND) &&
+        (Filter != &ResultBuilder::IsMember ||
+         (isa<CXXRecordDecl>(ND) && 
+          cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
+      AsNestedNameSpecifier = true;
+      return true;
+    }
+
     return false;
+  }
   
   // ... then it must be interesting!
   return true;
@@ -429,7 +457,8 @@
   Decl *CanonDecl = R.Declaration->getCanonicalDecl();
   unsigned IDNS = CanonDecl->getIdentifierNamespace();
 
-  if (!isInterestingDecl(R.Declaration))
+  bool AsNestedNameSpecifier = false;
+  if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
     return;
       
   ShadowMap &SMap = ShadowMaps.back();
@@ -491,10 +520,7 @@
   
   // 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()))
+  if (AsNestedNameSpecifier)
     R.StartsNestedNameSpecifier = true;
   
   // If this result is supposed to have an informative qualifier, add one.
@@ -527,7 +553,8 @@
     return;
   }
   
-  if (!isInterestingDecl(R.Declaration))
+  bool AsNestedNameSpecifier = false;
+  if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
     return;
   
   if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
@@ -539,10 +566,7 @@
   
   // 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()))
+  if (AsNestedNameSpecifier)
     R.StartsNestedNameSpecifier = true;
   
   // If this result is supposed to have an informative qualifier, add one.
@@ -553,7 +577,7 @@
       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());
+                            SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
     else
       R.QualifierIsInformative = false;
   }
@@ -664,9 +688,6 @@
   if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
     ND = Using->getTargetDecl();
 
-  if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND))
-    return Record->isInjectedClassName();
-    
   return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
     isa<ObjCPropertyDecl>(ND);
 }
@@ -2132,6 +2153,7 @@
   Results.EnterNewScope();
   if (const RecordType *Record = BaseType->getAs<RecordType>()) {
     // Access to a C/C++ class, struct, or union.
+    Results.allowNestedNameSpecifiers();
     CollectMemberLookupResults(Record->getDecl(), Record->getDecl(), Results);
 
     if (getLangOptions().CPlusPlus) {
@@ -2223,16 +2245,9 @@
   }
   
   ResultBuilder Results(*this, Filter);
+  Results.allowNestedNameSpecifiers();
   CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,Results);
   
-  if (getLangOptions().CPlusPlus) {
-    // We could have the start of a nested-name-specifier. Add those
-    // results as well.
-    Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
-    CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext, 
-                         Results);
-  }
-  
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results);
   HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
@@ -2518,14 +2533,11 @@
 #include "clang/Basic/OperatorKinds.def"
   
   // Add any type names visible from the current scope
+  Results.allowNestedNameSpecifiers();
   CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,Results);
   
   // Add any type specifiers
   AddTypeSpecifierResults(getLangOptions(), Results);
-  
-  // Add any nested-name-specifiers
-  Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
-  CollectLookupResults(S, Context.getTranslationUnitDecl(), CurContext,Results);
   Results.ExitScope();
   
   if (CodeCompleter->includeMacros())





More information about the cfe-commits mailing list