forked from OSchip/llvm-project
[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
This commit is contained in:
parent
9bf766c573
commit
b1296faee0
clang
include/clang/Sema
lib
unittests/Sema
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue