Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit ab2d09b

Browse files
committed
[Parser] Don't code-complete twice.
When we are consuming the current token just to enter a new token stream, we push the current token in the back of the stream so that we get it again. Unfortunately this had the effect where if the current token is a code-completion one, we would code-complete once during consuming it and another time after the stream ended. Fix this by making sure that, in this case, ConsumeAnyToken() will consume a code-completion token without invoking code-completion. rdar://12842503 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178199 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 9807a2e commit ab2d09b

File tree

6 files changed

+15
-9
lines changed

6 files changed

+15
-9
lines changed

Diff for: include/clang/Parse/Parser.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,12 @@ class Parser : public CodeCompletionHandler {
247247
/// This does not work with all kinds of tokens: strings and specific other
248248
/// tokens must be consumed with custom methods below. This returns the
249249
/// location of the consumed token.
250-
SourceLocation ConsumeToken() {
250+
SourceLocation ConsumeToken(bool ConsumeCodeCompletionTok = false) {
251251
assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
252252
!isTokenBrace() &&
253253
"Should consume special tokens with Consume*Token");
254254

255-
if (Tok.is(tok::code_completion))
255+
if (!ConsumeCodeCompletionTok && Tok.is(tok::code_completion))
256256
return handleUnexpectedCodeCompletionToken();
257257

258258
PrevTokLocation = Tok.getLocation();
@@ -291,7 +291,7 @@ class Parser : public CodeCompletionHandler {
291291
/// ConsumeAnyToken - Dispatch to the right Consume* method based on the
292292
/// current token type. This should only be used in cases where the type of
293293
/// the token really isn't known, e.g. in error recovery.
294-
SourceLocation ConsumeAnyToken() {
294+
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
295295
if (isTokenParen())
296296
return ConsumeParen();
297297
else if (isTokenBracket())
@@ -301,7 +301,7 @@ class Parser : public CodeCompletionHandler {
301301
else if (isTokenStringLiteral())
302302
return ConsumeStringToken();
303303
else
304-
return ConsumeToken();
304+
return ConsumeToken(ConsumeCodeCompletionTok);
305305
}
306306

307307
/// ConsumeParen - This consume method keeps the paren count up-to-date.

Diff for: lib/Parse/ParseCXXInlineMethods.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
407407
PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
408408

409409
// Consume the previously pushed token.
410-
ConsumeAnyToken();
410+
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
411411
assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
412412
&& "Inline method not starting with '{', ':' or 'try'");
413413

@@ -510,7 +510,7 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
510510
PP.EnterTokenStream(MI.Toks.data(), MI.Toks.size(), true, false);
511511

512512
// Consume the previously pushed token.
513-
ConsumeAnyToken();
513+
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
514514

515515
SourceLocation EqualLoc;
516516

Diff for: lib/Parse/ParseDecl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
931931
LA.Toks.push_back(Tok);
932932
PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
933933
// Consume the previously pushed token.
934-
ConsumeAnyToken();
934+
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
935935

936936
if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
937937
// FIXME: Do not warn on C++11 attributes, once we start supporting

Diff for: lib/Parse/ParseObjc.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2896,7 +2896,7 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
28962896
PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
28972897

28982898
// Consume the previously pushed token.
2899-
ConsumeAnyToken();
2899+
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
29002900

29012901
assert((Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
29022902
Tok.is(tok::colon)) &&

Diff for: lib/Parse/ParseTemplate.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1305,7 +1305,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {
13051305
PP.EnterTokenStream(LMT.Toks.data(), LMT.Toks.size(), true, false);
13061306

13071307
// Consume the previously pushed token.
1308-
ConsumeAnyToken();
1308+
ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
13091309
assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
13101310
&& "Inline method not starting with '{', ':' or 'try'");
13111311

Diff for: test/Index/complete-declarators.m

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ - (int)method:(id)param1 {
2222

2323
static P *p = 0;
2424
}
25+
- (boid)method2 {}
2526
@end
2627

2728
// RUN: c-index-test -code-completion-at=%s:7:4 %s | FileCheck -check-prefix=CHECK-CC0 %s
@@ -81,3 +82,8 @@ - (int)method:(id)param1 {
8182
// CHECK-CC5: NotImplemented:{TypedText unsigned} (50)
8283
// CHECK-CC5: NotImplemented:{TypedText void} (50)
8384
// CHECK-CC5: NotImplemented:{TypedText volatile} (50)
85+
86+
// Check that there are no duplicate entries if we code-complete after an @implementation
87+
// RUN: c-index-test -code-completion-at=%s:27:1 %s | FileCheck -check-prefix=CHECK-CC6 %s
88+
// CHECK-CC6: ObjCInterfaceDecl:{TypedText A}
89+
// CHECK-CC6-NOT: ObjCInterfaceDecl:{TypedText A}

0 commit comments

Comments
 (0)