[cfe-commits] r134615 - in /cfe/trunk: include/clang-c/Index.h include/clang/Sema/CodeCompleteConsumer.h lib/Frontend/ASTUnit.cpp lib/Sema/CodeCompleteConsumer.cpp lib/Sema/SemaCodeComplete.cpp test/Index/code-completion.cpp test/Index/complete-natural.m tools/c-index-test/c-index-test.c tools/libclang/CIndexCodeCompletion.cpp tools/libclang/libclang.darwin.exports tools/libclang/libclang.exports

Douglas Gregor dgregor at apple.com
Thu Jul 7 09:03:39 PDT 2011


Author: dgregor
Date: Thu Jul  7 11:03:39 2011
New Revision: 134615

URL: http://llvm.org/viewvc/llvm-project?rev=134615&view=rev
Log:
Introduce a new libclang aPI function,
clang_codeCompleteGetContexts(), that provides the client with
information about the context in which code completion has occurred
and what kinds of entities make sense as completions at that
point. Patch by Connor Wakamo!

Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/test/Index/code-completion.cpp
    cfe/trunk/test/Index/complete-natural.m
    cfe/trunk/tools/c-index-test/c-index-test.c
    cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
    cfe/trunk/tools/libclang/libclang.darwin.exports
    cfe/trunk/tools/libclang/libclang.exports

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Thu Jul  7 11:03:39 2011
@@ -2871,6 +2871,137 @@
 };
 
 /**
+ * \brief Bits that represent the context under which completion is occurring.
+ *
+ * The enumerators in this enumeration may be bitwise-OR'd together if multiple
+ * contexts are occurring simultaneously.
+ */
+enum CXCompletionContext {
+  /**
+   * \brief The context for completions is unexposed, as only Clang results
+   * should be included. (This is equivalent to having no context bits set.)
+   */
+  CXCompletionContext_Unexposed = 0,
+  
+  /**
+   * \brief Completions for any possible type should be included in the results.
+   */
+  CXCompletionContext_AnyType = 1 << 0,
+  
+  /**
+   * \brief Completions for any possible value (variables, function calls, etc.)
+   * should be included in the results.
+   */
+  CXCompletionContext_AnyValue = 1 << 1,
+  /**
+   * \brief Completions for values that resolve to an Objective-C object should
+   * be included in the results.
+   */
+  CXCompletionContext_ObjCObjectValue = 1 << 2,
+  /**
+   * \brief Completions for values that resolve to an Objective-C selector
+   * should be included in the results.
+   */
+  CXCompletionContext_ObjCSelectorValue = 1 << 3,
+  /**
+   * \brief Completions for values that resolve to a C++ class type should be
+   * included in the results.
+   */
+  CXCompletionContext_CXXClassTypeValue = 1 << 4,
+  
+  /**
+   * \brief Completions for fields of the member being accessed using the dot
+   * operator should be included in the results.
+   */
+  CXCompletionContext_DotMemberAccess = 1 << 5,
+  /**
+   * \brief Completions for fields of the member being accessed using the arrow
+   * operator should be included in the results.
+   */
+  CXCompletionContext_ArrowMemberAccess = 1 << 6,
+  /**
+   * \brief Completions for properties of the Objective-C object being accessed
+   * using the dot operator should be included in the results.
+   */
+  CXCompletionContext_ObjCPropertyAccess = 1 << 7,
+  
+  /**
+   * \brief Completions for enum tags should be included in the results.
+   */
+  CXCompletionContext_EnumTag = 1 << 8,
+  /**
+   * \brief Completions for union tags should be included in the results.
+   */
+  CXCompletionContext_UnionTag = 1 << 9,
+  /**
+   * \brief Completions for struct tags should be included in the results.
+   */
+  CXCompletionContext_StructTag = 1 << 10,
+  
+  /**
+   * \brief Completions for C++ class names should be included in the results.
+   */
+  CXCompletionContext_ClassTag = 1 << 11,
+  /**
+   * \brief Completions for C++ namespaces and namespace aliases should be
+   * included in the results.
+   */
+  CXCompletionContext_Namespace = 1 << 12,
+  /**
+   * \brief Completions for C++ nested name specifiers should be included in
+   * the results.
+   */
+  CXCompletionContext_NestedNameSpecifier = 1 << 13,
+  
+  /**
+   * \brief Completions for Objective-C interfaces (classes) should be included
+   * in the results.
+   */
+  CXCompletionContext_ObjCInterface = 1 << 14,
+  /**
+   * \brief Completions for Objective-C protocols should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCProtocol = 1 << 15,
+  /**
+   * \brief Completions for Objective-C categories should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCCategory = 1 << 16,
+  /**
+   * \brief Completions for Objective-C instance messages should be included
+   * in the results.
+   */
+  CXCompletionContext_ObjCInstanceMessage = 1 << 17,
+  /**
+   * \brief Completions for Objective-C class messages should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCClassMessage = 1 << 18,
+  /**
+   * \brief Completions for Objective-C selector names should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCSelectorName = 1 << 19,
+  
+  /**
+   * \brief Completions for preprocessor macro names should be included in
+   * the results.
+   */
+  CXCompletionContext_MacroName = 1 << 20,
+  
+  /**
+   * \brief Natural language completions should be included in the results.
+   */
+  CXCompletionContext_NaturalLanguage = 1 << 21,
+  
+  /**
+   * \brief The current context is unknown, so set all contexts.
+   */
+  CXCompletionContext_Unknown = ((1 << 22) - 1)
+};
+  
+/**
  * \brief Returns a default set of code-completion options that can be
  * passed to\c clang_codeCompleteAt(). 
  */
@@ -2991,6 +3122,19 @@
                                              unsigned Index);
 
 /**
+ * \brief Determines what compeltions are appropriate for the context
+ * the given code completion.
+ * 
+ * \param Results the code completion results to query
+ *
+ * \returns the kinds of completions that are appropriate for use
+ * along with the given code completion results.
+ */
+CINDEX_LINKAGE
+unsigned long long clang_codeCompleteGetContexts(
+                                                CXCodeCompleteResults *Results);
+  
+/**
  * @}
  */
 

Modified: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Thu Jul  7 11:03:39 2011
@@ -185,12 +185,26 @@
     /// is expected.
     CCC_ObjCMessageReceiver,
     /// \brief Code completion occurred on the right-hand side of a member
-    /// access expression.
+    /// access expression using the dot operator.
     ///
     /// The results of this completion are the members of the type being 
     /// accessed. The type itself is available via 
     /// \c CodeCompletionContext::getType().
-    CCC_MemberAccess,
+    CCC_DotMemberAccess,
+    /// \brief Code completion occurred on the right-hand side of a member
+    /// access expression using the arrow operator.
+    ///
+    /// The results of this completion are the members of the type being 
+    /// accessed. The type itself is available via 
+    /// \c CodeCompletionContext::getType().
+    CCC_ArrowMemberAccess,
+    /// \brief Code completion occurred on the right-hand side of an Objective-C
+    /// property access expression.
+    ///
+    /// The results of this completion are the members of the type being 
+    /// accessed. The type itself is available via 
+    /// \c CodeCompletionContext::getType().
+    CCC_ObjCPropertyAccess,
     /// \brief Code completion occurred after the "enum" keyword, to indicate
     /// an enumeration name.
     CCC_EnumTag,
@@ -235,6 +249,15 @@
     /// \brief Code completion in a parenthesized expression, which means that
     /// we may also have types here in C and Objective-C (as well as in C++).
     CCC_ParenthesizedExpression,
+    /// \brief Code completion where an Objective-C instance message is expcted.
+    CCC_ObjCInstanceMessage,
+    /// \brief Code completion where an Objective-C class message is expected. 
+    CCC_ObjCClassMessage,
+    /// \brief Code completion where a superclass of an Objective-C class is
+    /// expected.
+    CCC_ObjCSuperclass,
+    /// \brief Code completion where an Objective-C category name is expected.
+    CCC_ObjCCategoryName,
     /// \brief An unknown context, in which we are recovering from a parsing 
     /// error and don't know which completions we should give.
     CCC_Recovery
@@ -256,7 +279,8 @@
   
   /// \brief Construct a new code-completion context of the given kind.
   CodeCompletionContext(enum Kind Kind, QualType T) : Kind(Kind) { 
-    if (Kind == CCC_MemberAccess)
+    if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess ||
+        Kind == CCC_ObjCPropertyAccess)
       BaseType = T;
     else
       PreferredType = T;

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Thu Jul  7 11:03:39 2011
@@ -182,6 +182,10 @@
     // all types are available due to functional casts.
     if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND))
       Contexts |= (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
+    
+    // In Objective-C, you can only be a subclass of another Objective-C class
+    if (isa<ObjCInterfaceDecl>(ND))
+      Contexts |= (1 << (CodeCompletionContext::CCC_ObjCSuperclass - 1));
 
     // Deal with tag names.
     if (isa<EnumDecl>(ND)) {
@@ -208,6 +212,8 @@
              | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
   } else if (isa<ObjCProtocolDecl>(ND)) {
     Contexts = (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1));
+  } else if (isa<ObjCCategoryDecl>(ND)) {
+    Contexts = (1 << (CodeCompletionContext::CCC_ObjCCategoryName - 1));
   } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {
     Contexts = (1 << (CodeCompletionContext::CCC_Namespace - 1));
    
@@ -1902,7 +1908,7 @@
   /// results from an ASTUnit with the code-completion results provided to it,
   /// then passes the result on to 
   class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
-    unsigned NormalContexts;
+    unsigned long long NormalContexts;
     ASTUnit &AST;
     CodeCompleteConsumer &Next;
     
@@ -1916,22 +1922,24 @@
       // Compute the set of contexts in which we will look when we don't have
       // any information about the specific context.
       NormalContexts 
-        = (1 << (CodeCompletionContext::CCC_TopLevel - 1))
-        | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1))
-        | (1 << (CodeCompletionContext::CCC_ObjCImplementation - 1))
-        | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1))
-        | (1 << (CodeCompletionContext::CCC_Statement - 1))
-        | (1 << (CodeCompletionContext::CCC_Expression - 1))
-        | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
-        | (1 << (CodeCompletionContext::CCC_MemberAccess - 1))
-        | (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1))
-        | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1))
-        | (1 << (CodeCompletionContext::CCC_Recovery - 1));
+        = (1LL << (CodeCompletionContext::CCC_TopLevel - 1))
+        | (1LL << (CodeCompletionContext::CCC_ObjCInterface - 1))
+        | (1LL << (CodeCompletionContext::CCC_ObjCImplementation - 1))
+        | (1LL << (CodeCompletionContext::CCC_ObjCIvarList - 1))
+        | (1LL << (CodeCompletionContext::CCC_Statement - 1))
+        | (1LL << (CodeCompletionContext::CCC_Expression - 1))
+        | (1LL << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
+        | (1LL << (CodeCompletionContext::CCC_DotMemberAccess - 1))
+        | (1LL << (CodeCompletionContext::CCC_ArrowMemberAccess - 1))
+        | (1LL << (CodeCompletionContext::CCC_ObjCPropertyAccess - 1))
+        | (1LL << (CodeCompletionContext::CCC_ObjCProtocolName - 1))
+        | (1LL << (CodeCompletionContext::CCC_ParenthesizedExpression - 1))
+        | (1LL << (CodeCompletionContext::CCC_Recovery - 1));
 
       if (AST.getASTContext().getLangOptions().CPlusPlus)
-        NormalContexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1))
-                    | (1 << (CodeCompletionContext::CCC_UnionTag - 1))
-                    | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1));
+        NormalContexts |= (1LL << (CodeCompletionContext::CCC_EnumTag - 1))
+                   | (1LL << (CodeCompletionContext::CCC_UnionTag - 1))
+                   | (1LL << (CodeCompletionContext::CCC_ClassOrStructTag - 1));
     }
     
     virtual void ProcessCodeCompleteResults(Sema &S, 
@@ -1969,12 +1977,15 @@
   case CodeCompletionContext::CCC_Statement:
   case CodeCompletionContext::CCC_Expression:
   case CodeCompletionContext::CCC_ObjCMessageReceiver:
-  case CodeCompletionContext::CCC_MemberAccess:
+  case CodeCompletionContext::CCC_DotMemberAccess:
+  case CodeCompletionContext::CCC_ArrowMemberAccess:
+  case CodeCompletionContext::CCC_ObjCPropertyAccess:
   case CodeCompletionContext::CCC_Namespace:
   case CodeCompletionContext::CCC_Type:
   case CodeCompletionContext::CCC_Name:
   case CodeCompletionContext::CCC_PotentiallyQualifiedName:
   case CodeCompletionContext::CCC_ParenthesizedExpression:
+  case CodeCompletionContext::CCC_ObjCSuperclass:
     break;
     
   case CodeCompletionContext::CCC_EnumTag:
@@ -1993,6 +2004,9 @@
   case CodeCompletionContext::CCC_TypeQualifiers:
   case CodeCompletionContext::CCC_Other:
   case CodeCompletionContext::CCC_OtherWithMacros:
+  case CodeCompletionContext::CCC_ObjCInstanceMessage:
+  case CodeCompletionContext::CCC_ObjCClassMessage:
+  case CodeCompletionContext::CCC_ObjCCategoryName:
     // We're looking for nothing, or we're looking for names that cannot
     // be hidden.
     return;

Modified: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp Thu Jul  7 11:03:39 2011
@@ -46,7 +46,9 @@
   case CCC_ObjCImplementation:
   case CCC_ObjCIvarList:
   case CCC_ClassStructUnion:
-  case CCC_MemberAccess:
+  case CCC_DotMemberAccess:
+  case CCC_ArrowMemberAccess:
+  case CCC_ObjCPropertyAccess:
   case CCC_EnumTag:
   case CCC_UnionTag:
   case CCC_ClassOrStructTag:
@@ -64,6 +66,10 @@
   case CCC_TypeQualifiers:
   case CCC_Other:
   case CCC_OtherWithMacros:
+  case CCC_ObjCInstanceMessage:
+  case CCC_ObjCClassMessage:
+  case CCC_ObjCSuperclass:
+  case CCC_ObjCCategoryName:
     return false;
   }
   

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Jul  7 11:03:39 2011
@@ -3244,8 +3244,23 @@
       return;
   }
   
+  enum CodeCompletionContext::Kind contextKind;
+  
+  if (IsArrow) {
+    contextKind = CodeCompletionContext::CCC_ArrowMemberAccess;
+  }
+  else {
+    if (BaseType->isObjCObjectPointerType() ||
+        BaseType->isObjCObjectOrInterfaceType()) {
+      contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess;
+    }
+    else {
+      contextKind = CodeCompletionContext::CCC_DotMemberAccess;
+    }
+  }
+  
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
-                  CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
+                  CodeCompletionContext(contextKind,
                                         BaseType),
                         &ResultBuilder::IsMember);
   Results.EnterNewScope();
@@ -3471,10 +3486,17 @@
   }
   Results.ExitScope();
 
-  if (CodeCompleter->includeMacros())
+  //We need to make sure we're setting the right context, 
+  //so only say we include macros if the code completer says we do
+  enum CodeCompletionContext::Kind kind = CodeCompletionContext::CCC_Other;
+  if (CodeCompleter->includeMacros()) {
     AddMacroResults(PP, Results);
+    kind = CodeCompletionContext::CCC_OtherWithMacros;
+  }
+  
+  
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_OtherWithMacros,
+                            kind,
                             Results.data(),Results.size());
 }
 
@@ -4934,7 +4956,7 @@
                                         bool AtArgumentExpression,
                                         bool IsSuper) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
-                        CodeCompletionContext::CCC_Other);
+                        CodeCompletionContext::CCC_ObjCClassMessage);
   AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents, 
                              AtArgumentExpression, IsSuper, Results);
   
@@ -4954,7 +4976,7 @@
   }
 
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
+                            CodeCompletionContext::CCC_ObjCClassMessage,
                             Results.data(), Results.size());
 }
 
@@ -4997,7 +5019,7 @@
 
   // Build the set of methods we can see.
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
-                        CodeCompletionContext::CCC_Other);
+                        CodeCompletionContext::CCC_ObjCInstanceMessage);
   Results.EnterNewScope();
 
   // If this is a send-to-super, try to add the special "super" send 
@@ -5110,7 +5132,7 @@
   }
   
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
+                            CodeCompletionContext::CCC_ObjCInstanceMessage,
                             Results.data(),Results.size());
 }
 
@@ -5301,8 +5323,7 @@
                       false, Results);
 
   Results.ExitScope();
-  // FIXME: Add a special context for this, use cached global completion 
-  // results.
+  // FIXME: Use cached global completion results.
   HandleCodeCompleteResults(this, CodeCompleter,
                             CodeCompletionContext::CCC_Other,
                             Results.data(),Results.size());
@@ -5311,7 +5332,7 @@
 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
                                       SourceLocation ClassNameLoc) { 
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
-                        CodeCompletionContext::CCC_Other);
+                        CodeCompletionContext::CCC_ObjCSuperclass);
   Results.EnterNewScope();
   
   // Make sure that we ignore the class we're currently defining.
@@ -5325,10 +5346,9 @@
                       false, Results);
 
   Results.ExitScope();
-  // FIXME: Add a special context for this, use cached global completion 
-  // results.
+  // FIXME: Use cached global completion results.
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
+                            CodeCompletionContext::CCC_ObjCSuperclass,
                             Results.data(),Results.size());
 }
 
@@ -5342,8 +5362,7 @@
                       true, Results);
 
   Results.ExitScope();
-  // FIXME: Add a special context for this, use cached global completion 
-  // results.
+  // FIXME: Use cached global completion results.
   HandleCodeCompleteResults(this, CodeCompleter, 
                             CodeCompletionContext::CCC_Other,
                             Results.data(),Results.size());
@@ -5355,7 +5374,7 @@
   typedef CodeCompletionResult Result;
   
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
-                        CodeCompletionContext::CCC_Other);
+                        CodeCompletionContext::CCC_ObjCCategoryName);
   
   // Ignore any categories we find that have already been implemented by this
   // interface.
