summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Biryukov <ibiryukov@google.com>2019-05-28 15:21:03 +0000
committerIlya Biryukov <ibiryukov@google.com>2019-05-28 15:21:03 +0000
commitb1296faee050c65ca1e31632c2dc881984c97ad7 (patch)
treec916c8ec01e63252048d1ce9c949dbf956102543
parent9bf766c57343f14320c1ad6db456ce127f4d548c (diff)
downloadbcm5719-llvm-b1296faee050c65ca1e31632c2dc881984c97ad7.tar.gz
bcm5719-llvm-b1296faee050c65ca1e31632c2dc881984c97ad7.zip
[CodeComplete] Set preferred type for qualified-id
Reviewers: kadircet Reviewed By: kadircet Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D62514 llvm-svn: 361838
-rw-r--r--clang/include/clang/Sema/Sema.h4
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp5
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp16
-rw-r--r--clang/unittests/Sema/CodeCompleteTest.cpp26
4 files changed, 43 insertions, 8 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 60480d98beb..a1a7f5f6ea9 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10646,8 +10646,8 @@ public:
void CodeCompleteInitializer(Scope *S, Decl *D);
void CodeCompleteAfterIf(Scope *S);
- void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
- bool EnteringContext, QualType BaseType);
+ void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext,
+ QualType BaseType, QualType PreferredType);
void CodeCompleteUsing(Scope *S);
void CodeCompleteUsingDirective(Scope *S);
void CodeCompleteNamespaceDecl(Scope *S);
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 6173a6cd63e..da39e2e2237 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -232,13 +232,16 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
HasScopeSpecifier = true;
}
+ // Preferred type might change when parsing qualifiers, we need the original.
+ auto SavedType = PreferredType;
while (true) {
if (HasScopeSpecifier) {
if (Tok.is(tok::code_completion)) {
// Code completion for a nested-name-specifier, where the code
// completion token follows the '::'.
Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext,
- ObjectType.get());
+ ObjectType.get(),
+ SavedType.get(SS.getBeginLoc()));
// Include code completion token into the range of the scope otherwise
// when we try to annotate the scope tokens the dangling code completion
// token will cause assertion in
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 3682dd0f4d4..4f474032f60 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -5215,7 +5215,8 @@ void Sema::CodeCompleteAfterIf(Scope *S) {
}
void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
- bool EnteringContext, QualType BaseType) {
+ bool EnteringContext, QualType BaseType,
+ QualType PreferredType) {
if (SS.isEmpty() || !CodeCompleter)
return;
@@ -5224,13 +5225,15 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
// it can be useful for global code completion which have information about
// contexts/symbols that are not in the AST.
if (SS.isInvalid()) {
- CodeCompletionContext CC(CodeCompletionContext::CCC_Symbol);
+ CodeCompletionContext CC(CodeCompletionContext::CCC_Symbol, PreferredType);
CC.setCXXScopeSpecifier(SS);
// As SS is invalid, we try to collect accessible contexts from the current
// scope with a dummy lookup so that the completion consumer can try to
// guess what the specified scope is.
ResultBuilder DummyResults(*this, CodeCompleter->getAllocator(),
CodeCompleter->getCodeCompletionTUInfo(), CC);
+ if (!PreferredType.isNull())
+ DummyResults.setPreferredType(PreferredType);
if (S->getEntity()) {
CodeCompletionDeclConsumer Consumer(DummyResults, S->getEntity(),
BaseType);
@@ -5253,9 +5256,12 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
return;
- ResultBuilder Results(*this, CodeCompleter->getAllocator(),
- CodeCompleter->getCodeCompletionTUInfo(),
- CodeCompletionContext::CCC_Symbol);
+ ResultBuilder Results(
+ *this, CodeCompleter->getAllocator(),
+ CodeCompleter->getCodeCompletionTUInfo(),
+ CodeCompletionContext(CodeCompletionContext::CCC_Symbol, PreferredType));
+ if (!PreferredType.isNull())
+ Results.setPreferredType(PreferredType);
Results.EnterNewScope();
// The "template" keyword can follow "::" in the grammar, but only
diff --git a/clang/unittests/Sema/CodeCompleteTest.cpp b/clang/unittests/Sema/CodeCompleteTest.cpp
index 4e1068f4a39..1d0e7323849 100644
--- a/clang/unittests/Sema/CodeCompleteTest.cpp
+++ b/clang/unittests/Sema/CodeCompleteTest.cpp
@@ -454,5 +454,31 @@ TEST(PreferredTypeTest, FunctionArguments) {
}
)cpp";
EXPECT_THAT(collectPreferredTypes(Code), Each("volatile double *"));
+
+ Code = R"cpp(
+ namespace ns {
+ struct vector {
+ };
+ }
+ void accepts_vector(ns::vector);
+
+ void test() {
+ accepts_vector(^::^ns::^vector());
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("ns::vector"));
+
+ Code = R"cpp(
+ template <class T>
+ struct vector { using self = vector; };
+
+ void accepts_vector(vector<int>);
+ int foo(int);
+
+ void test() {
+ accepts_vector(^::^vector<decltype(foo(1))>::^self);
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("vector<int>"));
}
} // namespace
OpenPOWER on IntegriCloud