summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-27 23:58:17 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-27 23:58:17 +0000
commitc36633c47ac478465e133cfa9155cccc3c84b8ab (patch)
tree54957cf90e50ad415557616aee5f16812c6058cf
parentdeec07403cb88b6e72b8a25fff5e6f4b8d0705dd (diff)
downloadbcm5719-llvm-c36633c47ac478465e133cfa9155cccc3c84b8ab.tar.gz
bcm5719-llvm-c36633c47ac478465e133cfa9155cccc3c84b8ab.zip
[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 llvm-svn: 178199
-rw-r--r--clang/include/clang/Parse/Parser.h8
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp4
-rw-r--r--clang/lib/Parse/ParseDecl.cpp2
-rw-r--r--clang/lib/Parse/ParseObjc.cpp2
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp2
-rw-r--r--clang/test/Index/complete-declarators.m6
6 files changed, 15 insertions, 9 deletions
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index de18b86da02..1ac0f3be5ea 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -247,12 +247,12 @@ public:
/// This does not work with all kinds of tokens: strings and specific other
/// tokens must be consumed with custom methods below. This returns the
/// location of the consumed token.
- SourceLocation ConsumeToken() {
+ SourceLocation ConsumeToken(bool ConsumeCodeCompletionTok = false) {
assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
!isTokenBrace() &&
"Should consume special tokens with Consume*Token");
- if (Tok.is(tok::code_completion))
+ if (!ConsumeCodeCompletionTok && Tok.is(tok::code_completion))
return handleUnexpectedCodeCompletionToken();
PrevTokLocation = Tok.getLocation();
@@ -291,7 +291,7 @@ private:
/// ConsumeAnyToken - Dispatch to the right Consume* method based on the
/// current token type. This should only be used in cases where the type of
/// the token really isn't known, e.g. in error recovery.
- SourceLocation ConsumeAnyToken() {
+ SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
if (isTokenParen())
return ConsumeParen();
else if (isTokenBracket())
@@ -301,7 +301,7 @@ private:
else if (isTokenStringLiteral())
return ConsumeStringToken();
else
- return ConsumeToken();
+ return ConsumeToken(ConsumeCodeCompletionTok);
}
/// ConsumeParen - This consume method keeps the paren count up-to-date.
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 30aee20b267..bc634b57d9c 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -407,7 +407,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
// Consume the previously pushed token.
- ConsumeAnyToken();
+ ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
&& "Inline method not starting with '{', ':' or 'try'");
@@ -510,7 +510,7 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
PP.EnterTokenStream(MI.Toks.data(), MI.Toks.size(), true, false);
// Consume the previously pushed token.
- ConsumeAnyToken();
+ ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
SourceLocation EqualLoc;
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4d1147b5df9..7dfbf5ff86c 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -931,7 +931,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
LA.Toks.push_back(Tok);
PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
// Consume the previously pushed token.
- ConsumeAnyToken();
+ ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
// FIXME: Do not warn on C++11 attributes, once we start supporting
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index e4a880e89ab..fb0237ac05e 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -2896,7 +2896,7 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
// Consume the previously pushed token.
- ConsumeAnyToken();
+ ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
assert((Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
Tok.is(tok::colon)) &&
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 1327dd59e55..f14666922b9 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1305,7 +1305,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {
PP.EnterTokenStream(LMT.Toks.data(), LMT.Toks.size(), true, false);
// Consume the previously pushed token.
- ConsumeAnyToken();
+ ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
&& "Inline method not starting with '{', ':' or 'try'");
diff --git a/clang/test/Index/complete-declarators.m b/clang/test/Index/complete-declarators.m
index d42a3c7a6c4..b3a60ded110 100644
--- a/clang/test/Index/complete-declarators.m
+++ b/clang/test/Index/complete-declarators.m
@@ -22,6 +22,7 @@
static P *p = 0;
}
+- (boid)method2 {}
@end
// RUN: c-index-test -code-completion-at=%s:7:4 %s | FileCheck -check-prefix=CHECK-CC0 %s
@@ -81,3 +82,8 @@
// CHECK-CC5: NotImplemented:{TypedText unsigned} (50)
// CHECK-CC5: NotImplemented:{TypedText void} (50)
// CHECK-CC5: NotImplemented:{TypedText volatile} (50)
+
+// Check that there are no duplicate entries if we code-complete after an @implementation
+// RUN: c-index-test -code-completion-at=%s:27:1 %s | FileCheck -check-prefix=CHECK-CC6 %s
+// CHECK-CC6: ObjCInterfaceDecl:{TypedText A}
+// CHECK-CC6-NOT: ObjCInterfaceDecl:{TypedText A}
OpenPOWER on IntegriCloud