@@ -5379,7 +5398,7 @@
   Results.ExitScope();
   
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
+                            CodeCompletionContext::CCC_ObjCCategoryName,
                             Results.data(),Results.size());  
 }
 
@@ -5398,7 +5417,7 @@
     return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
     
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
-                        CodeCompletionContext::CCC_Other);
+                        CodeCompletionContext::CCC_ObjCCategoryName);
   
   // Add all of the categories that have have corresponding interface 
   // declarations in this class and any of its superclasses, except for
@@ -5419,7 +5438,7 @@
   Results.ExitScope();
   
   HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
+                            CodeCompletionContext::CCC_ObjCCategoryName,
                             Results.data(),Results.size());  
 }
 

Modified: cfe/trunk/test/Index/code-completion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/code-completion.cpp?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/test/Index/code-completion.cpp (original)
+++ cfe/trunk/test/Index/code-completion.cpp Thu Jul  7 11:03:39 2011
@@ -52,10 +52,21 @@
 // CHECK-MEMBER: CXXDestructor:{ResultType void}{Informative X::}{TypedText ~X}{LeftParen (}{RightParen )}
 // CHECK-MEMBER: CXXDestructor:{ResultType void}{Informative Y::}{TypedText ~Y}{LeftParen (}{RightParen )}
 // CHECK-MEMBER: CXXDestructor:{ResultType void}{TypedText ~Z}{LeftParen (}{RightParen )}
+// CHECK-MEMBER: Completion contexts:
+// CHECK-MEMBER-NEXT: Dot member access
 
 // CHECK-OVERLOAD: NotImplemented:{ResultType int &}{Text overloaded}{LeftParen (}{Text Z z}{Comma , }{CurrentParameter int second}{RightParen )}
 // CHECK-OVERLOAD: NotImplemented:{ResultType float &}{Text overloaded}{LeftParen (}{Text int i}{Comma , }{CurrentParameter long second}{RightParen )}
 // CHECK-OVERLOAD: NotImplemented:{ResultType double &}{Text overloaded}{LeftParen (}{Text float f}{Comma , }{CurrentParameter int second}{RightParen )}
+// CHECK-OVERLOAD: Completion contexts:
+// CHECK-OVERLOAD-NEXT: Any type
+// CHECK-OVERLOAD-NEXT: Any value
+// CHECK-OVERLOAD-NEXT: Enum tag
+// CHECK-OVERLOAD-NEXT: Union tag
+// CHECK-OVERLOAD-NEXT: Struct tag
+// CHECK-OVERLOAD-NEXT: Class name
+// CHECK-OVERLOAD-NEXT: Nested name specifier
+// CHECK-OVERLOAD-NEXT: Objective-C interface
 
 // RUN: c-index-test -code-completion-at=%s:37:10 %s | FileCheck -check-prefix=CHECK-EXPR %s
 // CHECK-EXPR: NotImplemented:{TypedText int} (50)
@@ -65,3 +76,12 @@
 // CHECK-EXPR: FieldDecl:{ResultType float}{Text Y::}{TypedText member} (18)
 // CHECK-EXPR: CXXMethod:{ResultType void}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )} (37)
 // CHECK-EXPR: Namespace:{TypedText N}{Text ::} (75)
+// CHECK-EXPR: Completion contexts:
+// CHECK-EXPR-NEXT: Any type
+// CHECK-EXPR-NEXT: Any value
+// CHECK-EXPR-NEXT: Enum tag
+// CHECK-EXPR-NEXT: Union tag
+// CHECK-EXPR-NEXT: Struct tag
+// CHECK-EXPR-NEXT: Class name
+// CHECK-EXPR-NEXT: Nested name specifier
+// CHECK-EXPR-NEXT: Objective-C interface

Modified: cfe/trunk/test/Index/complete-natural.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-natural.m?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-natural.m (original)
+++ cfe/trunk/test/Index/complete-natural.m Thu Jul  7 11:03:39 2011
@@ -11,8 +11,9 @@
 // RUN: c-index-test -code-completion-at=%s:4:32 %s > %t
 // RUN: echo "DONE" >> %t
 // RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t
-// CHECK-CC1-NOT: :
-// CHECK-CC1: DONE
+// CHECK-CC1: Completion contexts:
+// CHECK-CC1-NEXT: Natural language
+// CHECK-CC1-NEXT: DONE
 // RUN: c-index-test -code-completion-at=%s:5:18 %s > %t
 // RUN: echo "DONE" >> %t
 // RUN: FileCheck -check-prefix=CHECK-CC1 %s < %t

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Thu Jul  7 11:03:39 2011
@@ -1018,6 +1018,79 @@
   fprintf(file, "\n");
 }
 
