Files
clang-p2996/lldb/test/API/lang/cpp/dynamic-value/pass-to-base.cpp
Pavel Labath dd5d730072 [lldb] Better matching of types in anonymous namespaces (#102111)
This patch extends TypeQuery matching to support anonymous namespaces. A
new flag is added to control the behavior. In the "strict" mode, the
query must match the type exactly -- all anonymous namespaces included.
The dynamic type resolver in the itanium abi (the motivating use case
for this) uses this flag, as it queries using the name from the
demangles, which includes anonymous namespaces.

This ensures we don't confuse a type with a same-named type in an
anonymous namespace. However, this does *not* ensure we don't confuse
two types in anonymous namespacs (in different CUs). To resolve this, we
would need to use a completely different lookup algorithm, which
probably also requires a DWARF extension.

In the "lax" mode (the default), the anonymous namespaces in the query
are optional, and this allows one search for the type using the usual
language rules (`::A` matches `::(anonymous namespace)::A`).

This patch also changes the type context computation algorithm in
DWARFDIE, so that it includes anonymous namespace information. This
causes a slight change in behavior: the algorithm previously stopped
computing the context after encountering an anonymous namespace, which
caused the outer namespaces to be ignored. This meant that a type like
`NS::(anonymous namespace)::A` would be (incorrectly) recognized as
`::A`). This can cause code depending on the old behavior to misbehave.
The fix is to specify all the enclosing namespaces in the query, or use
a non-exact match.
2024-09-02 08:34:14 +02:00

50 lines
1.1 KiB
C++

#include "a.h"
void A::doSomething(A &anotherA) {
printf("In A %p doing something with %d.\n", this, m_a_value);
int tmp_value = anotherA.Value();
printf("Also have another A at %p: %d.\n", &anotherA, tmp_value); // Break here in doSomething.
}
class Extra
{
public:
Extra (int in_one, int in_two) : m_extra_one(in_one), m_extra_two(in_two) {}
private:
int m_extra_one;
int m_extra_two;
};
class B : public Extra, public virtual A
{
public:
B (int b_value, int a_value) : Extra(b_value, a_value), A(a_value), m_b_value(b_value) {}
B (int b_value, int a_value, A *client_A) : Extra(b_value, a_value), A(a_value, client_A), m_b_value(b_value) {}
virtual ~B () {}
private:
int m_b_value;
};
static A* my_global_A_ptr;
int
main (int argc, char **argv)
{
my_global_A_ptr = new B (100, 200);
B myB (10, 20, my_global_A_ptr);
B *second_fake_A_ptr = new B (150, 250);
B otherB (300, 400, second_fake_A_ptr);
myB.doSomething(otherB); // Break here and get real addresses of myB and otherB.
A reallyA (500);
myB.doSomething (reallyA); // Break here and get real address of reallyA.
myB.doSomething(*make_anonymous_B());
return 0;
}