Adding support for multiple inheritance – IR Generation for High-Level Language Constructs-1
Multiple inheritance adds another challenge. If a class inherits from two or more base classes, then we need to combine the data members in such a way that they are still accessible from the methods. Like in the single inheritance case, the solution is to append all data members, including the hidden vtable pointers.
The Circle class is not only a geometric shape but also a graphic object. To model this, we let the Circle class inherit from the Shape class and the GraphicObj class. In the class layout, the fields from the Shape class come first. Then, we append all fields of the GraphicObj class, including the hidden vtable pointer. After that, we add the new data members of the Circle class, resulting in the overall structure shown in Figure 5.4:

Figure 5.4 – Layout of classes and vtables with multiple inheritance
This approach has several implications. There can now be several pointers to the object. A pointer to the Shape or Circle class points to the top of the object, while a pointer to a GraphicObj class points to inside this object, the beginning of the embedded GraphicObj object. This has to be taken into account when comparing pointers.
Calling a virtual method is also affected. If a method is defined in the GraphicObj class, then this method expects the class layout of the GraphicObj class. If this method is not overridden in the Circle class, then there a two possibilities. The easy case is if the method call is done with a pointer to a GraphicObj instance: in this case, you look up the address of the method in the vtable of the GraphicObj class and call the function. The more complicated case is if you call the method with a pointer to the Circle class. Again, you can look up the address of the method in the vtable of the Circle class. The called method expects a this pointer to be an instance of the GraphicObj class, so we have to adjust that pointer, too. We can do this because we know the offset of the GraphicObj class inside the Circle class.
If a GrapicObj method is overridden in the Circle class, then nothing special needs to be done if the method is called through a pointer to the Circle class. However, if the method is called through a pointer to a GraphicObj instance, then we need to make another adjustment because the method needs a this pointer pointing to a Circle instance. At compilation time, we cannot compute this adjustment because we do not know whether or not this GraphicObj instance is part of a multiple inheritance hierarchy. To solve this, we store the adjustment we need to make to the this pointer before calling the method together with each function pointer in the vtable, as in Figure 5.5:

Figure 5.5 – vtable with adjustments to the this pointer
A method call now becomes the following:
- Look up the function pointer in the vtable.
- Adjust the this pointer.
- Call the method.