[cfe-commits] r111818 - in /cfe/trunk: include/clang/Sema/Action.h include/clang/Sema/CodeCompleteConsumer.h include/clang/Sema/Sema.h lib/Frontend/ASTUnit.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseObjc.cpp lib/Sema/SemaCodeComplete.cpp test/Index/complete-declarators.cpp test/Index/complete-declarators.m

Douglas Gregor dgregor at apple.com
Mon Aug 23 11:23:49 PDT 2010


Author: dgregor
Date: Mon Aug 23 13:23:48 2010
New Revision: 111818

URL: http://llvm.org/viewvc/llvm-project?rev=111818&view=rev
Log:
Introduce a new code-completion point when we're parsing a
declarator. Here, we can only see a few things (e.g., cvr-qualifiers,
nested name specifiers) and we do not want to provide other non-macro
completions. Previously, we would end up in recovery mode and would
provide a large number of non-relevant completions.


Added:
    cfe/trunk/test/Index/complete-declarators.cpp
    cfe/trunk/test/Index/complete-declarators.m
Modified:
    cfe/trunk/include/clang/Sema/Action.h
    cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp

Modified: cfe/trunk/include/clang/Sema/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Action.h?rev=111818&r1=111817&r2=111818&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Action.h (original)
+++ cfe/trunk/include/clang/Sema/Action.h Mon Aug 23 13:23:48 2010
@@ -2798,6 +2798,22 @@
   virtual void CodeCompleteOrdinaryName(Scope *S, 
                                     ParserCompletionContext CompletionContext) { }
   
+  /// \brief Code completion for a declarator name.
+  ///
+  /// 
+  ///
+  /// \param S The scope in which code completion occurs.
+  ///
+  /// \param AllowNonIdentifiers Whether non-identifier names are allowed in
+  /// this context, e.g., operator+.
+  ///
+  /// \param AllowNestedNameSpecifiers Whether nested-name-specifiers are 
+  /// allowed in this context, e.g., because it is a top-level declaration or
+  /// a friend declaration.
+  virtual void CodeCompleteDeclarator(Scope *S,
+                                      bool AllowNonIdentifiers,
+                                      bool AllowNestedNameSpecifiers) { }
+  
   /// \brief Code completion for a member access expression.
   ///
   /// This code completion action is invoked when the code-completion token

Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=111818&r1=111817&r2=111818&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Mon Aug 23 13:23:48 2010
@@ -164,7 +164,12 @@
     /// is expected.
     CCC_Namespace,
     /// \brief Code completion occurred where a type name is expected.
-    CCC_Type
+    CCC_Type,
+    /// \brief Code completion occurred where a new name is expected.
+    CCC_Name,
+    /// \brief Code completion occurred where a new name is expected and a
+    /// qualified name is permissible.
+    CCC_PotentiallyQualifiedName
   };
 
 private:

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=111818&r1=111817&r2=111818&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Aug 23 13:23:48 2010
@@ -4640,6 +4640,9 @@
   //@{
   virtual void CodeCompleteOrdinaryName(Scope *S,
                                      ParserCompletionContext CompletionContext);
+  virtual void CodeCompleteDeclarator(Scope *S,
+                                      bool AllowNonIdentifiers,
+                                      bool AllowNestedNameSpecifiers);
   virtual void CodeCompleteExpression(Scope *S, QualType T,
                                       bool IntegralConstantExpression = false);
   virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=111818&r1=111817&r2=111818&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Mon Aug 23 13:23:48 2010
@@ -235,7 +235,8 @@
           | (1 << (CodeCompletionContext::CCC_EnumTag - 1))
           | (1 << (CodeCompletionContext::CCC_UnionTag - 1))
           | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1))
-          | (1 << (CodeCompletionContext::CCC_Type - 1));
+          | (1 << (CodeCompletionContext::CCC_Type - 1))
+          | (1 << (CodeCompletionContext::CCC_PotentiallyQualifiedName - 1));
 
         if (isa<NamespaceDecl>(Results[I].Declaration) ||
             isa<NamespaceAliasDecl>(Results[I].Declaration))
@@ -275,7 +276,10 @@
         | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1))
         | (1 << (CodeCompletionContext::CCC_Statement - 1))
         | (1 << (CodeCompletionContext::CCC_Expression - 1))
-        | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
+        | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
+        | (1 << (CodeCompletionContext::CCC_Name - 1))
+        | (1 << (CodeCompletionContext::CCC_PotentiallyQualifiedName - 1));
+      
       CachedResult.Priority = Results[I].Priority;
       CachedResult.Kind = Results[I].CursorKind;
       CachedResult.TypeClass = STC_Void;
