Produce detailed function signatures which include parameter names

This commit is contained in:
romix 2017-12-27 15:49:26 -08:00
parent 3c6cf1017c
commit 8bdce31789
20 changed files with 123 additions and 54 deletions

View File

@ -1072,6 +1072,108 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
} // namespace
// Build a detailed function signature, including argument names.
static std::string get_function_signature(IndexFile* db,
NamespaceHelper* ns,
const CXIdxDeclInfo* decl) {
// Build the function name, with scope and parameters
ClangCursor decl_cursor = decl->cursor;
std::string type_desc = decl_cursor.get_type_description();
int args_num = clang_Cursor_getNumArguments(decl->cursor);
std::string function_name =
ns->QualifiedName(decl->semanticContainer, decl->entityInfo->name);
std::vector<std::string> arg_names;
for (int i = 0; i < args_num; i++) {
CXCursor arg = clang_Cursor_getArgument(decl->cursor, i);
auto id = ::ToString(clang_getCursorDisplayName(arg));
arg_names.push_back(id);
}
if (clang_Cursor_isVariadic(decl->cursor)) {
arg_names.push_back("");
args_num++;
}
size_t balance = 0, offset;
size_t closing_bracket_offset = 0;
// Scan the function type backwards.
// First pass: find the position of the closing bracket in the type.
for (offset = type_desc.size(); offset;) {
offset--;
// Remember that ) was seen.
if (type_desc[offset] == ')') {
balance++;
if (balance == 1) {
closing_bracket_offset = offset;
}
}
// Balanced paren pair that may appear before the paren enclosing
// function parameters, see clang/lib/AST/TypePrinter.cpp
else if (type_desc[offset] == '(' && --balance == 0 &&
!((offset >= 5 && !type_desc.compare(offset - 5, 5, "throw")) ||
(offset >= 6 && !type_desc.compare(offset - 6, 6, "typeof")) ||
(offset >= 7 && !type_desc.compare(offset - 7, 7, "_Atomic")) ||
(offset >= 8 && !type_desc.compare(offset - 8, 8, "decltype")) ||
(offset >= 8 && !type_desc.compare(offset - 8, 8, "noexcept")) ||
(offset >= 13 &&
!type_desc.compare(offset - 13, 13, "__attribute__"))))
break;
}
size_t function_name_offset = offset;
if (closing_bracket_offset > 0) {
// Insert the name of the last parameter right before the closing bracket.
int arg_idx = args_num - 1;
if (args_num > 0) {
if (!arg_names[arg_idx].empty()) {
type_desc.insert(closing_bracket_offset, arg_names[arg_idx]);
// Insert a space between the type and the argument name if required.
if (!isspace(type_desc[closing_bracket_offset - 1]) &&
type_desc[closing_bracket_offset - 1] != '*' &&
type_desc[closing_bracket_offset - 1] != '&')
type_desc.insert(closing_bracket_offset, " ");
}
arg_idx--;
}
balance = 1;
// Second pass: Insert argument names before each comma.
for (offset = closing_bracket_offset;
offset >= function_name_offset && args_num > 0;) {
offset--;
// Remember that ) was seen.
if (type_desc[offset] == ')' || type_desc[offset] == '>' ||
type_desc[offset] == ']' || type_desc[offset] == '}') {
balance++;
} else if (type_desc[offset] == ',' && balance == 1) {
if (!arg_names[arg_idx].empty()) {
type_desc.insert(offset, arg_names[arg_idx]);
// Insert a space between the type and the argument name if required.
if (!isspace(type_desc[offset - 1]) && type_desc[offset - 1] != '*' &&
type_desc[offset - 1] != '&')
type_desc.insert(offset, " ");
}
arg_idx--;
} else if (type_desc[offset] == '<' || type_desc[offset] == '[' ||
type_desc[offset] == '{')
balance--;
else if (type_desc[offset] == '(' && --balance == 0)
break;
}
}
if (function_name_offset > 0) {
type_desc.insert(function_name_offset, function_name);
} else {
type_desc.append(" " + function_name);
}
return type_desc;
}
void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
if (!kIndexStdDeclarations &&
clang_Location_isInSystemHeader(
@ -1310,40 +1412,7 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
// Build detailed name. The type desc looks like void (void *). We
// insert the qualified name before the first '('.
std::string qualified_name =
ns->QualifiedName(decl->semanticContainer, func->def.short_name);
std::string type_desc = decl_cursor.get_type_description();
{
size_t balance = 0, offset;
for (offset = type_desc.size(); offset;) {
offset--;
if (type_desc[offset] == ')')
balance++;
// Balanced paren pair that may appear before the paren enclosing
// function parameters, see clang/lib/AST/TypePrinter.cpp
else if (type_desc[offset] == '(' && --balance == 0 &&
!((offset >= 5 &&
!type_desc.compare(offset - 5, 5, "throw")) ||
(offset >= 6 &&
!type_desc.compare(offset - 6, 6, "typeof")) ||
(offset >= 7 &&
!type_desc.compare(offset - 7, 7, "_Atomic")) ||
(offset >= 8 &&
!type_desc.compare(offset - 8, 8, "decltype")) ||
(offset >= 8 &&
!type_desc.compare(offset - 8, 8, "noexcept")) ||
(offset >= 13 &&
!type_desc.compare(offset - 13, 13, "__attribute__"))))
break;
}
if (offset > 0) {
type_desc.insert(offset, qualified_name);
func->def.detailed_name = type_desc;
} else {
// type_desc is probably the name of a typedef.
func->def.detailed_name = type_desc + " " + qualified_name;
}
}
func->def.detailed_name = get_function_signature(db, ns, decl);
// CXCursor_OverloadedDeclRef in templates are not processed by
// OnIndexReference, thus we use TemplateVisitor to collect function

View File

@ -205,7 +205,7 @@ OUTPUT: make_functions.cc
"is_operator": false,
"usr": "c:@FT@>2#T#pTMakeUnique#P&&t0.1#*t0.0#",
"short_name": "MakeUnique",
"detailed_name": "T *MakeUnique(Args &&...)",
"detailed_name": "T *MakeUnique(Args &&... args)",
"declarations": [],
"definition_spelling": "4:4-4:14",
"definition_extent": "4:1-6:2",
@ -219,7 +219,7 @@ OUTPUT: make_functions.cc
"is_operator": false,
"usr": "c:@FT@>2#T#pTmaKE_NoRefs#Pt0.1#*t0.0#",
"short_name": "maKE_NoRefs",
"detailed_name": "T *maKE_NoRefs(Args...)",
"detailed_name": "T *maKE_NoRefs(Args... args)",
"declarations": [],
"definition_spelling": "9:4-9:15",
"definition_extent": "9:1-11:2",

View File

@ -15,7 +15,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@foo#I#I#",
"short_name": "foo",
"detailed_name": "int foo(int, int)",
"detailed_name": "int foo(int a, int b)",
"declarations": [{
"spelling": "1:5-1:8",
"extent": "1:1-1:18",

View File

@ -11,7 +11,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@foo#I#I#",
"short_name": "foo",
"detailed_name": "void foo(int, int)",
"detailed_name": "void foo(int a, int b)",
"declarations": [{
"spelling": "1:6-1:9",
"extent": "1:1-1:23",

View File

@ -13,7 +13,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@N@hello@F@foo#I#I#",
"short_name": "foo",
"detailed_name": "void hello::foo(int, int)",
"detailed_name": "void hello::foo(int a, int b)",
"declarations": [{
"spelling": "2:6-2:9",
"extent": "2:1-2:23",

View File

@ -20,7 +20,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@N@ns@F@Accept#I#",
"short_name": "Accept",
"detailed_name": "void ns::Accept(int)",
"detailed_name": "void ns::Accept(int a)",
"declarations": [],
"definition_spelling": "3:8-3:14",
"definition_extent": "3:3-3:24",

View File

@ -64,7 +64,7 @@ OUTPUT:
"is_operator": true,
"usr": "c:@S@Foo@F@operator()#I#I#",
"short_name": "operator()",
"detailed_name": "int Foo::operator()(int, int)",
"detailed_name": "int Foo::operator()(int a, int b)",
"declarations": [{
"spelling": "4:7-4:17",
"extent": "4:3-4:31",

View File

@ -73,7 +73,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@S@basic_string>#C#$@N@std@S@char_traits>#C#$@N@std@S@allocator>#C#",
"short_name": "LoadCompilationEntriesFromDirectory",
"detailed_name": "std::vector<CompilationEntry> LoadCompilationEntriesFromDirectory(const std::string &)",
"detailed_name": "std::vector<CompilationEntry> LoadCompilationEntriesFromDirectory(const std::string &project_directory)",
"declarations": [{
"spelling": "12:31-12:66",
"extent": "12:1-12:104",

View File

@ -96,7 +96,7 @@ OUTPUT: static_function_in_type.cc
"is_operator": false,
"usr": "c:@N@ns@S@Foo@F@Register#*$@N@ns@S@Manager#S",
"short_name": "Register",
"detailed_name": "void ns::Foo::Register(ns::Manager *)",
"detailed_name": "void ns::Foo::Register(ns::Manager *m)",
"declarations": [],
"definition_spelling": "5:11-5:19",
"definition_extent": "5:1-6:2",

View File

@ -17,7 +17,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@called#b#b#",
"short_name": "called",
"detailed_name": "bool called(bool, bool)",
"detailed_name": "bool called(bool a, bool b)",
"declarations": [{
"spelling": "3:6-3:12",
"extent": "3:1-3:28",

View File

@ -33,7 +33,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@S@Wrapper@F@Wrapper#I#",
"short_name": "Wrapper",
"detailed_name": "void Wrapper::Wrapper(int)",
"detailed_name": "void Wrapper::Wrapper(int i)",
"declarations": [{
"spelling": "2:3-2:10",
"extent": "2:3-2:17",

View File

@ -40,7 +40,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@foo#*$@S@ForwardType#$@S@ImplementedType#",
"short_name": "foo",
"detailed_name": "void foo(ForwardType *, ImplementedType)",
"detailed_name": "void foo(ForwardType *f, ImplementedType a)",
"declarations": [],
"definition_spelling": "4:6-4:9",
"definition_extent": "4:1-4:47",

View File

@ -31,7 +31,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@foo#*$@S@Foo#S0_#",
"short_name": "foo",
"detailed_name": "void foo(Foo *, Foo *)",
"detailed_name": "void foo(Foo *f, Foo *)",
"declarations": [{
"spelling": "3:6-3:9",
"extent": "3:1-3:23",

View File

@ -31,7 +31,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@foo#&$@S@Type#&1S1_#",
"short_name": "foo",
"detailed_name": "void foo(Type &, const Type &)",
"detailed_name": "void foo(Type &a0, const Type &a1)",
"declarations": [],
"definition_spelling": "3:6-3:9",
"definition_extent": "3:1-8:2",

View File

@ -39,7 +39,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@called#I#",
"short_name": "called",
"detailed_name": "void called(int)",
"detailed_name": "void called(int a)",
"declarations": [{
"spelling": "1:6-1:12",
"extent": "1:1-1:19",

View File

@ -17,7 +17,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@called#I#",
"short_name": "called",
"detailed_name": "void called(int)",
"detailed_name": "void called(int a)",
"declarations": [{
"spelling": "1:6-1:12",
"extent": "1:1-1:19",

View File

@ -12,7 +12,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@foo#I#",
"short_name": "foo",
"detailed_name": "void foo(int)",
"detailed_name": "void foo(int a)",
"declarations": [],
"definition_spelling": "1:6-1:9",
"definition_extent": "1:1-3:2",

View File

@ -18,7 +18,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@foo#I#",
"short_name": "foo",
"detailed_name": "void foo(int)",
"detailed_name": "void foo(int a)",
"declarations": [],
"definition_spelling": "1:6-1:9",
"definition_extent": "1:1-8:2",

View File

@ -25,7 +25,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@foo#*$@S@Foo#S0_#",
"short_name": "foo",
"detailed_name": "void foo(Foo *, Foo *)",
"detailed_name": "void foo(Foo *p0, Foo *p1)",
"declarations": [],
"definition_spelling": "3:6-3:9",
"definition_extent": "3:1-3:30",

View File

@ -12,7 +12,7 @@ OUTPUT:
"is_operator": false,
"usr": "c:@F@foo#I#",
"short_name": "foo",
"detailed_name": "void foo(int)",
"detailed_name": "void foo(int p)",
"declarations": [],
"definition_spelling": "1:6-1:9",
"definition_extent": "1:1-3:2",