forked from OSchip/llvm-project
[clang] Make sure codecompletion is called for calls even when inside a token.
Summary: Currently CodeCompleteCall only gets called after a comma or parantheses. This patch makes sure it is called even at the cases like: ```foo(1^);``` Reviewers: ilya-biryukov, ioeric, hokein Reviewed By: ilya-biryukov Subscribers: MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D51038 llvm-svn: 341824
This commit is contained in:
parent
cc08366035
commit
a32d253f10
clang
include/clang/Parse
lib
test
|
@ -214,6 +214,11 @@ class Parser : public CodeCompletionHandler {
|
|||
/// should not be set directly.
|
||||
bool InMessageExpression;
|
||||
|
||||
/// Gets set to true after calling ProduceSignatureHelp, it is for a
|
||||
/// workaround to make sure ProduceSignatureHelp is only called at the deepest
|
||||
/// function call.
|
||||
bool CalledSignatureHelp = false;
|
||||
|
||||
/// The "depth" of the template parameters currently being parsed.
|
||||
unsigned TemplateParameterDepth;
|
||||
|
||||
|
|
|
@ -2305,6 +2305,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
|
|||
QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(),
|
||||
ThisDecl->getLocation(), Exprs, T.getOpenLocation());
|
||||
CalledSignatureHelp = true;
|
||||
Actions.CodeCompleteExpression(getCurScope(), PreferredType);
|
||||
};
|
||||
if (ThisVarDecl) {
|
||||
|
@ -2317,6 +2318,12 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
|
|||
}
|
||||
|
||||
if (ParseExpressionList(Exprs, CommaLocs, ExprListCompleter)) {
|
||||
if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
|
||||
Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(),
|
||||
ThisDecl->getLocation(), Exprs, T.getOpenLocation());
|
||||
CalledSignatureHelp = true;
|
||||
}
|
||||
Actions.ActOnInitializerError(ThisDecl);
|
||||
SkipUntil(tok::r_paren, StopAtSemi);
|
||||
} else {
|
||||
|
|
|
@ -1652,6 +1652,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
|||
if (Tok.is(tok::code_completion)) {
|
||||
QualType PreferredType = Actions.ProduceCallSignatureHelp(
|
||||
getCurScope(), LHS.get(), None, PT.getOpenLocation());
|
||||
CalledSignatureHelp = true;
|
||||
Actions.CodeCompleteExpression(getCurScope(), PreferredType);
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
|
@ -1662,9 +1663,19 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
|||
if (ParseExpressionList(ArgExprs, CommaLocs, [&] {
|
||||
QualType PreferredType = Actions.ProduceCallSignatureHelp(
|
||||
getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation());
|
||||
CalledSignatureHelp = true;
|
||||
Actions.CodeCompleteExpression(getCurScope(), PreferredType);
|
||||
})) {
|
||||
(void)Actions.CorrectDelayedTyposInExpr(LHS);
|
||||
// If we got an error when parsing expression list, we don't call
|
||||
// the CodeCompleteCall handler inside the parser. So call it here
|
||||
// to make sure we get overload suggestions even when we are in the
|
||||
// middle of a parameter.
|
||||
if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
|
||||
Actions.ProduceCallSignatureHelp(getCurScope(), LHS.get(),
|
||||
ArgExprs, PT.getOpenLocation());
|
||||
CalledSignatureHelp = true;
|
||||
}
|
||||
LHS = ExprError();
|
||||
} else if (LHS.isInvalid()) {
|
||||
for (auto &E : ArgExprs)
|
||||
|
|
|
@ -1688,8 +1688,15 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
|
|||
QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
|
||||
DS.getEndLoc(), Exprs, T.getOpenLocation());
|
||||
CalledSignatureHelp = true;
|
||||
Actions.CodeCompleteExpression(getCurScope(), PreferredType);
|
||||
})) {
|
||||
if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
|
||||
Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
|
||||
DS.getEndLoc(), Exprs, T.getOpenLocation());
|
||||
CalledSignatureHelp = true;
|
||||
}
|
||||
SkipUntil(tok::r_paren, StopAtSemi);
|
||||
return ExprError();
|
||||
}
|
||||
|
@ -2818,13 +2825,22 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
|
|||
if (Tok.isNot(tok::r_paren)) {
|
||||
CommaLocsTy CommaLocs;
|
||||
if (ParseExpressionList(ConstructorArgs, CommaLocs, [&] {
|
||||
ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(),
|
||||
DeclaratorInfo).get();
|
||||
ParsedType TypeRep =
|
||||
Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
|
||||
QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
|
||||
DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen);
|
||||
CalledSignatureHelp = true;
|
||||
Actions.CodeCompleteExpression(getCurScope(), PreferredType);
|
||||
})) {
|
||||
})) {
|
||||
if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
|
||||
ParsedType TypeRep =
|
||||
Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
|
||||
Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
|
||||
DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen);
|
||||
CalledSignatureHelp = true;
|
||||
}
|
||||
SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
|
||||
return ExprError();
|
||||
}
|
||||
|
|
|
@ -422,8 +422,15 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
|
|||
getCurScope(),
|
||||
OmpPrivParm->getType()->getCanonicalTypeInternal(),
|
||||
OmpPrivParm->getLocation(), Exprs, LParLoc);
|
||||
CalledSignatureHelp = true;
|
||||
Actions.CodeCompleteExpression(getCurScope(), PreferredType);
|
||||
})) {
|
||||
if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
|
||||
Actions.ProduceConstructorSignatureHelp(
|
||||
getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
|
||||
OmpPrivParm->getLocation(), Exprs, LParLoc);
|
||||
CalledSignatureHelp = true;
|
||||
}
|
||||
Actions.ActOnInitializerError(OmpPrivParm);
|
||||
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
} else {
|
||||
|
|
|
@ -619,6 +619,10 @@ static std::string getOverloadAsString(const CodeCompletionString &CCS) {
|
|||
OS << "<#" << C.Text << "#>";
|
||||
break;
|
||||
|
||||
// FIXME: We can also print optional parameters of an overload.
|
||||
case CodeCompletionString::CK_Optional:
|
||||
break;
|
||||
|
||||
default: OS << C.Text; break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
int f(int i, int j = 2, int k = 5);
|
||||
int f(float x, float y...);
|
||||
|
||||
class A {
|
||||
public:
|
||||
A(int, int, int);
|
||||
};
|
||||
|
||||
void test() {
|
||||
A a(f(1, 2, 3, 4), 2, 3);
|
||||
}
|
||||
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:10 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:17 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:19 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:20 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:21 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
|
||||
// CHECK-CC1: OVERLOAD: [#int#]f(<#float x#>, float y)
|
||||
// CHECK-CC1: OVERLOAD: [#int#]f(<#int i#>)
|
||||
// CHECK-CC1-NOT, CHECK-CC2-NOT: OVERLOAD: A(
|
||||
// CHECK-CC2: OVERLOAD: [#int#]f(float x, float y)
|
||||
// CHECK-CC2-NOT: OVERLOAD: [#int#]f(int i)
|
||||
// CHECK-CC3: OVERLOAD: A(<#int#>, int, int)
|
||||
// CHECK-CC3: OVERLOAD: A(<#const A &#>)
|
||||
// CHECK-CC3: OVERLOAD: A(<#A &&#>)
|
||||
// CHECK-CC4: OVERLOAD: A(int, <#int#>, int)
|
|
@ -60,7 +60,6 @@ typedef void (^FooBlock)(Foo *someParameter);
|
|||
// RUN: c-index-test -code-completion-at=%s:51:16 %s | FileCheck -check-prefix=CHECK-NO %s
|
||||
// RUN: c-index-test -code-completion-at=%s:52:23 %s | FileCheck -check-prefix=CHECK-NO %s
|
||||
// RUN: c-index-test -code-completion-at=%s:53:12 %s | FileCheck -check-prefix=CHECK-NO %s
|
||||
// RUN: c-index-test -code-completion-at=%s:54:15 %s | FileCheck -check-prefix=CHECK-NO %s
|
||||
// RUN: c-index-test -code-completion-at=%s:56:15 %s | FileCheck -check-prefix=CHECK-NO %s
|
||||
// CHECK-NO: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35)
|
||||
// CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35)
|
||||
|
@ -69,4 +68,12 @@ typedef void (^FooBlock)(Foo *someParameter);
|
|||
// CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText onReadonly} (35)
|
||||
// CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent} (35)
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:54:15 %s | FileCheck -check-prefix=CHECK-NO1 %s
|
||||
// CHECK-NO1: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35)
|
||||
// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35)
|
||||
// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (35)
|
||||
// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler} (35)
|
||||
// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText onReadonly} (35)
|
||||
// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent} (35)
|
||||
// CHECK-NO1-NEXT: OverloadCandidate:{ResultType void}{Text func}{LeftParen (}{CurrentParameter int x}{RightParen )} (1)
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue