Index: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h =================================================================== --- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h +++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h @@ -1114,9 +1114,13 @@ /// \param Candidates an array of overload candidates. /// /// \param NumCandidates the number of overload candidates + /// + /// \param OpenParLoc location of the opening parenthesis of the argument + /// list. virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, - unsigned NumCandidates) {} + unsigned NumCandidates, + SourceLocation OpenParLoc) {} //@} /// Retrieve the allocator that will be used to allocate @@ -1166,7 +1170,8 @@ void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, - unsigned NumCandidates) override; + unsigned NumCandidates, + SourceLocation OpenParLoc) override; bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override; Index: cfe/trunk/include/clang/Sema/Sema.h =================================================================== --- cfe/trunk/include/clang/Sema/Sema.h +++ cfe/trunk/include/clang/Sema/Sema.h @@ -10230,9 +10230,11 @@ const VirtSpecifiers *VS = nullptr); void CodeCompleteBracketDeclarator(Scope *S); void CodeCompleteCase(Scope *S); - void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef Args); + void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef Args, + SourceLocation OpenParLoc); void CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc, - ArrayRef Args); + ArrayRef Args, + SourceLocation OpenParLoc); void CodeCompleteInitializer(Scope *S, Decl *D); void CodeCompleteReturn(Scope *S); void CodeCompleteAfterIf(Scope *S); Index: cfe/trunk/lib/Frontend/ASTUnit.cpp =================================================================== --- cfe/trunk/lib/Frontend/ASTUnit.cpp +++ cfe/trunk/lib/Frontend/ASTUnit.cpp @@ -1911,8 +1911,10 @@ void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, - unsigned NumCandidates) override { - Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates); + unsigned NumCandidates, + SourceLocation OpenParLoc) override { + Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates, + OpenParLoc); } CodeCompletionAllocator &getAllocator() override { Index: cfe/trunk/lib/Parse/ParseDecl.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp +++ cfe/trunk/lib/Parse/ParseDecl.cpp @@ -2304,7 +2304,7 @@ auto ConstructorCompleter = [&, ThisVarDecl] { Actions.CodeCompleteConstructor( getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(), - ThisDecl->getLocation(), Exprs); + ThisDecl->getLocation(), Exprs, T.getOpenLocation()); }; if (ThisVarDecl) { // ParseExpressionList can sometimes succeed even when ThisDecl is not Index: cfe/trunk/lib/Parse/ParseExpr.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseExpr.cpp +++ cfe/trunk/lib/Parse/ParseExpr.cpp @@ -1650,7 +1650,8 @@ CommaLocsTy CommaLocs; if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteCall(getCurScope(), LHS.get(), None); + Actions.CodeCompleteCall(getCurScope(), LHS.get(), None, + PT.getOpenLocation()); cutOffParsing(); return ExprError(); } @@ -1658,8 +1659,9 @@ if (OpKind == tok::l_paren || !LHS.isInvalid()) { if (Tok.isNot(tok::r_paren)) { if (ParseExpressionList(ArgExprs, CommaLocs, [&] { - Actions.CodeCompleteCall(getCurScope(), LHS.get(), ArgExprs); - })) { + Actions.CodeCompleteCall(getCurScope(), LHS.get(), ArgExprs, + PT.getOpenLocation()); + })) { (void)Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); } else if (LHS.isInvalid()) { Index: cfe/trunk/lib/Parse/ParseExprCXX.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseExprCXX.cpp +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp @@ -1687,7 +1687,7 @@ if (ParseExpressionList(Exprs, CommaLocs, [&] { Actions.CodeCompleteConstructor( getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DS.getEndLoc(), Exprs); + DS.getEndLoc(), Exprs, T.getOpenLocation()); })) { SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); @@ -2821,7 +2821,7 @@ DeclaratorInfo).get(); Actions.CodeCompleteConstructor( getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DeclaratorInfo.getEndLoc(), ConstructorArgs); + DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); })) { SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); return ExprError(); Index: cfe/trunk/lib/Parse/ParseOpenMP.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseOpenMP.cpp +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp @@ -415,11 +415,14 @@ ExprVector Exprs; CommaLocsTy CommaLocs; - if (ParseExpressionList(Exprs, CommaLocs, [this, OmpPrivParm, &Exprs] { - Actions.CodeCompleteConstructor( - getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(), - OmpPrivParm->getLocation(), Exprs); - })) { + SourceLocation LParLoc = T.getOpenLocation(); + if (ParseExpressionList( + Exprs, CommaLocs, [this, OmpPrivParm, LParLoc, &Exprs] { + Actions.CodeCompleteConstructor( + getCurScope(), + OmpPrivParm->getType()->getCanonicalTypeInternal(), + OmpPrivParm->getLocation(), Exprs, LParLoc); + })) { Actions.ActOnInitializerError(OmpPrivParm); SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); } else { Index: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp =================================================================== --- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp +++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp @@ -20,8 +20,8 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" #include "clang/Basic/IdentifierTable.h" -#include "clang/Sema/Sema.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Sema/Sema.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -29,6 +29,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -624,16 +625,17 @@ return OS.str(); } -void -PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef, - unsigned CurrentArg, - OverloadCandidate *Candidates, - unsigned NumCandidates) { +void PrintingCodeCompleteConsumer::ProcessOverloadCandidates( + Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates, + unsigned NumCandidates, SourceLocation OpenParLoc) { + OS << "OPENING_PAREN_LOC: "; + OpenParLoc.print(OS, SemaRef.getSourceManager()); + OS << "\n"; + for (unsigned I = 0; I != NumCandidates; ++I) { - if (CodeCompletionString *CCS - = Candidates[I].CreateSignatureString(CurrentArg, SemaRef, - getAllocator(), CCTUInfo, - includeBriefComments())) { + if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString( + CurrentArg, SemaRef, getAllocator(), CCTUInfo, + includeBriefComments())) { OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n"; } } Index: cfe/trunk/lib/Sema/SemaCodeComplete.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp @@ -4435,10 +4435,11 @@ return ParamType; } -static void CodeCompleteOverloadResults(Sema &SemaRef, Scope *S, - MutableArrayRef Candidates, - unsigned CurrentArg, - bool CompleteExpressionWithCurrentArg = true) { +static void +CodeCompleteOverloadResults(Sema &SemaRef, Scope *S, + MutableArrayRef Candidates, + unsigned CurrentArg, SourceLocation OpenParLoc, + bool CompleteExpressionWithCurrentArg = true) { QualType ParamType; if (CompleteExpressionWithCurrentArg) ParamType = getParamType(SemaRef, Candidates, CurrentArg); @@ -4449,12 +4450,12 @@ SemaRef.CodeCompleteExpression(S, ParamType); if (!Candidates.empty()) - SemaRef.CodeCompleter->ProcessOverloadCandidates(SemaRef, CurrentArg, - Candidates.data(), - Candidates.size()); + SemaRef.CodeCompleter->ProcessOverloadCandidates( + SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc); } -void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef Args) { +void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef Args, + SourceLocation OpenParLoc) { if (!CodeCompleter) return; @@ -4552,12 +4553,13 @@ } mergeCandidatesWithResults(*this, Results, CandidateSet, Loc); - CodeCompleteOverloadResults(*this, S, Results, Args.size(), + CodeCompleteOverloadResults(*this, S, Results, Args.size(), OpenParLoc, !CandidateSet.empty()); } void Sema::CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc, - ArrayRef Args) { + ArrayRef Args, + SourceLocation OpenParLoc) { if (!CodeCompleter) return; @@ -4592,7 +4594,7 @@ SmallVector Results; mergeCandidatesWithResults(*this, Results, CandidateSet, Loc); - CodeCompleteOverloadResults(*this, S, Results, Args.size()); + CodeCompleteOverloadResults(*this, S, Results, Args.size(), OpenParLoc); } void Sema::CodeCompleteInitializer(Scope *S, Decl *D) { Index: cfe/trunk/test/CodeCompletion/paren_locs.cpp =================================================================== --- cfe/trunk/test/CodeCompletion/paren_locs.cpp +++ cfe/trunk/test/CodeCompletion/paren_locs.cpp @@ -0,0 +1,33 @@ +void foo(int a, int b); +void foo(int a, int b, int c); + +void test() { + foo(10, ); + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:5:10 %s -o - \ + // RUN: | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1: OPENING_PAREN_LOC: {{.*}}paren_locs.cpp:5:6 + +#define FOO foo( + FOO 10, ); +#undef FOO + // RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:11:10 %s -o - \ + // RUN: | FileCheck -check-prefix=CHECK-CC2 %s + // CHECK-CC2: OPENING_PAREN_LOC: {{.*}}paren_locs.cpp:11:3 + + struct Foo { + Foo(int a, int b); + Foo(int a, int b, int c); + }; + Foo a(10, ); + // RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:21:12 %s -o - \ + // RUN: | FileCheck -check-prefix=CHECK-CC3 %s + // CHECK-CC3: OPENING_PAREN_LOC: {{.*}}paren_locs.cpp:21:8 + Foo(10, ); + // RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:25:10 %s -o - \ + // RUN: | FileCheck -check-prefix=CHECK-CC4 %s + // CHECK-CC4: OPENING_PAREN_LOC: {{.*}}paren_locs.cpp:25:6 + new Foo(10, ); + // RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:29:15 %s -o - \ + // RUN: | FileCheck -check-prefix=CHECK-CC5 %s + // CHECK-CC5: OPENING_PAREN_LOC: {{.*}}paren_locs.cpp:29:10 +} Index: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp =================================================================== --- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp +++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp @@ -653,7 +653,8 @@ void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, - unsigned NumCandidates) override { + unsigned NumCandidates, + SourceLocation OpenParLoc) override { StoredResults.reserve(StoredResults.size() + NumCandidates); for (unsigned I = 0; I != NumCandidates; ++I) { CodeCompletionString *StoredCompletion