From 1ca8bbb078bd5920d6ca154c05ab2dcbf53a7a8a Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 22 Aug 2017 10:25:48 +0000 Subject: [PATCH] Fix templated type alias completion when using global completion cache When we have enabled cache for global completions we did not have diagnostics for Bar and could not complete Ba as in provided code example. template struct Foo { T member; }; template using Bar = Foo; int main() { Ba } Patch by Ivan Donchevskii! Differential Revision: https://reviews.llvm.org/D35355 llvm-svn: 311442 --- clang/lib/Frontend/ASTUnit.cpp | 3 ++- clang/lib/Parse/ParseTemplate.cpp | 12 +++++++----- clang/test/Index/code-completion.cpp | 12 ++++++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 07f847ca944b..a4a1a5f3b007 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -243,7 +243,8 @@ static unsigned getDeclShowContexts(const NamedDecl *ND, uint64_t Contexts = 0; if (isa(ND) || isa(ND) || - isa(ND) || isa(ND)) { + isa(ND) || isa(ND) || + isa(ND)) { // Types can appear in these contexts. if (LangOpts.CPlusPlus || !isa(ND)) Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel) diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index fc1722ea6cd0..de54f572d821 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -198,9 +198,11 @@ Parser::ParseSingleDeclarationAfterTemplate( if (Tok.is(tok::kw_using)) { // FIXME: We should return the DeclGroup to the caller. - ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd, - prefixAttrs); - return nullptr; + auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd, + prefixAttrs); + if (!usingDeclPtr) + return nullptr; + return usingDeclPtr.get().getSingleDecl(); } // Parse the declaration specifiers, stealing any diagnostics from @@ -1023,8 +1025,8 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, ? OO_None : TemplateName.OperatorFunctionId.Operator; - TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create( - SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK, + TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create( + SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK, LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds); Tok.setAnnotationValue(TemplateId); diff --git a/clang/test/Index/code-completion.cpp b/clang/test/Index/code-completion.cpp index f52bb10a35b0..00f158f3d09d 100644 --- a/clang/test/Index/code-completion.cpp +++ b/clang/test/Index/code-completion.cpp @@ -37,6 +37,16 @@ Z::operator int() const { return 0; } +template +struct Foo { T member; }; + +template using Bar = Foo; + +void test_template_alias() { + // RUN: env CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:47:1 %s | FileCheck -check-prefix=CHECK-TEMPLATE-ALIAS %s + +} + // CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member} // CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member} // CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member} @@ -88,3 +98,5 @@ Z::operator int() const { // CHECK-EXPR-NEXT: Class name // CHECK-EXPR-NEXT: Nested name specifier // CHECK-EXPR-NEXT: Objective-C interface + +// CHECK-TEMPLATE-ALIAS: AliasTemplateDecl:{TypedText Bar}{LeftAngle <}{Placeholder typename T}{RightAngle >} (50)