Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts > %t 2>&1
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-1 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-2 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-3 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-4 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-5 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-6 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-7 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-8 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-9 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-10 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-11 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-12 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-13 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-14 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-15 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-16 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-17 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-18 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-19 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-20 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-21 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-22 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-23 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-24 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-25 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-26 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-27 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-28 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-29 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-30 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-31 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-32 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-33 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-34 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-35 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-36 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-37 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-38 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-39 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-40 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-41 %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK-42 %s < %t
|
2011-04-11 02:00:32 +08:00
|
|
|
// RUN: FileCheck --check-prefix=CHECK-43 %s < %t
|
2012-03-21 14:57:19 +08:00
|
|
|
// RUN: FileCheck --check-prefix=CHECK-44 %s < %t
|
2012-10-17 04:25:33 +08:00
|
|
|
// RUN: FileCheck --check-prefix=CHECK-45 %s < %t
|
2010-02-11 16:02:13 +08:00
|
|
|
|
2010-02-14 07:40:17 +08:00
|
|
|
// For now, just verify this doesn't crash.
|
|
|
|
namespace test0 {
|
|
|
|
struct Obj {};
|
|
|
|
|
|
|
|
struct Base { virtual const Obj *foo() = 0; };
|
|
|
|
struct Derived : Base { virtual Obj *foo() { return new Obj(); } };
|
|
|
|
|
|
|
|
void test(Derived *D) { D->foo(); }
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Test1 {
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-1: Vtable for 'Test1::A' (3 entries).
|
|
|
|
// CHECK-1-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-1-NEXT: 1 | Test1::A RTTI
|
|
|
|
// CHECK-1-NEXT: -- (Test1::A, 0) vtable address --
|
|
|
|
// CHECK-1-NEXT: 2 | void Test1::A::f()
|
2010-02-11 16:02:13 +08:00
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void A::f() { }
|
2010-02-12 13:25:12 +08:00
|
|
|
|
2010-02-11 16:02:13 +08:00
|
|
|
}
|
|
|
|
|
2010-02-12 02:20:28 +08:00
|
|
|
namespace Test2 {
|
|
|
|
|
|
|
|
// This is a smoke test of the vtable dumper.
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-2: Vtable for 'Test2::A' (9 entries).
|
|
|
|
// CHECK-2-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-2-NEXT: 1 | Test2::A RTTI
|
|
|
|
// CHECK-2-NEXT: -- (Test2::A, 0) vtable address --
|
|
|
|
// CHECK-2-NEXT: 2 | void Test2::A::f()
|
|
|
|
// CHECK-2-NEXT: 3 | void Test2::A::f() const
|
|
|
|
// CHECK-2-NEXT: 4 | Test2::A *Test2::A::g(int)
|
|
|
|
// CHECK-2-NEXT: 5 | Test2::A::~A() [complete]
|
|
|
|
// CHECK-2-NEXT: 6 | Test2::A::~A() [deleting]
|
|
|
|
// CHECK-2-NEXT: 7 | void Test2::A::h()
|
2010-09-05 08:17:29 +08:00
|
|
|
// CHECK-2-NEXT: 8 | Test2::A &Test2::A::operator=(const Test2::A &)
|
2010-02-12 02:20:28 +08:00
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
virtual void f() const;
|
|
|
|
|
|
|
|
virtual A* g(int a);
|
|
|
|
virtual ~A();
|
|
|
|
virtual void h();
|
2010-02-12 02:21:49 +08:00
|
|
|
virtual A& operator=(const A&);
|
2010-02-12 02:20:28 +08:00
|
|
|
};
|
|
|
|
void A::f() { }
|
|
|
|
|
2010-02-12 10:38:13 +08:00
|
|
|
// Another simple vtable dumper test.
|
2010-02-12 13:25:12 +08:00
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-3: Vtable for 'Test2::B' (6 entries).
|
|
|
|
// CHECK-3-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-3-NEXT: 1 | Test2::B RTTI
|
|
|
|
// CHECK-3-NEXT: -- (Test2::B, 0) vtable address --
|
|
|
|
// CHECK-3-NEXT: 2 | void Test2::B::f()
|
|
|
|
// CHECK-3-NEXT: 3 | void Test2::B::g() [pure]
|
|
|
|
// CHECK-3-NEXT: 4 | Test2::B::~B() [complete] [pure]
|
|
|
|
// CHECK-3-NEXT: 5 | Test2::B::~B() [deleting] [pure]
|
2010-02-12 10:38:13 +08:00
|
|
|
struct B {
|
|
|
|
virtual void f();
|
|
|
|
virtual void g() = 0;
|
|
|
|
virtual ~B() = 0;
|
|
|
|
};
|
2010-02-12 13:25:12 +08:00
|
|
|
void B::f() { }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Test3 {
|
2010-02-12 10:38:13 +08:00
|
|
|
|
2010-02-12 13:25:12 +08:00
|
|
|
// If a function in a derived class overrides a function in a primary base,
|
|
|
|
// then the function should not have an entry in the derived class (unless the return
|
|
|
|
// value requires adjusting).
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-4: Vtable for 'Test3::A' (3 entries).
|
|
|
|
// CHECK-4-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-4-NEXT: 1 | Test3::A RTTI
|
|
|
|
// CHECK-4-NEXT: -- (Test3::A, 0) vtable address --
|
|
|
|
// CHECK-4-NEXT: 2 | void Test3::A::f()
|
2010-02-12 13:25:12 +08:00
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void A::f() { }
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-5: Vtable for 'Test3::B' (4 entries).
|
|
|
|
// CHECK-5-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-5-NEXT: 1 | Test3::B RTTI
|
|
|
|
// CHECK-5-NEXT: -- (Test3::A, 0) vtable address --
|
|
|
|
// CHECK-5-NEXT: -- (Test3::B, 0) vtable address --
|
|
|
|
// CHECK-5-NEXT: 2 | void Test3::B::f()
|
|
|
|
// CHECK-5-NEXT: 3 | void Test3::B::g()
|
2010-02-12 13:25:12 +08:00
|
|
|
struct B : A {
|
|
|
|
virtual void f();
|
|
|
|
virtual void g();
|
|
|
|
};
|
2010-02-12 10:38:13 +08:00
|
|
|
void B::f() { }
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-6: Vtable for 'Test3::C' (5 entries).
|
|
|
|
// CHECK-6-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-6-NEXT: 1 | Test3::C RTTI
|
|
|
|
// CHECK-6-NEXT: -- (Test3::A, 0) vtable address --
|
|
|
|
// CHECK-6-NEXT: -- (Test3::C, 0) vtable address --
|
|
|
|
// CHECK-6-NEXT: 2 | void Test3::A::f()
|
|
|
|
// CHECK-6-NEXT: 3 | void Test3::C::g()
|
|
|
|
// CHECK-6-NEXT: 4 | void Test3::C::h()
|
2010-02-12 13:25:12 +08:00
|
|
|
struct C : A {
|
|
|
|
virtual void g();
|
|
|
|
virtual void h();
|
|
|
|
};
|
|
|
|
void C::g() { }
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-7: Vtable for 'Test3::D' (5 entries).
|
|
|
|
// CHECK-7-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-7-NEXT: 1 | Test3::D RTTI
|
|
|
|
// CHECK-7-NEXT: -- (Test3::A, 0) vtable address --
|
|
|
|
// CHECK-7-NEXT: -- (Test3::B, 0) vtable address --
|
|
|
|
// CHECK-7-NEXT: -- (Test3::D, 0) vtable address --
|
|
|
|
// CHECK-7-NEXT: 2 | void Test3::D::f()
|
|
|
|
// CHECK-7-NEXT: 3 | void Test3::D::g()
|
|
|
|
// CHECK-7-NEXT: 4 | void Test3::D::h()
|
2010-02-12 13:25:12 +08:00
|
|
|
struct D : B {
|
|
|
|
virtual void f();
|
|
|
|
virtual void g();
|
|
|
|
virtual void h();
|
|
|
|
};
|
|
|
|
|
|
|
|
void D::f() { }
|
2010-02-12 02:20:28 +08:00
|
|
|
}
|
2010-02-12 14:15:07 +08:00
|
|
|
|
2010-02-14 04:11:51 +08:00
|
|
|
namespace Test4 {
|
|
|
|
|
2010-02-14 05:07:32 +08:00
|
|
|
// Test non-virtual result adjustments.
|
2010-02-14 04:11:51 +08:00
|
|
|
|
|
|
|
struct R1 { int r1; };
|
|
|
|
struct R2 { int r2; };
|
|
|
|
struct R3 : R1, R2 { int r3; };
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual R2 *f();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-8: Vtable for 'Test4::B' (4 entries).
|
|
|
|
// CHECK-8-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-8-NEXT: 1 | Test4::B RTTI
|
|
|
|
// CHECK-8-NEXT: -- (Test4::A, 0) vtable address --
|
|
|
|
// CHECK-8-NEXT: -- (Test4::B, 0) vtable address --
|
|
|
|
// CHECK-8-NEXT: 2 | Test4::R3 *Test4::B::f()
|
|
|
|
// CHECK-8-NEXT: [return adjustment: 4 non-virtual]
|
|
|
|
// CHECK-8-NEXT: 3 | Test4::R3 *Test4::B::f()
|
2010-02-14 04:11:51 +08:00
|
|
|
|
|
|
|
struct B : A {
|
|
|
|
virtual R3 *f();
|
|
|
|
};
|
|
|
|
R3 *B::f() { return 0; }
|
2010-02-14 05:07:32 +08:00
|
|
|
|
|
|
|
// Test virtual result adjustments.
|
|
|
|
struct V1 { int v1; };
|
|
|
|
struct V2 : virtual V1 { int v1; };
|
|
|
|
|
|
|
|
struct C {
|
|
|
|
virtual V1 *f();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-9: Vtable for 'Test4::D' (4 entries).
|
|
|
|
// CHECK-9-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-9-NEXT: 1 | Test4::D RTTI
|
|
|
|
// CHECK-9-NEXT: -- (Test4::C, 0) vtable address --
|
|
|
|
// CHECK-9-NEXT: -- (Test4::D, 0) vtable address --
|
|
|
|
// CHECK-9-NEXT: 2 | Test4::V2 *Test4::D::f()
|
|
|
|
// CHECK-9-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset]
|
|
|
|
// CHECK-9-NEXT: 3 | Test4::V2 *Test4::D::f()
|
2010-02-14 05:07:32 +08:00
|
|
|
struct D : C {
|
|
|
|
virtual V2 *f();
|
|
|
|
};
|
|
|
|
V2 *D::f() { return 0; };
|
|
|
|
|
|
|
|
// Virtual result adjustments with an additional non-virtual adjustment.
|
|
|
|
struct V3 : virtual R3 { int r3; };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-10: Vtable for 'Test4::E' (4 entries).
|
|
|
|
// CHECK-10-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-10-NEXT: 1 | Test4::E RTTI
|
|
|
|
// CHECK-10-NEXT: -- (Test4::A, 0) vtable address --
|
|
|
|
// CHECK-10-NEXT: -- (Test4::E, 0) vtable address --
|
|
|
|
// CHECK-10-NEXT: 2 | Test4::V3 *Test4::E::f()
|
|
|
|
// CHECK-10-NEXT: [return adjustment: 4 non-virtual, -24 vbase offset offset]
|
|
|
|
// CHECK-10-NEXT: 3 | Test4::V3 *Test4::E::f()
|
2010-02-14 05:07:32 +08:00
|
|
|
|
|
|
|
struct E : A {
|
|
|
|
virtual V3 *f();
|
|
|
|
};
|
|
|
|
V3 *E::f() { return 0;}
|
|
|
|
|
2010-02-14 05:16:54 +08:00
|
|
|
// Test that a pure virtual member doesn't get a thunk.
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-11: Vtable for 'Test4::F' (5 entries).
|
|
|
|
// CHECK-11-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-11-NEXT: 1 | Test4::F RTTI
|
|
|
|
// CHECK-11-NEXT: -- (Test4::A, 0) vtable address --
|
|
|
|
// CHECK-11-NEXT: -- (Test4::F, 0) vtable address --
|
|
|
|
// CHECK-11-NEXT: 2 | Test4::R3 *Test4::F::f() [pure]
|
|
|
|
// CHECK-11-NEXT: 3 | void Test4::F::g()
|
|
|
|
// CHECK-11-NEXT: 4 | Test4::R3 *Test4::F::f() [pure]
|
2010-02-14 05:16:54 +08:00
|
|
|
struct F : A {
|
|
|
|
virtual void g();
|
|
|
|
virtual R3 *f() = 0;
|
|
|
|
};
|
|
|
|
void F::g() { }
|
|
|
|
|
2010-02-14 04:11:51 +08:00
|
|
|
}
|
|
|
|
|
2010-02-14 06:05:23 +08:00
|
|
|
namespace Test5 {
|
|
|
|
|
2010-02-14 07:40:17 +08:00
|
|
|
// Simple secondary vtables without 'this' pointer adjustments.
|
2010-02-14 06:05:23 +08:00
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
virtual void g();
|
|
|
|
int a;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B1 : A {
|
|
|
|
virtual void f();
|
|
|
|
int b1;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B2 : A {
|
|
|
|
virtual void g();
|
|
|
|
int b2;
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-12: Vtable for 'Test5::C' (9 entries).
|
|
|
|
// CHECK-12-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-12-NEXT: 1 | Test5::C RTTI
|
|
|
|
// CHECK-12-NEXT: -- (Test5::A, 0) vtable address --
|
|
|
|
// CHECK-12-NEXT: -- (Test5::B1, 0) vtable address --
|
|
|
|
// CHECK-12-NEXT: -- (Test5::C, 0) vtable address --
|
|
|
|
// CHECK-12-NEXT: 2 | void Test5::B1::f()
|
|
|
|
// CHECK-12-NEXT: 3 | void Test5::A::g()
|
|
|
|
// CHECK-12-NEXT: 4 | void Test5::C::h()
|
|
|
|
// CHECK-12-NEXT: 5 | offset_to_top (-16)
|
|
|
|
// CHECK-12-NEXT: 6 | Test5::C RTTI
|
|
|
|
// CHECK-12-NEXT: -- (Test5::A, 16) vtable address --
|
|
|
|
// CHECK-12-NEXT: -- (Test5::B2, 16) vtable address --
|
|
|
|
// CHECK-12-NEXT: 7 | void Test5::A::f()
|
|
|
|
// CHECK-12-NEXT: 8 | void Test5::B2::g()
|
2010-02-14 06:05:23 +08:00
|
|
|
struct C : B1, B2 {
|
|
|
|
virtual void h();
|
|
|
|
};
|
|
|
|
void C::h() { }
|
|
|
|
}
|
|
|
|
|
2010-02-14 07:40:17 +08:00
|
|
|
namespace Test6 {
|
2010-02-12 14:15:07 +08:00
|
|
|
|
2010-02-14 07:40:17 +08:00
|
|
|
// Simple non-virtual 'this' pointer adjustments.
|
|
|
|
struct A1 {
|
|
|
|
virtual void f();
|
|
|
|
int a;
|
|
|
|
};
|
2010-02-12 14:15:07 +08:00
|
|
|
|
2010-02-14 07:40:17 +08:00
|
|
|
struct A2 {
|
|
|
|
virtual void f();
|
|
|
|
int a;
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-13: Vtable for 'Test6::C' (6 entries).
|
|
|
|
// CHECK-13-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-13-NEXT: 1 | Test6::C RTTI
|
|
|
|
// CHECK-13-NEXT: -- (Test6::A1, 0) vtable address --
|
|
|
|
// CHECK-13-NEXT: -- (Test6::C, 0) vtable address --
|
|
|
|
// CHECK-13-NEXT: 2 | void Test6::C::f()
|
|
|
|
// CHECK-13-NEXT: 3 | offset_to_top (-16)
|
|
|
|
// CHECK-13-NEXT: 4 | Test6::C RTTI
|
|
|
|
// CHECK-13-NEXT: -- (Test6::A2, 16) vtable address --
|
|
|
|
// CHECK-13-NEXT: 5 | void Test6::C::f()
|
|
|
|
// CHECK-13-NEXT: [this adjustment: -16 non-virtual]
|
2010-02-14 07:40:17 +08:00
|
|
|
struct C : A1, A2 {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void C::f() { }
|
|
|
|
|
2010-02-14 08:16:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace Test7 {
|
|
|
|
|
|
|
|
// Test that the D::f overrider for A::f have different 'this' pointer
|
|
|
|
// adjustments in the two A base subobjects.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
int a;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B1 : A { };
|
|
|
|
struct B2 : A { };
|
|
|
|
|
|
|
|
struct C { virtual void c(); };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-14: Vtable for 'Test7::D' (10 entries).
|
|
|
|
// CHECK-14-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-14-NEXT: 1 | Test7::D RTTI
|
|
|
|
// CHECK-14-NEXT: -- (Test7::C, 0) vtable address --
|
|
|
|
// CHECK-14-NEXT: -- (Test7::D, 0) vtable address --
|
|
|
|
// CHECK-14-NEXT: 2 | void Test7::C::c()
|
|
|
|
// CHECK-14-NEXT: 3 | void Test7::D::f()
|
|
|
|
// CHECK-14-NEXT: 4 | offset_to_top (-8)
|
|
|
|
// CHECK-14-NEXT: 5 | Test7::D RTTI
|
|
|
|
// CHECK-14-NEXT: -- (Test7::A, 8) vtable address --
|
|
|
|
// CHECK-14-NEXT: -- (Test7::B1, 8) vtable address --
|
|
|
|
// CHECK-14-NEXT: 6 | void Test7::D::f()
|
|
|
|
// CHECK-14-NEXT: [this adjustment: -8 non-virtual]
|
|
|
|
// CHECK-14-NEXT: 7 | offset_to_top (-24)
|
|
|
|
// CHECK-14-NEXT: 8 | Test7::D RTTI
|
|
|
|
// CHECK-14-NEXT: -- (Test7::A, 24) vtable address --
|
|
|
|
// CHECK-14-NEXT: -- (Test7::B2, 24) vtable address --
|
|
|
|
// CHECK-14-NEXT: 9 | void Test7::D::f()
|
|
|
|
// CHECK-14-NEXT: [this adjustment: -24 non-virtual]
|
2010-02-14 08:16:19 +08:00
|
|
|
struct D : C, B1, B2 {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void D::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-15 01:05:59 +08:00
|
|
|
|
|
|
|
namespace Test8 {
|
|
|
|
|
|
|
|
// Test that we don't try to layout vtables for classes that don't have
|
|
|
|
// virtual bases or virtual member functions.
|
|
|
|
|
|
|
|
struct A { };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-15: Vtable for 'Test8::B' (3 entries).
|
|
|
|
// CHECK-15-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-15-NEXT: 1 | Test8::B RTTI
|
|
|
|
// CHECK-15-NEXT: -- (Test8::B, 0) vtable address --
|
|
|
|
// CHECK-15-NEXT: 2 | void Test8::B::f()
|
2010-02-15 01:05:59 +08:00
|
|
|
struct B : A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void B::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-16 12:59:55 +08:00
|
|
|
|
|
|
|
namespace Test9 {
|
|
|
|
|
|
|
|
// Simple test of vbase offsets.
|
|
|
|
|
|
|
|
struct A1 { int a1; };
|
|
|
|
struct A2 { int a2; };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-16: Vtable for 'Test9::B' (5 entries).
|
|
|
|
// CHECK-16-NEXT: 0 | vbase_offset (16)
|
|
|
|
// CHECK-16-NEXT: 1 | vbase_offset (12)
|
|
|
|
// CHECK-16-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-16-NEXT: 3 | Test9::B RTTI
|
|
|
|
// CHECK-16-NEXT: -- (Test9::B, 0) vtable address --
|
|
|
|
// CHECK-16-NEXT: 4 | void Test9::B::f()
|
2010-02-16 12:59:55 +08:00
|
|
|
struct B : virtual A1, virtual A2 {
|
|
|
|
int b;
|
|
|
|
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void B::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-17 00:02:57 +08:00
|
|
|
|
|
|
|
namespace Test10 {
|
|
|
|
|
|
|
|
// Test for a bug where we would not emit secondary vtables for bases
|
|
|
|
// of a primary base.
|
|
|
|
struct A1 { virtual void a1(); };
|
|
|
|
struct A2 { virtual void a2(); };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-17: Vtable for 'Test10::C' (7 entries).
|
|
|
|
// CHECK-17-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-17-NEXT: 1 | Test10::C RTTI
|
|
|
|
// CHECK-17-NEXT: -- (Test10::A1, 0) vtable address --
|
|
|
|
// CHECK-17-NEXT: -- (Test10::B, 0) vtable address --
|
|
|
|
// CHECK-17-NEXT: -- (Test10::C, 0) vtable address --
|
|
|
|
// CHECK-17-NEXT: 2 | void Test10::A1::a1()
|
|
|
|
// CHECK-17-NEXT: 3 | void Test10::C::f()
|
|
|
|
// CHECK-17-NEXT: 4 | offset_to_top (-8)
|
|
|
|
// CHECK-17-NEXT: 5 | Test10::C RTTI
|
|
|
|
// CHECK-17-NEXT: -- (Test10::A2, 8) vtable address --
|
|
|
|
// CHECK-17-NEXT: 6 | void Test10::A2::a2()
|
2010-02-17 00:02:57 +08:00
|
|
|
struct B : A1, A2 {
|
|
|
|
int b;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : B {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void C::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-17 00:49:35 +08:00
|
|
|
|
|
|
|
namespace Test11 {
|
|
|
|
|
|
|
|
// Very simple test of vtables for virtual bases.
|
|
|
|
struct A1 { int a; };
|
|
|
|
struct A2 { int b; };
|
|
|
|
|
|
|
|
struct B : A1, virtual A2 {
|
|
|
|
int b;
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-18: Vtable for 'Test11::C' (8 entries).
|
|
|
|
// CHECK-18-NEXT: 0 | vbase_offset (24)
|
|
|
|
// CHECK-18-NEXT: 1 | vbase_offset (8)
|
|
|
|
// CHECK-18-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-18-NEXT: 3 | Test11::C RTTI
|
|
|
|
// CHECK-18-NEXT: -- (Test11::C, 0) vtable address --
|
|
|
|
// CHECK-18-NEXT: 4 | void Test11::C::f()
|
|
|
|
// CHECK-18-NEXT: 5 | vbase_offset (16)
|
|
|
|
// CHECK-18-NEXT: 6 | offset_to_top (-8)
|
|
|
|
// CHECK-18-NEXT: 7 | Test11::C RTTI
|
2010-02-17 00:49:35 +08:00
|
|
|
struct C : virtual B {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void C::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-23 11:26:17 +08:00
|
|
|
|
|
|
|
namespace Test12 {
|
|
|
|
|
|
|
|
// Test that the right vcall offsets are generated in the right order.
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-19: Vtable for 'Test12::B' (19 entries).
|
|
|
|
// CHECK-19-NEXT: 0 | vbase_offset (8)
|
|
|
|
// CHECK-19-NEXT: 1 | offset_to_top (0)
|
|
|
|
// CHECK-19-NEXT: 2 | Test12::B RTTI
|
|
|
|
// CHECK-19-NEXT: -- (Test12::B, 0) vtable address --
|
|
|
|
// CHECK-19-NEXT: 3 | void Test12::B::f()
|
|
|
|
// CHECK-19-NEXT: 4 | void Test12::B::a()
|
|
|
|
// CHECK-19-NEXT: 5 | vcall_offset (32)
|
|
|
|
// CHECK-19-NEXT: 6 | vcall_offset (16)
|
|
|
|
// CHECK-19-NEXT: 7 | vcall_offset (-8)
|
|
|
|
// CHECK-19-NEXT: 8 | vcall_offset (0)
|
|
|
|
// CHECK-19-NEXT: 9 | offset_to_top (-8)
|
|
|
|
// CHECK-19-NEXT: 10 | Test12::B RTTI
|
|
|
|
// CHECK-19-NEXT: -- (Test12::A, 8) vtable address --
|
|
|
|
// CHECK-19-NEXT: -- (Test12::A1, 8) vtable address --
|
|
|
|
// CHECK-19-NEXT: 11 | void Test12::A1::a1()
|
|
|
|
// CHECK-19-NEXT: 12 | void Test12::B::a()
|
|
|
|
// CHECK-19-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
|
|
|
|
// CHECK-19-NEXT: 13 | offset_to_top (-24)
|
|
|
|
// CHECK-19-NEXT: 14 | Test12::B RTTI
|
|
|
|
// CHECK-19-NEXT: -- (Test12::A2, 24) vtable address --
|
|
|
|
// CHECK-19-NEXT: 15 | void Test12::A2::a2()
|
|
|
|
// CHECK-19-NEXT: 16 | offset_to_top (-40)
|
|
|
|
// CHECK-19-NEXT: 17 | Test12::B RTTI
|
|
|
|
// CHECK-19-NEXT: -- (Test12::A3, 40) vtable address --
|
|
|
|
// CHECK-19-NEXT: 18 | void Test12::A3::a3()
|
2010-02-23 11:26:17 +08:00
|
|
|
struct A1 {
|
|
|
|
virtual void a1();
|
|
|
|
int a;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct A2 {
|
|
|
|
virtual void a2();
|
|
|
|
int a;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct A3 {
|
|
|
|
virtual void a3();
|
|
|
|
int a;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct A : A1, A2, A3 {
|
|
|
|
virtual void a();
|
|
|
|
int i;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
virtual void f();
|
|
|
|
|
|
|
|
virtual void a();
|
|
|
|
};
|
|
|
|
void B::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-23 11:48:14 +08:00
|
|
|
|
|
|
|
namespace Test13 {
|
|
|
|
|
|
|
|
// Test that we don't try to emit a vtable for 'A' twice.
|
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-20: Vtable for 'Test13::C' (6 entries).
|
|
|
|
// CHECK-20-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-20-NEXT: 1 | vbase_offset (0)
|
|
|
|
// CHECK-20-NEXT: 2 | vcall_offset (0)
|
|
|
|
// CHECK-20-NEXT: 3 | offset_to_top (0)
|
|
|
|
// CHECK-20-NEXT: 4 | Test13::C RTTI
|
|
|
|
// CHECK-20-NEXT: -- (Test13::A, 0) vtable address --
|
|
|
|
// CHECK-20-NEXT: -- (Test13::B, 0) vtable address --
|
|
|
|
// CHECK-20-NEXT: -- (Test13::C, 0) vtable address --
|
|
|
|
// CHECK-20-NEXT: 5 | void Test13::C::f()
|
2010-02-23 11:48:14 +08:00
|
|
|
struct C : virtual B, virtual A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void C::f() { }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-02-26 06:18:35 +08:00
|
|
|
namespace Test14 {
|
|
|
|
|
|
|
|
// Verify that we handle A being a non-virtual base of B, which is a virtual base.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : A { };
|
|
|
|
|
|
|
|
struct C : virtual B { };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-21: Vtable for 'Test14::D' (5 entries).
|
|
|
|
// CHECK-21-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-21-NEXT: 1 | vcall_offset (0)
|
|
|
|
// CHECK-21-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-21-NEXT: 3 | Test14::D RTTI
|
|
|
|
// CHECK-21-NEXT: -- (Test14::A, 0) vtable address --
|
|
|
|
// CHECK-21-NEXT: -- (Test14::B, 0) vtable address --
|
|
|
|
// CHECK-21-NEXT: -- (Test14::C, 0) vtable address --
|
|
|
|
// CHECK-21-NEXT: -- (Test14::D, 0) vtable address --
|
|
|
|
// CHECK-21-NEXT: 4 | void Test14::D::f()
|
2010-02-26 06:18:35 +08:00
|
|
|
struct D : C, virtual B {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void D::f() { }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-02-27 12:05:52 +08:00
|
|
|
namespace Test15 {
|
|
|
|
|
|
|
|
// Test that we don't emit an extra vtable for B since it's a primary base of C.
|
|
|
|
struct A { virtual void a(); };
|
|
|
|
struct B { virtual void b(); };
|
|
|
|
|
|
|
|
struct C : virtual B { };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-22: Vtable for 'Test15::D' (11 entries).
|
|
|
|
// CHECK-22-NEXT: 0 | vbase_offset (8)
|
|
|
|
// CHECK-22-NEXT: 1 | vbase_offset (8)
|
|
|
|
// CHECK-22-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-22-NEXT: 3 | Test15::D RTTI
|
|
|
|
// CHECK-22-NEXT: -- (Test15::A, 0) vtable address --
|
|
|
|
// CHECK-22-NEXT: -- (Test15::D, 0) vtable address --
|
|
|
|
// CHECK-22-NEXT: 4 | void Test15::A::a()
|
|
|
|
// CHECK-22-NEXT: 5 | void Test15::D::f()
|
|
|
|
// CHECK-22-NEXT: 6 | vbase_offset (0)
|
|
|
|
// CHECK-22-NEXT: 7 | vcall_offset (0)
|
|
|
|
// CHECK-22-NEXT: 8 | offset_to_top (-8)
|
|
|
|
// CHECK-22-NEXT: 9 | Test15::D RTTI
|
|
|
|
// CHECK-22-NEXT: -- (Test15::B, 8) vtable address --
|
|
|
|
// CHECK-22-NEXT: -- (Test15::C, 8) vtable address --
|
|
|
|
// CHECK-22-NEXT: 10 | void Test15::B::b()
|
2010-02-27 12:05:52 +08:00
|
|
|
struct D : A, virtual B, virtual C {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void D::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-27 12:12:52 +08:00
|
|
|
|
|
|
|
namespace Test16 {
|
|
|
|
|
|
|
|
// Test that destructors share vcall offsets.
|
|
|
|
|
|
|
|
struct A { virtual ~A(); };
|
|
|
|
struct B { virtual ~B(); };
|
|
|
|
|
|
|
|
struct C : A, B { virtual ~C(); };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-23: Vtable for 'Test16::D' (15 entries).
|
|
|
|
// CHECK-23-NEXT: 0 | vbase_offset (8)
|
|
|
|
// CHECK-23-NEXT: 1 | offset_to_top (0)
|
|
|
|
// CHECK-23-NEXT: 2 | Test16::D RTTI
|
|
|
|
// CHECK-23-NEXT: -- (Test16::D, 0) vtable address --
|
|
|
|
// CHECK-23-NEXT: 3 | void Test16::D::f()
|
|
|
|
// CHECK-23-NEXT: 4 | Test16::D::~D() [complete]
|
|
|
|
// CHECK-23-NEXT: 5 | Test16::D::~D() [deleting]
|
|
|
|
// CHECK-23-NEXT: 6 | vcall_offset (-8)
|
|
|
|
// CHECK-23-NEXT: 7 | offset_to_top (-8)
|
|
|
|
// CHECK-23-NEXT: 8 | Test16::D RTTI
|
|
|
|
// CHECK-23-NEXT: -- (Test16::A, 8) vtable address --
|
|
|
|
// CHECK-23-NEXT: -- (Test16::C, 8) vtable address --
|
|
|
|
// CHECK-23-NEXT: 9 | Test16::D::~D() [complete]
|
|
|
|
// CHECK-23-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
|
|
|
// CHECK-23-NEXT: 10 | Test16::D::~D() [deleting]
|
|
|
|
// CHECK-23-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
|
|
|
// CHECK-23-NEXT: 11 | offset_to_top (-16)
|
|
|
|
// CHECK-23-NEXT: 12 | Test16::D RTTI
|
|
|
|
// CHECK-23-NEXT: -- (Test16::B, 16) vtable address --
|
|
|
|
// CHECK-23-NEXT: 13 | Test16::D::~D() [complete]
|
|
|
|
// CHECK-23-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset]
|
|
|
|
// CHECK-23-NEXT: 14 | Test16::D::~D() [deleting]
|
|
|
|
// CHECK-23-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset]
|
2010-02-27 12:12:52 +08:00
|
|
|
struct D : virtual C {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void D::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-27 14:38:03 +08:00
|
|
|
|
|
|
|
namespace Test17 {
|
|
|
|
|
|
|
|
// Test that we don't mark E::f in the C-in-E vtable as unused.
|
|
|
|
struct A { virtual void f(); };
|
|
|
|
struct B : virtual A { virtual void f(); };
|
|
|
|
struct C : virtual A { virtual void f(); };
|
|
|
|
struct D : virtual B, virtual C { virtual void f(); };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-24: Vtable for 'Test17::E' (13 entries).
|
|
|
|
// CHECK-24-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-24-NEXT: 1 | vbase_offset (8)
|
|
|
|
// CHECK-24-NEXT: 2 | vbase_offset (0)
|
|
|
|
// CHECK-24-NEXT: 3 | vbase_offset (0)
|
|
|
|
// CHECK-24-NEXT: 4 | vcall_offset (0)
|
|
|
|
// CHECK-24-NEXT: 5 | offset_to_top (0)
|
|
|
|
// CHECK-24-NEXT: 6 | Test17::E RTTI
|
|
|
|
// CHECK-24-NEXT: -- (Test17::A, 0) vtable address --
|
|
|
|
// CHECK-24-NEXT: -- (Test17::B, 0) vtable address --
|
|
|
|
// CHECK-24-NEXT: -- (Test17::D, 0) vtable address --
|
|
|
|
// CHECK-24-NEXT: -- (Test17::E, 0) vtable address --
|
|
|
|
// CHECK-24-NEXT: 7 | void Test17::E::f()
|
|
|
|
// CHECK-24-NEXT: 8 | vbase_offset (-8)
|
|
|
|
// CHECK-24-NEXT: 9 | vcall_offset (-8)
|
|
|
|
// CHECK-24-NEXT: 10 | offset_to_top (-8)
|
|
|
|
// CHECK-24-NEXT: 11 | Test17::E RTTI
|
|
|
|
// CHECK-24-NEXT: -- (Test17::C, 8) vtable address --
|
|
|
|
// CHECK-24-NEXT: 12 | void Test17::E::f()
|
|
|
|
// CHECK-24-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
2010-02-27 14:38:03 +08:00
|
|
|
class E : virtual D {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void E::f() {}
|
|
|
|
|
|
|
|
}
|
2010-02-28 00:52:49 +08:00
|
|
|
|
|
|
|
namespace Test18 {
|
|
|
|
|
|
|
|
// Test that we compute the right 'this' adjustment offsets.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
virtual void g();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : A, B {
|
|
|
|
virtual void g();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-25: Vtable for 'Test18::D' (24 entries).
|
|
|
|
// CHECK-25-NEXT: 0 | vbase_offset (8)
|
|
|
|
// CHECK-25-NEXT: 1 | vbase_offset (0)
|
|
|
|
// CHECK-25-NEXT: 2 | vbase_offset (0)
|
|
|
|
// CHECK-25-NEXT: 3 | vcall_offset (8)
|
|
|
|
// CHECK-25-NEXT: 4 | vcall_offset (0)
|
|
|
|
// CHECK-25-NEXT: 5 | offset_to_top (0)
|
|
|
|
// CHECK-25-NEXT: 6 | Test18::D RTTI
|
|
|
|
// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --
|
|
|
|
// CHECK-25-NEXT: -- (Test18::B, 0) vtable address --
|
|
|
|
// CHECK-25-NEXT: -- (Test18::D, 0) vtable address --
|
|
|
|
// CHECK-25-NEXT: 7 | void Test18::D::f()
|
|
|
|
// CHECK-25-NEXT: 8 | void Test18::C::g()
|
|
|
|
// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
|
|
|
|
// CHECK-25-NEXT: 9 | void Test18::D::h()
|
|
|
|
// CHECK-25-NEXT: 10 | vcall_offset (0)
|
|
|
|
// CHECK-25-NEXT: 11 | vcall_offset (-8)
|
|
|
|
// CHECK-25-NEXT: 12 | vbase_offset (-8)
|
|
|
|
// CHECK-25-NEXT: 13 | offset_to_top (-8)
|
|
|
|
// CHECK-25-NEXT: 14 | Test18::D RTTI
|
|
|
|
// CHECK-25-NEXT: -- (Test18::A, 8) vtable address --
|
|
|
|
// CHECK-25-NEXT: -- (Test18::C, 8) vtable address --
|
|
|
|
// CHECK-25-NEXT: 15 | void Test18::D::f()
|
|
|
|
// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
|
|
|
|
// CHECK-25-NEXT: 16 | void Test18::C::g()
|
|
|
|
// CHECK-25-NEXT: 17 | vbase_offset (-16)
|
|
|
|
// CHECK-25-NEXT: 18 | vcall_offset (-8)
|
|
|
|
// CHECK-25-NEXT: 19 | vcall_offset (-16)
|
|
|
|
// CHECK-25-NEXT: 20 | offset_to_top (-16)
|
|
|
|
// CHECK-25-NEXT: 21 | Test18::D RTTI
|
|
|
|
// CHECK-25-NEXT: -- (Test18::B, 16) vtable address --
|
|
|
|
// CHECK-25-NEXT: 22 | void Test18::D::f()
|
|
|
|
// CHECK-25-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset]
|
|
|
|
// CHECK-25-NEXT: 23 | [unused] void Test18::C::g()
|
|
|
|
|
|
|
|
// CHECK-25: Construction vtable for ('Test18::B', 0) in 'Test18::D' (7 entries).
|
|
|
|
// CHECK-25-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-25-NEXT: 1 | vcall_offset (0)
|
|
|
|
// CHECK-25-NEXT: 2 | vcall_offset (0)
|
|
|
|
// CHECK-25-NEXT: 3 | offset_to_top (0)
|
|
|
|
// CHECK-25-NEXT: 4 | Test18::B RTTI
|
|
|
|
// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --
|
|
|
|
// CHECK-25-NEXT: -- (Test18::B, 0) vtable address --
|
|
|
|
// CHECK-25-NEXT: 5 | void Test18::B::f()
|
|
|
|
// CHECK-25-NEXT: 6 | void Test18::A::g()
|
|
|
|
|
|
|
|
// CHECK-25: Construction vtable for ('Test18::C', 8) in 'Test18::D' (20 entries).
|
|
|
|
// CHECK-25-NEXT: 0 | vcall_offset (0)
|
|
|
|
// CHECK-25-NEXT: 1 | vcall_offset (0)
|
|
|
|
// CHECK-25-NEXT: 2 | vbase_offset (-8)
|
|
|
|
// CHECK-25-NEXT: 3 | offset_to_top (0)
|
|
|
|
// CHECK-25-NEXT: 4 | Test18::C RTTI
|
|
|
|
// CHECK-25-NEXT: -- (Test18::A, 8) vtable address --
|
|
|
|
// CHECK-25-NEXT: -- (Test18::C, 8) vtable address --
|
|
|
|
// CHECK-25-NEXT: 5 | void Test18::A::f()
|
|
|
|
// CHECK-25-NEXT: 6 | void Test18::C::g()
|
|
|
|
// CHECK-25-NEXT: 7 | vbase_offset (-16)
|
|
|
|
// CHECK-25-NEXT: 8 | vcall_offset (-8)
|
|
|
|
// CHECK-25-NEXT: 9 | vcall_offset (0)
|
|
|
|
// CHECK-25-NEXT: 10 | offset_to_top (-8)
|
|
|
|
// CHECK-25-NEXT: 11 | Test18::C RTTI
|
|
|
|
// CHECK-25-NEXT: -- (Test18::B, 16) vtable address --
|
|
|
|
// CHECK-25-NEXT: 12 | void Test18::B::f()
|
|
|
|
// CHECK-25-NEXT: 13 | [unused] void Test18::C::g()
|
|
|
|
// CHECK-25-NEXT: 14 | vcall_offset (8)
|
|
|
|
// CHECK-25-NEXT: 15 | vcall_offset (16)
|
|
|
|
// CHECK-25-NEXT: 16 | offset_to_top (8)
|
|
|
|
// CHECK-25-NEXT: 17 | Test18::C RTTI
|
|
|
|
// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --
|
|
|
|
// CHECK-25-NEXT: 18 | void Test18::B::f()
|
|
|
|
// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
|
|
|
// CHECK-25-NEXT: 19 | void Test18::C::g()
|
|
|
|
// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
|
|
|
|
|
|
|
|
// CHECK-25: Construction vtable for ('Test18::B', 16) in 'Test18::D' (13 entries).
|
|
|
|
// CHECK-25-NEXT: 0 | vbase_offset (-16)
|
|
|
|
// CHECK-25-NEXT: 1 | vcall_offset (-16)
|
|
|
|
// CHECK-25-NEXT: 2 | vcall_offset (0)
|
|
|
|
// CHECK-25-NEXT: 3 | offset_to_top (0)
|
|
|
|
// CHECK-25-NEXT: 4 | Test18::B RTTI
|
|
|
|
// CHECK-25-NEXT: -- (Test18::B, 16) vtable address --
|
|
|
|
// CHECK-25-NEXT: 5 | void Test18::B::f()
|
|
|
|
// CHECK-25-NEXT: 6 | [unused] void Test18::A::g()
|
|
|
|
// CHECK-25-NEXT: 7 | vcall_offset (0)
|
|
|
|
// CHECK-25-NEXT: 8 | vcall_offset (16)
|
|
|
|
// CHECK-25-NEXT: 9 | offset_to_top (16)
|
|
|
|
// CHECK-25-NEXT: 10 | Test18::B RTTI
|
|
|
|
// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --
|
|
|
|
// CHECK-25-NEXT: 11 | void Test18::B::f()
|
|
|
|
// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
|
|
|
// CHECK-25-NEXT: 12 | void Test18::A::g()
|
2010-02-28 00:52:49 +08:00
|
|
|
struct D : virtual B, virtual C, virtual A
|
|
|
|
{
|
|
|
|
virtual void f();
|
|
|
|
virtual void h();
|
|
|
|
};
|
|
|
|
void D::f() {}
|
|
|
|
|
2010-02-28 00:55:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace Test19 {
|
|
|
|
|
|
|
|
// Another 'this' adjustment test.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
int a;
|
|
|
|
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : A {
|
|
|
|
int b;
|
|
|
|
|
|
|
|
virtual void g();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C {
|
|
|
|
virtual void c();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-26: Vtable for 'Test19::D' (13 entries).
|
|
|
|
// CHECK-26-NEXT: 0 | vbase_offset (24)
|
|
|
|
// CHECK-26-NEXT: 1 | offset_to_top (0)
|
|
|
|
// CHECK-26-NEXT: 2 | Test19::D RTTI
|
|
|
|
// CHECK-26-NEXT: -- (Test19::C, 0) vtable address --
|
|
|
|
// CHECK-26-NEXT: -- (Test19::D, 0) vtable address --
|
|
|
|
// CHECK-26-NEXT: 3 | void Test19::C::c()
|
|
|
|
// CHECK-26-NEXT: 4 | void Test19::D::f()
|
|
|
|
// CHECK-26-NEXT: 5 | offset_to_top (-8)
|
|
|
|
// CHECK-26-NEXT: 6 | Test19::D RTTI
|
|
|
|
// CHECK-26-NEXT: -- (Test19::A, 8) vtable address --
|
|
|
|
// CHECK-26-NEXT: -- (Test19::B, 8) vtable address --
|
|
|
|
// CHECK-26-NEXT: 7 | void Test19::D::f()
|
|
|
|
// CHECK-26-NEXT: [this adjustment: -8 non-virtual]
|
|
|
|
// CHECK-26-NEXT: 8 | void Test19::B::g()
|
|
|
|
// CHECK-26-NEXT: 9 | vcall_offset (-24)
|
|
|
|
// CHECK-26-NEXT: 10 | offset_to_top (-24)
|
|
|
|
// CHECK-26-NEXT: 11 | Test19::D RTTI
|
|
|
|
// CHECK-26-NEXT: -- (Test19::A, 24) vtable address --
|
|
|
|
// CHECK-26-NEXT: 12 | void Test19::D::f()
|
|
|
|
// CHECK-26-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
2010-02-28 00:55:58 +08:00
|
|
|
struct D : C, B, virtual A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void D::f() { }
|
|
|
|
|
2010-02-28 02:16:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace Test20 {
|
|
|
|
|
|
|
|
// pure virtual member functions should never have 'this' adjustments.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void f() = 0;
|
|
|
|
virtual void g();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : A { };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-27: Vtable for 'Test20::C' (9 entries).
|
|
|
|
// CHECK-27-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-27-NEXT: 1 | Test20::C RTTI
|
|
|
|
// CHECK-27-NEXT: -- (Test20::A, 0) vtable address --
|
|
|
|
// CHECK-27-NEXT: -- (Test20::C, 0) vtable address --
|
|
|
|
// CHECK-27-NEXT: 2 | void Test20::C::f() [pure]
|
|
|
|
// CHECK-27-NEXT: 3 | void Test20::A::g()
|
|
|
|
// CHECK-27-NEXT: 4 | void Test20::C::h()
|
|
|
|
// CHECK-27-NEXT: 5 | offset_to_top (-8)
|
|
|
|
// CHECK-27-NEXT: 6 | Test20::C RTTI
|
|
|
|
// CHECK-27-NEXT: -- (Test20::A, 8) vtable address --
|
|
|
|
// CHECK-27-NEXT: -- (Test20::B, 8) vtable address --
|
|
|
|
// CHECK-27-NEXT: 7 | void Test20::C::f() [pure]
|
|
|
|
// CHECK-27-NEXT: 8 | void Test20::A::g()
|
2010-02-28 02:16:50 +08:00
|
|
|
struct C : A, B {
|
|
|
|
virtual void f() = 0;
|
|
|
|
virtual void h();
|
|
|
|
};
|
|
|
|
void C::h() { }
|
|
|
|
|
|
|
|
}
|
2010-02-28 03:21:58 +08:00
|
|
|
|
|
|
|
namespace Test21 {
|
|
|
|
|
|
|
|
// Test that we get vbase offsets right in secondary vtables.
|
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A { };
|
|
|
|
class C : virtual B { };
|
|
|
|
class D : virtual C { };
|
|
|
|
|
|
|
|
class E : virtual C { };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-28: Vtable for 'Test21::F' (16 entries).
|
|
|
|
// CHECK-28-NEXT: 0 | vbase_offset (8)
|
|
|
|
// CHECK-28-NEXT: 1 | vbase_offset (0)
|
|
|
|
// CHECK-28-NEXT: 2 | vbase_offset (0)
|
|
|
|
// CHECK-28-NEXT: 3 | vbase_offset (0)
|
|
|
|
// CHECK-28-NEXT: 4 | vbase_offset (0)
|
|
|
|
// CHECK-28-NEXT: 5 | vcall_offset (0)
|
|
|
|
// CHECK-28-NEXT: 6 | offset_to_top (0)
|
|
|
|
// CHECK-28-NEXT: 7 | Test21::F RTTI
|
|
|
|
// CHECK-28-NEXT: -- (Test21::A, 0) vtable address --
|
|
|
|
// CHECK-28-NEXT: -- (Test21::B, 0) vtable address --
|
|
|
|
// CHECK-28-NEXT: -- (Test21::C, 0) vtable address --
|
|
|
|
// CHECK-28-NEXT: -- (Test21::D, 0) vtable address --
|
|
|
|
// CHECK-28-NEXT: -- (Test21::F, 0) vtable address --
|
|
|
|
// CHECK-28-NEXT: 8 | void Test21::F::f()
|
|
|
|
// CHECK-28-NEXT: 9 | vbase_offset (-8)
|
|
|
|
// CHECK-28-NEXT: 10 | vbase_offset (-8)
|
|
|
|
// CHECK-28-NEXT: 11 | vbase_offset (-8)
|
|
|
|
// CHECK-28-NEXT: 12 | vcall_offset (-8)
|
|
|
|
// CHECK-28-NEXT: 13 | offset_to_top (-8)
|
|
|
|
// CHECK-28-NEXT: 14 | Test21::F RTTI
|
|
|
|
// CHECK-28-NEXT: -- (Test21::E, 8) vtable address --
|
|
|
|
// CHECK-28-NEXT: 15 | [unused] void Test21::F::f()
|
2010-03-11 14:44:31 +08:00
|
|
|
//
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-28: Virtual base offset offsets for 'Test21::F' (5 entries).
|
|
|
|
// CHECK-28-NEXT: Test21::A | -32
|
|
|
|
// CHECK-28-NEXT: Test21::B | -40
|
|
|
|
// CHECK-28-NEXT: Test21::C | -48
|
|
|
|
// CHECK-28-NEXT: Test21::D | -56
|
|
|
|
// CHECK-28-NEXT: Test21::E | -64
|
2010-02-28 03:21:58 +08:00
|
|
|
class F : virtual D, virtual E {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void F::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-28 05:09:00 +08:00
|
|
|
|
|
|
|
namespace Test22 {
|
|
|
|
|
|
|
|
// Very simple construction vtable test.
|
|
|
|
struct V1 {
|
|
|
|
int v1;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct V2 : virtual V1 {
|
|
|
|
int v2;
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-29: Vtable for 'Test22::C' (8 entries).
|
|
|
|
// CHECK-29-NEXT: 0 | vbase_offset (16)
|
|
|
|
// CHECK-29-NEXT: 1 | vbase_offset (12)
|
|
|
|
// CHECK-29-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-29-NEXT: 3 | Test22::C RTTI
|
|
|
|
// CHECK-29-NEXT: -- (Test22::C, 0) vtable address --
|
|
|
|
// CHECK-29-NEXT: 4 | void Test22::C::f()
|
|
|
|
// CHECK-29-NEXT: 5 | vbase_offset (-4)
|
|
|
|
// CHECK-29-NEXT: 6 | offset_to_top (-16)
|
|
|
|
// CHECK-29-NEXT: 7 | Test22::C RTTI
|
|
|
|
// CHECK-29-NEXT: -- (Test22::V2, 16) vtable address --
|
2010-02-28 05:09:00 +08:00
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-29: Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries).
|
|
|
|
// CHECK-29-NEXT: 0 | vbase_offset (-4)
|
|
|
|
// CHECK-29-NEXT: 1 | offset_to_top (0)
|
|
|
|
// CHECK-29-NEXT: 2 | Test22::V2 RTTI
|
2010-02-28 05:09:00 +08:00
|
|
|
|
|
|
|
struct C : virtual V1, virtual V2 {
|
|
|
|
int c;
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void C::f() { }
|
|
|
|
|
|
|
|
}
|
2010-02-28 09:43:58 +08:00
|
|
|
|
|
|
|
namespace Test23 {
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
int a;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
int b;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : A, virtual B {
|
|
|
|
int c;
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-30: Vtable for 'Test23::D' (7 entries).
|
|
|
|
// CHECK-30-NEXT: 0 | vbase_offset (20)
|
|
|
|
// CHECK-30-NEXT: 1 | vbase_offset (24)
|
|
|
|
// CHECK-30-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-30-NEXT: 3 | Test23::D RTTI
|
|
|
|
// CHECK-30-NEXT: -- (Test23::C, 0) vtable address --
|
|
|
|
// CHECK-30-NEXT: -- (Test23::D, 0) vtable address --
|
|
|
|
// CHECK-30-NEXT: 4 | vbase_offset (-4)
|
|
|
|
// CHECK-30-NEXT: 5 | offset_to_top (-24)
|
|
|
|
// CHECK-30-NEXT: 6 | Test23::D RTTI
|
|
|
|
// CHECK-30-NEXT: -- (Test23::B, 24) vtable address --
|
|
|
|
|
|
|
|
// CHECK-30: Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries).
|
|
|
|
// CHECK-30-NEXT: 0 | vbase_offset (20)
|
|
|
|
// CHECK-30-NEXT: 1 | vbase_offset (24)
|
|
|
|
// CHECK-30-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-30-NEXT: 3 | Test23::C RTTI
|
|
|
|
// CHECK-30-NEXT: -- (Test23::C, 0) vtable address --
|
|
|
|
// CHECK-30-NEXT: 4 | vbase_offset (-4)
|
|
|
|
// CHECK-30-NEXT: 5 | offset_to_top (-24)
|
|
|
|
// CHECK-30-NEXT: 6 | Test23::C RTTI
|
|
|
|
// CHECK-30-NEXT: -- (Test23::B, 24) vtable address --
|
|
|
|
|
|
|
|
// CHECK-30: Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries).
|
|
|
|
// CHECK-30-NEXT: 0 | vbase_offset (-4)
|
|
|
|
// CHECK-30-NEXT: 1 | offset_to_top (0)
|
|
|
|
// CHECK-30-NEXT: 2 | Test23::B RTTI
|
|
|
|
// CHECK-30-NEXT: -- (Test23::B, 24) vtable address --
|
2010-02-28 09:43:58 +08:00
|
|
|
|
|
|
|
struct D : virtual A, virtual B, C {
|
|
|
|
int d;
|
|
|
|
|
|
|
|
void f();
|
|
|
|
};
|
|
|
|
void D::f() { }
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
D d;
|
2010-02-28 09:43:58 +08:00
|
|
|
}
|
2010-03-01 01:59:36 +08:00
|
|
|
|
|
|
|
namespace Test24 {
|
|
|
|
|
|
|
|
// Another construction vtable test.
|
|
|
|
|
2010-03-01 02:08:38 +08:00
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A { };
|
|
|
|
struct C : virtual A { };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-31: Vtable for 'Test24::D' (10 entries).
|
|
|
|
// CHECK-31-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-31-NEXT: 1 | vcall_offset (0)
|
|
|
|
// CHECK-31-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-31-NEXT: 3 | Test24::D RTTI
|
|
|
|
// CHECK-31-NEXT: -- (Test24::A, 0) vtable address --
|
|
|
|
// CHECK-31-NEXT: -- (Test24::B, 0) vtable address --
|
|
|
|
// CHECK-31-NEXT: -- (Test24::D, 0) vtable address --
|
|
|
|
// CHECK-31-NEXT: 4 | void Test24::D::f()
|
|
|
|
// CHECK-31-NEXT: 5 | vbase_offset (-8)
|
|
|
|
// CHECK-31-NEXT: 6 | vcall_offset (-8)
|
|
|
|
// CHECK-31-NEXT: 7 | offset_to_top (-8)
|
|
|
|
// CHECK-31-NEXT: 8 | Test24::D RTTI
|
|
|
|
// CHECK-31-NEXT: -- (Test24::C, 8) vtable address --
|
|
|
|
// CHECK-31-NEXT: 9 | [unused] void Test24::D::f()
|
|
|
|
|
|
|
|
// CHECK-31: Construction vtable for ('Test24::B', 0) in 'Test24::D' (5 entries).
|
|
|
|
// CHECK-31-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-31-NEXT: 1 | vcall_offset (0)
|
|
|
|
// CHECK-31-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-31-NEXT: 3 | Test24::B RTTI
|
|
|
|
// CHECK-31-NEXT: -- (Test24::A, 0) vtable address --
|
|
|
|
// CHECK-31-NEXT: -- (Test24::B, 0) vtable address --
|
|
|
|
// CHECK-31-NEXT: 4 | void Test24::A::f()
|
|
|
|
|
|
|
|
// CHECK-31: Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries).
|
|
|
|
// CHECK-31-NEXT: 0 | vbase_offset (-8)
|
|
|
|
// CHECK-31-NEXT: 1 | vcall_offset (-8)
|
|
|
|
// CHECK-31-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-31-NEXT: 3 | Test24::C RTTI
|
|
|
|
// CHECK-31-NEXT: -- (Test24::C, 8) vtable address --
|
|
|
|
// CHECK-31-NEXT: 4 | [unused] void Test24::A::f()
|
|
|
|
// CHECK-31-NEXT: 5 | vcall_offset (0)
|
|
|
|
// CHECK-31-NEXT: 6 | offset_to_top (8)
|
|
|
|
// CHECK-31-NEXT: 7 | Test24::C RTTI
|
|
|
|
// CHECK-31-NEXT: -- (Test24::A, 0) vtable address --
|
|
|
|
// CHECK-31-NEXT: 8 | void Test24::A::f()
|
2010-03-01 01:59:36 +08:00
|
|
|
struct D : B, C {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void D::f() { }
|
2010-03-01 02:37:33 +08:00
|
|
|
|
2010-03-01 01:59:36 +08:00
|
|
|
}
|
2010-03-03 12:58:02 +08:00
|
|
|
|
|
|
|
namespace Test25 {
|
|
|
|
|
|
|
|
// This mainly tests that we don't assert on this class hierarchy.
|
|
|
|
|
|
|
|
struct V {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct A : virtual V { };
|
|
|
|
struct B : virtual V { };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-32: Vtable for 'Test25::C' (11 entries).
|
|
|
|
// CHECK-32-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-32-NEXT: 1 | vcall_offset (0)
|
|
|
|
// CHECK-32-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-32-NEXT: 3 | Test25::C RTTI
|
|
|
|
// CHECK-32-NEXT: -- (Test25::A, 0) vtable address --
|
|
|
|
// CHECK-32-NEXT: -- (Test25::C, 0) vtable address --
|
|
|
|
// CHECK-32-NEXT: -- (Test25::V, 0) vtable address --
|
|
|
|
// CHECK-32-NEXT: 4 | void Test25::V::f()
|
|
|
|
// CHECK-32-NEXT: 5 | void Test25::C::g()
|
|
|
|
// CHECK-32-NEXT: 6 | vbase_offset (-8)
|
|
|
|
// CHECK-32-NEXT: 7 | vcall_offset (-8)
|
|
|
|
// CHECK-32-NEXT: 8 | offset_to_top (-8)
|
|
|
|
// CHECK-32-NEXT: 9 | Test25::C RTTI
|
|
|
|
// CHECK-32-NEXT: -- (Test25::B, 8) vtable address --
|
|
|
|
// CHECK-32-NEXT: 10 | [unused] void Test25::V::f()
|
|
|
|
|
|
|
|
// CHECK-32: Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries).
|
|
|
|
// CHECK-32-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-32-NEXT: 1 | vcall_offset (0)
|
|
|
|
// CHECK-32-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-32-NEXT: 3 | Test25::A RTTI
|
|
|
|
// CHECK-32-NEXT: -- (Test25::A, 0) vtable address --
|
|
|
|
// CHECK-32-NEXT: -- (Test25::V, 0) vtable address --
|
|
|
|
// CHECK-32-NEXT: 4 | void Test25::V::f()
|
|
|
|
|
|
|
|
// CHECK-32: Construction vtable for ('Test25::B', 8) in 'Test25::C' (9 entries).
|
|
|
|
// CHECK-32-NEXT: 0 | vbase_offset (-8)
|
|
|
|
// CHECK-32-NEXT: 1 | vcall_offset (-8)
|
|
|
|
// CHECK-32-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-32-NEXT: 3 | Test25::B RTTI
|
|
|
|
// CHECK-32-NEXT: -- (Test25::B, 8) vtable address --
|
|
|
|
// CHECK-32-NEXT: 4 | [unused] void Test25::V::f()
|
|
|
|
// CHECK-32-NEXT: 5 | vcall_offset (0)
|
|
|
|
// CHECK-32-NEXT: 6 | offset_to_top (8)
|
|
|
|
// CHECK-32-NEXT: 7 | Test25::B RTTI
|
|
|
|
// CHECK-32-NEXT: -- (Test25::V, 0) vtable address --
|
|
|
|
// CHECK-32-NEXT: 8 | void Test25::V::f()
|
2010-03-03 12:58:02 +08:00
|
|
|
struct C : A, virtual V, B {
|
|
|
|
virtual void g();
|
|
|
|
};
|
|
|
|
void C::g() { }
|
|
|
|
|
|
|
|
}
|
2010-03-10 14:51:42 +08:00
|
|
|
|
|
|
|
namespace Test26 {
|
|
|
|
|
|
|
|
// Test that we generate the right number of entries in the C-in-D construction vtable, and that
|
|
|
|
// we don't mark A::a as unused.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void a();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B {
|
|
|
|
virtual void c();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : virtual A {
|
|
|
|
virtual void b();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-33: Vtable for 'Test26::D' (15 entries).
|
|
|
|
// CHECK-33-NEXT: 0 | vbase_offset (8)
|
|
|
|
// CHECK-33-NEXT: 1 | vbase_offset (8)
|
|
|
|
// CHECK-33-NEXT: 2 | vbase_offset (0)
|
|
|
|
// CHECK-33-NEXT: 3 | vcall_offset (0)
|
|
|
|
// CHECK-33-NEXT: 4 | offset_to_top (0)
|
|
|
|
// CHECK-33-NEXT: 5 | Test26::D RTTI
|
|
|
|
// CHECK-33-NEXT: -- (Test26::B, 0) vtable address --
|
|
|
|
// CHECK-33-NEXT: -- (Test26::D, 0) vtable address --
|
|
|
|
// CHECK-33-NEXT: 6 | void Test26::B::c()
|
|
|
|
// CHECK-33-NEXT: 7 | void Test26::D::d()
|
|
|
|
// CHECK-33-NEXT: 8 | vcall_offset (0)
|
|
|
|
// CHECK-33-NEXT: 9 | vbase_offset (0)
|
|
|
|
// CHECK-33-NEXT: 10 | vcall_offset (0)
|
|
|
|
// CHECK-33-NEXT: 11 | offset_to_top (-8)
|
|
|
|
// CHECK-33-NEXT: 12 | Test26::D RTTI
|
|
|
|
// CHECK-33-NEXT: -- (Test26::A, 8) vtable address --
|
|
|
|
// CHECK-33-NEXT: -- (Test26::C, 8) vtable address --
|
|
|
|
// CHECK-33-NEXT: 13 | void Test26::A::a()
|
|
|
|
// CHECK-33-NEXT: 14 | void Test26::C::b()
|
|
|
|
|
|
|
|
// CHECK-33: Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries).
|
|
|
|
// CHECK-33-NEXT: 0 | vcall_offset (0)
|
|
|
|
// CHECK-33-NEXT: 1 | vbase_offset (0)
|
|
|
|
// CHECK-33-NEXT: 2 | vcall_offset (0)
|
|
|
|
// CHECK-33-NEXT: 3 | offset_to_top (0)
|
|
|
|
// CHECK-33-NEXT: 4 | Test26::C RTTI
|
|
|
|
// CHECK-33-NEXT: -- (Test26::A, 8) vtable address --
|
|
|
|
// CHECK-33-NEXT: -- (Test26::C, 8) vtable address --
|
|
|
|
// CHECK-33-NEXT: 5 | void Test26::A::a()
|
|
|
|
// CHECK-33-NEXT: 6 | void Test26::C::b()
|
2010-03-10 14:51:42 +08:00
|
|
|
class D : virtual B, virtual C {
|
|
|
|
virtual void d();
|
|
|
|
};
|
|
|
|
void D::d() { }
|
|
|
|
|
2010-03-10 14:51:56 +08:00
|
|
|
}
|
2010-03-11 03:15:26 +08:00
|
|
|
|
|
|
|
namespace Test27 {
|
|
|
|
|
|
|
|
// Test that we don't generate a secondary vtable for C in the D-in-E vtable, since
|
|
|
|
// C doesn't have any virtual bases.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void a();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B {
|
|
|
|
virtual void b();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C {
|
|
|
|
virtual void c();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D : A, virtual B, C {
|
|
|
|
virtual void d();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-34: Vtable for 'Test27::E' (13 entries).
|
|
|
|
// CHECK-34-NEXT: 0 | vbase_offset (16)
|
|
|
|
// CHECK-34-NEXT: 1 | offset_to_top (0)
|
|
|
|
// CHECK-34-NEXT: 2 | Test27::E RTTI
|
|
|
|
// CHECK-34-NEXT: -- (Test27::A, 0) vtable address --
|
|
|
|
// CHECK-34-NEXT: -- (Test27::D, 0) vtable address --
|
|
|
|
// CHECK-34-NEXT: -- (Test27::E, 0) vtable address --
|
|
|
|
// CHECK-34-NEXT: 3 | void Test27::A::a()
|
|
|
|
// CHECK-34-NEXT: 4 | void Test27::D::d()
|
|
|
|
// CHECK-34-NEXT: 5 | void Test27::E::e()
|
|
|
|
// CHECK-34-NEXT: 6 | offset_to_top (-8)
|
|
|
|
// CHECK-34-NEXT: 7 | Test27::E RTTI
|
|
|
|
// CHECK-34-NEXT: -- (Test27::C, 8) vtable address --
|
|
|
|
// CHECK-34-NEXT: 8 | void Test27::C::c()
|
|
|
|
// CHECK-34-NEXT: 9 | vcall_offset (0)
|
|
|
|
// CHECK-34-NEXT: 10 | offset_to_top (-16)
|
|
|
|
// CHECK-34-NEXT: 11 | Test27::E RTTI
|
|
|
|
// CHECK-34-NEXT: -- (Test27::B, 16) vtable address --
|
|
|
|
// CHECK-34-NEXT: 12 | void Test27::B::b()
|
|
|
|
|
|
|
|
// CHECK-34: Construction vtable for ('Test27::D', 0) in 'Test27::E' (9 entries).
|
|
|
|
// CHECK-34-NEXT: 0 | vbase_offset (16)
|
|
|
|
// CHECK-34-NEXT: 1 | offset_to_top (0)
|
|
|
|
// CHECK-34-NEXT: 2 | Test27::D RTTI
|
|
|
|
// CHECK-34-NEXT: -- (Test27::A, 0) vtable address --
|
|
|
|
// CHECK-34-NEXT: -- (Test27::D, 0) vtable address --
|
|
|
|
// CHECK-34-NEXT: 3 | void Test27::A::a()
|
|
|
|
// CHECK-34-NEXT: 4 | void Test27::D::d()
|
|
|
|
// CHECK-34-NEXT: 5 | vcall_offset (0)
|
|
|
|
// CHECK-34-NEXT: 6 | offset_to_top (-16)
|
|
|
|
// CHECK-34-NEXT: 7 | Test27::D RTTI
|
|
|
|
// CHECK-34-NEXT: -- (Test27::B, 16) vtable address --
|
|
|
|
// CHECK-34-NEXT: 8 | void Test27::B::b()
|
2010-03-11 03:15:26 +08:00
|
|
|
struct E : D {
|
|
|
|
virtual void e();
|
|
|
|
};
|
|
|
|
void E::e() { }
|
2010-03-11 03:39:11 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Test28 {
|
|
|
|
|
|
|
|
// Check that we do include the vtable for B in the D-in-E construction vtable, since
|
|
|
|
// B is a base class of a virtual base (C).
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void a();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B {
|
|
|
|
virtual void b();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : A, B {
|
|
|
|
virtual void c();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D : virtual C {
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-35: Vtable for 'Test28::E' (14 entries).
|
|
|
|
// CHECK-35-NEXT: 0 | vbase_offset (8)
|
|
|
|
// CHECK-35-NEXT: 1 | offset_to_top (0)
|
|
|
|
// CHECK-35-NEXT: 2 | Test28::E RTTI
|
|
|
|
// CHECK-35-NEXT: -- (Test28::D, 0) vtable address --
|
|
|
|
// CHECK-35-NEXT: -- (Test28::E, 0) vtable address --
|
|
|
|
// CHECK-35-NEXT: 3 | void Test28::E::e()
|
|
|
|
// CHECK-35-NEXT: 4 | vcall_offset (8)
|
|
|
|
// CHECK-35-NEXT: 5 | vcall_offset (0)
|
|
|
|
// CHECK-35-NEXT: 6 | vcall_offset (0)
|
|
|
|
// CHECK-35-NEXT: 7 | offset_to_top (-8)
|
|
|
|
// CHECK-35-NEXT: 8 | Test28::E RTTI
|
|
|
|
// CHECK-35-NEXT: -- (Test28::A, 8) vtable address --
|
|
|
|
// CHECK-35-NEXT: -- (Test28::C, 8) vtable address --
|
|
|
|
// CHECK-35-NEXT: 9 | void Test28::A::a()
|
|
|
|
// CHECK-35-NEXT: 10 | void Test28::C::c()
|
|
|
|
// CHECK-35-NEXT: 11 | offset_to_top (-16)
|
|
|
|
// CHECK-35-NEXT: 12 | Test28::E RTTI
|
|
|
|
// CHECK-35-NEXT: -- (Test28::B, 16) vtable address --
|
|
|
|
// CHECK-35-NEXT: 13 | void Test28::B::b()
|
|
|
|
|
|
|
|
// CHECK-35: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries).
|
|
|
|
// CHECK-35-NEXT: 0 | vbase_offset (8)
|
|
|
|
// CHECK-35-NEXT: 1 | offset_to_top (0)
|
|
|
|
// CHECK-35-NEXT: 2 | Test28::D RTTI
|
|
|
|
// CHECK-35-NEXT: -- (Test28::D, 0) vtable address --
|
|
|
|
// CHECK-35-NEXT: 3 | vcall_offset (8)
|
|
|
|
// CHECK-35-NEXT: 4 | vcall_offset (0)
|
|
|
|
// CHECK-35-NEXT: 5 | vcall_offset (0)
|
|
|
|
// CHECK-35-NEXT: 6 | offset_to_top (-8)
|
|
|
|
// CHECK-35-NEXT: 7 | Test28::D RTTI
|
|
|
|
// CHECK-35-NEXT: -- (Test28::A, 8) vtable address --
|
|
|
|
// CHECK-35-NEXT: -- (Test28::C, 8) vtable address --
|
|
|
|
// CHECK-35-NEXT: 8 | void Test28::A::a()
|
|
|
|
// CHECK-35-NEXT: 9 | void Test28::C::c()
|
|
|
|
// CHECK-35-NEXT: 10 | offset_to_top (-16)
|
|
|
|
// CHECK-35-NEXT: 11 | Test28::D RTTI
|
|
|
|
// CHECK-35-NEXT: -- (Test28::B, 16) vtable address --
|
|
|
|
// CHECK-35-NEXT: 12 | void Test28::B::b()
|
2010-03-11 03:39:11 +08:00
|
|
|
struct E : D {
|
|
|
|
virtual void e();
|
|
|
|
};
|
|
|
|
void E::e() { }
|
|
|
|
|
2010-03-11 03:15:26 +08:00
|
|
|
}
|
2010-03-29 23:08:41 +08:00
|
|
|
|
|
|
|
namespace Test29 {
|
|
|
|
|
|
|
|
// Test that the covariant return thunk for B::f will have a virtual 'this' adjustment,
|
|
|
|
// matching gcc.
|
|
|
|
|
|
|
|
struct V1 { };
|
|
|
|
struct V2 : virtual V1 { };
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual V1 *f();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-36: Vtable for 'Test29::B' (6 entries).
|
|
|
|
// CHECK-36-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-36-NEXT: 1 | vcall_offset (0)
|
|
|
|
// CHECK-36-NEXT: 2 | offset_to_top (0)
|
|
|
|
// CHECK-36-NEXT: 3 | Test29::B RTTI
|
|
|
|
// CHECK-36-NEXT: -- (Test29::A, 0) vtable address --
|
|
|
|
// CHECK-36-NEXT: -- (Test29::B, 0) vtable address --
|
|
|
|
// CHECK-36-NEXT: 4 | Test29::V2 *Test29::B::f()
|
|
|
|
// CHECK-36-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset]
|
|
|
|
// CHECK-36-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
|
|
|
// CHECK-36-NEXT: 5 | Test29::V2 *Test29::B::f()
|
2010-03-29 23:08:41 +08:00
|
|
|
struct B : virtual A {
|
|
|
|
virtual V2 *f();
|
|
|
|
};
|
|
|
|
V2 *B::f() { return 0; }
|
|
|
|
|
|
|
|
}
|
2010-04-11 02:42:27 +08:00
|
|
|
|
|
|
|
namespace Test30 {
|
|
|
|
|
|
|
|
// Test that we don't assert when generating a vtable for F.
|
|
|
|
struct A { };
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
int i;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D : virtual C, B { };
|
|
|
|
struct E : virtual D { };
|
|
|
|
|
|
|
|
struct F : E {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void F::f() { }
|
|
|
|
|
|
|
|
}
|
2010-04-11 04:39:29 +08:00
|
|
|
|
|
|
|
namespace Test31 {
|
|
|
|
|
|
|
|
// Test that we don't add D::f twice to the primary vtable.
|
|
|
|
struct A {
|
|
|
|
int a;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : A, virtual B {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-37: Vtable for 'Test31::D' (11 entries).
|
|
|
|
// CHECK-37-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-37-NEXT: 1 | vbase_offset (8)
|
|
|
|
// CHECK-37-NEXT: 2 | vcall_offset (0)
|
|
|
|
// CHECK-37-NEXT: 3 | offset_to_top (0)
|
|
|
|
// CHECK-37-NEXT: 4 | Test31::D RTTI
|
|
|
|
// CHECK-37-NEXT: -- (Test31::B, 0) vtable address --
|
|
|
|
// CHECK-37-NEXT: -- (Test31::D, 0) vtable address --
|
|
|
|
// CHECK-37-NEXT: 5 | void Test31::D::f()
|
|
|
|
// CHECK-37-NEXT: 6 | vbase_offset (-8)
|
|
|
|
// CHECK-37-NEXT: 7 | vcall_offset (-8)
|
|
|
|
// CHECK-37-NEXT: 8 | offset_to_top (-8)
|
|
|
|
// CHECK-37-NEXT: 9 | Test31::D RTTI
|
|
|
|
// CHECK-37-NEXT: -- (Test31::C, 8) vtable address --
|
|
|
|
// CHECK-37-NEXT: 10 | void Test31::D::f()
|
|
|
|
// CHECK-37-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
2010-04-11 04:39:29 +08:00
|
|
|
struct D : virtual C {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void D::f() { }
|
|
|
|
|
|
|
|
}
|
2010-04-11 05:35:33 +08:00
|
|
|
|
|
|
|
namespace Test32 {
|
|
|
|
|
|
|
|
// Check that we correctly lay out the virtual bases of 'Test32::D'.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A { };
|
|
|
|
struct C : A, virtual B { };
|
|
|
|
struct D : virtual B { };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-38: Virtual base offset offsets for 'Test32::E' (3 entries).
|
|
|
|
// CHECK-38-NEXT: Test32::A | -32
|
|
|
|
// CHECK-38-NEXT: Test32::B | -24
|
|
|
|
// CHECK-38-NEXT: Test32::D | -40
|
2010-04-11 05:35:33 +08:00
|
|
|
struct E : C, virtual D {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void E::f() { }
|
|
|
|
|
|
|
|
}
|
2010-04-12 04:04:11 +08:00
|
|
|
|
|
|
|
namespace Test33 {
|
|
|
|
|
|
|
|
// Test that we don't emit too many vcall offsets in 'Test32::F'.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void a();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B {
|
|
|
|
virtual void b();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : virtual A, virtual B {
|
|
|
|
virtual void c();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D : virtual C { };
|
|
|
|
|
|
|
|
struct E : A, D {
|
|
|
|
virtual void e();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-39: Vtable for 'Test33::F' (30 entries).
|
|
|
|
// CHECK-39-NEXT: 0 | vbase_offset (24)
|
|
|
|
// CHECK-39-NEXT: 1 | vbase_offset (16)
|
|
|
|
// CHECK-39-NEXT: 2 | vbase_offset (16)
|
|
|
|
// CHECK-39-NEXT: 3 | vbase_offset (8)
|
|
|
|
// CHECK-39-NEXT: 4 | offset_to_top (0)
|
|
|
|
// CHECK-39-NEXT: 5 | Test33::F RTTI
|
|
|
|
// CHECK-39-NEXT: -- (Test33::A, 0) vtable address --
|
|
|
|
// CHECK-39-NEXT: -- (Test33::F, 0) vtable address --
|
|
|
|
// CHECK-39-NEXT: 6 | void Test33::A::a()
|
|
|
|
// CHECK-39-NEXT: 7 | void Test33::F::f()
|
|
|
|
// CHECK-39-NEXT: 8 | vcall_offset (0)
|
|
|
|
// CHECK-39-NEXT: 9 | vcall_offset (0)
|
|
|
|
// CHECK-39-NEXT: 10 | vbase_offset (16)
|
|
|
|
// CHECK-39-NEXT: 11 | vbase_offset (8)
|
|
|
|
// CHECK-39-NEXT: 12 | vbase_offset (8)
|
|
|
|
// CHECK-39-NEXT: 13 | offset_to_top (-8)
|
|
|
|
// CHECK-39-NEXT: 14 | Test33::F RTTI
|
|
|
|
// CHECK-39-NEXT: -- (Test33::A, 8) vtable address --
|
|
|
|
// CHECK-39-NEXT: -- (Test33::E, 8) vtable address --
|
|
|
|
// CHECK-39-NEXT: 15 | void Test33::A::a()
|
|
|
|
// CHECK-39-NEXT: 16 | void Test33::E::e()
|
|
|
|
// CHECK-39-NEXT: 17 | vbase_offset (0)
|
|
|
|
// CHECK-39-NEXT: 18 | vcall_offset (0)
|
|
|
|
// CHECK-39-NEXT: 19 | vbase_offset (8)
|
|
|
|
// CHECK-39-NEXT: 20 | vbase_offset (0)
|
|
|
|
// CHECK-39-NEXT: 21 | vcall_offset (0)
|
|
|
|
// CHECK-39-NEXT: 22 | offset_to_top (-16)
|
|
|
|
// CHECK-39-NEXT: 23 | Test33::F RTTI
|
|
|
|
// CHECK-39-NEXT: -- (Test33::A, 16) vtable address --
|
|
|
|
// CHECK-39-NEXT: -- (Test33::C, 16) vtable address --
|
|
|
|
// CHECK-39-NEXT: -- (Test33::D, 16) vtable address --
|
|
|
|
// CHECK-39-NEXT: 24 | void Test33::A::a()
|
|
|
|
// CHECK-39-NEXT: 25 | void Test33::C::c()
|
|
|
|
// CHECK-39-NEXT: 26 | vcall_offset (0)
|
|
|
|
// CHECK-39-NEXT: 27 | offset_to_top (-24)
|
|
|
|
// CHECK-39-NEXT: 28 | Test33::F RTTI
|
|
|
|
// CHECK-39-NEXT: -- (Test33::B, 24) vtable address --
|
|
|
|
// CHECK-39-NEXT: 29 | void Test33::B::b()
|
2010-04-12 04:04:11 +08:00
|
|
|
struct F : virtual E, A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void F::f() { }
|
|
|
|
|
|
|
|
}
|
2010-04-12 06:20:36 +08:00
|
|
|
|
|
|
|
namespace Test34 {
|
|
|
|
|
2010-04-12 13:32:01 +08:00
|
|
|
// Test that we lay out the construction vtable for 'Test34::E' in 'Test34::F' correctly.
|
2010-04-12 06:20:36 +08:00
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void a();
|
|
|
|
};
|
|
|
|
struct B : virtual A { };
|
|
|
|
|
|
|
|
struct C : B, A {
|
|
|
|
virtual void c();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D : A, C { };
|
|
|
|
|
|
|
|
struct E : virtual D {
|
|
|
|
virtual void e();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-40: Construction vtable for ('Test34::E', 0) in 'Test34::F' (22 entries).
|
|
|
|
// CHECK-40-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-40-NEXT: 1 | vbase_offset (8)
|
|
|
|
// CHECK-40-NEXT: 2 | vcall_offset (0)
|
|
|
|
// CHECK-40-NEXT: 3 | offset_to_top (0)
|
|
|
|
// CHECK-40-NEXT: 4 | Test34::E RTTI
|
|
|
|
// CHECK-40-NEXT: -- (Test34::A, 0) vtable address --
|
|
|
|
// CHECK-40-NEXT: -- (Test34::E, 0) vtable address --
|
|
|
|
// CHECK-40-NEXT: 5 | void Test34::A::a()
|
|
|
|
// CHECK-40-NEXT: 6 | void Test34::E::e()
|
|
|
|
// CHECK-40-NEXT: 7 | vcall_offset (8)
|
|
|
|
// CHECK-40-NEXT: 8 | vcall_offset (0)
|
|
|
|
// CHECK-40-NEXT: 9 | vbase_offset (-8)
|
|
|
|
// CHECK-40-NEXT: 10 | offset_to_top (-8)
|
|
|
|
// CHECK-40-NEXT: 11 | Test34::E RTTI
|
|
|
|
// CHECK-40-NEXT: -- (Test34::A, 8) vtable address --
|
|
|
|
// CHECK-40-NEXT: -- (Test34::D, 8) vtable address --
|
|
|
|
// CHECK-40-NEXT: 12 | void Test34::A::a()
|
|
|
|
// CHECK-40-NEXT: 13 | vbase_offset (-16)
|
|
|
|
// CHECK-40-NEXT: 14 | vcall_offset (-16)
|
|
|
|
// CHECK-40-NEXT: 15 | offset_to_top (-16)
|
|
|
|
// CHECK-40-NEXT: 16 | Test34::E RTTI
|
|
|
|
// CHECK-40-NEXT: -- (Test34::B, 16) vtable address --
|
|
|
|
// CHECK-40-NEXT: -- (Test34::C, 16) vtable address --
|
|
|
|
// CHECK-40-NEXT: 17 | [unused] void Test34::A::a()
|
|
|
|
// CHECK-40-NEXT: 18 | void Test34::C::c()
|
|
|
|
// CHECK-40-NEXT: 19 | offset_to_top (-24)
|
|
|
|
// CHECK-40-NEXT: 20 | Test34::E RTTI
|
|
|
|
// CHECK-40-NEXT: -- (Test34::A, 24) vtable address --
|
|
|
|
// CHECK-40-NEXT: 21 | void Test34::A::a()
|
2010-04-12 06:20:36 +08:00
|
|
|
struct F : E {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
void F::f() { }
|
|
|
|
|
|
|
|
}
|
2010-04-16 00:12:58 +08:00
|
|
|
|
|
|
|
namespace Test35 {
|
|
|
|
|
|
|
|
// Test that we lay out the virtual bases of 'Test35::H' in the correct order.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void a();
|
|
|
|
|
|
|
|
int i;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
virtual void b();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C {
|
|
|
|
virtual void c();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D : C, virtual B {
|
|
|
|
virtual void d();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct E : D {
|
|
|
|
virtual void e();
|
|
|
|
|
|
|
|
bool b;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct F : virtual D { };
|
|
|
|
struct G : virtual E { };
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-41: Vtable for 'Test35::H' (32 entries).
|
|
|
|
// CHECK-41-NEXT: 0 | vbase_offset (32)
|
|
|
|
// CHECK-41-NEXT: 1 | vbase_offset (0)
|
|
|
|
// CHECK-41-NEXT: 2 | vcall_offset (0)
|
|
|
|
// CHECK-41-NEXT: 3 | vcall_offset (0)
|
|
|
|
// CHECK-41-NEXT: 4 | vbase_offset (16)
|
|
|
|
// CHECK-41-NEXT: 5 | vbase_offset (8)
|
|
|
|
// CHECK-41-NEXT: 6 | offset_to_top (0)
|
|
|
|
// CHECK-41-NEXT: 7 | Test35::H RTTI
|
|
|
|
// CHECK-41-NEXT: -- (Test35::C, 0) vtable address --
|
|
|
|
// CHECK-41-NEXT: -- (Test35::D, 0) vtable address --
|
|
|
|
// CHECK-41-NEXT: -- (Test35::F, 0) vtable address --
|
|
|
|
// CHECK-41-NEXT: -- (Test35::H, 0) vtable address --
|
|
|
|
// CHECK-41-NEXT: 8 | void Test35::C::c()
|
|
|
|
// CHECK-41-NEXT: 9 | void Test35::D::d()
|
|
|
|
// CHECK-41-NEXT: 10 | void Test35::H::h()
|
|
|
|
// CHECK-41-NEXT: 11 | vbase_offset (0)
|
|
|
|
// CHECK-41-NEXT: 12 | vbase_offset (24)
|
|
|
|
// CHECK-41-NEXT: 13 | vcall_offset (0)
|
|
|
|
// CHECK-41-NEXT: 14 | vbase_offset (8)
|
|
|
|
// CHECK-41-NEXT: 15 | offset_to_top (-8)
|
|
|
|
// CHECK-41-NEXT: 16 | Test35::H RTTI
|
|
|
|
// CHECK-41-NEXT: -- (Test35::B, 8) vtable address --
|
|
|
|
// CHECK-41-NEXT: -- (Test35::G, 8) vtable address --
|
|
|
|
// CHECK-41-NEXT: 17 | void Test35::B::b()
|
|
|
|
// CHECK-41-NEXT: 18 | vcall_offset (0)
|
|
|
|
// CHECK-41-NEXT: 19 | offset_to_top (-16)
|
|
|
|
// CHECK-41-NEXT: 20 | Test35::H RTTI
|
|
|
|
// CHECK-41-NEXT: -- (Test35::A, 16) vtable address --
|
|
|
|
// CHECK-41-NEXT: 21 | void Test35::A::a()
|
|
|
|
// CHECK-41-NEXT: 22 | vcall_offset (0)
|
|
|
|
// CHECK-41-NEXT: 23 | vcall_offset (0)
|
|
|
|
// CHECK-41-NEXT: 24 | vcall_offset (0)
|
|
|
|
// CHECK-41-NEXT: 25 | vbase_offset (-16)
|
|
|
|
// CHECK-41-NEXT: 26 | vbase_offset (-24)
|
|
|
|
// CHECK-41-NEXT: 27 | offset_to_top (-32)
|
|
|
|
// CHECK-41-NEXT: 28 | Test35::H RTTI
|
|
|
|
// CHECK-41-NEXT: -- (Test35::C, 32) vtable address --
|
|
|
|
// CHECK-41-NEXT: -- (Test35::D, 32) vtable address --
|
|
|
|
// CHECK-41-NEXT: -- (Test35::E, 32) vtable address --
|
|
|
|
// CHECK-41-NEXT: 29 | void Test35::C::c()
|
|
|
|
// CHECK-41-NEXT: 30 | void Test35::D::d()
|
|
|
|
// CHECK-41-NEXT: 31 | void Test35::E::e()
|
|
|
|
|
|
|
|
// CHECK-41: Virtual base offset offsets for 'Test35::H' (4 entries).
|
|
|
|
// CHECK-41-NEXT: Test35::A | -32
|
|
|
|
// CHECK-41-NEXT: Test35::B | -24
|
|
|
|
// CHECK-41-NEXT: Test35::D | -56
|
|
|
|
// CHECK-41-NEXT: Test35::E | -64
|
2010-04-16 00:12:58 +08:00
|
|
|
struct H : F, G {
|
|
|
|
virtual void h();
|
|
|
|
};
|
|
|
|
void H::h() { }
|
|
|
|
|
|
|
|
}
|
2010-04-18 01:24:33 +08:00
|
|
|
|
|
|
|
namespace Test36 {
|
|
|
|
|
|
|
|
// Test that we don't mark B::f as unused in the vtable for D.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A { };
|
|
|
|
|
|
|
|
struct C : virtual A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
// CHECK-42: Vtable for 'Test36::D' (12 entries).
|
|
|
|
// CHECK-42-NEXT: 0 | vbase_offset (8)
|
|
|
|
// CHECK-42-NEXT: 1 | vbase_offset (8)
|
|
|
|
// CHECK-42-NEXT: 2 | vcall_offset (0)
|
|
|
|
// CHECK-42-NEXT: 3 | offset_to_top (0)
|
|
|
|
// CHECK-42-NEXT: 4 | Test36::D RTTI
|
|
|
|
// CHECK-42-NEXT: -- (Test36::C, 0) vtable address --
|
|
|
|
// CHECK-42-NEXT: -- (Test36::D, 0) vtable address --
|
|
|
|
// CHECK-42-NEXT: 5 | void Test36::C::f()
|
|
|
|
// CHECK-42-NEXT: 6 | void Test36::D::g()
|
|
|
|
// CHECK-42-NEXT: 7 | vbase_offset (0)
|
|
|
|
// CHECK-42-NEXT: 8 | vcall_offset (-8)
|
|
|
|
// CHECK-42-NEXT: 9 | offset_to_top (-8)
|
|
|
|
// CHECK-42-NEXT: 10 | Test36::D RTTI
|
|
|
|
// CHECK-42-NEXT: -- (Test36::A, 8) vtable address --
|
|
|
|
// CHECK-42-NEXT: -- (Test36::B, 8) vtable address --
|
|
|
|
// CHECK-42-NEXT: 11 | void Test36::C::f()
|
|
|
|
// CHECK-42-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
2010-04-18 01:24:33 +08:00
|
|
|
struct D : virtual B, C {
|
|
|
|
virtual void g();
|
|
|
|
};
|
|
|
|
void D::g() { }
|
|
|
|
|
|
|
|
}
|
2011-04-11 02:00:32 +08:00
|
|
|
|
|
|
|
namespace Test37 {
|
|
|
|
|
|
|
|
// Test that we give C::f the right vtable index. (PR9660).
|
|
|
|
struct A {
|
|
|
|
virtual A* f() = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
virtual B* f();
|
|
|
|
};
|
|
|
|
|
|
|
|
// CHECK-43: VTable indices for 'Test37::C' (1 entries).
|
|
|
|
// CHECK-43-NEXT: 1 | Test37::C *Test37::C::f()
|
|
|
|
struct C : B {
|
|
|
|
virtual C* f();
|
|
|
|
};
|
|
|
|
|
|
|
|
C* C::f() { return 0; }
|
|
|
|
|
|
|
|
}
|
2012-03-21 14:57:19 +08:00
|
|
|
|
|
|
|
// rdar://problem/10959710
|
|
|
|
namespace Test38 {
|
|
|
|
struct A {
|
|
|
|
virtual void *foo();
|
|
|
|
virtual const void *foo() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
// CHECK-44: Vtable for 'Test38::B' (7 entries).
|
|
|
|
// CHECK-44-NEXT: 0 | vbase_offset (0)
|
|
|
|
// CHECK-44-NEXT: 1 | vcall_offset (0)
|
|
|
|
// CHECK-44-NEXT: 2 | vcall_offset (0)
|
|
|
|
// CHECK-44-NEXT: 3 | offset_to_top (0)
|
|
|
|
// CHECK-44-NEXT: 4 | Test38::B RTTI
|
|
|
|
// CHECK-44-NEXT: -- (Test38::A, 0) vtable address --
|
|
|
|
// CHECK-44-NEXT: -- (Test38::B, 0) vtable address --
|
|
|
|
// CHECK-44-NEXT: 5 | void *Test38::B::foo()
|
|
|
|
// CHECK-44-NEXT: 6 | const void *Test38::B::foo() const
|
|
|
|
class B : virtual public A {
|
|
|
|
void *foo();
|
|
|
|
const void *foo() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
void *B::foo() { return 0; }
|
|
|
|
}
|
2012-10-17 04:25:33 +08:00
|
|
|
|
|
|
|
namespace Test39 {
|
|
|
|
struct A {
|
|
|
|
virtual void foo() = delete;
|
|
|
|
};
|
|
|
|
|
|
|
|
// CHECK-45: Vtable for 'Test39::B' (4 entries).
|
|
|
|
// CHECK-45-NEXT: 0 | offset_to_top (0)
|
|
|
|
// CHECK-45-NEXT: 1 | Test39::B RTTI
|
|
|
|
// CHECK-45-NEXT: -- (Test39::A, 0) vtable address --
|
|
|
|
// CHECK-45-NEXT: -- (Test39::B, 0) vtable address --
|
|
|
|
// CHECK-45-NEXT: 2 | void Test39::A::foo() [deleted]
|
|
|
|
// CHECK-45-NEXT: 3 | void Test39::B::foo2()
|
|
|
|
struct B: A {
|
|
|
|
virtual void foo2();
|
|
|
|
};
|
|
|
|
|
|
|
|
void B::foo2() {
|
|
|
|
}
|
|
|
|
}
|