Author: Pavel Labath Date: 2024-11-15T12:24:12+01:00 New Revision: 10b048c8922d746b14e991f468e00b3ca67c9d95
URL: https://github.com/llvm/llvm-project/commit/10b048c8922d746b14e991f468e00b3ca67c9d95 DIFF: https://github.com/llvm/llvm-project/commit/10b048c8922d746b14e991f468e00b3ca67c9d95.diff LOG: [lldb] Make CompilerDecl::GetName (always) return template args (#116068) I ran into this while look at a different bug (patch coming soon). This function has only two callers. The first is SBTypeStaticField::GetName (which doesn't care about templates), and the other is CompilerDecl::GetCompilerContext (in the TypeQuery constructor), which does want template arguments. This function was (normally) returning the name without template args. Since this code is only used when looking up a type in another shared library, the odds of running into this bug are relatively low, but I add a test to demonstrate the scenario and the fix for it nonetheless. Amazingly (and scarily), this test actually passes without this change in the default configuration -- and only fails with -gsimple-template-names. The reason for that is that in the non-simplified case we create a regular CXXRecordDecl whose name is "bar<int>" (instead of a template record "foo" with an argument of "int"). When evaluating the expression, we are somehow able to replace this with a proper template specialization decl. Added: lldb/test/API/lang/cpp/forward/Makefile lldb/test/API/lang/cpp/forward/TestCPPForwardDeclaration.py lldb/test/API/lang/cpp/forward/foo.cpp lldb/test/API/lang/cpp/forward/foo.h lldb/test/API/lang/cpp/forward/main.cpp Modified: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index f5063175d6e070..c5249088a291b8 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -9116,7 +9116,7 @@ ConstString TypeSystemClang::DeclGetName(void *opaque_decl) { clang::NamedDecl *nd = llvm::dyn_cast<NamedDecl>((clang::Decl *)opaque_decl); if (nd != nullptr) - return ConstString(nd->getDeclName().getAsString()); + return ConstString(GetTypeNameForDecl(nd, /*qualified=*/false)); } return ConstString(); } diff --git a/lldb/test/API/lang/cpp/forward/Makefile b/lldb/test/API/lang/cpp/forward/Makefile new file mode 100644 index 00000000000000..0b806b314397c5 --- /dev/null +++ b/lldb/test/API/lang/cpp/forward/Makefile @@ -0,0 +1,5 @@ +CXX_SOURCES := main.cpp +DYLIB_CXX_SOURCES := foo.cpp +DYLIB_NAME := foo + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/forward/TestCPPForwardDeclaration.py b/lldb/test/API/lang/cpp/forward/TestCPPForwardDeclaration.py new file mode 100644 index 00000000000000..5e9dd9c2227dd5 --- /dev/null +++ b/lldb/test/API/lang/cpp/forward/TestCPPForwardDeclaration.py @@ -0,0 +1,61 @@ +"""Test that forward declaration of a c++ template gets resolved correctly.""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + + +class ForwardDeclarationTestCase(TestBase): + def do_test(self, dictionary=None): + """Display *bar_ptr when stopped on a function with forward declaration of struct bar.""" + self.build(dictionary=dictionary) + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + environment = self.registerSharedLibrariesWithTarget(target, ["foo"]) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_symbol(self, "foo", num_expected_locations=1) + + process = target.LaunchSimple( + None, environment, self.get_process_working_directory() + ) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect( + "thread list", + STOPPED_DUE_TO_BREAKPOINT, + substrs=["stopped", "stop reason = breakpoint"], + ) + + # The breakpoint should have a hit count of 1. + lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1) + + self.expect_expr( + "*bar_ptr", + result_type="bar<int>", + result_children=[ValueCheck(value="47", name="a", type="int")], + ) + + def test(self): + self.do_test() + + @no_debug_info_test + @skipIfDarwin + @skipIf(compiler=no_match("clang")) + @skipIf(compiler_version=["<", "8.0"]) + @expectedFailureAll(oslist=["windows"]) + def test_debug_names(self): + """Test that we are able to find complete types when using DWARF v5 + accelerator tables""" + self.do_test(dict(CFLAGS_EXTRAS="-gdwarf-5 -gpubnames")) + + @no_debug_info_test + @skipIf(compiler=no_match("clang")) + def test_simple_template_names(self): + """Test that we are able to find complete types when using DWARF v5 + accelerator tables""" + self.do_test(dict(CFLAGS_EXTRAS="-gsimple-template-names")) diff --git a/lldb/test/API/lang/cpp/forward/foo.cpp b/lldb/test/API/lang/cpp/forward/foo.cpp new file mode 100644 index 00000000000000..6a2f0a49c4b62e --- /dev/null +++ b/lldb/test/API/lang/cpp/forward/foo.cpp @@ -0,0 +1,3 @@ +#include "foo.h" + +int foo(bar<int> *bar_ptr) { return 1; } diff --git a/lldb/test/API/lang/cpp/forward/foo.h b/lldb/test/API/lang/cpp/forward/foo.h new file mode 100644 index 00000000000000..a80b39f03febcc --- /dev/null +++ b/lldb/test/API/lang/cpp/forward/foo.h @@ -0,0 +1,3 @@ +template <typename T> struct bar; + +LLDB_TEST_API int foo(bar<int> *bar_ptr); diff --git a/lldb/test/API/lang/cpp/forward/main.cpp b/lldb/test/API/lang/cpp/forward/main.cpp new file mode 100644 index 00000000000000..c47036b9aa0a7c --- /dev/null +++ b/lldb/test/API/lang/cpp/forward/main.cpp @@ -0,0 +1,13 @@ +#include "foo.h" + +template <typename T> struct bar { + T a; +}; + +int main() { + bar<int> b{47}; + + foo(&b); + + return 0; +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits