This fixes a regression caused by us starting to parse types from declarations. The code in TypeSystemClang was assuming that the value held in ClangASTMetadata was authoritative, but this isn't (and cannot) be the case when the type is parsed from a forward-declaration. For the fix, I add a new "don't know" state to ClangASTMetadata, and make sure DWARFASTParserClang sets it only when it encounters a forward declaration. In this case, the type system will fall back to completing the type. This does mean that we will be completing more types than before, but I'm hoping this will offset by the fact that we don't search for definition DIEs eagerly. In particular, I don't expect it to make a difference in -fstandalone-debug scenarios, since types will nearly always be present as definitions. To avoid this cost, we'd need to create some sort of a back channel to query the DWARFASTParser about the dynamicness of the type without actually completing it. I'd like to avoid that if it is not necessary.
52 lines
1.2 KiB
C++
52 lines
1.2 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());
|
|
|
|
take_A(&myB);
|
|
|
|
return 0;
|
|
}
|