]> granicus.if.org Git - clang/commitdiff
Introduce a new code-completion context for a parenthesized
authorDouglas Gregor <dgregor@apple.com>
Tue, 14 Sep 2010 23:59:36 +0000 (23:59 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 14 Sep 2010 23:59:36 +0000 (23:59 +0000)
expression, e.g., after the '(' that could also be a type cast. Here,
we provide types as code-completion results in C/Objective-C (C++
already had them), although we wouldn't in a normal expression context.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113904 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/CodeCompleteConsumer.h
include/clang/Sema/Sema.h
lib/Frontend/ASTUnit.cpp
lib/Parse/ParseExpr.cpp
lib/Sema/SemaCodeComplete.cpp
test/Index/complete-exprs.c

index 6c1ecbf2cc294573f556839c095daa8cedbeaca0..452a18425061e46db30d981c27408cf430c61da3 100644 (file)
@@ -212,7 +212,10 @@ public:
     /// \brief Code completion for a selector, as in an @selector expression.
     CCC_SelectorName,
     /// \brief Code completion within a type-qualifier list.
-    CCC_TypeQualifiers
+    CCC_TypeQualifiers,
+    /// \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
   };
 
 private:
index cd3aa7dce64b4a0706e6e9479ca7a24340e440ec..abdd083779f157af901328539a378346f3be3432 100644 (file)
@@ -4295,7 +4295,10 @@ public:
     /// in the grammar.
     PCC_RecoveryInFunction,
     /// \brief Code completion occurs where only a type is permitted.
-    PCC_Type
+    PCC_Type,
+    /// \brief Code completion occurs in a parenthesized expression, which
+    /// might also be a type cast.
+    PCC_ParenthesizedExpression
   };
 
   void CodeCompleteOrdinaryName(Scope *S,
index c203ffa9352333c4d355ddd2a90f3573cc9ce6d1..926e017f16813cbad9628ba1d5db800a1486ca71 100644 (file)
@@ -115,7 +115,8 @@ static unsigned getDeclShowContexts(NamedDecl *ND,
                 | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1))
                 | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1))
                 | (1 << (CodeCompletionContext::CCC_Statement - 1))
-                | (1 << (CodeCompletionContext::CCC_Type - 1));
+                | (1 << (CodeCompletionContext::CCC_Type - 1))
+              | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1));
 
     // In C++, types can appear in expressions contexts (for functional casts).
     if (LangOpts.CPlusPlus)
@@ -147,6 +148,7 @@ static unsigned getDeclShowContexts(NamedDecl *ND,
     // Values can appear in these contexts.
     Contexts = (1 << (CodeCompletionContext::CCC_Statement - 1))
              | (1 << (CodeCompletionContext::CCC_Expression - 1))
+             | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1))
              | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
   } else if (isa<ObjCProtocolDecl>(ND)) {
     Contexts = (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1));
@@ -237,7 +239,8 @@ void ASTUnit::CacheCodeCompletionResults() {
           | (1 << (CodeCompletionContext::CCC_UnionTag - 1))
           | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1))
           | (1 << (CodeCompletionContext::CCC_Type - 1))
-          | (1 << (CodeCompletionContext::CCC_PotentiallyQualifiedName - 1));
+          | (1 << (CodeCompletionContext::CCC_PotentiallyQualifiedName - 1))
+          | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1));
 
         if (isa<NamespaceDecl>(Results[I].Declaration) ||
             isa<NamespaceAliasDecl>(Results[I].Declaration))
@@ -279,7 +282,9 @@ void ASTUnit::CacheCodeCompletionResults() {
         | (1 << (CodeCompletionContext::CCC_Expression - 1))
         | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
         | (1 << (CodeCompletionContext::CCC_MacroNameUse - 1))
-        | (1 << (CodeCompletionContext::CCC_PreprocessorExpression - 1));
+        | (1 << (CodeCompletionContext::CCC_PreprocessorExpression - 1))
+        | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1));
+
       
       CachedResult.Priority = Results[I].Priority;
       CachedResult.Kind = Results[I].CursorKind;
@@ -1517,8 +1522,9 @@ namespace {
         | (1 << (CodeCompletionContext::CCC_Expression - 1))
         | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
         | (1 << (CodeCompletionContext::CCC_MemberAccess - 1))
-        | (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1));
-      
+        | (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1))
+        | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1));
+
       if (AST.getASTContext().getLangOptions().CPlusPlus)
         NormalContexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1))
                     | (1 << (CodeCompletionContext::CCC_UnionTag - 1))
