Single Inheritance

Single inheritance is very straightforward: Each “structure” (class) is laid out in memory after one another in declaration order.

class Base
{
public:
    void SetA(int value)
    {
        _a = value;
    }

private:
    int _a;
};

class Derived: public Base
{
public:
    void SetB(int value)
    {
        SetA(value);
        _b = value;
    }

protected:
    int _b;
}

Here, a and b will be laid out to follow one another in memory so that inheriting from a class is simply a matter of

declaring a the base class as a first member in the inheriting class:

%Base = type {
    i32         ; '_a' in class Base
}

define void @Base_SetA(%Base* %this, i32 %value) nounwind {
    %1 = getelementptr %Base* %this, i32 0, i32 0
    store i32 %value, i32* %1
    ret void
}

%Derived = type {
    i32,        ; '_a' from class Base
    i32         ; '_b' from class Derived
}

define void @Derived_SetB(%Derived* %this, i32 %value) nounwind {
    %1 = bitcast %Derived* %this to %Base*
    call void @Base_SetA(%Base* %1, i32 %value)
    %2 = getelementptr %Derived* %this, i32 0, i32 1
    store i32 %value, i32* %2
    ret void
}

So the base class simply becomes plain members of the type declaration for the derived class.

And then the compiler must insert appropriate type casts whenever the derived class is being referenced as its base class as shown above with the bitcast operator.