diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 26 | ||||
| -rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.h | 1 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/virt.cpp | 8 | 
4 files changed, 29 insertions, 8 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index e3581d88d24..a60a72b74fa 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -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(); diff --git a/clang/lib/AST/RecordLayoutBuilder.h b/clang/lib/AST/RecordLayoutBuilder.h index e7d49b55a8e..41c002d61dc 100644 --- a/clang/lib/AST/RecordLayoutBuilder.h +++ b/clang/lib/AST/RecordLayoutBuilder.h @@ -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); diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index f88ed048fd3..c20e90e8ce6 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -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()) { diff --git a/clang/test/CodeGenCXX/virt.cpp b/clang/test/CodeGenCXX/virt.cpp new file mode 100644 index 00000000000..a07d8e011f7 --- /dev/null +++ b/clang/test/CodeGenCXX/virt.cpp @@ -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");  | 

