From 462722d135431de2b35d410b941d61d4968b58af Mon Sep 17 00:00:00 2001 From: Siva Chandra Date: Fri, 27 Mar 2015 00:10:04 +0000 Subject: [PATCH] [DWARF] Generate qualified names of functions if linkage names are missing. Summary: This is similar to the change introduced for variable DIEs in r233098. If the linkage names of functions are missing in the DWARF, then their fully qualified names (similar to the name that would be got by demangling their linkage name) is generated using the decl context. This change fixes TestNamespace when the test case is compiled with GCC, hence it is enabled for GCC. The test and the test case are also enhanced to cover variadic functions. Test Plan: dotest.py -C -p TestNamespace Reviewers: clayborg Reviewed By: clayborg Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D8623 llvm-svn: 233336 --- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 49 ++++++++++++++++++- lldb/test/lang/cpp/namespace/TestNamespace.py | 4 +- lldb/test/lang/cpp/namespace/main.cpp | 17 +++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 487438b1e1f9e..28bfcb9cae996 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1095,7 +1095,54 @@ SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompile Mangled func_name; if (mangled) func_name.SetValue(ConstString(mangled), true); - else if (name) + else if (die->GetParent()->Tag() == DW_TAG_compile_unit && + LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()) && + strcmp(name, "main") != 0) + { + // If the mangled name is not present in the DWARF, generate the demangled name + // using the decl context. We skip if the function is "main" as its name is + // never mangled. + bool is_static = false; + bool is_variadic = false; + unsigned type_quals = 0; + std::vector param_types; + std::vector param_decls; + const DWARFDebugInfoEntry *decl_ctx_die = NULL; + DWARFDeclContext decl_ctx; + StreamString sstr; + + die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx); + sstr << decl_ctx.GetQualifiedName(); + + clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(dwarf_cu, + die, + &decl_ctx_die); + ParseChildParameters(sc, + containing_decl_ctx, + dwarf_cu, + die, + true, + is_static, + is_variadic, + param_types, + param_decls, + type_quals); + sstr << "("; + for (size_t i = 0; i < param_types.size(); i++) + { + if (i > 0) + sstr << ", "; + sstr << param_types[i].GetTypeName(); + } + if (is_variadic) + sstr << ", ..."; + sstr << ")"; + if (type_quals & clang::Qualifiers::Const) + sstr << " const"; + + func_name.SetValue(ConstString(sstr.GetData()), false); + } + else func_name.SetValue(ConstString(name), false); FunctionSP func_sp; diff --git a/lldb/test/lang/cpp/namespace/TestNamespace.py b/lldb/test/lang/cpp/namespace/TestNamespace.py index e9f78e036763e..4e249264b1cd8 100644 --- a/lldb/test/lang/cpp/namespace/TestNamespace.py +++ b/lldb/test/lang/cpp/namespace/TestNamespace.py @@ -21,7 +21,6 @@ def test_with_dsym_and_run_command(self): self.namespace_variable_commands() # rdar://problem/8668674 - @expectedFailureGcc # llvm.org/pr15302: lldb does not print 'anonymous namespace' when the inferior is built with GCC (4.7) @dwarf_test def test_with_dwarf_and_run_command(self): """Test that anonymous and named namespace variables display correctly.""" @@ -117,6 +116,9 @@ def namespace_variable_commands(self): self.expect("p myanonfunc", patterns = ['\(anonymous namespace\)::myanonfunc\(int\)']) + self.expect("p variadic_sum", + patterns = ['\(anonymous namespace\)::variadic_sum\(int, ...\)']) + if __name__ == '__main__': import atexit lldb.SBDebugger.Initialize() diff --git a/lldb/test/lang/cpp/namespace/main.cpp b/lldb/test/lang/cpp/namespace/main.cpp index 9f3583b47e27a..4dec275c2c5a0 100644 --- a/lldb/test/lang/cpp/namespace/main.cpp +++ b/lldb/test/lang/cpp/namespace/main.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +#include + namespace { typedef unsigned int my_uint_t; int i; // Find the line number for anonymous namespace variable i. @@ -15,6 +17,20 @@ namespace { { return a + a; } + + int + variadic_sum (int arg_count...) + { + int sum = 0; + va_list args; + va_start(args, arg_count); + + for (int i = 0; i < arg_count; i++) + sum += va_arg(args, int); + + va_end(args); + return sum; + } } namespace A { @@ -67,6 +83,7 @@ int Foo::myfunc(int a) j = 4; printf("::i=%d\n", ::i); printf("A::B::j=%d\n", A::B::j); + printf("variadic_sum=%d\n", variadic_sum(3, 1, 2, 3)); myanonfunc(3); return myfunc2(3) + j + i + a + 2 + anon_uint + a_uint + b_uint + y_uint; // Set break point at this line. }