+void print_completion_contexts(unsigned long long contexts, FILE *file) {
+  fprintf(file, "Completion contexts:\n");
+  if (contexts == CXCompletionContext_Unknown) {
+    fprintf(file, "Unknown\n");
+  }
+  if (contexts & CXCompletionContext_AnyType) {
+    fprintf(file, "Any type\n");
+  }
+  if (contexts & CXCompletionContext_AnyValue) {
+    fprintf(file, "Any value\n");
+  }
+  if (contexts & CXCompletionContext_ObjCObjectValue) {
+    fprintf(file, "Objective-C object value\n");
+  }
+  if (contexts & CXCompletionContext_ObjCSelectorValue) {
+    fprintf(file, "Objective-C selector value\n");
+  }
+  if (contexts & CXCompletionContext_CXXClassTypeValue) {
+    fprintf(file, "C++ class type value\n");
+  }
+  if (contexts & CXCompletionContext_DotMemberAccess) {
+    fprintf(file, "Dot member access\n");
+  }
+  if (contexts & CXCompletionContext_ArrowMemberAccess) {
+    fprintf(file, "Arrow member access\n");
+  }
+  if (contexts & CXCompletionContext_ObjCPropertyAccess) {
+    fprintf(file, "Objective-C property access\n");
+  }
+  if (contexts & CXCompletionContext_EnumTag) {
+    fprintf(file, "Enum tag\n");
+  }
+  if (contexts & CXCompletionContext_UnionTag) {
+    fprintf(file, "Union tag\n");
+  }
+  if (contexts & CXCompletionContext_StructTag) {
+    fprintf(file, "Struct tag\n");
+  }
+  if (contexts & CXCompletionContext_ClassTag) {
+    fprintf(file, "Class name\n");
+  }
+  if (contexts & CXCompletionContext_Namespace) {
+    fprintf(file, "Namespace or namespace alias\n");
+  }
+  if (contexts & CXCompletionContext_NestedNameSpecifier) {
+    fprintf(file, "Nested name specifier\n");
+  }
+  if (contexts & CXCompletionContext_ObjCInterface) {
+    fprintf(file, "Objective-C interface\n");
+  }
+  if (contexts & CXCompletionContext_ObjCProtocol) {
+    fprintf(file, "Objective-C protocol\n");
+  }
+  if (contexts & CXCompletionContext_ObjCCategory) {
+    fprintf(file, "Objective-C category\n");
+  }
+  if (contexts & CXCompletionContext_ObjCInstanceMessage) {
+    fprintf(file, "Objective-C instance method\n");
+  }
+  if (contexts & CXCompletionContext_ObjCClassMessage) {
+    fprintf(file, "Objective-C class method\n");
+  }
+  if (contexts & CXCompletionContext_ObjCSelectorName) {
+    fprintf(file, "Objective-C selector name\n");
+  }
+  if (contexts & CXCompletionContext_MacroName) {
+    fprintf(file, "Macro name\n");
+  }
+  if (contexts & CXCompletionContext_NaturalLanguage) {
+    fprintf(file, "Natural language\n");
+  }
+}
+
 int my_stricmp(const char *s1, const char *s2) {
   while (*s1 && *s2) {
     int c1 = tolower((unsigned char)*s1), c2 = tolower((unsigned char)*s2);
@@ -1099,6 +1172,7 @@
 
   if (results) {
     unsigned i, n = results->NumResults;
+    unsigned long long contexts;
     if (!timing_only) {      
       /* Sort the code-completion results based on the typed text. */
       clang_sortCodeCompletionResults(results->Results, results->NumResults);
@@ -1112,6 +1186,10 @@
       PrintDiagnostic(diag);
       clang_disposeDiagnostic(diag);
     }
+    
+    contexts = clang_codeCompleteGetContexts(results);
+    print_completion_contexts(contexts, stdout);
+    
     clang_disposeCodeCompleteResults(results);
   }
   clang_disposeTranslationUnit(TU);

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Thu Jul  7 11:03:39 2011
@@ -235,6 +235,13 @@
   
   /// \brief Allocator used to store code completion results.
   clang::CodeCompletionAllocator CodeCompletionAllocator;
+  
+  /// \brief Context under which completion occurred.
+  enum clang::CodeCompletionContext::Kind ContextKind;
+  
+  /// \brief A bitfield representing the acceptable completions for the
+  /// current context.
+  unsigned long long Contexts;
 };
 
 /// \brief Tracks the number of code-completion result objects that are 
@@ -273,6 +280,177 @@
   
 } // end extern "C"
 
