зеркало из https://github.com/microsoft/clang-1.git
Introduce a new libclang function, clang_getCursorDisplayName(), which
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
This commit is contained in:
Родитель
3f0fee315c
Коммит
358559d8d7
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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]
|
|
@ -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))
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -42,6 +42,7 @@ _clang_getCompletionPriority
|
|||
_clang_getCursor
|
||||
_clang_getCursorAvailability
|
||||
_clang_getCursorDefinition
|
||||
_clang_getCursorDisplayName
|
||||
_clang_getCursorExtent
|
||||
_clang_getCursorKind
|
||||
_clang_getCursorKindSpelling
|
||||
|
|
|
@ -42,6 +42,7 @@ clang_getCompletionPriority
|
|||
clang_getCursor
|
||||
clang_getCursorAvailability
|
||||
clang_getCursorDefinition
|
||||
clang_getCursorDisplayName
|
||||
clang_getCursorExtent
|
||||
clang_getCursorKind
|
||||
clang_getCursorKindSpelling
|
||||
|
|
Загрузка…
Ссылка в новой задаче