aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorSam McCall <sam.mccall@gmail.com>2021-03-12 12:00:54 +0100
committerSam McCall <sam.mccall@gmail.com>2021-03-16 12:46:40 +0100
commit128ce70eef9948b81e725fd0e2ed46a7c004a118 (patch)
tree104b05fe8ae20199118acf43ad5188798d0220e8 /clang/lib/Parse/ParseDecl.cpp
parent5ac3b37599d3da80887033df66ecea4aea4dc347 (diff)
downloadllvm-128ce70eef9948b81e725fd0e2ed46a7c004a118.zip
llvm-128ce70eef9948b81e725fd0e2ed46a7c004a118.tar.gz
llvm-128ce70eef9948b81e725fd0e2ed46a7c004a118.tar.bz2
[CodeCompletion] Avoid spurious signature help for init-list args
Somewhat surprisingly, signature help is emitted as a side-effect of computing the expected type of a function argument. The reason is that both actions require enumerating the possible function signatures and running partial overload resolution, and doing this twice would be wasteful and complicated. Change #1: document this, it's subtle :-) However, sometimes we need to compute the expected type without having reached the code completion cursor yet - in particular to allow completion of designators. eb4ab3358cd4dc834a761191b5531b38114f7b13 did this but introduced a regression - it emits signature help in the wrong location as a side-effect. Change #2: only emit signature help if the code completion cursor was reached. Currently there is PP.isCodeCompletionReached(), but we can't use it because it's set *after* running code completion. It'd be nice to set this implicitly when the completion token is lexed, but ConsumeCodeCompletionToken() makes this complicated. Change #3: call cutOffParsing() *first* when seeing a completion token. After this, the fact that the Sema::Produce*SignatureHelp() functions are even more confusing, as they only sometimes do that. I don't want to rename them in this patch as it's another large mechanical change, but we should soon. Change #4: prepare to rename ProduceSignatureHelp() to GuessArgumentType() etc. Differential Revision: https://reviews.llvm.org/D98488
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp19
1 files changed, 12 insertions, 7 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 9edf4d3..a044fbc 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1970,8 +1970,8 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// Check to see if we have a function *definition* which must have a body.
if (D.isFunctionDeclarator()) {
if (Tok.is(tok::equal) && NextToken().is(tok::code_completion)) {
- Actions.CodeCompleteAfterFunctionEquals(D);
cutOffParsing();
+ Actions.CodeCompleteAfterFunctionEquals(D);
return nullptr;
}
// Look at the next token to make sure that this isn't a function
@@ -2310,9 +2310,9 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
InitializerScopeRAII InitScope(*this, D, ThisDecl);
if (Tok.is(tok::code_completion)) {
+ cutOffParsing();
Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
Actions.FinalizeDeclaration(ThisDecl);
- cutOffParsing();
return nullptr;
}
@@ -3090,10 +3090,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
= DSContext == DeclSpecContext::DSC_top_level ||
(DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified());
+ cutOffParsing();
Actions.CodeCompleteDeclSpec(getCurScope(), DS,
AllowNonIdentifiers,
AllowNestedNameSpecifiers);
- return cutOffParsing();
+ return;
}
if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
@@ -3106,8 +3107,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
else if (CurParsedObjCImpl)
CCC = Sema::PCC_ObjCImplementation;
+ cutOffParsing();
Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
- return cutOffParsing();
+ return;
}
case tok::coloncolon: // ::foo::bar
@@ -4362,8 +4364,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// Parse the tag portion of this.
if (Tok.is(tok::code_completion)) {
// Code completion for an enum name.
+ cutOffParsing();
Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
- return cutOffParsing();
+ return;
}
// If attributes exist after tag, parse them.
@@ -5457,11 +5460,12 @@ void Parser::ParseTypeQualifierListOpt(
switch (Tok.getKind()) {
case tok::code_completion:
+ cutOffParsing();
if (CodeCompletionHandler)
(*CodeCompletionHandler)();
else
Actions.CodeCompleteTypeQualifiers(DS);
- return cutOffParsing();
+ return;
case tok::kw_const:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
@@ -6998,8 +7002,9 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
std::move(attrs), T.getCloseLocation());
return;
} else if (Tok.getKind() == tok::code_completion) {
+ cutOffParsing();
Actions.CodeCompleteBracketDeclarator(getCurScope());
- return cutOffParsing();
+ return;
}
// If valid, this location is the position where we read the 'static' keyword.