mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 17:11:59 +00:00
Produce detailed function signatures which include parameter names
This commit is contained in:
parent
3c6cf1017c
commit
8bdce31789
137
src/indexer.cc
137
src/indexer.cc
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user