forked from OSchip/llvm-project
[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.
eb4ab3358c
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
This commit is contained in:
parent
5ac3b37599
commit
128ce70eef
|
@ -1253,6 +1253,19 @@ TEST(SignatureHelpTest, Overloads) {
|
|||
EXPECT_EQ(0, Results.activeParameter);
|
||||
}
|
||||
|
||||
TEST(SignatureHelpTest, OverloadInitListRegression) {
|
||||
auto Results = signatures(R"cpp(
|
||||
struct A {int x;};
|
||||
struct B {B(A);};
|
||||
void f();
|
||||
int main() {
|
||||
B b({1});
|
||||
f(^);
|
||||
}
|
||||
)cpp");
|
||||
EXPECT_THAT(Results.signatures, UnorderedElementsAre(Sig("f() -> void")));
|
||||
}
|
||||
|
||||
TEST(SignatureHelpTest, DefaultArgs) {
|
||||
auto Results = signatures(R"cpp(
|
||||
void bar(int x, int y = 0);
|
||||
|
|
|
@ -306,6 +306,9 @@ public:
|
|||
/// Clients should be very careful when using this funciton, as it stores a
|
||||
/// function_ref, clients should make sure all calls to get() with the same
|
||||
/// location happen while function_ref is alive.
|
||||
///
|
||||
/// The callback should also emit signature help as a side-effect, but only
|
||||
/// if the completion point has been reached.
|
||||
void enterFunctionArgument(SourceLocation Tok,
|
||||
llvm::function_ref<QualType()> ComputeType);
|
||||
|
||||
|
@ -318,6 +321,12 @@ public:
|
|||
/// Handles all type casts, including C-style cast, C++ casts, etc.
|
||||
void enterTypeCast(SourceLocation Tok, QualType CastType);
|
||||
|
||||
/// Get the expected type associated with this location, if any.
|
||||
///
|
||||
/// If the location is a function argument, determining the expected type
|
||||
/// involves considering all function overloads and the arguments so far.
|
||||
/// In this case, signature help for these function overloads will be reported
|
||||
/// as a side-effect (only if the completion point has been reached).
|
||||
QualType get(SourceLocation Tok) const {
|
||||
if (!Enabled || Tok != ExpectedLoc)
|
||||
return QualType();
|
||||
|
@ -12216,8 +12225,14 @@ public:
|
|||
const VirtSpecifiers *VS = nullptr);
|
||||
void CodeCompleteBracketDeclarator(Scope *S);
|
||||
void CodeCompleteCase(Scope *S);
|
||||
/// Reports signatures for a call to CodeCompleteConsumer and returns the
|
||||
/// preferred type for the current argument. Returned type can be null.
|
||||
/// Determines the preferred type of the current function argument, by
|
||||
/// examining the signatures of all possible overloads.
|
||||
/// Returns null if unknown or ambiguous, or if code completion is off.
|
||||
///
|
||||
/// If the code completion point has been reached, also reports the function
|
||||
/// signatures that were considered.
|
||||
///
|
||||
/// FIXME: rename to GuessCallArgumentType to reduce confusion.
|
||||
QualType ProduceCallSignatureHelp(Scope *S, Expr *Fn, ArrayRef<Expr *> Args,
|
||||
SourceLocation OpenParLoc);
|
||||
QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type,
|
||||
|
|
|
@ -441,9 +441,9 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
|
|||
CurLexer->Lex(Tok);
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
setCodeCompletionReached();
|
||||
if (CodeComplete)
|
||||
CodeComplete->CodeCompleteInConditionalExclusion();
|
||||
setCodeCompletionReached();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -966,10 +966,10 @@ void Preprocessor::HandleDirective(Token &Result) {
|
|||
case tok::eod:
|
||||
return; // null directive.
|
||||
case tok::code_completion:
|
||||
setCodeCompletionReached();
|
||||
if (CodeComplete)
|
||||
CodeComplete->CodeCompleteDirective(
|
||||
CurPPLexer->getConditionalStackDepth() > 0);
|
||||
setCodeCompletionReached();
|
||||
return;
|
||||
case tok::numeric_constant: // # 7 GNU line marker directive.
|
||||
if (getLangOpts().AsmPreprocessor)
|
||||
|
|
|
@ -442,15 +442,15 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File,
|
|||
|
||||
void Preprocessor::CodeCompleteIncludedFile(llvm::StringRef Dir,
|
||||
bool IsAngled) {
|
||||
setCodeCompletionReached();
|
||||
if (CodeComplete)
|
||||
CodeComplete->CodeCompleteIncludedFile(Dir, IsAngled);
|
||||
setCodeCompletionReached();
|
||||
}
|
||||
|
||||
void Preprocessor::CodeCompleteNaturalLanguage() {
|
||||
setCodeCompletionReached();
|
||||
if (CodeComplete)
|
||||
CodeComplete->CodeCompleteNaturalLanguage();
|
||||
setCodeCompletionReached();
|
||||
}
|
||||
|
||||
/// getSpelling - This method is used to get the spelling of a token into a
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -63,8 +63,8 @@ Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,
|
|||
ObjCDeclContextSwitch ObjCDC(*this);
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteNamespaceDecl(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteNamespaceDecl(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -283,8 +283,8 @@ Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
|
|||
ConsumeToken(); // eat the '='.
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -471,8 +471,8 @@ Parser::ParseUsingDirectiveOrDeclaration(DeclaratorContext Context,
|
|||
SourceLocation UsingLoc = ConsumeToken();
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteUsing(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteUsing(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -525,8 +525,8 @@ Decl *Parser::ParseUsingDirective(DeclaratorContext Context,
|
|||
SourceLocation NamespcLoc = ConsumeToken();
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteUsingDirective(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteUsingDirective(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1433,8 +1433,9 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
// Code completion for a struct, class, or union name.
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteTag(getCurScope(), TagType);
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
// C++03 [temp.explicit] 14.7.2/8:
|
||||
|
@ -2749,8 +2750,8 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
|
|||
else if (KW.is(tok::kw_delete))
|
||||
DefinitionKind = FunctionDefinitionKind::Deleted;
|
||||
else if (KW.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteAfterFunctionEquals(DeclaratorInfo);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteAfterFunctionEquals(DeclaratorInfo);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -3498,9 +3499,10 @@ void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
|
|||
|
||||
do {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
|
||||
MemInitializers);
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
|
||||
|
|
|
@ -159,9 +159,9 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
|
|||
/// Parse an expr that doesn't include (top-level) commas.
|
||||
ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteExpression(getCurScope(),
|
||||
PreferredType.get(Tok.getLocation()));
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
|
@ -1156,9 +1156,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
|
|||
ConsumeToken();
|
||||
|
||||
if (Tok.is(tok::code_completion) && &II != Ident_super) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCClassPropertyRefExpr(
|
||||
getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc);
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
}
|
||||
// Allow either an identifier or the keyword 'class' (in C++).
|
||||
|
@ -1724,9 +1724,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
|
|||
Res = ParseBlockLiteralExpression();
|
||||
break;
|
||||
case tok::code_completion: {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteExpression(getCurScope(),
|
||||
PreferredType.get(Tok.getLocation()));
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
}
|
||||
case tok::l_square:
|
||||
|
@ -1856,9 +1856,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
|||
if (InMessageExpression)
|
||||
return LHS;
|
||||
|
||||
cutOffParsing();
|
||||
Actions.CodeCompletePostfixExpression(
|
||||
getCurScope(), LHS, PreferredType.get(Tok.getLocation()));
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
|
||||
case tok::identifier:
|
||||
|
@ -2140,12 +2140,12 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
|||
CorrectedBase = Base;
|
||||
|
||||
// Code completion for a member access expression.
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteMemberReferenceExpr(
|
||||
getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow,
|
||||
Base && ExprStatementTokLoc == Base->getBeginLoc(),
|
||||
PreferredType.get(Tok.getLocation()));
|
||||
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
|
@ -2778,10 +2778,10 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
|
|||
CastTy = nullptr;
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteExpression(
|
||||
getCurScope(), PreferredType.get(Tok.getLocation()),
|
||||
/*IsParenthesized=*/ExprType >= CompoundLiteral);
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
|
@ -3412,8 +3412,9 @@ Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs,
|
|||
/// \endverbatim
|
||||
void Parser::ParseBlockId(SourceLocation CaretLoc) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type);
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the specifier-qualifier-list piece.
|
||||
|
@ -3598,8 +3599,8 @@ Optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
|
|||
} else {
|
||||
// Parse the platform name.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteAvailabilityPlatformName();
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteAvailabilityPlatformName();
|
||||
return None;
|
||||
}
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
|
|
|
@ -235,6 +235,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
|
|||
while (true) {
|
||||
if (HasScopeSpecifier) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
// Code completion for a nested-name-specifier, where the code
|
||||
// completion token follows the '::'.
|
||||
Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext,
|
||||
|
@ -245,7 +246,6 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
|
|||
// token will cause assertion in
|
||||
// Preprocessor::AnnotatePreviousCachedTokens.
|
||||
SS.setEndLoc(Tok.getLocation());
|
||||
cutOffParsing();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -877,9 +877,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
|
|||
// expression parser perform the completion.
|
||||
if (Tok.is(tok::code_completion) &&
|
||||
!(getLangOpts().ObjC && Tentative)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
|
||||
/*AfterAmpersand=*/false);
|
||||
cutOffParsing();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -891,6 +891,7 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
|
|||
}
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
// If we're in Objective-C++ and we have a bare '[', then this is more
|
||||
// likely to be a message receiver.
|
||||
if (getLangOpts().ObjC && Tentative && First)
|
||||
|
@ -898,7 +899,6 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
|
|||
else
|
||||
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
|
||||
/*AfterAmpersand=*/false);
|
||||
cutOffParsing();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -943,9 +943,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
|
|||
ConsumeToken();
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
|
||||
/*AfterAmpersand=*/true);
|
||||
cutOffParsing();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1996,8 +1996,8 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
|
|||
PreferredType.enterCondition(Actions, Tok.getLocation());
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
|
||||
return Sema::ConditionError();
|
||||
}
|
||||
|
||||
|
@ -2608,10 +2608,10 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
|
|||
}
|
||||
|
||||
case tok::code_completion: {
|
||||
// Don't try to parse any further.
|
||||
cutOffParsing();
|
||||
// Code completion for the operator name.
|
||||
Actions.CodeCompleteOperatorName(getCurScope());
|
||||
cutOffParsing();
|
||||
// Don't try to parse any further.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -200,9 +200,9 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator(
|
|||
SourceLocation DotLoc = ConsumeToken();
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteDesignator(DesignatorCompletion.PreferredBaseType,
|
||||
DesignatorCompletion.InitExprs, Desig);
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
}
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
|
|
|
@ -50,8 +50,8 @@ Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) {
|
|||
SourceLocation AtLoc = ConsumeToken(); // the "@"
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -219,8 +219,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
|
|||
|
||||
// Code completion after '@interface'.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCInterfaceDecl(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCInterfaceDecl(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -253,8 +253,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
|
|||
SourceLocation categoryLoc;
|
||||
IdentifierInfo *categoryId = nullptr;
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -308,8 +308,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
|
|||
|
||||
// Code completion of superclass names.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -472,8 +472,8 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs(
|
|||
if (Tok.is(tok::code_completion)) {
|
||||
// FIXME: If these aren't protocol references, we'll need different
|
||||
// completions.
|
||||
Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
|
||||
|
||||
// FIXME: Better recovery here?.
|
||||
return nullptr;
|
||||
|
@ -635,10 +635,11 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
|
|||
|
||||
// Code completion within an Objective-C interface.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
||||
CurParsedObjCImpl? Sema::PCC_ObjCImplementation
|
||||
: Sema::PCC_ObjCInterface);
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't have an @ directive, parse it as a function definition.
|
||||
|
@ -668,8 +669,9 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
|
|||
// Otherwise, we have an @ directive, eat the @.
|
||||
SourceLocation AtLoc = ConsumeToken(); // the "@"
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID();
|
||||
|
@ -778,8 +780,9 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
|
|||
// We break out of the big loop in two cases: when we see @end or when we see
|
||||
// EOF. In the former case, eat the @end. In the later case, emit an error.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
||||
return cutOffParsing();
|
||||
return;
|
||||
} else if (Tok.isObjCAtKeyword(tok::objc_end)) {
|
||||
ConsumeToken(); // the "end" identifier
|
||||
} else {
|
||||
|
@ -847,8 +850,9 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
|
|||
|
||||
while (1) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS);
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
const IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||
|
||||
|
@ -893,11 +897,12 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
|
|||
}
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
if (IsSetter)
|
||||
Actions.CodeCompleteObjCPropertySetter(getCurScope());
|
||||
else
|
||||
Actions.CodeCompleteObjCPropertyGetter(getCurScope());
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
SourceLocation SelLoc;
|
||||
|
@ -1146,9 +1151,10 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
|
|||
|
||||
while (1) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCPassingType(
|
||||
getCurScope(), DS, Context == DeclaratorContext::ObjCParameter);
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier))
|
||||
|
@ -1335,9 +1341,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
|
||||
/*ReturnType=*/nullptr);
|
||||
cutOffParsing();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1354,9 +1360,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
methodAttrs);
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
|
||||
ReturnType);
|
||||
cutOffParsing();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1416,12 +1422,12 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
|
||||
// Code completion for the next piece of the selector.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
KeyIdents.push_back(SelIdent);
|
||||
Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
|
||||
mType == tok::minus,
|
||||
/*AtParameterName=*/true,
|
||||
ReturnType, KeyIdents);
|
||||
cutOffParsing();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1441,11 +1447,11 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
|
||||
// Code completion for the next piece of the selector.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
|
||||
mType == tok::minus,
|
||||
/*AtParameterName=*/false,
|
||||
ReturnType, KeyIdents);
|
||||
cutOffParsing();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1527,8 +1533,8 @@ ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
|
|||
|
||||
while (1) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1626,12 +1632,12 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers(
|
|||
}
|
||||
|
||||
QualType BaseT = Actions.GetTypeFromParser(baseType);
|
||||
cutOffParsing();
|
||||
if (!BaseT.isNull() && BaseT->acceptsObjCTypeParams()) {
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type);
|
||||
} else {
|
||||
Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs);
|
||||
}
|
||||
cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1920,8 +1926,9 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
|
|||
// Set the default visibility to private.
|
||||
if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCAtVisibility(getCurScope());
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Tok.getObjCKeywordID()) {
|
||||
|
@ -1950,9 +1957,10 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
|
|||
}
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
||||
Sema::PCC_ObjCInstanceVariableList);
|
||||
return cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
// This needs to duplicate a small amount of code from
|
||||
|
@ -2017,8 +2025,8 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
|
|||
ConsumeToken(); // the "protocol" identifier
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCProtocolDecl(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCProtocolDecl(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -2101,8 +2109,8 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
|
|||
|
||||
// Code completion after '@implementation'.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCImplementationDecl(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCImplementationDecl(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -2139,8 +2147,8 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
|
|||
IdentifierInfo *categoryId = nullptr;
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -2309,8 +2317,8 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
|
|||
|
||||
while (true) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -2327,8 +2335,8 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
|
|||
if (TryConsumeToken(tok::equal)) {
|
||||
// property '=' ivar-name
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -2387,8 +2395,8 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
|
|||
|
||||
while (true) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -2724,8 +2732,8 @@ Decl *Parser::ParseObjCMethodDefinition() {
|
|||
StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc,
|
||||
ParsedStmtContext StmtCtx) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCAtStatement(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCAtStatement(getCurScope());
|
||||
return StmtError();
|
||||
}
|
||||
|
||||
|
@ -2765,8 +2773,8 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc,
|
|||
ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
|
||||
switch (Tok.getKind()) {
|
||||
case tok::code_completion:
|
||||
Actions.CodeCompleteObjCAtExpression(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCAtExpression(getCurScope());
|
||||
return ExprError();
|
||||
|
||||
case tok::minus:
|
||||
|
@ -3012,8 +3020,8 @@ ExprResult Parser::ParseObjCMessageExpression() {
|
|||
SourceLocation LBracLoc = ConsumeBracket(); // consume '['
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCMessageReceiver(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCMessageReceiver(getCurScope());
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
|
@ -3149,6 +3157,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
|||
InMessageExpressionRAIIObject InMessage(*this, true);
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
if (SuperLoc.isValid())
|
||||
Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, None,
|
||||
false);
|
||||
|
@ -3158,7 +3167,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
|||
else
|
||||
Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
|
||||
None, false);
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
|
@ -3187,6 +3195,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
|||
/// Parse the expression after ':'
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
if (SuperLoc.isValid())
|
||||
Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
|
||||
KeyIdents,
|
||||
|
@ -3200,7 +3209,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
|||
KeyIdents,
|
||||
/*AtArgumentExpression=*/true);
|
||||
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
|
@ -3225,6 +3233,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
|||
|
||||
// Code completion after each argument.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
if (SuperLoc.isValid())
|
||||
Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
|
||||
KeyIdents,
|
||||
|
@ -3237,7 +3246,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
|||
Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
|
||||
KeyIdents,
|
||||
/*AtArgumentExpression=*/false);
|
||||
cutOffParsing();
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
|
@ -3577,8 +3585,8 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
|
|||
ConsumeParen();
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
|
@ -3603,8 +3611,8 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
|
|||
break;
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
|
|
|
@ -441,9 +441,9 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
|
|||
ConsumeToken();
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
|
||||
Actions.FinalizeDeclaration(OmpPrivParm);
|
||||
cutOffParsing();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -178,8 +178,8 @@ Retry:
|
|||
}
|
||||
|
||||
case tok::code_completion:
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement);
|
||||
return StmtError();
|
||||
|
||||
case tok::identifier: {
|
||||
|
@ -726,8 +726,8 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
|
|||
ColonLoc = SourceLocation();
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteCase(getCurScope());
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteCase(getCurScope());
|
||||
return StmtError();
|
||||
}
|
||||
|
||||
|
@ -1472,8 +1472,8 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
|
|||
// Pop the 'else' scope if needed.
|
||||
InnerScope.Exit();
|
||||
} else if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen);
|
||||
return StmtError();
|
||||
} else if (InnerStatementTrailingElseLoc.isValid()) {
|
||||
Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
|
||||
|
@ -1827,10 +1827,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
|
|||
FullExprArg ThirdPart(Actions);
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
||||
C99orCXXorObjC? Sema::PCC_ForInit
|
||||
: Sema::PCC_Expression);
|
||||
cutOffParsing();
|
||||
return StmtError();
|
||||
}
|
||||
|
||||
|
@ -1898,8 +1898,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
|
|||
ConsumeToken(); // consume 'in'
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCForCollection(getCurScope(), DG);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCForCollection(getCurScope(), DG);
|
||||
return StmtError();
|
||||
}
|
||||
Collection = ParseExpression();
|
||||
|
@ -1934,8 +1934,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
|
|||
ConsumeToken(); // consume 'in'
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCForCollection(getCurScope(), nullptr);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteObjCForCollection(getCurScope(), nullptr);
|
||||
return StmtError();
|
||||
}
|
||||
Collection = ParseExpression();
|
||||
|
@ -2188,9 +2188,9 @@ StmtResult Parser::ParseReturnStatement() {
|
|||
PreferredType.enterReturn(Actions, Tok.getLocation());
|
||||
// FIXME: Code completion for co_return.
|
||||
if (Tok.is(tok::code_completion) && !IsCoreturn) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteExpression(getCurScope(),
|
||||
PreferredType.get(Tok.getLocation()));
|
||||
cutOffParsing();
|
||||
return StmtError();
|
||||
}
|
||||
|
||||
|
|
|
@ -870,6 +870,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
|||
SingleDecl = ParseObjCMethodDefinition();
|
||||
break;
|
||||
case tok::code_completion:
|
||||
cutOffParsing();
|
||||
if (CurParsedObjCImpl) {
|
||||
// Code-complete Objective-C methods even without leading '-'/'+' prefix.
|
||||
Actions.CodeCompleteObjCMethodDecl(getCurScope(),
|
||||
|
@ -879,7 +880,6 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
|||
Actions.CodeCompleteOrdinaryName(
|
||||
getCurScope(),
|
||||
CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace);
|
||||
cutOffParsing();
|
||||
return nullptr;
|
||||
case tok::kw_import:
|
||||
SingleDecl = ParseModuleImport(SourceLocation());
|
||||
|
@ -2114,21 +2114,21 @@ SourceLocation Parser::handleUnexpectedCodeCompletionToken() {
|
|||
|
||||
for (Scope *S = getCurScope(); S; S = S->getParent()) {
|
||||
if (S->getFlags() & Scope::FnScope) {
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
||||
Sema::PCC_RecoveryInFunction);
|
||||
cutOffParsing();
|
||||
return PrevTokLocation;
|
||||
}
|
||||
|
||||
if (S->getFlags() & Scope::ClassScope) {
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class);
|
||||
return PrevTokLocation;
|
||||
}
|
||||
}
|
||||
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace);
|
||||
return PrevTokLocation;
|
||||
}
|
||||
|
||||
|
@ -2452,8 +2452,8 @@ bool Parser::ParseModuleName(
|
|||
while (true) {
|
||||
if (!Tok.is(tok::identifier)) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteModuleImport(UseLoc, Path);
|
||||
cutOffParsing();
|
||||
Actions.CodeCompleteModuleImport(UseLoc, Path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -5711,8 +5711,9 @@ ProduceSignatureHelp(Sema &SemaRef, Scope *S,
|
|||
unsigned CurrentArg, SourceLocation OpenParLoc) {
|
||||
if (Candidates.empty())
|
||||
return QualType();
|
||||
SemaRef.CodeCompleter->ProcessOverloadCandidates(
|
||||
SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc);
|
||||
if (SemaRef.getPreprocessor().isCodeCompletionReached())
|
||||
SemaRef.CodeCompleter->ProcessOverloadCandidates(
|
||||
SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc);
|
||||
return getParamType(SemaRef, Candidates, CurrentArg);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,3 +62,18 @@ void aux() {
|
|||
Test<T> X{.x = T(2)};
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:62:14 %s -o - -std=c++2a | FileCheck -check-prefix=CHECK-CC3 %s
|
||||
}
|
||||
|
||||
namespace signature_regression {
|
||||
// Verify that an old bug is gone: passing an init-list as a constructor arg
|
||||
// would emit overloads as a side-effect.
|
||||
struct S{int x;};
|
||||
int wrongFunction(S);
|
||||
int rightFunction();
|
||||
int dummy = wrongFunction({1});
|
||||
int x = rightFunction();
|
||||
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:73:25 %s -o - -std=c++2a | FileCheck -check-prefix=CHECK-SIGNATURE-REGRESSION %s
|
||||
// CHECK-SIGNATURE-REGRESSION-NOT: OVERLOAD: [#int#]wrongFunction
|
||||
// CHECK-SIGNATURE-REGRESSION: OVERLOAD: [#int#]rightFunction
|
||||
// CHECK-SIGNATURE-REGRESSION-NOT: OVERLOAD: [#int#]wrongFunction
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue