mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 03:36:06 +00:00
Add ability to layout the vtable pointer in trivial cases. I noticed
that we would silently do bad things with virtual bases in the layout code, so, we just turn them off. When people do better things with them, we can turn them back on. llvm-svn: 77556
This commit is contained in:
parent
13ddd8514f
commit
3dc7eb9440
@ -24,11 +24,19 @@ ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx)
|
||||
: Ctx(Ctx), Size(0), Alignment(8), StructPacking(0), NextOffset(0),
|
||||
IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8) {}
|
||||
|
||||
void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
|
||||
if (RD->isPolymorphic())
|
||||
{
|
||||
assert (RD->getNumBases() == 0 && "no polymorphic inheritance yet");
|
||||
int AS = 0;
|
||||
UpdateAlignment(Ctx.Target.getPointerAlign(AS));
|
||||
Size += Ctx.Target.getPointerWidth(AS);
|
||||
NextOffset = Size;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
|
||||
assert(!RD->isPolymorphic() &&
|
||||
"FIXME: We don't support polymorphic classes yet!");
|
||||
|
||||
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
|
||||
e = RD->bases_end(); i != e; ++i) {
|
||||
if (!i->isVirtual()) {
|
||||
@ -74,14 +82,20 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
|
||||
UpdateAlignment(AA->getAlignment());
|
||||
|
||||
// If this is a C++ class, lay out the nonvirtual bases.
|
||||
if (Ctx.getLangOptions().CPlusPlus)
|
||||
LayoutNonVirtualBases(cast<CXXRecordDecl>(D));
|
||||
if (Ctx.getLangOptions().CPlusPlus) {
|
||||
const CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
|
||||
LayoutVtable(RD);
|
||||
LayoutNonVirtualBases(RD);
|
||||
|
||||
assert (RD->getNumVBases() == 0
|
||||
&& "FIXME: We don't support virtual bases yet!");
|
||||
}
|
||||
|
||||
LayoutFields(D);
|
||||
|
||||
NonVirtualSize = Size;
|
||||
NonVirtualAlignment = Alignment;
|
||||
|
||||
|
||||
// Finally, round the size of the total struct up to the alignment of the
|
||||
// struct itself.
|
||||
FinishLayout();
|
||||
|
@ -48,6 +48,7 @@ class ASTRecordLayoutBuilder {
|
||||
void LayoutFields(const RecordDecl *D);
|
||||
void LayoutField(const FieldDecl *D);
|
||||
|
||||
void LayoutVtable(const CXXRecordDecl *RD);
|
||||
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
|
||||
void LayoutNonVirtualBase(const CXXRecordDecl *RD);
|
||||
|
||||
|
@ -381,8 +381,6 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
|
||||
|
||||
// FIXME. This may have to move to a better place.
|
||||
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(TD)) {
|
||||
assert(!RD->isPolymorphic() &&
|
||||
"FIXME: We don't support polymorphic classes yet!");
|
||||
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
|
||||
e = RD->bases_end(); i != e; ++i) {
|
||||
if (!i->isVirtual()) {
|
||||
|
8
clang/test/CodeGenCXX/virt.cpp
Normal file
8
clang/test/CodeGenCXX/virt.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
// RUN: clang-cc %s -emit-llvm -o - -std=c++0x
|
||||
|
||||
class A {
|
||||
public:
|
||||
virtual void foo();
|
||||
};
|
||||
|
||||
static_assert (sizeof (A) == (sizeof(void *)), "vtable pointer layout");
|
Loading…
x
Reference in New Issue
Block a user