summaryrefslogtreecommitdiff
path: root/lldb/test/API/lang
diff options
context:
space:
mode:
authorMingming Liu <mingmingl@google.com>2025-09-10 15:25:31 -0700
committerGitHub <noreply@github.com>2025-09-10 15:25:31 -0700
commit1417dafa1db9cb1b2b09438aa9f53ea5ab6e36e2 (patch)
tree57f4b1f313c8cf74eed8819870f39c36ea263c68 /lldb/test/API/lang
parent898b813bc8a6d0276bf0f4769f5f2f64b34e632d (diff)
parentb8cefcb601ddaa18482555c4ff363c01a270c2fe (diff)
Merge branch 'main' into users/mingmingl-llvm/samplefdo-profile-formatusers/mingmingl-llvm/samplefdo-profile-format
Diffstat (limited to 'lldb/test/API/lang')
-rw-r--r--lldb/test/API/lang/cpp/abi_tag_structors/Makefile3
-rw-r--r--lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py116
-rw-r--r--lldb/test/API/lang/cpp/abi_tag_structors/main.cpp62
-rw-r--r--lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py76
-rw-r--r--lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.cpp6
-rw-r--r--lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.h11
-rw-r--r--lldb/test/API/lang/cpp/expr-definition-in-dylib/main.cpp15
-rw-r--r--lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py3
8 files changed, 278 insertions, 14 deletions
diff --git a/lldb/test/API/lang/cpp/abi_tag_structors/Makefile b/lldb/test/API/lang/cpp/abi_tag_structors/Makefile
new file mode 100644
index 000000000000..99998b20bcb0
--- /dev/null
+++ b/lldb/test/API/lang/cpp/abi_tag_structors/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py b/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py
new file mode 100644
index 000000000000..87d8adb42b82
--- /dev/null
+++ b/lldb/test/API/lang/cpp/abi_tag_structors/TestAbiTagStructors.py
@@ -0,0 +1,116 @@
+"""
+Test that we can call structors/destructors
+annotated (and thus mangled) with ABI tags.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class AbiTagStructorsTestCase(TestBase):
+ @expectedFailureAll(oslist=["windows"])
+ def test_with_structor_linkage_names(self):
+ self.build(dictionary={"CXXFLAGS_EXTRAS": "-gstructor-decl-linkage-names"})
+
+ lldbutil.run_to_source_breakpoint(
+ self, "Break here", lldb.SBFileSpec("main.cpp", False)
+ )
+
+ self.expect_expr(
+ "Tagged()",
+ result_type="Tagged",
+ result_children=[ValueCheck(name="x", value="15")],
+ )
+ self.expect_expr(
+ "Tagged(-17)",
+ result_type="Tagged",
+ result_children=[ValueCheck(name="x", value="-17")],
+ )
+ self.expect_expr("t1 = t2", result_type="Tagged")
+
+ self.expect("expr Tagged t3(t1)", error=False)
+ self.expect("expr t1.~Tagged()", error=False)
+
+ self.expect("expr t1.~Tagged()", error=False)
+
+ self.expect(
+ "expression -- struct $Derived : virtual public Tagged { int y; $Derived(int val) : Tagged(val) { y = x; } };",
+ error=False,
+ )
+ self.expect(
+ "expression -- struct $Derived2 : virtual public $Derived { int z; $Derived2() : $Derived(10) { z = y; } };",
+ error=False,
+ )
+ self.expect_expr(
+ "$Derived2 d; d",
+ result_type="$Derived2",
+ result_children=[
+ ValueCheck(
+ name="$Derived",
+ children=[
+ ValueCheck(
+ name="Tagged", children=[ValueCheck(name="x", value="15")]
+ ),
+ ValueCheck(name="y", value="15"),
+ ],
+ ),
+ ValueCheck(name="z", value="15"),
+ ],
+ )
+
+ # Calls to deleting and base object destructor variants (D0 and D2 in Itanium ABI)
+ self.expect_expr(
+ "struct D : public HasVirtualDtor {}; D d; d.func()",
+ result_type="int",
+ result_value="10",
+ )
+
+ @expectedFailureAll(oslist=["windows"])
+ def test_no_structor_linkage_names(self):
+ """
+ Test that without linkage names on structor declarations we can't call
+ ABI-tagged structors.
+ """
+ self.build(dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"})
+
+ lldbutil.run_to_source_breakpoint(
+ self, "Break here", lldb.SBFileSpec("main.cpp", False)
+ )
+
+ self.expect("expression Tagged(17)", error=True)
+ self.expect("expr Tagged t3(t1)", error=True)
+ self.expect("expr t1.~Tagged()", error=True)
+
+ ## Calls to deleting and base object destructor variants (D0 and D2 in Itanium ABI)
+ self.expect(
+ "expression -- struct D : public HasVirtualDtor {}; D d; d.func()",
+ error=True,
+ )
+
+ self.expect("expression -- Derived d(16); d", error=True)
+
+ def do_nested_structor_test(self):
+ """
+ Test that calling ABI-tagged ctors of function local classes is not supported,
+ but calling un-tagged functions is.
+ """
+ lldbutil.run_to_source_breakpoint(
+ self, "Break nested", lldb.SBFileSpec("main.cpp", False)
+ )
+
+ self.expect("expression Local()", error=False)
+ self.expect(
+ "expression TaggedLocal()", error=True, substrs=["Couldn't look up symbols"]
+ )
+
+ @expectedFailureAll(oslist=["windows"])
+ def test_nested_no_structor_linkage_names(self):
+ self.build(dictionary={"CXXFLAGS_EXTRAS": "-gstructor-decl-linkage-names"})
+ self.do_nested_structor_test()
+
+ @expectedFailureAll(oslist=["windows"])
+ def test_nested_with_structor_linkage_names(self):
+ self.build(dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"})
+ self.do_nested_structor_test()
diff --git a/lldb/test/API/lang/cpp/abi_tag_structors/main.cpp b/lldb/test/API/lang/cpp/abi_tag_structors/main.cpp
new file mode 100644
index 000000000000..ddf237491b83
--- /dev/null
+++ b/lldb/test/API/lang/cpp/abi_tag_structors/main.cpp
@@ -0,0 +1,62 @@
+#include <cstdio>
+
+struct Tagged {
+ [[gnu::abi_tag("Default")]] Tagged() : x(15) { std::puts(__func__); }
+ [[gnu::abi_tag("Value")]] Tagged(int val) : x(val) { std::puts(__func__); }
+ [[gnu::abi_tag("Copy")]] Tagged(const Tagged &lhs) : x(lhs.x) {
+ std::puts(__func__);
+ }
+ [[gnu::abi_tag("CopyAssign")]] Tagged &operator=(const Tagged &) {
+ std::puts(__func__);
+ return *this;
+ }
+ [[gnu::abi_tag("Dtor")]] ~Tagged() { std::puts(__func__); }
+
+ int x;
+};
+
+struct Base {
+ virtual ~Base() { std::puts(__func__); }
+ virtual int func() { return 5; }
+};
+
+struct HasVirtualDtor : public Base {
+ int func() override { return 10; }
+
+ [[gnu::abi_tag("VirtualDtor")]] ~HasVirtualDtor() override {
+ std::puts(__func__);
+ }
+};
+
+struct HasNestedCtor {
+ HasNestedCtor() {
+ struct TaggedLocal {
+ [[gnu::abi_tag("Local")]] TaggedLocal() { std::puts(__func__); }
+ };
+
+ struct Local {
+ Local() { std::puts(__func__); }
+ };
+
+ TaggedLocal l1;
+ Local l2;
+ std::puts("Break nested");
+ }
+};
+
+int main() {
+ Tagged t;
+ Tagged t1(10);
+ Tagged t2(t1);
+ t1 = t2;
+
+ Base b;
+ HasVirtualDtor vdtor;
+ vdtor.func();
+
+ std::puts("Break here");
+
+ HasNestedCtor nested;
+
+ return 0;
+}
diff --git a/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py b/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py
index 70d7fd096c7c..c0545c70c84e 100644
--- a/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py
+++ b/lldb/test/API/lang/cpp/expr-definition-in-dylib/TestExprDefinitionInDylib.py
@@ -5,15 +5,14 @@ from lldbsuite.test import lldbutil
class ExprDefinitionInDylibTestCase(TestBase):
- NO_DEBUG_INFO_TESTCASE = True
@skipIfWindows
- def test(self):
+ def test_with_structor_linkage_names(self):
"""
Tests that we can call functions whose definition
is in a different LLDB module than it's declaration.
"""
- self.build()
+ self.build(dictionary={"CXXFLAGS_EXTRAS": "-gstructor-decl-linkage-names"})
target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
self.assertTrue(target, VALID_TARGET)
@@ -31,10 +30,71 @@ class ExprDefinitionInDylibTestCase(TestBase):
)
self.expect_expr("f.method()", result_value="-72", result_type="int")
- self.expect_expr("Foo()", result_type="Foo")
- # FIXME: mangled name lookup for ABI-tagged ctors fails because
- # the debug-info AST doesn't have ABI-tag information.
- self.expect(
- "expr Bar()", error=True, substrs=["error: Couldn't look up symbols"]
+ self.expect_expr("Foo(10)", result_type="Foo")
+
+ self.expect_expr("Base()", result_type="Base")
+
+ self.expect_expr("Bar()", result_type="Bar")
+
+ # Test a more complex setup: expression that has a three bases:
+ # 1. definition is in local module
+ # 2. definition is in different module
+ # 3. definition is in expression context (and has it's own virtual base)
+ self.expect_expr(
+ "struct ExprBase : virtual Foo { int z; ExprBase() : Foo(11) { z = x; } }; struct Expr : virtual Local, virtual Foo, virtual ExprBase { int w; Expr() : Local(), Foo(12), ExprBase() { w = y; } }; Expr tmp; tmp",
+ result_type="Expr",
+ result_children=[
+ ValueCheck(
+ name="Local",
+ children=[
+ ValueCheck(
+ name="Foo", children=[ValueCheck(name="x", value="12")]
+ ),
+ ValueCheck(name="y", value="12"),
+ ],
+ ),
+ ValueCheck(name="Foo", children=[ValueCheck(name="x", value="12")]),
+ ValueCheck(
+ name="ExprBase",
+ children=[
+ ValueCheck(
+ name="Foo", children=[ValueCheck(name="x", value="12")]
+ ),
+ ValueCheck(name="z", value="12"),
+ ],
+ ),
+ ValueCheck(name="w", value="12"),
+ ],
)
+
+ @skipIfWindows
+ def test_no_structor_linkage_names(self):
+ """
+ Tests that if structor declarations don't have linkage names, we can't
+ call ABI-tagged constructors. But non-tagged ones are fine.
+ """
+ self.build(dictionary={"CXXFLAGS_EXTRAS": "-gno-structor-decl-linkage-names"})
+
+ target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
+ self.assertTrue(target, VALID_TARGET)
+
+ env = self.registerSharedLibrariesWithTarget(target, ["lib"])
+
+ breakpoint = lldbutil.run_break_set_by_file_and_line(
+ self, "main.cpp", line_number("main.cpp", "return")
+ )
+
+ process = target.LaunchSimple(None, env, self.get_process_working_directory())
+
+ self.assertIsNotNone(
+ lldbutil.get_one_thread_stopped_at_breakpoint_id(self.process(), breakpoint)
+ )
+
+ self.expect_expr("f.method()", result_value="-72", result_type="int")
+
+ self.expect_expr("Foo(10)", result_type="Foo")
+
+ self.expect("Base()", error=True)
+
+ self.expect("Bar()", error=True)
diff --git a/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.cpp b/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.cpp
index 1a08817f5cda..aa3921ffe0b1 100644
--- a/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.cpp
+++ b/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.cpp
@@ -4,10 +4,14 @@
int Foo::method() { return -72; }
-Foo::Foo() { std::puts(__func__); }
+Foo::Foo(int val) : x(val) { std::puts(__func__); }
Foo::~Foo() { std::puts(__func__); }
Bar::Bar() { std::puts(__func__); }
Bar::~Bar() { std::puts(__func__); }
+
+Base::Base() { std::puts(__func__); }
+
+Base::~Base() { std::puts(__func__); }
diff --git a/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.h b/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.h
index 5ec227946cba..513c9a0f9c87 100644
--- a/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.h
+++ b/lldb/test/API/lang/cpp/expr-definition-in-dylib/lib.h
@@ -3,11 +3,18 @@
struct Foo {
int method();
- Foo();
+ Foo(int val);
~Foo();
+
+ int x;
+};
+
+struct Base {
+ [[gnu::abi_tag("BaseCtor")]] Base();
+ [[gnu::abi_tag("BaseDtor")]] ~Base();
};
-struct Bar {
+struct Bar : public Base {
[[gnu::abi_tag("Ctor")]] Bar();
[[gnu::abi_tag("Dtor")]] ~Bar();
};
diff --git a/lldb/test/API/lang/cpp/expr-definition-in-dylib/main.cpp b/lldb/test/API/lang/cpp/expr-definition-in-dylib/main.cpp
index 4d6bece21eca..ff43190b991c 100644
--- a/lldb/test/API/lang/cpp/expr-definition-in-dylib/main.cpp
+++ b/lldb/test/API/lang/cpp/expr-definition-in-dylib/main.cpp
@@ -1,7 +1,18 @@
#include "lib.h"
+struct Local : public virtual Foo {
+ Local();
+ ~Local();
+ int y;
+};
+
+Local::Local() : Foo(5) { y = x; }
+Local::~Local() {}
+
int main() {
- Foo f;
- Bar b;
+ Foo f(5);
+ Base b1;
+ Bar b2;
+ Local l1;
return f.method();
}
diff --git a/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py
index 8efa53bdbf72..d8a729b322fe 100644
--- a/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py
+++ b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py
@@ -9,7 +9,7 @@ class LibCxxInternalsRecognizerTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
@add_test_categories(["libc++"])
- @skipIf(compiler="clang", compiler_version=["<", "16.0"])
+ @skipIf(compiler="clang", compiler_version=["<", "19.0"])
def test_frame_recognizer(self):
"""Test that implementation details of libc++ are hidden"""
self.build()
@@ -40,6 +40,7 @@ class LibCxxInternalsRecognizerTestCase(TestBase):
"Callable::operator()(int) const": ["::invoke", "test_invoke"],
# Containers
"MyKey::operator<(MyKey const&) const": [
+ "::operator()",
"less",
"::emplace",
"test_containers",