diff options
-rw-r--r-- | include/clang/Sema/CodeCompleteConsumer.h | 5 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 5 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 17 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 19 | ||||
-rw-r--r-- | test/Index/complete-exprs.c | 16 |
6 files changed, 57 insertions, 13 deletions
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index 6c1ecbf2cc..452a184250 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -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: diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index cd3aa7dce6..abdd083779 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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, diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index c203ffa935..926e017f16 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -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: diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 1c2b343141..4ee924543a 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -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)); diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 135c59365b..7dc2cb3609 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -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: diff --git a/test/Index/complete-exprs.c b/test/Index/complete-exprs.c index fd84d1c0e3..c2b373f3a4 100644 --- a/test/Index/complete-exprs.c +++ b/test/Index/complete-exprs.c @@ -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} |