@@ -1532,6 +1536,8 @@
   case CodeCompletionContext::CCC_MemberAccess:
   case CodeCompletionContext::CCC_Namespace:
   case CodeCompletionContext::CCC_Type:
+  case CodeCompletionContext::CCC_Name:
+  case CodeCompletionContext::CCC_PotentiallyQualifiedName:
     break;
     
   case CodeCompletionContext::CCC_EnumTag:

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=111818&r1=111817&r2=111818&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Aug 23 13:23:48 2010
@@ -853,21 +853,7 @@
 void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
                                         const ParsedTemplateInfo &TemplateInfo,
                                         AccessSpecifier AS,
-                                        DeclSpecContext DSContext) {
-  if (Tok.is(tok::code_completion)) {
-    Action::ParserCompletionContext CCC = Action::PCC_Namespace;
-    if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
-      CCC = DSContext == DSC_class? Action::PCC_MemberTemplate 
-                                  : Action::PCC_Template;
-    else if (DSContext == DSC_class)
-      CCC = Action::PCC_Class;
-    else if (ObjCImpDecl)
-      CCC = Action::PCC_ObjCImplementation;
-    
-    Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
-    ConsumeCodeCompletionToken();
-  }
-  
+                                        DeclSpecContext DSContext) {  
   DS.SetRangeStart(Tok.getLocation());
   while (1) {
     bool isInvalid = false;
@@ -884,6 +870,38 @@
       DS.Finish(Diags, PP);
       return;
 
+    case tok::code_completion: {
+      Action::ParserCompletionContext CCC = Action::PCC_Namespace;
+      if (DS.hasTypeSpecifier()) {
+        bool AllowNonIdentifiers
+          = (getCurScope()->getFlags() & (Scope::ControlScope |
+                                          Scope::BlockScope |
+                                          Scope::TemplateParamScope |
+                                          Scope::FunctionPrototypeScope |
+                                          Scope::AtCatchScope)) == 0;
+        bool AllowNestedNameSpecifiers
+          = DSContext == DSC_top_level || 
+            (DSContext == DSC_class && DS.isFriendSpecified());
+
+        Actions.CodeCompleteDeclarator(getCurScope(), AllowNonIdentifiers, 
+                                       AllowNestedNameSpecifiers);
+        ConsumeCodeCompletionToken();
+        return;
+      } 
+      
+      if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
+        CCC = DSContext == DSC_class? Action::PCC_MemberTemplate 
+                                    : Action::PCC_Template;
+      else if (DSContext == DSC_class)
+        CCC = Action::PCC_Class;
+      else if (ObjCImpDecl)
+        CCC = Action::PCC_ObjCImplementation;
+      
+      Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
+      ConsumeCodeCompletionToken();
+      return;
+    }
+
     case tok::coloncolon: // ::foo::bar
       // C++ scope specifier.  Annotate and loop, or bail out on error.
       if (TryAnnotateCXXScopeToken(true)) {
@@ -2501,6 +2519,7 @@
                                      DirectDeclParseFunction DirectDeclParser) {
   if (Diags.hasAllExtensionsSilenced())
     D.setExtension();
+  
   // C++ member pointers start with a '::' or a nested-name.
   // Member pointers get special handling, since there's no place for the
   // scope spec in the generic path below.

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=111818&r1=111817&r2=111818&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Mon Aug 23 13:23:48 2010
@@ -774,9 +774,9 @@
 ///     __attribute__((unused))
 ///
 Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
-                                       tok::TokenKind mType,
-                                       Decl *IDecl,
-                                       tok::ObjCKeywordKind MethodImplKind) {
+                                  tok::TokenKind mType,
+                                  Decl *IDecl,
+                                  tok::ObjCKeywordKind MethodImplKind) {
   ParsingDeclRAIIObject PD(*this);
 
   if (Tok.is(tok::code_completion)) {

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=111818&r1=111817&r2=111818&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Mon Aug 23 13:23:48 2010
@@ -2222,7 +2222,7 @@
 void Sema::CodeCompleteOrdinaryName(Scope *S, 
                                     ParserCompletionContext CompletionContext) {
   typedef CodeCompleteConsumer::Result Result;
-  ResultBuilder Results(*this);
+  ResultBuilder Results(*this);  
 
   // Determine how to filter results, e.g., so that the names of
   // values (functions, enumerators, function templates, etc.) are
@@ -2268,6 +2268,45 @@
                             Results.data(),Results.size());
 }
 
+void Sema::CodeCompleteDeclarator(Scope *S,
+                                  bool AllowNonIdentifiers,
+                                  bool AllowNestedNameSpecifiers) {
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder Results(*this);    
+  Results.EnterNewScope();
+  
+  // Type qualifiers can come after names.
+  Results.AddResult(Result("const"));
+  Results.AddResult(Result("volatile"));
+  if (getLangOptions().C99)
+    Results.AddResult(Result("restrict"));
+
+  if (getLangOptions().CPlusPlus) {
+    if (AllowNonIdentifiers) {
+      Results.AddResult(Result("operator")); 
+    }
+    
+    // Add nested-name-specifiers.
+    if (AllowNestedNameSpecifiers) {
+      Results.allowNestedNameSpecifiers();
+      CodeCompletionDeclConsumer Consumer(Results, CurContext);
+      LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
+                         CodeCompleter->includeGlobals());
+    }
+  }
+  Results.ExitScope();
+
+  // Allow macros for names.
+  if (CodeCompleter->includeMacros())
+    AddMacroResults(PP, Results);
+  
+  HandleCodeCompleteResults(this, CodeCompleter,
+                        AllowNestedNameSpecifiers
+                          ? CodeCompletionContext::CCC_PotentiallyQualifiedName
+                          : CodeCompletionContext::CCC_Name,
+                            Results.data(), Results.size());
+}
+
 /// \brief Perform code-completion in an expression context when we know what
 /// type we're looking for.
 ///

Added: cfe/trunk/test/Index/complete-declarators.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-declarators.cpp?rev=111818&view=auto
==============================================================================
--- cfe/trunk/test/Index/complete-declarators.cpp (added)
+++ cfe/trunk/test/Index/complete-declarators.cpp Mon Aug 23 13:23:48 2010
@@ -0,0 +1,39 @@
+// This test is line- and column-sensitive, so test commands are at the bottom.
+namespace N {
+  struct X {
+    int f(X);
+  };
+}
+
+int g(int a);
+
+struct Y { };
+
+struct Z {
+  int member;
+  friend int N::X::f(N::X);
+};
+
+// RUN: c-index-test -code-completion-at=%s:8:5 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: NotImplemented:{TypedText const} (30)
+// CHECK-CC1: NotImplemented:{TypedText N}{Text ::} (75)
+// CHECK-CC1: NotImplemented:{TypedText operator} (30)
+// CHECK-CC1: NotImplemented:{TypedText volatile} (30)
+// RUN: c-index-test -code-completion-at=%s:8:11 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: NotImplemented:{TypedText const} (30)
+// CHECK-CC2-NOT: NotImplemented:{TypedText N}{Text ::} (75)
+// CHECK-CC2-NOT: NotImplemented:{TypedText operator} (30)
+// CHECK-CC2: NotImplemented:{TypedText volatile} (30)
+// RUN: c-index-test -code-completion-at=%s:13:7 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: NotImplemented:{TypedText const} (30)
+// CHECK-CC3-NOT: NotImplemented:{TypedText N}{Text ::} (75)
+// CHECK-CC3: NotImplemented:{TypedText operator} (30)
+// CHECK-CC3: NotImplemented:{TypedText volatile} (30)
+// RUN: c-index-test -code-completion-at=%s:14:14 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: NotImplemented:{TypedText const} (30)
+// CHECK-CC4: NotImplemented:{TypedText N}{Text ::} (75)
+// CHECK-CC4: NotImplemented:{TypedText operator} (30)
+// CHECK-CC4: NotImplemented:{TypedText volatile} (30)
+// CHECK-CC4: StructDecl:{TypedText Y} (40)
+// CHECK-CC4: StructDecl:{TypedText Z} (20)
+

Added: cfe/trunk/test/Index/complete-declarators.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-declarators.m?rev=111818&view=auto
==============================================================================
--- cfe/trunk/test/Index/complete-declarators.m (added)
+++ cfe/trunk/test/Index/complete-declarators.m Mon Aug 23 13:23:48 2010
@@ -0,0 +1,29 @@
+// This test is line- and column-sensitive, so test commands are at the bottom.
+ at protocol P
+- (int)method:(id)param1;
+ at end
+
+ at interface A <P>
+- (int)method:(id)param1;
+
+ at property int prop1;
+ at end
+
+ at implementation A
+- (int)method:(id)param1 {
+  for(id x in param1) {
+    int y;
+  }
+}
+ at end
+
+// RUN: c-index-test -code-completion-at=%s:7:19 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1-NOT: NotImplemented:{TypedText extern} (30)
+// CHECK-CC1: NotImplemented:{TypedText param1} (30)
+// RUN: c-index-test -code-completion-at=%s:9:15 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: c-index-test -code-completion-at=%s:14:10 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: c-index-test -code-completion-at=%s:15:9 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: NotImplemented:{TypedText const} (30)
+// CHECK-CC2-NOT: int
+// CHECK-CC2: NotImplemented:{TypedText restrict} (30)
+// CHECK-CC2: NotImplemented:{TypedText volatile} (30)





More information about the cfe-commits mailing list