diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h b/clang/include/clang/Sema/CodeCompleteConsumer.h index 00e76eadaf83..4f28fb2cca64 100644 --- a/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -146,7 +146,7 @@ class Sema; class CodeCompletionContext { public: enum Kind { - /// \brief An unspecified code-completion context, where the + /// \brief An unspecified code-completion context. CCC_Other, /// \brief Code completion occurred within a "top-level" completion context, /// e.g., at namespace or global scope. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 79362ce7107b..80b7952ad983 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4938,7 +4938,10 @@ public: PCC_Type, /// \brief Code completion occurs in a parenthesized expression, which /// might also be a type cast. - PCC_ParenthesizedExpression + PCC_ParenthesizedExpression, + /// \brief Code completion occurs within a sequence of declaration + /// specifiers within a function, method, or block. + PCC_LocalDeclarationSpecifiers }; void CodeCompleteOrdinaryName(Scope *S, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index b81503193983..bff4e184c2ae 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -920,7 +920,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, return; } - if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) + if (getCurScope()->getFnParent() || getCurScope()->getBlockParent()) + CCC = Sema::PCC_LocalDeclarationSpecifiers; + else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate : Sema::PCC_Template; else if (DSContext == DSC_class) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index cf088007c880..e7a9a8d83865 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1286,6 +1286,7 @@ static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC, case Sema::PCC_RecoveryInFunction: case Sema::PCC_Type: case Sema::PCC_ParenthesizedExpression: + case Sema::PCC_LocalDeclarationSpecifiers: break; } } @@ -1325,6 +1326,7 @@ static bool WantTypesInContext(Sema::ParserCompletionContext CCC, case Sema::PCC_RecoveryInFunction: case Sema::PCC_Type: case Sema::PCC_ParenthesizedExpression: + case Sema::PCC_LocalDeclarationSpecifiers: return true; case Sema::PCC_Expression: @@ -1768,6 +1770,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, } case Sema::PCC_Type: + case Sema::PCC_LocalDeclarationSpecifiers: break; } @@ -2719,6 +2722,9 @@ static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S, case Sema::PCC_ParenthesizedExpression: return CodeCompletionContext::CCC_ParenthesizedExpression; + + case Sema::PCC_LocalDeclarationSpecifiers: + return CodeCompletionContext::CCC_Type; } return CodeCompletionContext::CCC_Other; @@ -2818,6 +2824,7 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, case PCC_Template: case PCC_MemberTemplate: case PCC_Type: + case PCC_LocalDeclarationSpecifiers: Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName); break; @@ -2873,6 +2880,7 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, case PCC_ForInit: case PCC_Condition: case PCC_Type: + case PCC_LocalDeclarationSpecifiers: break; } diff --git a/clang/test/Index/complete-declarators.m b/clang/test/Index/complete-declarators.m index bff5afd0f43c..747da018af50 100644 --- a/clang/test/Index/complete-declarators.m +++ b/clang/test/Index/complete-declarators.m @@ -19,6 +19,8 @@ for(q in param1) { int y; } + + static P *p = 0; } @end @@ -43,3 +45,28 @@ // CHECK-CC4-NOT: VarDecl:{ResultType int}{TypedText q2} // CHECK-CC4: NotImplemented:{ResultType A *}{TypedText self} (34) // CHECK-CC4: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (40) +// RUN: c-index-test -code-completion-at=%s:23:10 %s | FileCheck -check-prefix=CHECK-CC5 %s +// CHECK-CC5: NotImplemented:{TypedText _Bool} (50) +// CHECK-CC5: NotImplemented:{TypedText _Complex} (50) +// CHECK-CC5: NotImplemented:{TypedText _Imaginary} (50) +// CHECK-CC5: ObjCInterfaceDecl:{TypedText A} (50) +// CHECK-CC5: NotImplemented:{TypedText char} (50) +// CHECK-CC5: TypedefDecl:{TypedText Class} (50) +// CHECK-CC5: NotImplemented:{TypedText const} (50) +// CHECK-CC5: NotImplemented:{TypedText double} (50) +// CHECK-CC5: NotImplemented:{TypedText enum} (50) +// CHECK-CC5: NotImplemented:{TypedText float} (50) +// CHECK-CC5: TypedefDecl:{TypedText id} (50) +// CHECK-CC5: NotImplemented:{TypedText int} (50) +// CHECK-CC5: NotImplemented:{TypedText long} (50) +// CHECK-CC5: NotImplemented:{TypedText restrict} (50) +// CHECK-CC5: TypedefDecl:{TypedText SEL} (50) +// CHECK-CC5: NotImplemented:{TypedText short} (50) +// CHECK-CC5: NotImplemented:{TypedText signed} (50) +// CHECK-CC5: NotImplemented:{TypedText struct} (50) +// CHECK-CC5: NotImplemented:{TypedText typeof}{HorizontalSpace }{Placeholder expression} (40) +// CHECK-CC5: NotImplemented:{TypedText typeof}{LeftParen (}{Placeholder type}{RightParen )} (40) +// CHECK-CC5: NotImplemented:{TypedText union} (50) +// CHECK-CC5: NotImplemented:{TypedText unsigned} (50) +// CHECK-CC5: NotImplemented:{TypedText void} (50) +// CHECK-CC5: NotImplemented:{TypedText volatile} (50)