Index: include/clang/Sema/CodeCompleteConsumer.h =================================================================== --- include/clang/Sema/CodeCompleteConsumer.h +++ include/clang/Sema/CodeCompleteConsumer.h @@ -763,6 +763,11 @@ /// referring to. In the latter case, the declaration might be NULL. const NamedDecl *Declaration = nullptr; + /// When Kind == RK_Declaration and a FieldDecl has been passed as + /// Declaration, this will hold the identifiers name. To be used later on when + /// generating constructors for the variable. + llvm::Optional PreferredTypedName = llvm::None; + union { /// When Kind == RK_Keyword, the string representing the keyword /// or symbol's spelling. Index: lib/Sema/SemaCodeComplete.cpp =================================================================== --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -170,9 +170,14 @@ void AdjustResultPriorityForDecl(Result &R); - void MaybeAddConstructorResults(Result R); + void MaybeAddConstructorResults( + Result R, llvm::Optional PreferredTypeName = llvm::None); public: + void AddConstructorResults( + const CXXRecordDecl *Record, Result R, + llvm::Optional PreferredTypedName = llvm::None); + explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, const CodeCompletionContext &CompletionContext, @@ -808,12 +813,58 @@ } } -void ResultBuilder::MaybeAddConstructorResults(Result R) { +static void AddTemplateParameterChunks(ASTContext &Context, + const PrintingPolicy &Policy, + const TemplateDecl *Template, + CodeCompletionBuilder &Result, + unsigned MaxParameters = 0, + unsigned Start = 0, + bool InDefaultArg = false); + +void ResultBuilder::AddConstructorResults( + const CXXRecordDecl *Record, Result R, + llvm::Optional PreferredTypedName) { + ASTContext &Context = SemaRef.Context; + QualType RecordTy = Context.getTypeDeclType(Record); + DeclarationName ConstructorName = + Context.DeclarationNames.getCXXConstructorName( + Context.getCanonicalType(RecordTy)); + DeclContext::lookup_result Ctors = Record->lookup(ConstructorName); + // If there are no constructor results, add a generic constructor with + // template args and one parameter with type's name. + if (Ctors.begin() == Ctors.end()) { + CodeCompletionBuilder Result(Allocator, CCTUInfo); + Result.AddTypedTextChunk(Result.getAllocator().CopyString( + PreferredTypedName ? *PreferredTypedName : Record->getName())); + if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) { + Result.AddChunk(CodeCompletionString::CK_LeftAngle); + AddTemplateParameterChunks(Context, SemaRef.getPrintingPolicy(), Template, + Result); + Result.AddChunk(CodeCompletionString::CK_RightAngle); + } + Result.AddChunk(CodeCompletionString::CK_LeftParen); + Result.AddPlaceholderChunk( + Result.getAllocator().CopyString(Record->getName())); + Result.AddChunk(CodeCompletionString::CK_RightParen); + Results.push_back( + CodeCompletionResult(Result.TakeString(), Record, CCP_CodePattern)); + return; + } + R.PreferredTypedName = PreferredTypedName; + for (DeclContext::lookup_iterator I = Ctors.begin(), E = Ctors.end(); I != E; + ++I) { + R.Declaration = *I; + R.CursorKind = getCursorKindForDecl(R.Declaration); + Results.push_back(R); + } +} + +void ResultBuilder::MaybeAddConstructorResults( + Result R, llvm::Optional PreferredTypedName) { if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration || !CompletionContext.wantConstructorResults()) return; - ASTContext &Context = SemaRef.Context; const NamedDecl *D = R.Declaration; const CXXRecordDecl *Record = nullptr; if (const ClassTemplateDecl *ClassTemplate = dyn_cast(D)) @@ -831,19 +882,7 @@ if (!Record) return; - - QualType RecordTy = Context.getTypeDeclType(Record); - DeclarationName ConstructorName - = Context.DeclarationNames.getCXXConstructorName( - Context.getCanonicalType(RecordTy)); - DeclContext::lookup_result Ctors = Record->lookup(ConstructorName); - for (DeclContext::lookup_iterator I = Ctors.begin(), - E = Ctors.end(); - I != E; ++I) { - R.Declaration = *I; - R.CursorKind = getCursorKindForDecl(R.Declaration); - Results.push_back(R); - } + AddConstructorResults(Record, R, PreferredTypedName); } static bool isConstructor(const Decl *ND) { @@ -2624,9 +2663,9 @@ const PrintingPolicy &Policy, const TemplateDecl *Template, CodeCompletionBuilder &Result, - unsigned MaxParameters = 0, - unsigned Start = 0, - bool InDefaultArg = false) { + unsigned MaxParameters, + unsigned Start, + bool InDefaultArg) { bool FirstParameter = true; // Prefer to take the template parameter names from the first declaration of @@ -2760,9 +2799,10 @@ } /// Add the name of the given declaration -static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, - const NamedDecl *ND, - CodeCompletionBuilder &Result) { +static void +AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, + const NamedDecl *ND, CodeCompletionBuilder &Result, + llvm::Optional PreferredTypedName = llvm::None) { DeclarationName Name = ND->getDeclName(); if (!Name) return; @@ -2809,6 +2849,7 @@ break; case DeclarationName::CXXConstructorName: { + StringRef TypedText; CXXRecordDecl *Record = nullptr; QualType Ty = Name.getCXXNameType(); if (const RecordType *RecordTy = Ty->getAs()) @@ -2816,14 +2857,18 @@ else if (const InjectedClassNameType *InjectedTy = Ty->getAs()) Record = InjectedTy->getDecl(); - else { - Result.AddTypedTextChunk( - Result.getAllocator().CopyString(ND->getNameAsString())); - break; - } + + if(PreferredTypedName) + TypedText = *PreferredTypedName; + else if (Record) + TypedText = Record->getName(); + else + TypedText = ND->getName(); Result.AddTypedTextChunk( - Result.getAllocator().CopyString(Record->getNameAsString())); + Result.getAllocator().CopyString(TypedText)); + if (!Record) + break; if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) { Result.AddChunk(CodeCompletionString::CK_LeftAngle); AddTemplateParameterChunks(Context, Policy, Template, Result); @@ -2979,7 +3024,7 @@ if (const FunctionDecl *Function = dyn_cast(ND)) { AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, Ctx, Policy); - AddTypedNameChunk(Ctx, Policy, ND, Result); + AddTypedNameChunk(Ctx, Policy, ND, Result, PreferredTypedName); Result.AddChunk(CodeCompletionString::CK_LeftParen); AddFunctionParameterChunks(PP, Policy, Function, Result); Result.AddChunk(CodeCompletionString::CK_RightParen); @@ -2991,7 +3036,7 @@ AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, Ctx, Policy); FunctionDecl *Function = FunTmpl->getTemplatedDecl(); - AddTypedNameChunk(Ctx, Policy, Function, Result); + AddTypedNameChunk(Ctx, Policy, Function, Result, PreferredTypedName); // Figure out which template parameters are deduced (or have default // arguments). @@ -5073,11 +5118,27 @@ } // Add completions for base classes. + PrintingPolicy Policy = getCompletionPrintingPolicy(*this); CodeCompletionBuilder Builder(Results.getAllocator(), Results.getCodeCompletionTUInfo()); - PrintingPolicy Policy = getCompletionPrintingPolicy(*this); bool SawLastInitializer = Initializers.empty(); CXXRecordDecl *ClassDecl = Constructor->getParent(); + + auto AddBase = [&](const CXXBaseSpecifier &Base) { + const auto *ND = Base.getType()->getAsCXXRecordDecl(); + Results.AddConstructorResults( + ND, + CodeCompletionResult(ND, SawLastInitializer ? CCP_NextInitializer + : CCP_MemberDeclaration), + StringRef(Builder.getAllocator().CopyString( + Base.getType().getAsString(Policy)))); + }; + auto AddField = [&](const FieldDecl *FD, CodeCompletionString *CCS) { + Results.AddResult(CodeCompletionResult( + CCS, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration, + CXCursor_MemberRef, CXAvailability_Available, FD)); + }; + for (const auto &Base : ClassDecl->bases()) { if (!InitializedBases.insert(Context.getCanonicalType(Base.getType())) .second) { @@ -5089,15 +5150,7 @@ continue; } - Builder.AddTypedTextChunk( - Results.getAllocator().CopyString( - Base.getType().getAsString(Policy))); - Builder.AddChunk(CodeCompletionString::CK_LeftParen); - Builder.AddPlaceholderChunk("args"); - Builder.AddChunk(CodeCompletionString::CK_RightParen); - Results.AddResult(CodeCompletionResult(Builder.TakeString(), - SawLastInitializer? CCP_NextInitializer - : CCP_MemberDeclaration)); + AddBase(Base); SawLastInitializer = false; } @@ -5113,15 +5166,7 @@ continue; } - Builder.AddTypedTextChunk( - Builder.getAllocator().CopyString( - Base.getType().getAsString(Policy))); - Builder.AddChunk(CodeCompletionString::CK_LeftParen); - Builder.AddPlaceholderChunk("args"); - Builder.AddChunk(CodeCompletionString::CK_RightParen); - Results.AddResult(CodeCompletionResult(Builder.TakeString(), - SawLastInitializer? CCP_NextInitializer - : CCP_MemberDeclaration)); + AddBase(Base); SawLastInitializer = false; } @@ -5139,18 +5184,25 @@ if (!Field->getDeclName()) continue; - Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( - Field->getIdentifier()->getName())); - Builder.AddChunk(CodeCompletionString::CK_LeftParen); - Builder.AddPlaceholderChunk("args"); - Builder.AddChunk(CodeCompletionString::CK_RightParen); - Results.AddResult(CodeCompletionResult(Builder.TakeString(), - SawLastInitializer? CCP_NextInitializer - : CCP_MemberDeclaration, - CXCursor_MemberRef, - CXAvailability_Available, - Field)); SawLastInitializer = false; + StringRef FieldName = Field->getIdentifier()->getName(); + // Check if field is a cxx class/struct/union, if not it can't have a + // constructor. + const CXXRecordDecl *RD = Field->getType()->getAsCXXRecordDecl(); + if (!RD) { + Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(FieldName)); + Builder.AddChunk(CodeCompletionString::CK_LeftParen); + Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString( + Field->getType().getAsString(Policy))); + Builder.AddChunk(CodeCompletionString::CK_RightParen); + AddField(Field, Builder.TakeString()); + continue; + } + Results.AddConstructorResults( + RD, + CodeCompletionResult(Field, SawLastInitializer ? CCP_NextInitializer + : CCP_MemberDeclaration), + Field->getIdentifier()->getName()); } Results.ExitScope(); Index: test/CodeCompletion/ctor-initializer.cpp =================================================================== --- test/CodeCompletion/ctor-initializer.cpp +++ test/CodeCompletion/ctor-initializer.cpp @@ -2,14 +2,14 @@ Base1() : {} // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:2:12 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:2:12 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s - // CHECK-CC1: COMPLETION: Pattern : member1(<#args#>) - // CHECK-CC1: COMPLETION: Pattern : member2(<#args#> + // CHECK-CC1: COMPLETION: Pattern : member1(<#int#>) + // CHECK-CC1: COMPLETION: Pattern : member2(<#float#>) Base1(int) : member1(123), {} // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:8:30 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:8:30 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s - // CHECK-CC2-NOT: COMPLETION: Pattern : member1(<#args#>) - // CHECK-CC2: COMPLETION: Pattern : member2(<#args#> + // CHECK-CC2-NOT: COMPLETION: Pattern : member1(<#int#>) + // CHECK-CC2: COMPLETION: Pattern : member2(<#float#>) int member1; float member2; @@ -25,31 +25,31 @@ Derived::Derived() : {} // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:25:22 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:25:22 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s -// CHECK-CC3: COMPLETION: Pattern : Base1(<#args#>) -// CHECK-CC3: COMPLETION: Pattern : deriv1(<#args#>) +// CHECK-CC3: COMPLETION: Base1 : Base1() +// CHECK-CC3: COMPLETION: Base1 : Base1(<#int#>) +// CHECK-CC3: COMPLETION: Pattern : deriv1(<#int#>) Derived::Derived(int) try : { } catch (...) { } -// RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:31:29 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s -// RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:31:29 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s -// CHECK-CC4: COMPLETION: Pattern : Base1(<#args#>) -// CHECK-CC4: COMPLETION: Pattern : deriv1(<#args#>) +// RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:32:29 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:32:29 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s Derived::Derived(float) try : Base1(), { } catch (...) { } -// RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:39:39 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s -// RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:39:39 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s -// CHECK-CC5-NOT: COMPLETION: Pattern : Base1(<#args#>) -// CHECK-CC5: COMPLETION: Pattern : deriv1(<#args#>) +// RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:38:39 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:38:39 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s +// CHECK-CC5-NOT: COMPLETION: Base1 : Base1() +// CHECK-CC5-NOT: COMPLETION: Base1 : Base1(<#int#>) +// CHECK-CC5: COMPLETION: Pattern : deriv1(<#int#>) struct A { A() : , member2() {} // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:49:9 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:49:9 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s - // CHECK-CC6: COMPLETION: Pattern : member1(<#args#> + // CHECK-CC6: COMPLETION: Pattern : member1(<#int#>) int member1, member2; }; @@ -57,20 +57,20 @@ B() : member2() {} // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:57:9 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:57:9 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s - // CHECK-CC7: COMPLETION: Pattern : member1(<#args#> + // CHECK-CC7: COMPLETION: Pattern : member1(<#int#>) // Check in the middle and at the end of identifier too. // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:57:13 %s -o - | FileCheck -check-prefix=CHECK-CC8 %s // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:57:16 %s -o - | FileCheck -check-prefix=CHECK-CC8 %s - // CHECK-CC8: COMPLETION: Pattern : member2(<#args#> + // CHECK-CC8: COMPLETION: Pattern : member2(<#int#>) int member1, member2; }; struct Base2 { - Base2(int); + Base2(int, float x = 3); }; struct Composition1 { - Composition1() : b2_elem() {} + Composition1() : b2_elem(2) {} // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:73:28 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:73:28 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s // CHECK-CC9: OVERLOAD: Base2(<#int#>) @@ -88,3 +88,7 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:84:35 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s Composition1 c1_elem; }; +// RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:84:20 %s -o - | FileCheck -check-prefix=CHECK-CC10 %s +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:84:20 %s -o - | FileCheck -check-prefix=CHECK-CC10 %s +// CHECK-CC10: Composition1 : c1_elem() +// CHECK-CC10: Composition1 : c1_elem(<#Base2#>) Index: test/CodeCompletion/ordinary-name-cxx11.cpp =================================================================== --- test/CodeCompletion/ordinary-name-cxx11.cpp +++ test/CodeCompletion/ordinary-name-cxx11.cpp @@ -62,6 +62,7 @@ // CHECK-CC1-NEXT: COMPLETION: wchar_t // CHECK-CC1-NEXT: COMPLETION: Pattern : while(<#condition#>){<#statements#> // CHECK-CC1: COMPLETION: X : X + // CHECK-CC1-NEXT: COMPLETION: Pattern : X(<#X#>) // CHECK-CC1-NEXT: COMPLETION: y : [#int#]y // CHECK-CC1-NEXT: COMPLETION: z : [#void#]z(<#int#>) @@ -197,6 +198,7 @@ // CHECK-CC4-NEXT: COMPLETION: volatile // CHECK-CC4-NEXT: COMPLETION: wchar_t // CHECK-CC4-NEXT: COMPLETION: X : X + // CHECK-CC4-NEXT: COMPLETION: Pattern : X(<#X#>) // CHECK-CC4-NEXT: COMPLETION: y : [#int#]y // CHECK-CC4-NEXT: COMPLETION: z : [#void#]z(<#int#>) @@ -257,5 +259,6 @@ // CHECK-NO-RTTI-NEXT: COMPLETION: wchar_t // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : while(<#condition#>){<#statements#> // CHECK-NO-RTTI: COMPLETION: X : X + // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : X(<#X#>) // CHECK-NO-RTTI-NEXT: COMPLETION: y : [#int#]y // CHECK-NO-RTTI-NEXT: COMPLETION: z : [#void#]z(<#int#>) Index: test/CodeCompletion/ordinary-name.cpp =================================================================== --- test/CodeCompletion/ordinary-name.cpp +++ test/CodeCompletion/ordinary-name.cpp @@ -55,6 +55,7 @@ // CHECK-CC1-NEXT: COMPLETION: wchar_t // CHECK-CC1-NEXT: COMPLETION: Pattern : while(<#condition#>){<#statements#> // CHECK-CC1: COMPLETION: X : X + // CHECK-CC1-NEXT: COMPLETION: Pattern : X(<#X#>) // CHECK-CC1-NEXT: COMPLETION: y : [#int#]y // CHECK-CC1-NEXT: COMPLETION: z : [#void#]z(<#int#>) @@ -171,6 +172,7 @@ // CHECK-CC4-NEXT: COMPLETION: volatile // CHECK-CC4-NEXT: COMPLETION: wchar_t // CHECK-CC4-NEXT: COMPLETION: X : X + // CHECK-CC4-NEXT: COMPLETION: Pattern : X(<#X#>) // CHECK-CC4-NEXT: COMPLETION: y : [#int#]y // CHECK-CC4-NEXT: COMPLETION: z : [#void#]z(<#int#>) @@ -225,5 +227,6 @@ // CHECK-NO-RTTI-NEXT: COMPLETION: wchar_t // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : while(<#condition#>){<#statements#> // CHECK-NO-RTTI: COMPLETION: X : X + // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : X(<#X#>) // CHECK-NO-RTTI-NEXT: COMPLETION: y : [#int#]y // CHECK-NO-RTTI-NEXT: COMPLETION: z : [#void#]z(<#int#>) Index: test/CodeCompletion/templates.cpp =================================================================== --- test/CodeCompletion/templates.cpp +++ test/CodeCompletion/templates.cpp @@ -19,7 +19,9 @@ v.foo(); // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:18:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: allocator<<#typename T#>> + // CHECK-CC1-NEXT: allocator<<#typename T#>>(<#allocator#>) // CHECK-CC1-NEXT: vector<<#typename T#>{#, <#typename Alloc#>#}> + // CHECK-CC1-NEXT: vector<<#typename T#>{#, <#typename Alloc#>#}>(<#vector#>) // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:5 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: foo // CHECK-CC2: in_base Index: test/Index/complete-ctor-inits.cpp =================================================================== --- test/Index/complete-ctor-inits.cpp +++ test/Index/complete-ctor-inits.cpp @@ -30,27 +30,33 @@ }; // RUN: c-index-test -code-completion-at=%s:18:10 %s | FileCheck -check-prefix=CHECK-CC1 %s -// CHECK-CC1: MemberRef:{TypedText a}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CC1: MemberRef:{TypedText b}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CC1: MemberRef:{TypedText c}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CC1: NotImplemented:{TypedText Virt}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CC1: NotImplemented:{TypedText X}{LeftParen (}{Placeholder args}{RightParen )} (7) -// CHECK-CC1: NotImplemented:{TypedText Y}{LeftParen (}{Placeholder args}{RightParen )} (35) +// CHECK-CC1: MemberRef:{TypedText a}{LeftParen (}{Placeholder int}{RightParen )} (35) +// CHECK-CC1: MemberRef:{TypedText b}{LeftParen (}{Placeholder int}{RightParen )} (35) +// CHECK-CC1: MemberRef:{TypedText c}{LeftParen (}{Placeholder int}{RightParen )} (35) +// CHECK-CC1: CXXConstructor:{TypedText Virt}{LeftParen (}{Placeholder const Virt &}{RightParen )} (35) +// CHECK-CC1: CXXConstructor:{TypedText Virt}{LeftParen (}{Placeholder Virt &&}{RightParen )} (35) +// CHECK-CC1: CXXConstructor:{TypedText X}{LeftParen (}{Placeholder int}{RightParen )} (7) +// CHECK-CC1: CXXConstructor:{TypedText Y}{LeftParen (}{Placeholder const Y &}{RightParen )} (35) +// CHECK-CC1: CXXConstructor:{TypedText Y}{LeftParen (}{Placeholder Y &&}{RightParen )} (35) // RUN: c-index-test -code-completion-at=%s:18:23 %s | FileCheck -check-prefix=CHECK-CC2 %s -// CHECK-CC2: MemberRef:{TypedText a}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CC2: MemberRef:{TypedText b}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CC2: MemberRef:{TypedText c}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CC2: NotImplemented:{TypedText Virt}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CC2: NotImplemented:{TypedText Y}{LeftParen (}{Placeholder args}{RightParen )} (7) +// CHECK-CC2: MemberRef:{TypedText a}{LeftParen (}{Placeholder int}{RightParen )} (35) +// CHECK-CC2: MemberRef:{TypedText b}{LeftParen (}{Placeholder int}{RightParen )} (35) +// CHECK-CC2: MemberRef:{TypedText c}{LeftParen (}{Placeholder int}{RightParen )} (35) +// CHECK-CC2: CXXConstructor:{TypedText Virt}{LeftParen (}{Placeholder const Virt &}{RightParen )} (35) +// CHECK-CC2: CXXConstructor:{TypedText Virt}{LeftParen (}{Placeholder Virt &&}{RightParen )} (35) +// CHECK-CC2: CXXConstructor:{TypedText Y}{LeftParen (}{Placeholder const Y &}{RightParen )} (7) +// CHECK-CC2: CXXConstructor:{TypedText Y}{LeftParen (}{Placeholder Y &&}{RightParen )} (7) // RUN: c-index-test -code-completion-at=%s:18:36 %s | FileCheck -check-prefix=CHECK-CC3 %s -// CHECK-CC3: MemberRef:{TypedText a}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CC3-NOT: MemberRef:{TypedText b}{LeftParen (}{Placeholder args}{RightParen )} -// CHECK-CC3: MemberRef:{TypedText c}{LeftParen (}{Placeholder args}{RightParen )} (7) -// CHECK-CC3-NOT: NotImplemented:{TypedText Virt}{LeftParen (}{Placeholder args}{RightParen )} -// CHECK-CC3: NotImplemented:{TypedText Y}{LeftParen (}{Placeholder args}{RightParen )} (35) +// CHECK-CC3: MemberRef:{TypedText a}{LeftParen (}{Placeholder int}{RightParen )} (35) +// CHECK-CC3-NOT: MemberRef:{TypedText b}{LeftParen (}{Placeholder int}{RightParen )} +// CHECK-CC3: MemberRef:{TypedText c}{LeftParen (}{Placeholder int}{RightParen )} (35) +// CHECK-CC3-NOT: CXXConstructor:{TypedText Virt}{LeftParen (}{Placeholder const Virt &}{RightParen )} (35) +// CHECK-CC3-NOT: CXXConstructor:{TypedText Virt}{LeftParen (}{Placeholder Virt &&}{RightParen )} (35) +// CHECK-CC3: CXXConstructor:{TypedText Y}{LeftParen (}{Placeholder const Y &}{RightParen )} (35) +// CHECK-CC3: CXXConstructor:{TypedText Y}{LeftParen (}{Placeholder Y &&}{RightParen )} (35) // RUN: c-index-test -code-completion-at=%s:22:10 -target i386-apple-darwin %s | FileCheck -check-prefix=CHECK-CC4 %s -// CHECK-CC4: MemberRef:{TypedText a}{LeftParen (}{Placeholder args}{RightParen )} (7) +// CHECK-CC4: MemberRef:{TypedText a}{LeftParen (}{Placeholder int}{RightParen )} (35) // RUN: c-index-test -code-completion-at=%s:26:10 %s Index: test/Index/complete-cxx-inline-methods.cpp =================================================================== --- test/Index/complete-cxx-inline-methods.cpp +++ test/Index/complete-cxx-inline-methods.cpp @@ -21,6 +21,13 @@ int value; MyCls *object; }; + +template +class X {}; + +class Y : public X { + Y() : X() {} +}; } // RUN: c-index-test -code-completion-at=%s:4:9 -std=c++98 %s | FileCheck %s @@ -35,10 +42,12 @@ // CHECK-NEXT: Container Kind: StructDecl // RUN: c-index-test -code-completion-at=%s:18:41 %s | FileCheck -check-prefix=CHECK-CTOR-INIT %s -// CHECK-CTOR-INIT: NotImplemented:{TypedText MyCls}{LeftParen (}{Placeholder args}{RightParen )} (7) -// CHECK-CTOR-INIT: MemberRef:{TypedText object}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CTOR-INIT: MemberRef:{TypedText value}{LeftParen (}{Placeholder args}{RightParen )} (35) +// CHECK-CTOR-INIT: ClassDecl:{TypedText MyCls}{LeftParen (}{Placeholder MyCls}{RightParen )} (40) +// CHECK-CTOR-INIT: MemberRef:{TypedText object}{LeftParen (}{Placeholder MyCls *}{RightParen )} (35) +// CHECK-CTOR-INIT: MemberRef:{TypedText value}{LeftParen (}{Placeholder int}{RightParen )} (35) // RUN: c-index-test -code-completion-at=%s:18:55 %s | FileCheck -check-prefix=CHECK-CTOR-INIT-2 %s -// CHECK-CTOR-INIT-2-NOT: NotImplemented:{TypedText MyCls}{LeftParen (}{Placeholder args}{RightParen )} -// CHECK-CTOR-INIT-2: MemberRef:{TypedText object}{LeftParen (}{Placeholder args}{RightParen )} (35) -// CHECK-CTOR-INIT-2: MemberRef:{TypedText value}{LeftParen (}{Placeholder args}{RightParen )} (7) +// CHECK-CTOR-INIT-2-NOT: ClassDecl:{TypedText MyCls}{LeftParen (}{Placeholder MyCls}{RightParen )} (40) +// CHECK-CTOR-INIT-2: MemberRef:{TypedText object}{LeftParen (}{Placeholder MyCls *}{RightParen )} (35) +// CHECK-CTOR-INIT-2: MemberRef:{TypedText value}{LeftParen (}{Placeholder int}{RightParen )} (35) +// RUN: c-index-test -code-completion-at=%s:29:9 %s | FileCheck -check-prefix=CHECK-CTOR-INIT-3 %s +// CHECK-CTOR-INIT-3: ClassDecl:{TypedText X}{LeftParen (}{Placeholder X}{RightParen )} (40)