@@ -1561,6 +1567,7 @@ void CalculateHiddenNames(const CodeCompletionContext &Context,
   case CodeCompletionContext::CCC_Type:
   case CodeCompletionContext::CCC_Name:
   case CodeCompletionContext::CCC_PotentiallyQualifiedName:
+  case CodeCompletionContext::CCC_ParenthesizedExpression:
     break;
     
   case CodeCompletionContext::CCC_EnumTag:
index 1c2b343141df6b9fbb4b07b7876e54a15eb15786..4ee924543a666d8f5434a668b2c5dae2f1065477 100644 (file)
@@ -1452,6 +1452,14 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
   bool isAmbiguousTypeId;
   CastTy = ParsedType();
 
+  if (Tok.is(tok::code_completion)) {
+    Actions.CodeCompleteOrdinaryName(getCurScope(), 
+                 ExprType >= CompoundLiteral? Sema::PCC_ParenthesizedExpression
+                                            : Sema::PCC_Expression);
+    ConsumeCodeCompletionToken();
+    return ExprError();
+  }
+  
   if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
     Diag(Tok, diag::ext_gnu_statement_expr);
     StmtResult Stmt(ParseCompoundStatement(0, true));
index 135c59365b79d07e75f2eb74117d0da4b07b8155..7dc2cb3609d1c24b28161a21d6096cd2c15f516e 100644 (file)
@@ -1176,6 +1176,7 @@ static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
   case Sema::PCC_Condition:
   case Sema::PCC_RecoveryInFunction:
   case Sema::PCC_Type:
+  case Sema::PCC_ParenthesizedExpression:
     break;
   }
 }
@@ -1205,9 +1206,6 @@ static void AddTypedefResult(ResultBuilder &Results) {
 
 static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
                                const LangOptions &LangOpts) {
-  if (LangOpts.CPlusPlus)
-    return true;
-  
   switch (CCC) {
   case Sema::PCC_Namespace:
   case Sema::PCC_Class:
@@ -1217,16 +1215,19 @@ static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
   case Sema::PCC_Statement:
   case Sema::PCC_RecoveryInFunction:
   case Sema::PCC_Type:
+  case Sema::PCC_ParenthesizedExpression:
     return true;
     
-  case Sema::PCC_ObjCInterface:
-  case Sema::PCC_ObjCImplementation:
   case Sema::PCC_Expression:
   case Sema::PCC_Condition:
+    return LangOpts.CPlusPlus;
+      
+  case Sema::PCC_ObjCInterface:
+  case Sema::PCC_ObjCImplementation:
     return false;
     
   case Sema::PCC_ForInit:
-    return LangOpts.ObjC1 || LangOpts.C99;
+    return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
   }
   
   return false;
@@ -1556,6 +1557,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
     AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     // Fall through: conditions and statements can have expressions.
 
+  case Sema::PCC_ParenthesizedExpression:
   case Sema::PCC_Expression: {
     CodeCompletionString *Pattern = 0;
     if (SemaRef.getLangOptions().CPlusPlus) {
@@ -2453,6 +2455,9 @@ static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
 
   case Sema::PCC_Type:
     return CodeCompletionContext::CCC_Type;
+
+  case Sema::PCC_ParenthesizedExpression:
+    return CodeCompletionContext::CCC_ParenthesizedExpression;
   }
   
   return CodeCompletionContext::CCC_Other;
@@ -2559,6 +2564,7 @@ void Sema::CodeCompleteOrdinaryName(Scope *S,
     Results.setPreferredType(Context.VoidTy);
     // Fall through
       
+  case PCC_ParenthesizedExpression:
   case PCC_Expression:
   case PCC_ForInit:
   case PCC_Condition:
@@ -2591,6 +2597,7 @@ void Sema::CodeCompleteOrdinaryName(Scope *S,
   Results.ExitScope();
 
   switch (CompletionContext) {
+  case PCC_ParenthesizedExpression:
   case PCC_Expression:
   case PCC_Statement:
   case PCC_RecoveryInFunction:
index fd84d1c0e3947f8909fe26a69bbbf208d4b7c11f..c2b373f3a488bebf0af6ed02faff434a23109050 100644 (file)
@@ -18,6 +18,12 @@ void f3(const char*, ...) __attribute__((sentinel(0)));
 void f4(const char* str) {
   f3(str, NULL);
 }
+
+typedef int type;
+void f5(float f) {
+  (type)f;
+}
+
 // RUN: c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
 // RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: NotImplemented:{TypedText __PRETTY_FUNCTION__} (60)
@@ -51,3 +57,13 @@ void f4(const char* str) {
 // CHECK-CC6: FunctionDecl:{ResultType void}{TypedText f3}{LeftParen (}{Placeholder const char *, ...}{Text , NULL}{RightParen )} (45)
 // CHECK-CC6: NotImplemented:{TypedText void} (65)
 // CHECK-CC6: NotImplemented:{TypedText volatile} (65)
+
+// RUN: c-index-test -code-completion-at=%s:24:4 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC7 %s
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:24:4 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC7 %s
+// CHECK-CC7: ParmDecl:{ResultType float}{TypedText f} (8)
+// CHECK-CC7: VarDecl:{ResultType struct X}{TypedText f1} (50) (deprecated)
+// CHECK-CC7: FunctionDecl:{ResultType void}{TypedText f2}{LeftParen (}{RightParen )} (50)
+// CHECK-CC7: FunctionDecl:{ResultType void}{TypedText f3}{LeftParen (}{Placeholder const char *, ...}{Text , NULL}{RightParen )} (50)
+// CHECK-CC7: FunctionDecl:{ResultType void}{TypedText f4}{LeftParen (}{Placeholder const char *str}{RightParen )} (50)
+// CHECK-CC7: FunctionDecl:{ResultType void}{TypedText f5}{LeftParen (}{Placeholder float f}{RightParen )} (50)
+// CHECK-CC7: TypedefDecl:{TypedText type}