+static unsigned long long getContextsForContextKind(
+                                          enum CodeCompletionContext::Kind kind, 
+                                                    Sema &S) {
+  unsigned long long contexts = 0;
+  switch (kind) {
+    case CodeCompletionContext::CCC_OtherWithMacros: {
+      //We can allow macros here, but we don't know what else is permissible
+      //So we'll say the only thing permissible are macros
+      contexts = CXCompletionContext_MacroName;
+      break;
+    }
+    case CodeCompletionContext::CCC_TopLevel:
+    case CodeCompletionContext::CCC_ObjCIvarList:
+    case CodeCompletionContext::CCC_ClassStructUnion:
+    case CodeCompletionContext::CCC_Type: {
+      contexts = CXCompletionContext_AnyType | 
+                 CXCompletionContext_ObjCInterface;
+      if (S.getLangOptions().CPlusPlus) {
+        contexts |= CXCompletionContext_EnumTag |
+                    CXCompletionContext_UnionTag |
+                    CXCompletionContext_StructTag |
+                    CXCompletionContext_ClassTag |
+                    CXCompletionContext_NestedNameSpecifier;
+      }
+      break;
+    }
+    case CodeCompletionContext::CCC_Statement: {
+      contexts = CXCompletionContext_AnyType |
+                 CXCompletionContext_ObjCInterface |
+                 CXCompletionContext_AnyValue;
+      if (S.getLangOptions().CPlusPlus) {
+        contexts |= CXCompletionContext_EnumTag |
+                    CXCompletionContext_UnionTag |
+                    CXCompletionContext_StructTag |
+                    CXCompletionContext_ClassTag |
+                    CXCompletionContext_NestedNameSpecifier;
+      }
+      break;
+    }
+    case CodeCompletionContext::CCC_Expression: {
+      contexts = CXCompletionContext_AnyValue;
+      if (S.getLangOptions().CPlusPlus) {
+        contexts |= CXCompletionContext_AnyType |
+                    CXCompletionContext_ObjCInterface |
+                    CXCompletionContext_EnumTag |
+                    CXCompletionContext_UnionTag |
+                    CXCompletionContext_StructTag |
+                    CXCompletionContext_ClassTag |
+                    CXCompletionContext_NestedNameSpecifier;
+      }
+      break;
+    }
+    case CodeCompletionContext::CCC_ObjCMessageReceiver: {
+      contexts = CXCompletionContext_ObjCObjectValue |
+                 CXCompletionContext_ObjCSelectorValue |
+                 CXCompletionContext_ObjCInterface;
+      if (S.getLangOptions().CPlusPlus) {
+        contexts |= CXCompletionContext_CXXClassTypeValue |
+                    CXCompletionContext_AnyType |
+                    CXCompletionContext_EnumTag |
+                    CXCompletionContext_UnionTag |
+                    CXCompletionContext_StructTag |
+                    CXCompletionContext_ClassTag |
+                    CXCompletionContext_NestedNameSpecifier;
+      }
+      break;
+    }
+    case CodeCompletionContext::CCC_DotMemberAccess: {
+      contexts = CXCompletionContext_DotMemberAccess;
+      break;
+    }
+    case CodeCompletionContext::CCC_ArrowMemberAccess: {
+      contexts = CXCompletionContext_ArrowMemberAccess;
+      break;
+    }
+    case CodeCompletionContext::CCC_ObjCPropertyAccess: {
+      contexts = CXCompletionContext_ObjCPropertyAccess;
+      break;
+    }
+    case CodeCompletionContext::CCC_EnumTag: {
+      contexts = CXCompletionContext_EnumTag |
+                 CXCompletionContext_NestedNameSpecifier;
+      break;
+    }
+    case CodeCompletionContext::CCC_UnionTag: {
+      contexts = CXCompletionContext_UnionTag |
+                 CXCompletionContext_NestedNameSpecifier;
+      break;
+    }
+    case CodeCompletionContext::CCC_ClassOrStructTag: {
+      contexts = CXCompletionContext_StructTag |
+                 CXCompletionContext_ClassTag |
+                 CXCompletionContext_NestedNameSpecifier;
+      break;
+    }
+    case CodeCompletionContext::CCC_ObjCProtocolName: {
+      contexts = CXCompletionContext_ObjCProtocol;
+      break;
+    }
+    case CodeCompletionContext::CCC_Namespace: {
+      contexts = CXCompletionContext_Namespace;
+      break;
+    }
+    case CodeCompletionContext::CCC_PotentiallyQualifiedName: {
+      contexts = CXCompletionContext_NestedNameSpecifier;
+      break;
+    }
+    case CodeCompletionContext::CCC_MacroNameUse: {
+      contexts = CXCompletionContext_MacroName;
+      break;
+    }
+    case CodeCompletionContext::CCC_NaturalLanguage: {
+      contexts = CXCompletionContext_NaturalLanguage;
+      break;
+    }
+    case CodeCompletionContext::CCC_SelectorName: {
+      contexts = CXCompletionContext_ObjCSelectorName;
+      break;
+    }
+    case CodeCompletionContext::CCC_ParenthesizedExpression: {
+      contexts = CXCompletionContext_AnyType |
+                 CXCompletionContext_ObjCInterface |
+                 CXCompletionContext_AnyValue;
+      if (S.getLangOptions().CPlusPlus) {
+        contexts |= CXCompletionContext_EnumTag |
+                    CXCompletionContext_UnionTag |
+                    CXCompletionContext_StructTag |
+                    CXCompletionContext_ClassTag |
+                    CXCompletionContext_NestedNameSpecifier;
+      }
+      break;
+    }
+    case CodeCompletionContext::CCC_ObjCInstanceMessage: {
+      contexts = CXCompletionContext_ObjCInstanceMessage;
+      break;
+    }
+    case CodeCompletionContext::CCC_ObjCClassMessage: {
+      contexts = CXCompletionContext_ObjCClassMessage;
+      break;
+    }
+    case CodeCompletionContext::CCC_ObjCSuperclass: {
+      contexts = CXCompletionContext_ObjCInterface;
+      break;
+    }
+    case CodeCompletionContext::CCC_ObjCCategoryName: {
+      contexts = CXCompletionContext_ObjCCategory;
+      break;
+    }
+    case CodeCompletionContext::CCC_Other:
+    case CodeCompletionContext::CCC_ObjCInterface:
+    case CodeCompletionContext::CCC_ObjCImplementation:
+    case CodeCompletionContext::CCC_Name:
+    case CodeCompletionContext::CCC_MacroName:
+    case CodeCompletionContext::CCC_PreprocessorExpression:
+    case CodeCompletionContext::CCC_PreprocessorDirective:
+    case CodeCompletionContext::CCC_TypeQualifiers: {
+      //Only Clang results should be accepted, so we'll set all of the other
+      //context bits to 0 (i.e. the empty set)
+      contexts = CXCompletionContext_Unexposed;
+      break;
+    }
+    case CodeCompletionContext::CCC_Recovery: {
+      //We don't know what the current context is, so we'll return unknown
+      //This is the equivalent of setting all of the other context bits
+      contexts = CXCompletionContext_Unknown;
+      break;
+    }
+  }
+  return contexts;
+}
+
 namespace {
   class CaptureCompletionResults : public CodeCompleteConsumer {
     AllocatedCXCodeCompleteResults &AllocatedResults;
@@ -298,6 +476,11 @@
         R.CompletionString = StoredCompletion;
         StoredResults.push_back(R);
       }
+      
+      enum CodeCompletionContext::Kind kind = Context.getKind();
+      
+      AllocatedResults.ContextKind = kind;
+      AllocatedResults.Contexts = getContextsForContextKind(kind, S);
     }
     
     virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
@@ -538,6 +721,15 @@
   return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
 }
 
+unsigned long long
+clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
+  AllocatedCXCodeCompleteResults *Results
+    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
+  if (!Results)
+    return 0;
+  
+  return Results->Contexts;
+}
 
 } // end extern "C"
 

Modified: cfe/trunk/tools/libclang/libclang.darwin.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.darwin.exports?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.darwin.exports (original)
+++ cfe/trunk/tools/libclang/libclang.darwin.exports Thu Jul  7 11:03:39 2011
@@ -6,6 +6,7 @@
 _clang_codeCompleteAt
 _clang_codeCompleteGetDiagnostic
 _clang_codeCompleteGetNumDiagnostics
+_clang_codeCompleteGetContexts
 _clang_constructUSR_ObjCCategory
 _clang_constructUSR_ObjCClass
 _clang_constructUSR_ObjCIvar

Modified: cfe/trunk/tools/libclang/libclang.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=134615&r1=134614&r2=134615&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.exports (original)
+++ cfe/trunk/tools/libclang/libclang.exports Thu Jul  7 11:03:39 2011
@@ -6,6 +6,7 @@
 clang_codeCompleteAt
 clang_codeCompleteGetDiagnostic
 clang_codeCompleteGetNumDiagnostics
+clang_codeCompleteGetContexts
 clang_constructUSR_ObjCCategory
 clang_constructUSR_ObjCClass
 clang_constructUSR_ObjCIvar





More information about the cfe-commits mailing list