Skip to content

Commit

Permalink
Produce detailed function signatures which include parameter names
Browse files Browse the repository at this point in the history
  • Loading branch information
romix committed Dec 27, 2017
1 parent 3c6cf10 commit 8bdce31
Show file tree
Hide file tree
Showing 20 changed files with 123 additions and 54 deletions.
137 changes: 103 additions & 34 deletions src/indexer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions tests/constructors/make_functions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ int foo(int a, int b) { return 0; }
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/function_declaration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ void foo(int a, int b);
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/namespaces/function_declaration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ void foo(int a, int b);
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/namespaces/namespace_reference.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ void Runner() {
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/operators/operator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Foo &operator += (const Foo&, const int&);
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/outline/outline2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ c:@F@LoadCompilationEntriesFromDirectory#&1$@N@std@N@__cxx11@S@basic_string>#C#$
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/outline/static_function_in_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion tests/usage/func_called_from_macro_argument.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void caller() {
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/usage/func_called_implicit_ctor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Wrapper caller() {
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/usage/type_usage_declare_param.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void foo(ForwardType* f, ImplementedType a) {}
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/usage/type_usage_declare_param_prototype.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void foo(Foo* f, Foo*) {}
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/usage/type_usage_declare_qualifiers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void foo(Type& a0, const Type& a1) {
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/usage/usage_inside_of_call.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void foo() {
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/usage/usage_inside_of_call_simple.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void foo() {
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/usage/var_usage_func_parameter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void foo(int a) {
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/usage/var_usage_shadowed_parameter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void foo(int a) {
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/vars/function_param.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void foo(Foo* p0, Foo* p1) {}
"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",
Expand Down
2 changes: 1 addition & 1 deletion tests/vars/function_shadow_param.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void foo(int p) {
"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",
Expand Down

0 comments on commit 8bdce31

Please sign in to comment.