]> granicus.if.org Git - clang/commitdiff
Print the results of code-completion for overloading by displaying the
authorDouglas Gregor <dgregor@apple.com>
Wed, 23 Sep 2009 00:34:09 +0000 (00:34 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 23 Sep 2009 00:34:09 +0000 (00:34 +0000)
signature of the function with the current parameter highlighted as a
placeholder.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82593 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/CodeCompleteConsumer.h
lib/Sema/CodeCompleteConsumer.cpp
lib/Sema/SemaCodeComplete.cpp
test/CodeCompletion/call.cpp

index 058012cd1299342cabefdafcc225d0e4be473b48..d2f509df7b2ccd53085c3ab0945b90b685cd5d06 100644 (file)
@@ -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.
index f1b475a6df5c8858453722039c36c101ef25e465..a3d4d92fc3cc5b29f8bad3ff7924c852fdcda4b2 100644 (file)
@@ -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;
     }
   }
 
index 754d505bc0212cf24a044bc71ebfc7273490d4b3..f879dae6961bf0c5444d0a2445626e96faed4977 100644 (file)
@@ -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;
index 9a6f578abc91018b85c1ef66b0265370f8c28233..448b8ebb6ef232ce5467fda936e2be54765277f6 100644 (file)
@@ -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
 }