Skip to content

Commit 10b048c

Browse files
authored
[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.
1 parent 56720a4 commit 10b048c

File tree

6 files changed

+86
-1
lines changed

6 files changed

+86
-1
lines changed

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9116,7 +9116,7 @@ ConstString TypeSystemClang::DeclGetName(void *opaque_decl) {
91169116
clang::NamedDecl *nd =
91179117
llvm::dyn_cast<NamedDecl>((clang::Decl *)opaque_decl);
91189118
if (nd != nullptr)
9119-
return ConstString(nd->getDeclName().getAsString());
9119+
return ConstString(GetTypeNameForDecl(nd, /*qualified=*/false));
91209120
}
91219121
return ConstString();
91229122
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CXX_SOURCES := main.cpp
2+
DYLIB_CXX_SOURCES := foo.cpp
3+
DYLIB_NAME := foo
4+
5+
include Makefile.rules
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""Test that forward declaration of a c++ template gets resolved correctly."""
2+
3+
import lldb
4+
from lldbsuite.test.lldbtest import *
5+
from lldbsuite.test.decorators import *
6+
import lldbsuite.test.lldbutil as lldbutil
7+
8+
9+
class ForwardDeclarationTestCase(TestBase):
10+
def do_test(self, dictionary=None):
11+
"""Display *bar_ptr when stopped on a function with forward declaration of struct bar."""
12+
self.build(dictionary=dictionary)
13+
exe = self.getBuildArtifact("a.out")
14+
target = self.dbg.CreateTarget(exe)
15+
self.assertTrue(target, VALID_TARGET)
16+
17+
environment = self.registerSharedLibrariesWithTarget(target, ["foo"])
18+
19+
# Break inside the foo function which takes a bar_ptr argument.
20+
lldbutil.run_break_set_by_symbol(self, "foo", num_expected_locations=1)
21+
22+
process = target.LaunchSimple(
23+
None, environment, self.get_process_working_directory()
24+
)
25+
self.assertTrue(process, PROCESS_IS_VALID)
26+
27+
# The stop reason of the thread should be breakpoint.
28+
self.expect(
29+
"thread list",
30+
STOPPED_DUE_TO_BREAKPOINT,
31+
substrs=["stopped", "stop reason = breakpoint"],
32+
)
33+
34+
# The breakpoint should have a hit count of 1.
35+
lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1)
36+
37+
self.expect_expr(
38+
"*bar_ptr",
39+
result_type="bar<int>",
40+
result_children=[ValueCheck(value="47", name="a", type="int")],
41+
)
42+
43+
def test(self):
44+
self.do_test()
45+
46+
@no_debug_info_test
47+
@skipIfDarwin
48+
@skipIf(compiler=no_match("clang"))
49+
@skipIf(compiler_version=["<", "8.0"])
50+
@expectedFailureAll(oslist=["windows"])
51+
def test_debug_names(self):
52+
"""Test that we are able to find complete types when using DWARF v5
53+
accelerator tables"""
54+
self.do_test(dict(CFLAGS_EXTRAS="-gdwarf-5 -gpubnames"))
55+
56+
@no_debug_info_test
57+
@skipIf(compiler=no_match("clang"))
58+
def test_simple_template_names(self):
59+
"""Test that we are able to find complete types when using DWARF v5
60+
accelerator tables"""
61+
self.do_test(dict(CFLAGS_EXTRAS="-gsimple-template-names"))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "foo.h"
2+
3+
int foo(bar<int> *bar_ptr) { return 1; }

lldb/test/API/lang/cpp/forward/foo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
template <typename T> struct bar;
2+
3+
LLDB_TEST_API int foo(bar<int> *bar_ptr);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "foo.h"
2+
3+
template <typename T> struct bar {
4+
T a;
5+
};
6+
7+
int main() {
8+
bar<int> b{47};
9+
10+
foo(&b);
11+
12+
return 0;
13+
}

0 commit comments

Comments
 (0)