[cfe-dev] Cannot access the offset of a virtual base class in a given case

David Blaikie dblaikie at gmail.com
Mon Aug 22 07:31:11 PDT 2011


On Mon, Aug 22, 2011 at 7:01 AM, Xiaolong Tang <xiaolong.snake at gmail.com> wrote:
>
> Hi Everyone,
>
> I have a question about the layout of a C++ record.
>
> Given the following class hierarchy:
>
> // A virtual class
> class Foo {
> public:
>  virtual void f() {};
> };
>
> // A virtual class
> class Bar {
> public:
>  virtual void g() {};
> };
>
> // Two virtual bases
> class Zoo : virtual public Foo, virtual public Bar {
> public:
>  int x;
>  int y;
>  virtual void g() { x = x + y; };
>  virtual void f() { x = x - y; };
> };
>
>
> Following is the code I use to access the offset of the virtual bases of a
> class:
>
>    // Suppose that "Record" denotes a RecordDecl
>
>    // The layout code generation for the backend, e.g., LLVM IR
>    const CGRecordLayout &Layout = CGM.getTypes().getCGRecordLayout(Record);
>    // In C++ mode
>    const CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record);
>
>    // Virtual bases
>    for (CXXRecordDecl::base_class_const_iterator I = CXXRecord->vbases_begin(),
>         E = CXXRecord->vbases_end(); I != E; ++I) {
>      // The type of a virtual base
>      const RecordType *BaseTy = I->getType()->getAs<RecordType>();
>      // The decl of the virtual base
>      const CXXRecordDecl *BaseDecl = dyn_cast<CXXRecordDecl>(BaseTy->getDecl());
>      // Accessing the index of the base
>      unsigned fieldNo  = Layout.getVirtualBaseIndex(BaseDecl);
>    }
>
> Fed with the given class hierarchy, the last statement of the above
> code, i.e., "getVirtualBaseIndex(BaseDecl)", causes an assertion
> failure.
>
>  Assertion failed: (CompleteObjectVirtualBases.count(base) && "Invalid virtual base!"), ...
>
> The failure means that the virtual base "Foo" is not in the
> layout mapping from the virtual bases of the class "Zoo" to their
> offsets. So, can someone point out any hints about this missing?
>
> P.S. When the class "Foo" contains one data member, the above
> issue goes away.

My stab in the dark would be that this sounds rather like the Empty
Base Class optimization at work (
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=319 ).
If Foo has no members then there's no reason to ever access it so its
offset doesn't need to be computable (because it doesn't actually
exist).

No doubt someone with more actual clang knowledge can confirm/provide
more detail, but perhaps this'll help put you in the right direction
until then.

- David




More information about the cfe-dev mailing list