Introduce a new libclang function, clang_getCursorDisplayName(), which
authorDouglas Gregor <dgregor@apple.com>
Sat, 2 Oct 2010 22:49:11 +0000 (22:49 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 2 Oct 2010 22:49:11 +0000 (22:49 +0000)
produces a simple "display" name that captures the
arguments/parameters for a function, function template, class
template, or class template specialization.

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

include/clang-c/Index.h
test/Index/print-display-names.cpp [new file with mode: 0644]
tools/c-index-test/c-index-test.c
tools/libclang/CIndex.cpp
tools/libclang/libclang.darwin.exports
tools/libclang/libclang.exports

index f78df52d83eaa066ac13d04ec7f0e09b974b06e8..707c0df20170a786f8b4ab3005b50860eafbe950 100644 (file)
@@ -1884,6 +1884,15 @@ CINDEX_LINKAGE CXString clang_constructUSR_ObjCProperty(const char *property,
  */
 CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor);
 
+/**
+ * \brief Retrieve the display name for the entity referenced by this cursor.
+ *
+ * The display name contains extra information that helps identify the cursor,
+ * such as the parameters of a function or template or the arguments of a 
+ * class template specialization.
+ */
+CINDEX_LINKAGE CXString clang_getCursorDisplayName(CXCursor);
+  
 /** \brief For a cursor that is a reference, retrieve a cursor representing the
  * entity that it references.
  *
diff --git a/test/Index/print-display-names.cpp b/test/Index/print-display-names.cpp
new file mode 100644 (file)
index 0000000..94fe466
--- /dev/null
@@ -0,0 +1,20 @@
+template<typename T, typename>
+class ClassTmpl { };
+
+typedef int Integer;
+
+template class ClassTmpl<Integer, Integer>;
+
+void f(ClassTmpl<float, Integer> p);
+
+template<typename T>
+void g(ClassTmpl<T, T>);
+
+template<> void g<int>(ClassTmpl<int, int>);
+
+// RUN: c-index-test -test-load-source all-display %s | FileCheck %s
+// CHECK: print-display-names.cpp:2:7: ClassTemplate=ClassTmpl<T, typename>:2:7
+// CHECK: print-display-names.cpp:6:16: ClassDecl=ClassTmpl<Integer, Integer>:6:16 (Definition)
+// CHECK: print-display-names.cpp:8:6: FunctionDecl=f(ClassTmpl<float, Integer>):8:6
+// CHECK: print-display-names.cpp:11:6: FunctionTemplate=g(ClassTmpl<T, T>):11:6
+// CHECK: print-display-names.cpp:13:17: FunctionDecl=g<>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6]
index f83162295d4dfbf1bc36973df5b4f7afef3fd621..9c5a67d30495c904a30ff6c54b2dfb87e66d4ac3 100644 (file)
@@ -156,6 +156,8 @@ int parse_remapped_files(int argc, const char **argv, int start_arg,
 /* Pretty-printing.                                                           */
 /******************************************************************************/
 
+int want_display_name = 0;
+
 static void PrintCursor(CXCursor Cursor) {
   if (clang_isInvalid(Cursor.kind)) {
     CXString ks = clang_getCursorKindSpelling(Cursor.kind);
@@ -171,7 +173,8 @@ static void PrintCursor(CXCursor Cursor) {
     unsigned num_overridden;
 
     ks = clang_getCursorKindSpelling(Cursor.kind);
-    string = clang_getCursorSpelling(Cursor);
+    string = want_display_name? clang_getCursorDisplayName(Cursor) 
+                              : clang_getCursorSpelling(Cursor);
     printf("%s=%s", clang_getCString(ks),
                     clang_getCString(string));
     clang_disposeString(ks);
@@ -604,6 +607,11 @@ static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
 
     /* Perform some simple filtering. */
     if (!strcmp(filter, "all") || !strcmp(filter, "local")) ck = NULL;
+    else if (!strcmp(filter, "all-display") || 
+             !strcmp(filter, "local-display")) {
+      ck = NULL;
+      want_display_name = 1;
+    }
     else if (!strcmp(filter, "none")) K = (enum CXCursorKind) ~0;
     else if (!strcmp(filter, "category")) K = CXCursor_ObjCCategoryDecl;
     else if (!strcmp(filter, "interface")) K = CXCursor_ObjCInterfaceDecl;
@@ -661,7 +669,8 @@ int perform_test_load_source(int argc, const char **argv,
   int result;
   
   Idx = clang_createIndex(/* excludeDeclsFromPCH */
-                          !strcmp(filter, "local") ? 1 : 0,
+                          (!strcmp(filter, "local") || 
+                           !strcmp(filter, "local-display"))? 1 : 0,
                           /* displayDiagnosics=*/1);
 
   if (UseExternalASTs && strlen(UseExternalASTs))
index 4f551b4190e1a9e0415cf8deaed8b4026c171d66..57367dd1596f71743bb83b429f3edf49e32e4928 100644 (file)
@@ -33,6 +33,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/System/Mutex.h"
 #include "llvm/System/Program.h"
@@ -2705,6 +2706,90 @@ CXString clang_getCursorSpelling(CXCursor C) {
   return createCXString("");
 }
 
+CXString clang_getCursorDisplayName(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return clang_getCursorSpelling(C);
+  
+  Decl *D = getCursorDecl(C);
+  if (!D)
+    return createCXString("");
+
+  PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
+    D = FunTmpl->getTemplatedDecl();
+  
+  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+    llvm::SmallString<64> Str;
+    llvm::raw_svector_ostream OS(Str);
+    OS << Function->getNameAsString();
+    if (Function->getPrimaryTemplate())
+      OS << "<>";
+    OS << "(";
+    for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
+      if (I)
+        OS << ", ";
+      OS << Function->getParamDecl(I)->getType().getAsString(Policy);
+    }
+    
+    if (Function->isVariadic()) {
+      if (Function->getNumParams())
+        OS << ", ";
+      OS << "...";
+    }
+    OS << ")";
+    return createCXString(OS.str());
+  }
+  
+  if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
+    llvm::SmallString<64> Str;
+    llvm::raw_svector_ostream OS(Str);
+    OS << ClassTemplate->getNameAsString();
+    OS << "<";
+    TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
+    for (unsigned I = 0, N = Params->size(); I != N; ++I) {
+      if (I)
+        OS << ", ";
+      
+      NamedDecl *Param = Params->getParam(I);
+      if (Param->getIdentifier()) {
+        OS << Param->getIdentifier()->getName();
+        continue;
+      }
+      
+      // There is no parameter name, which makes this tricky. Try to come up
+      // with something useful that isn't too long.
+      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
+        OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
+      else if (NonTypeTemplateParmDecl *NTTP
+                                    = dyn_cast<NonTypeTemplateParmDecl>(Param))
+        OS << NTTP->getType().getAsString(Policy);
+      else
+        OS << "template<...> class";
+    }
+    
+    OS << ">";
+    return createCXString(OS.str());
+  }
+  
+  if (ClassTemplateSpecializationDecl *ClassSpec
+                              = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+    // If the type was explicitly written, use that.
+    if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
+      return createCXString(TSInfo->getType().getAsString(Policy));
+    
+    llvm::SmallString<64> Str;
+    llvm::raw_svector_ostream OS(Str);
+    OS << ClassSpec->getNameAsString();
+    OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                            ClassSpec->getTemplateArgs().getFlatArgumentList(),
+                                      ClassSpec->getTemplateArgs().flat_size(),
+                                                                Policy);
+    return createCXString(OS.str());
+  }
+  
+  return clang_getCursorSpelling(C);
+}
+  
 CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
   switch (Kind) {
   case CXCursor_FunctionDecl:
index d2e246e7e8dd94e05d7cfda9ff15de58bca835c6..0682a58e6b97b4c32b83b8e1cbac9bf798b10a2b 100644 (file)
@@ -42,6 +42,7 @@ _clang_getCompletionPriority
 _clang_getCursor
 _clang_getCursorAvailability
 _clang_getCursorDefinition
+_clang_getCursorDisplayName
 _clang_getCursorExtent
 _clang_getCursorKind
 _clang_getCursorKindSpelling
index d8ae1e47b39cdb73f0eab2209c862606a10ac7e1..e7e4f8be14dcbc1aa746a429cb93e81de193a06e 100644 (file)
@@ -42,6 +42,7 @@ clang_getCompletionPriority
 clang_getCursor
 clang_getCursorAvailability
 clang_getCursorDefinition
+clang_getCursorDisplayName
 clang_getCursorExtent
 clang_getCursorKind
 clang_getCursorKindSpelling