forked from OSchip/llvm-project
Print the results of code-completion for overloading by displaying the
signature of the function with the current parameter highlighted as a placeholder. llvm-svn: 82593
This commit is contained in:
parent
05f477c177
commit
f0f51985a1
|
@ -273,6 +273,11 @@ public:
|
|||
/// \brief Retrieve the function type of the entity, regardless of how the
|
||||
/// function is stored.
|
||||
const FunctionType *getFunctionType() const;
|
||||
|
||||
/// \brief Create a new code-completion string that describes the function
|
||||
/// signature of this overload candidate.
|
||||
CodeCompletionString *CreateSignatureString(unsigned CurrentArg,
|
||||
Sema &S) const;
|
||||
};
|
||||
|
||||
/// \brief Deregisters and destroys this code-completion consumer.
|
||||
|
|
|
@ -169,26 +169,10 @@ PrintingCodeCompleteConsumer::ProcessOverloadCandidates(unsigned CurrentArg,
|
|||
OverloadCandidate *Candidates,
|
||||
unsigned NumCandidates) {
|
||||
for (unsigned I = 0; I != NumCandidates; ++I) {
|
||||
std::string ArgString;
|
||||
QualType ArgType;
|
||||
|
||||
if (FunctionDecl *Function = Candidates[I].getFunction()) {
|
||||
if (CurrentArg < Function->getNumParams()) {
|
||||
ArgString = Function->getParamDecl(CurrentArg)->getNameAsString();
|
||||
ArgType = Function->getParamDecl(CurrentArg)->getOriginalType();
|
||||
}
|
||||
} else if (const FunctionProtoType *Proto
|
||||
= dyn_cast<FunctionProtoType>(
|
||||
Candidates[I].getFunctionType())) {
|
||||
if (CurrentArg < Proto->getNumArgs())
|
||||
ArgType = Proto->getArgType(CurrentArg);
|
||||
}
|
||||
|
||||
if (ArgType.isNull())
|
||||
OS << "...\n"; // We have no prototype or we're matching an ellipsis.
|
||||
else {
|
||||
ArgType.getAsStringInternal(ArgString, SemaRef.Context.PrintingPolicy);
|
||||
OS << ArgString << "\n";
|
||||
if (CodeCompletionString *CCS
|
||||
= Candidates[I].CreateSignatureString(CurrentArg, SemaRef)) {
|
||||
OS << CCS->getAsString() << "\n";
|
||||
delete CCS;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -869,6 +869,68 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
CodeCompletionString *
|
||||
CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
|
||||
unsigned CurrentArg,
|
||||
Sema &S) const {
|
||||
CodeCompletionString *Result = new CodeCompletionString;
|
||||
FunctionDecl *FDecl = getFunction();
|
||||
const FunctionProtoType *Proto
|
||||
= dyn_cast<FunctionProtoType>(getFunctionType());
|
||||
if (!FDecl && !Proto) {
|
||||
// Function without a prototype. Just give the return type and a
|
||||
// highlighted ellipsis.
|
||||
const FunctionType *FT = getFunctionType();
|
||||
Result->AddTextChunk(
|
||||
FT->getResultType().getAsString(S.Context.PrintingPolicy).c_str());
|
||||
Result->AddTextChunk("(");
|
||||
Result->AddPlaceholderChunk("...");
|
||||
Result->AddTextChunk("(");
|
||||
return Result;
|
||||
}
|
||||
|
||||
if (FDecl)
|
||||
Result->AddTextChunk(FDecl->getNameAsString().c_str());
|
||||
else
|
||||
Result->AddTextChunk(
|
||||
Proto->getResultType().getAsString(S.Context.PrintingPolicy).c_str());
|
||||
|
||||
Result->AddTextChunk("(");
|
||||
unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
|
||||
for (unsigned I = 0; I != NumParams; ++I) {
|
||||
if (I)
|
||||
Result->AddTextChunk(", ");
|
||||
|
||||
std::string ArgString;
|
||||
QualType ArgType;
|
||||
|
||||
if (FDecl) {
|
||||
ArgString = FDecl->getParamDecl(I)->getNameAsString();
|
||||
ArgType = FDecl->getParamDecl(I)->getOriginalType();
|
||||
} else {
|
||||
ArgType = Proto->getArgType(I);
|
||||
}
|
||||
|
||||
ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
|
||||
|
||||
if (I == CurrentArg)
|
||||
Result->AddPlaceholderChunk(ArgString.c_str());
|
||||
else
|
||||
Result->AddTextChunk(ArgString.c_str());
|
||||
}
|
||||
|
||||
if (Proto && Proto->isVariadic()) {
|
||||
Result->AddTextChunk(", ");
|
||||
if (CurrentArg < NumParams)
|
||||
Result->AddTextChunk("...");
|
||||
else
|
||||
Result->AddPlaceholderChunk("...");
|
||||
}
|
||||
Result->AddTextChunk(")");
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct SortCodeCompleteResult {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
|
|
|
@ -18,11 +18,11 @@ void f();
|
|||
void test() {
|
||||
f(Y(), 0, 0);
|
||||
// RUN: clang-cc -fsyntax-only -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CC1 %s &&
|
||||
// CHECK-CC1: int ZZ
|
||||
// CHECK-NEXT-CC1: int j
|
||||
// CHECK-NEXT-CC1: float y
|
||||
// CHECK-CC1: f(struct N::Y y, <#int ZZ#>)
|
||||
// CHECK-NEXT-CC1: f(int i, <#int j#>, int k)
|
||||
// CHECK-NEXT-CC1: f(float x, <#float y#>)
|
||||
// RUN: clang-cc -fsyntax-only -code-completion-at=%s:19:13 %s -o - | FileCheck -check-prefix=CC2 %s &&
|
||||
// FIXME: two ellipses are showing up when they shouldn't
|
||||
// CHECK-CC2: int k
|
||||
// FIXME: two extra overloads are showing up!
|
||||
// CHECK-CC2: f(int i, int j, <#int k#>)
|
||||
// RUN: true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue