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);
|
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) {
|
TEST(SignatureHelpTest, DefaultArgs) {
|
||||||
auto Results = signatures(R"cpp(
|
auto Results = signatures(R"cpp(
|
||||||
void bar(int x, int y = 0);
|
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
|
/// 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
|
/// function_ref, clients should make sure all calls to get() with the same
|
||||||
/// location happen while function_ref is alive.
|
/// 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,
|
void enterFunctionArgument(SourceLocation Tok,
|
||||||
llvm::function_ref<QualType()> ComputeType);
|
llvm::function_ref<QualType()> ComputeType);
|
||||||
|
|
||||||
|
@ -318,6 +321,12 @@ public:
|
||||||
/// Handles all type casts, including C-style cast, C++ casts, etc.
|
/// Handles all type casts, including C-style cast, C++ casts, etc.
|
||||||
void enterTypeCast(SourceLocation Tok, QualType CastType);
|
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 {
|
QualType get(SourceLocation Tok) const {
|
||||||
if (!Enabled || Tok != ExpectedLoc)
|
if (!Enabled || Tok != ExpectedLoc)
|
||||||
return QualType();
|
return QualType();
|
||||||
|
@ -12216,8 +12225,14 @@ public:
|
||||||
const VirtSpecifiers *VS = nullptr);
|
const VirtSpecifiers *VS = nullptr);
|
||||||
void CodeCompleteBracketDeclarator(Scope *S);
|
void CodeCompleteBracketDeclarator(Scope *S);
|
||||||
void CodeCompleteCase(Scope *S);
|
void CodeCompleteCase(Scope *S);
|
||||||
/// Reports signatures for a call to CodeCompleteConsumer and returns the
|
/// Determines the preferred type of the current function argument, by
|
||||||
/// preferred type for the current argument. Returned type can be null.
|
/// 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,
|
QualType ProduceCallSignatureHelp(Scope *S, Expr *Fn, ArrayRef<Expr *> Args,
|
||||||
SourceLocation OpenParLoc);
|
SourceLocation OpenParLoc);
|
||||||
QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type,
|
QualType ProduceConstructorSignatureHelp(Scope *S, QualType Type,
|
||||||
|
|
|
@ -441,9 +441,9 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
|
||||||
CurLexer->Lex(Tok);
|
CurLexer->Lex(Tok);
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
setCodeCompletionReached();
|
||||||
if (CodeComplete)
|
if (CodeComplete)
|
||||||
CodeComplete->CodeCompleteInConditionalExclusion();
|
CodeComplete->CodeCompleteInConditionalExclusion();
|
||||||
setCodeCompletionReached();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,10 +966,10 @@ void Preprocessor::HandleDirective(Token &Result) {
|
||||||
case tok::eod:
|
case tok::eod:
|
||||||
return; // null directive.
|
return; // null directive.
|
||||||
case tok::code_completion:
|
case tok::code_completion:
|
||||||
|
setCodeCompletionReached();
|
||||||
if (CodeComplete)
|
if (CodeComplete)
|
||||||
CodeComplete->CodeCompleteDirective(
|
CodeComplete->CodeCompleteDirective(
|
||||||
CurPPLexer->getConditionalStackDepth() > 0);
|
CurPPLexer->getConditionalStackDepth() > 0);
|
||||||
setCodeCompletionReached();
|
|
||||||
return;
|
return;
|
||||||
case tok::numeric_constant: // # 7 GNU line marker directive.
|
case tok::numeric_constant: // # 7 GNU line marker directive.
|
||||||
if (getLangOpts().AsmPreprocessor)
|
if (getLangOpts().AsmPreprocessor)
|
||||||
|
|
|
@ -442,15 +442,15 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File,
|
||||||
|
|
||||||
void Preprocessor::CodeCompleteIncludedFile(llvm::StringRef Dir,
|
void Preprocessor::CodeCompleteIncludedFile(llvm::StringRef Dir,
|
||||||
bool IsAngled) {
|
bool IsAngled) {
|
||||||
|
setCodeCompletionReached();
|
||||||
if (CodeComplete)
|
if (CodeComplete)
|
||||||
CodeComplete->CodeCompleteIncludedFile(Dir, IsAngled);
|
CodeComplete->CodeCompleteIncludedFile(Dir, IsAngled);
|
||||||
setCodeCompletionReached();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preprocessor::CodeCompleteNaturalLanguage() {
|
void Preprocessor::CodeCompleteNaturalLanguage() {
|
||||||
|
setCodeCompletionReached();
|
||||||
if (CodeComplete)
|
if (CodeComplete)
|
||||||
CodeComplete->CodeCompleteNaturalLanguage();
|
CodeComplete->CodeCompleteNaturalLanguage();
|
||||||
setCodeCompletionReached();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getSpelling - This method is used to get the spelling of a token into a
|
/// 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.
|
// Check to see if we have a function *definition* which must have a body.
|
||||||
if (D.isFunctionDeclarator()) {
|
if (D.isFunctionDeclarator()) {
|
||||||
if (Tok.is(tok::equal) && NextToken().is(tok::code_completion)) {
|
if (Tok.is(tok::equal) && NextToken().is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteAfterFunctionEquals(D);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteAfterFunctionEquals(D);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// Look at the next token to make sure that this isn't a function
|
// 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);
|
InitializerScopeRAII InitScope(*this, D, ThisDecl);
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
|
Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
|
||||||
Actions.FinalizeDeclaration(ThisDecl);
|
Actions.FinalizeDeclaration(ThisDecl);
|
||||||
cutOffParsing();
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3090,10 +3090,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
||||||
= DSContext == DeclSpecContext::DSC_top_level ||
|
= DSContext == DeclSpecContext::DSC_top_level ||
|
||||||
(DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified());
|
(DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified());
|
||||||
|
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteDeclSpec(getCurScope(), DS,
|
Actions.CodeCompleteDeclSpec(getCurScope(), DS,
|
||||||
AllowNonIdentifiers,
|
AllowNonIdentifiers,
|
||||||
AllowNestedNameSpecifiers);
|
AllowNestedNameSpecifiers);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
|
if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
|
||||||
|
@ -3106,8 +3107,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
||||||
else if (CurParsedObjCImpl)
|
else if (CurParsedObjCImpl)
|
||||||
CCC = Sema::PCC_ObjCImplementation;
|
CCC = Sema::PCC_ObjCImplementation;
|
||||||
|
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
|
Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::coloncolon: // ::foo::bar
|
case tok::coloncolon: // ::foo::bar
|
||||||
|
@ -4362,8 +4364,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
||||||
// Parse the tag portion of this.
|
// Parse the tag portion of this.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
// Code completion for an enum name.
|
// Code completion for an enum name.
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
|
Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes exist after tag, parse them.
|
// If attributes exist after tag, parse them.
|
||||||
|
@ -5457,11 +5460,12 @@ void Parser::ParseTypeQualifierListOpt(
|
||||||
|
|
||||||
switch (Tok.getKind()) {
|
switch (Tok.getKind()) {
|
||||||
case tok::code_completion:
|
case tok::code_completion:
|
||||||
|
cutOffParsing();
|
||||||
if (CodeCompletionHandler)
|
if (CodeCompletionHandler)
|
||||||
(*CodeCompletionHandler)();
|
(*CodeCompletionHandler)();
|
||||||
else
|
else
|
||||||
Actions.CodeCompleteTypeQualifiers(DS);
|
Actions.CodeCompleteTypeQualifiers(DS);
|
||||||
return cutOffParsing();
|
return;
|
||||||
|
|
||||||
case tok::kw_const:
|
case tok::kw_const:
|
||||||
isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
|
isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
|
||||||
|
@ -6998,8 +7002,9 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
std::move(attrs), T.getCloseLocation());
|
std::move(attrs), T.getCloseLocation());
|
||||||
return;
|
return;
|
||||||
} else if (Tok.getKind() == tok::code_completion) {
|
} else if (Tok.getKind() == tok::code_completion) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteBracketDeclarator(getCurScope());
|
Actions.CodeCompleteBracketDeclarator(getCurScope());
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If valid, this location is the position where we read the 'static' keyword.
|
// 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);
|
ObjCDeclContextSwitch ObjCDC(*this);
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteNamespaceDecl(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteNamespaceDecl(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,8 +283,8 @@ Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
|
||||||
ConsumeToken(); // eat the '='.
|
ConsumeToken(); // eat the '='.
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,8 +471,8 @@ Parser::ParseUsingDirectiveOrDeclaration(DeclaratorContext Context,
|
||||||
SourceLocation UsingLoc = ConsumeToken();
|
SourceLocation UsingLoc = ConsumeToken();
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteUsing(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteUsing(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,8 +525,8 @@ Decl *Parser::ParseUsingDirective(DeclaratorContext Context,
|
||||||
SourceLocation NamespcLoc = ConsumeToken();
|
SourceLocation NamespcLoc = ConsumeToken();
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteUsingDirective(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteUsingDirective(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1433,8 +1433,9 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
// Code completion for a struct, class, or union name.
|
// Code completion for a struct, class, or union name.
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteTag(getCurScope(), TagType);
|
Actions.CodeCompleteTag(getCurScope(), TagType);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++03 [temp.explicit] 14.7.2/8:
|
// C++03 [temp.explicit] 14.7.2/8:
|
||||||
|
@ -2749,8 +2750,8 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
|
||||||
else if (KW.is(tok::kw_delete))
|
else if (KW.is(tok::kw_delete))
|
||||||
DefinitionKind = FunctionDefinitionKind::Deleted;
|
DefinitionKind = FunctionDefinitionKind::Deleted;
|
||||||
else if (KW.is(tok::code_completion)) {
|
else if (KW.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteAfterFunctionEquals(DeclaratorInfo);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteAfterFunctionEquals(DeclaratorInfo);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3498,9 +3499,10 @@ void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
|
Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
|
||||||
MemInitializers);
|
MemInitializers);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
|
MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
|
||||||
|
|
|
@ -159,9 +159,9 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
|
||||||
/// Parse an expr that doesn't include (top-level) commas.
|
/// Parse an expr that doesn't include (top-level) commas.
|
||||||
ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
|
ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteExpression(getCurScope(),
|
Actions.CodeCompleteExpression(getCurScope(),
|
||||||
PreferredType.get(Tok.getLocation()));
|
PreferredType.get(Tok.getLocation()));
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1156,9 +1156,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion) && &II != Ident_super) {
|
if (Tok.is(tok::code_completion) && &II != Ident_super) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteObjCClassPropertyRefExpr(
|
Actions.CodeCompleteObjCClassPropertyRefExpr(
|
||||||
getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc);
|
getCurScope(), II, ILoc, ExprStatementTokLoc == ILoc);
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
// Allow either an identifier or the keyword 'class' (in C++).
|
// Allow either an identifier or the keyword 'class' (in C++).
|
||||||
|
@ -1724,9 +1724,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
|
||||||
Res = ParseBlockLiteralExpression();
|
Res = ParseBlockLiteralExpression();
|
||||||
break;
|
break;
|
||||||
case tok::code_completion: {
|
case tok::code_completion: {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteExpression(getCurScope(),
|
Actions.CodeCompleteExpression(getCurScope(),
|
||||||
PreferredType.get(Tok.getLocation()));
|
PreferredType.get(Tok.getLocation()));
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
case tok::l_square:
|
case tok::l_square:
|
||||||
|
@ -1856,9 +1856,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
||||||
if (InMessageExpression)
|
if (InMessageExpression)
|
||||||
return LHS;
|
return LHS;
|
||||||
|
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompletePostfixExpression(
|
Actions.CodeCompletePostfixExpression(
|
||||||
getCurScope(), LHS, PreferredType.get(Tok.getLocation()));
|
getCurScope(), LHS, PreferredType.get(Tok.getLocation()));
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
|
|
||||||
case tok::identifier:
|
case tok::identifier:
|
||||||
|
@ -2140,12 +2140,12 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
||||||
CorrectedBase = Base;
|
CorrectedBase = Base;
|
||||||
|
|
||||||
// Code completion for a member access expression.
|
// Code completion for a member access expression.
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteMemberReferenceExpr(
|
Actions.CodeCompleteMemberReferenceExpr(
|
||||||
getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow,
|
getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow,
|
||||||
Base && ExprStatementTokLoc == Base->getBeginLoc(),
|
Base && ExprStatementTokLoc == Base->getBeginLoc(),
|
||||||
PreferredType.get(Tok.getLocation()));
|
PreferredType.get(Tok.getLocation()));
|
||||||
|
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2778,10 +2778,10 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
|
||||||
CastTy = nullptr;
|
CastTy = nullptr;
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteExpression(
|
Actions.CodeCompleteExpression(
|
||||||
getCurScope(), PreferredType.get(Tok.getLocation()),
|
getCurScope(), PreferredType.get(Tok.getLocation()),
|
||||||
/*IsParenthesized=*/ExprType >= CompoundLiteral);
|
/*IsParenthesized=*/ExprType >= CompoundLiteral);
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3412,8 +3412,9 @@ Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs,
|
||||||
/// \endverbatim
|
/// \endverbatim
|
||||||
void Parser::ParseBlockId(SourceLocation CaretLoc) {
|
void Parser::ParseBlockId(SourceLocation CaretLoc) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type);
|
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the specifier-qualifier-list piece.
|
// Parse the specifier-qualifier-list piece.
|
||||||
|
@ -3598,8 +3599,8 @@ Optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
|
||||||
} else {
|
} else {
|
||||||
// Parse the platform name.
|
// Parse the platform name.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteAvailabilityPlatformName();
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteAvailabilityPlatformName();
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if (Tok.isNot(tok::identifier)) {
|
if (Tok.isNot(tok::identifier)) {
|
||||||
|
|
|
@ -235,6 +235,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
|
||||||
while (true) {
|
while (true) {
|
||||||
if (HasScopeSpecifier) {
|
if (HasScopeSpecifier) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
// Code completion for a nested-name-specifier, where the code
|
// Code completion for a nested-name-specifier, where the code
|
||||||
// completion token follows the '::'.
|
// completion token follows the '::'.
|
||||||
Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext,
|
Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext,
|
||||||
|
@ -245,7 +246,6 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
|
||||||
// token will cause assertion in
|
// token will cause assertion in
|
||||||
// Preprocessor::AnnotatePreviousCachedTokens.
|
// Preprocessor::AnnotatePreviousCachedTokens.
|
||||||
SS.setEndLoc(Tok.getLocation());
|
SS.setEndLoc(Tok.getLocation());
|
||||||
cutOffParsing();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,9 +877,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
|
||||||
// expression parser perform the completion.
|
// expression parser perform the completion.
|
||||||
if (Tok.is(tok::code_completion) &&
|
if (Tok.is(tok::code_completion) &&
|
||||||
!(getLangOpts().ObjC && Tentative)) {
|
!(getLangOpts().ObjC && Tentative)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
|
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
|
||||||
/*AfterAmpersand=*/false);
|
/*AfterAmpersand=*/false);
|
||||||
cutOffParsing();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,6 +891,7 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
// If we're in Objective-C++ and we have a bare '[', then this is more
|
// If we're in Objective-C++ and we have a bare '[', then this is more
|
||||||
// likely to be a message receiver.
|
// likely to be a message receiver.
|
||||||
if (getLangOpts().ObjC && Tentative && First)
|
if (getLangOpts().ObjC && Tentative && First)
|
||||||
|
@ -898,7 +899,6 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
|
||||||
else
|
else
|
||||||
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
|
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
|
||||||
/*AfterAmpersand=*/false);
|
/*AfterAmpersand=*/false);
|
||||||
cutOffParsing();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -943,9 +943,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
|
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
|
||||||
/*AfterAmpersand=*/true);
|
/*AfterAmpersand=*/true);
|
||||||
cutOffParsing();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1996,8 +1996,8 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
|
||||||
PreferredType.enterCondition(Actions, Tok.getLocation());
|
PreferredType.enterCondition(Actions, Tok.getLocation());
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
|
||||||
return Sema::ConditionError();
|
return Sema::ConditionError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2608,10 +2608,10 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::code_completion: {
|
case tok::code_completion: {
|
||||||
|
// Don't try to parse any further.
|
||||||
|
cutOffParsing();
|
||||||
// Code completion for the operator name.
|
// Code completion for the operator name.
|
||||||
Actions.CodeCompleteOperatorName(getCurScope());
|
Actions.CodeCompleteOperatorName(getCurScope());
|
||||||
cutOffParsing();
|
|
||||||
// Don't try to parse any further.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,9 +200,9 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator(
|
||||||
SourceLocation DotLoc = ConsumeToken();
|
SourceLocation DotLoc = ConsumeToken();
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteDesignator(DesignatorCompletion.PreferredBaseType,
|
Actions.CodeCompleteDesignator(DesignatorCompletion.PreferredBaseType,
|
||||||
DesignatorCompletion.InitExprs, Desig);
|
DesignatorCompletion.InitExprs, Desig);
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
if (Tok.isNot(tok::identifier)) {
|
if (Tok.isNot(tok::identifier)) {
|
||||||
|
|
|
@ -50,8 +50,8 @@ Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) {
|
||||||
SourceLocation AtLoc = ConsumeToken(); // the "@"
|
SourceLocation AtLoc = ConsumeToken(); // the "@"
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,8 +219,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
|
||||||
|
|
||||||
// Code completion after '@interface'.
|
// Code completion after '@interface'.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCInterfaceDecl(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCInterfaceDecl(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,8 +253,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
|
||||||
SourceLocation categoryLoc;
|
SourceLocation categoryLoc;
|
||||||
IdentifierInfo *categoryId = nullptr;
|
IdentifierInfo *categoryId = nullptr;
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,8 +308,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
|
||||||
|
|
||||||
// Code completion of superclass names.
|
// Code completion of superclass names.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,8 +472,8 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs(
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
// FIXME: If these aren't protocol references, we'll need different
|
// FIXME: If these aren't protocol references, we'll need different
|
||||||
// completions.
|
// completions.
|
||||||
Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
|
||||||
|
|
||||||
// FIXME: Better recovery here?.
|
// FIXME: Better recovery here?.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -635,10 +635,11 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
|
||||||
|
|
||||||
// Code completion within an Objective-C interface.
|
// Code completion within an Objective-C interface.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
||||||
CurParsedObjCImpl? Sema::PCC_ObjCImplementation
|
CurParsedObjCImpl? Sema::PCC_ObjCImplementation
|
||||||
: Sema::PCC_ObjCInterface);
|
: Sema::PCC_ObjCInterface);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have an @ directive, parse it as a function definition.
|
// 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 @.
|
// Otherwise, we have an @ directive, eat the @.
|
||||||
SourceLocation AtLoc = ConsumeToken(); // the "@"
|
SourceLocation AtLoc = ConsumeToken(); // the "@"
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID();
|
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
|
// 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.
|
// EOF. In the former case, eat the @end. In the later case, emit an error.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
Actions.CodeCompleteObjCAtDirective(getCurScope());
|
||||||
return cutOffParsing();
|
return;
|
||||||
} else if (Tok.isObjCAtKeyword(tok::objc_end)) {
|
} else if (Tok.isObjCAtKeyword(tok::objc_end)) {
|
||||||
ConsumeToken(); // the "end" identifier
|
ConsumeToken(); // the "end" identifier
|
||||||
} else {
|
} else {
|
||||||
|
@ -847,8 +850,9 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS);
|
Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
const IdentifierInfo *II = Tok.getIdentifierInfo();
|
const IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||||
|
|
||||||
|
@ -893,11 +897,12 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
if (IsSetter)
|
if (IsSetter)
|
||||||
Actions.CodeCompleteObjCPropertySetter(getCurScope());
|
Actions.CodeCompleteObjCPropertySetter(getCurScope());
|
||||||
else
|
else
|
||||||
Actions.CodeCompleteObjCPropertyGetter(getCurScope());
|
Actions.CodeCompleteObjCPropertyGetter(getCurScope());
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLocation SelLoc;
|
SourceLocation SelLoc;
|
||||||
|
@ -1146,9 +1151,10 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteObjCPassingType(
|
Actions.CodeCompleteObjCPassingType(
|
||||||
getCurScope(), DS, Context == DeclaratorContext::ObjCParameter);
|
getCurScope(), DS, Context == DeclaratorContext::ObjCParameter);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.isNot(tok::identifier))
|
if (Tok.isNot(tok::identifier))
|
||||||
|
@ -1335,9 +1341,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
|
ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
|
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
|
||||||
/*ReturnType=*/nullptr);
|
/*ReturnType=*/nullptr);
|
||||||
cutOffParsing();
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1354,9 +1360,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
methodAttrs);
|
methodAttrs);
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
|
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
|
||||||
ReturnType);
|
ReturnType);
|
||||||
cutOffParsing();
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1416,12 +1422,12 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
|
|
||||||
// Code completion for the next piece of the selector.
|
// Code completion for the next piece of the selector.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
KeyIdents.push_back(SelIdent);
|
KeyIdents.push_back(SelIdent);
|
||||||
Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
|
Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
|
||||||
mType == tok::minus,
|
mType == tok::minus,
|
||||||
/*AtParameterName=*/true,
|
/*AtParameterName=*/true,
|
||||||
ReturnType, KeyIdents);
|
ReturnType, KeyIdents);
|
||||||
cutOffParsing();
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1441,11 +1447,11 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
|
|
||||||
// Code completion for the next piece of the selector.
|
// Code completion for the next piece of the selector.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
|
Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
|
||||||
mType == tok::minus,
|
mType == tok::minus,
|
||||||
/*AtParameterName=*/false,
|
/*AtParameterName=*/false,
|
||||||
ReturnType, KeyIdents);
|
ReturnType, KeyIdents);
|
||||||
cutOffParsing();
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1527,8 +1533,8 @@ ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1626,12 +1632,12 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers(
|
||||||
}
|
}
|
||||||
|
|
||||||
QualType BaseT = Actions.GetTypeFromParser(baseType);
|
QualType BaseT = Actions.GetTypeFromParser(baseType);
|
||||||
|
cutOffParsing();
|
||||||
if (!BaseT.isNull() && BaseT->acceptsObjCTypeParams()) {
|
if (!BaseT.isNull() && BaseT->acceptsObjCTypeParams()) {
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type);
|
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type);
|
||||||
} else {
|
} else {
|
||||||
Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs);
|
Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs);
|
||||||
}
|
}
|
||||||
cutOffParsing();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1920,8 +1926,9 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
|
||||||
// Set the default visibility to private.
|
// Set the default visibility to private.
|
||||||
if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec
|
if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteObjCAtVisibility(getCurScope());
|
Actions.CodeCompleteObjCAtVisibility(getCurScope());
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Tok.getObjCKeywordID()) {
|
switch (Tok.getObjCKeywordID()) {
|
||||||
|
@ -1950,9 +1957,10 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
||||||
Sema::PCC_ObjCInstanceVariableList);
|
Sema::PCC_ObjCInstanceVariableList);
|
||||||
return cutOffParsing();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This needs to duplicate a small amount of code from
|
// This needs to duplicate a small amount of code from
|
||||||
|
@ -2017,8 +2025,8 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
|
||||||
ConsumeToken(); // the "protocol" identifier
|
ConsumeToken(); // the "protocol" identifier
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCProtocolDecl(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCProtocolDecl(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2101,8 +2109,8 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
|
||||||
|
|
||||||
// Code completion after '@implementation'.
|
// Code completion after '@implementation'.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCImplementationDecl(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCImplementationDecl(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2139,8 +2147,8 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
|
||||||
IdentifierInfo *categoryId = nullptr;
|
IdentifierInfo *categoryId = nullptr;
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2309,8 +2317,8 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2327,8 +2335,8 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
|
||||||
if (TryConsumeToken(tok::equal)) {
|
if (TryConsumeToken(tok::equal)) {
|
||||||
// property '=' ivar-name
|
// property '=' ivar-name
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2387,8 +2395,8 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2724,8 +2732,8 @@ Decl *Parser::ParseObjCMethodDefinition() {
|
||||||
StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc,
|
StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc,
|
||||||
ParsedStmtContext StmtCtx) {
|
ParsedStmtContext StmtCtx) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCAtStatement(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCAtStatement(getCurScope());
|
||||||
return StmtError();
|
return StmtError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2765,8 +2773,8 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc,
|
||||||
ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
|
ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
|
||||||
switch (Tok.getKind()) {
|
switch (Tok.getKind()) {
|
||||||
case tok::code_completion:
|
case tok::code_completion:
|
||||||
Actions.CodeCompleteObjCAtExpression(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCAtExpression(getCurScope());
|
||||||
return ExprError();
|
return ExprError();
|
||||||
|
|
||||||
case tok::minus:
|
case tok::minus:
|
||||||
|
@ -3012,8 +3020,8 @@ ExprResult Parser::ParseObjCMessageExpression() {
|
||||||
SourceLocation LBracLoc = ConsumeBracket(); // consume '['
|
SourceLocation LBracLoc = ConsumeBracket(); // consume '['
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCMessageReceiver(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCMessageReceiver(getCurScope());
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3149,6 +3157,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||||
InMessageExpressionRAIIObject InMessage(*this, true);
|
InMessageExpressionRAIIObject InMessage(*this, true);
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
if (SuperLoc.isValid())
|
if (SuperLoc.isValid())
|
||||||
Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, None,
|
Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, None,
|
||||||
false);
|
false);
|
||||||
|
@ -3158,7 +3167,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||||
else
|
else
|
||||||
Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
|
Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
|
||||||
None, false);
|
None, false);
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3187,6 +3195,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||||
/// Parse the expression after ':'
|
/// Parse the expression after ':'
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
if (SuperLoc.isValid())
|
if (SuperLoc.isValid())
|
||||||
Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
|
Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
|
||||||
KeyIdents,
|
KeyIdents,
|
||||||
|
@ -3200,7 +3209,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||||
KeyIdents,
|
KeyIdents,
|
||||||
/*AtArgumentExpression=*/true);
|
/*AtArgumentExpression=*/true);
|
||||||
|
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3225,6 +3233,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||||
|
|
||||||
// Code completion after each argument.
|
// Code completion after each argument.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
if (SuperLoc.isValid())
|
if (SuperLoc.isValid())
|
||||||
Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
|
Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
|
||||||
KeyIdents,
|
KeyIdents,
|
||||||
|
@ -3237,7 +3246,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||||
Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
|
Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
|
||||||
KeyIdents,
|
KeyIdents,
|
||||||
/*AtArgumentExpression=*/false);
|
/*AtArgumentExpression=*/false);
|
||||||
cutOffParsing();
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3577,8 +3585,8 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3603,8 +3611,8 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -441,9 +441,9 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
|
Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
|
||||||
Actions.FinalizeDeclaration(OmpPrivParm);
|
Actions.FinalizeDeclaration(OmpPrivParm);
|
||||||
cutOffParsing();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,8 +178,8 @@ Retry:
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::code_completion:
|
case tok::code_completion:
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement);
|
||||||
return StmtError();
|
return StmtError();
|
||||||
|
|
||||||
case tok::identifier: {
|
case tok::identifier: {
|
||||||
|
@ -726,8 +726,8 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
|
||||||
ColonLoc = SourceLocation();
|
ColonLoc = SourceLocation();
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteCase(getCurScope());
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteCase(getCurScope());
|
||||||
return StmtError();
|
return StmtError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1472,8 +1472,8 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
|
||||||
// Pop the 'else' scope if needed.
|
// Pop the 'else' scope if needed.
|
||||||
InnerScope.Exit();
|
InnerScope.Exit();
|
||||||
} else if (Tok.is(tok::code_completion)) {
|
} else if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen);
|
||||||
return StmtError();
|
return StmtError();
|
||||||
} else if (InnerStatementTrailingElseLoc.isValid()) {
|
} else if (InnerStatementTrailingElseLoc.isValid()) {
|
||||||
Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
|
Diag(InnerStatementTrailingElseLoc, diag::warn_dangling_else);
|
||||||
|
@ -1827,10 +1827,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
|
||||||
FullExprArg ThirdPart(Actions);
|
FullExprArg ThirdPart(Actions);
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
||||||
C99orCXXorObjC? Sema::PCC_ForInit
|
C99orCXXorObjC? Sema::PCC_ForInit
|
||||||
: Sema::PCC_Expression);
|
: Sema::PCC_Expression);
|
||||||
cutOffParsing();
|
|
||||||
return StmtError();
|
return StmtError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1898,8 +1898,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
|
||||||
ConsumeToken(); // consume 'in'
|
ConsumeToken(); // consume 'in'
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCForCollection(getCurScope(), DG);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCForCollection(getCurScope(), DG);
|
||||||
return StmtError();
|
return StmtError();
|
||||||
}
|
}
|
||||||
Collection = ParseExpression();
|
Collection = ParseExpression();
|
||||||
|
@ -1934,8 +1934,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
|
||||||
ConsumeToken(); // consume 'in'
|
ConsumeToken(); // consume 'in'
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCForCollection(getCurScope(), nullptr);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteObjCForCollection(getCurScope(), nullptr);
|
||||||
return StmtError();
|
return StmtError();
|
||||||
}
|
}
|
||||||
Collection = ParseExpression();
|
Collection = ParseExpression();
|
||||||
|
@ -2188,9 +2188,9 @@ StmtResult Parser::ParseReturnStatement() {
|
||||||
PreferredType.enterReturn(Actions, Tok.getLocation());
|
PreferredType.enterReturn(Actions, Tok.getLocation());
|
||||||
// FIXME: Code completion for co_return.
|
// FIXME: Code completion for co_return.
|
||||||
if (Tok.is(tok::code_completion) && !IsCoreturn) {
|
if (Tok.is(tok::code_completion) && !IsCoreturn) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteExpression(getCurScope(),
|
Actions.CodeCompleteExpression(getCurScope(),
|
||||||
PreferredType.get(Tok.getLocation()));
|
PreferredType.get(Tok.getLocation()));
|
||||||
cutOffParsing();
|
|
||||||
return StmtError();
|
return StmtError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -870,6 +870,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
||||||
SingleDecl = ParseObjCMethodDefinition();
|
SingleDecl = ParseObjCMethodDefinition();
|
||||||
break;
|
break;
|
||||||
case tok::code_completion:
|
case tok::code_completion:
|
||||||
|
cutOffParsing();
|
||||||
if (CurParsedObjCImpl) {
|
if (CurParsedObjCImpl) {
|
||||||
// Code-complete Objective-C methods even without leading '-'/'+' prefix.
|
// Code-complete Objective-C methods even without leading '-'/'+' prefix.
|
||||||
Actions.CodeCompleteObjCMethodDecl(getCurScope(),
|
Actions.CodeCompleteObjCMethodDecl(getCurScope(),
|
||||||
|
@ -879,7 +880,6 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
||||||
Actions.CodeCompleteOrdinaryName(
|
Actions.CodeCompleteOrdinaryName(
|
||||||
getCurScope(),
|
getCurScope(),
|
||||||
CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace);
|
CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace);
|
||||||
cutOffParsing();
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
case tok::kw_import:
|
case tok::kw_import:
|
||||||
SingleDecl = ParseModuleImport(SourceLocation());
|
SingleDecl = ParseModuleImport(SourceLocation());
|
||||||
|
@ -2114,21 +2114,21 @@ SourceLocation Parser::handleUnexpectedCodeCompletionToken() {
|
||||||
|
|
||||||
for (Scope *S = getCurScope(); S; S = S->getParent()) {
|
for (Scope *S = getCurScope(); S; S = S->getParent()) {
|
||||||
if (S->getFlags() & Scope::FnScope) {
|
if (S->getFlags() & Scope::FnScope) {
|
||||||
|
cutOffParsing();
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
Actions.CodeCompleteOrdinaryName(getCurScope(),
|
||||||
Sema::PCC_RecoveryInFunction);
|
Sema::PCC_RecoveryInFunction);
|
||||||
cutOffParsing();
|
|
||||||
return PrevTokLocation;
|
return PrevTokLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S->getFlags() & Scope::ClassScope) {
|
if (S->getFlags() & Scope::ClassScope) {
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class);
|
||||||
return PrevTokLocation;
|
return PrevTokLocation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace);
|
||||||
return PrevTokLocation;
|
return PrevTokLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2452,8 +2452,8 @@ bool Parser::ParseModuleName(
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!Tok.is(tok::identifier)) {
|
if (!Tok.is(tok::identifier)) {
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteModuleImport(UseLoc, Path);
|
|
||||||
cutOffParsing();
|
cutOffParsing();
|
||||||
|
Actions.CodeCompleteModuleImport(UseLoc, Path);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5711,8 +5711,9 @@ ProduceSignatureHelp(Sema &SemaRef, Scope *S,
|
||||||
unsigned CurrentArg, SourceLocation OpenParLoc) {
|
unsigned CurrentArg, SourceLocation OpenParLoc) {
|
||||||
if (Candidates.empty())
|
if (Candidates.empty())
|
||||||
return QualType();
|
return QualType();
|
||||||
SemaRef.CodeCompleter->ProcessOverloadCandidates(
|
if (SemaRef.getPreprocessor().isCodeCompletionReached())
|
||||||
SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc);
|
SemaRef.CodeCompleter->ProcessOverloadCandidates(
|
||||||
|
SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc);
|
||||||
return getParamType(SemaRef, Candidates, CurrentArg);
|
return getParamType(SemaRef, Candidates, CurrentArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,3 +62,18 @@ void aux() {
|
||||||
Test<T> X{.x = T(2)};
|
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
|
// 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