[CIR] Upstream missing support for vtables and virtual bases
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
### Overview
Upstream code from the incubator project to replace errorNYI calls in the
CIR codegen implementation related to vtable and virtual base class handling
in the Itanium C++ ABI:
- **Relative vtable layout for virtual base offset**: loading a 32-bit signed
offset (`SInt32Ty` with 4-byte alignment) for relative layout vs
pointer-sized offset for absolute layout in `getVirtualBaseClassOffset`
- **WholeProgramVTables metadata**: calling
`emitVTableTypeMetadata(RD, VTable, VTLayout)` for non-`available_externally`
vtable definitions
- **Explicit instantiation declaration linkage**: checking Microsoft ABI for
`DiscardableODRLinkage`, and for non-MSVC checking
`shouldEmitAvailableExternallyVTable` to choose between
`AvailableExternallyLinkage` and `ExternalLinkage`
- **Combined virtual + non-virtual base offset**: computing a combined offset
by adding the non-virtual offset constant to the virtual offset, casting to
byte pointer, applying `PtrStrideOp`, and casting back
- **Devirtualized destructor calls**: using
`CIRGenCallee::forDirect(CGM.GetAddrOfFunction(...))` to call the devirtualized
destructor directly instead of going through the vtable
Upstream NYI locations:
- `CIRGenItaniumCXXABI.cpp` — `getVirtualBaseClassOffset`: relative layout
- `CIRGenItaniumCXXABI.cpp` — `emitVTableDefinitions`: WholeProgramVTables
- `CIRGenVTables.cpp` — `getVTableLinkage`: explicit instantiation declaration
- `CIRGenClass.cpp` — `applyNonVirtualAndVirtualOffset`: both virtual and
non-virtual offset present
- `CIRGenExprCXX.cpp` — `emitCXXMemberOrOperatorMemberCallExpr`: devirtualized
destructor call
### Suggested minimal test case
```cpp
struct VBase { virtual ~VBase() {} int vb; };
struct Middle : virtual VBase { int m; };
struct Derived : Middle { int d; };
void test_virtual_base_cast(Derived *d) {
VBase *vb = d;
vb->vb = 42;
}
struct Final final : VBase {
~Final() override {}
};
void test_devirtualized_dtor(Final *f) {
delete f;
}
```
### Existing incubator tests
- `clang/test/CIR/CodeGen/virtual-base-cast.cpp`
- `clang/test/CIR/CodeGen/vbase.cpp`
- `clang/test/CIR/CodeGen/vtable-available-externally.cpp`
- `clang/test/CIR/CodeGen/vtable-thunk-virtual-inheritance.cpp`
- `clang/test/CIR/CodeGen/virtual-destructor-calls.cpp`
- `clang/test/CIR/CodeGen/dynamic-cast-relative-layout.cpp`
Contributor guide
Research direction
Start by reading the five named CIR files at their listed NYI locations and run the existing incubator tests, especially virtual-base-cast.cpp and virtual-destructor-calls.cpp. Compare the upstream implementations for each case and verify that the listed vtable, virtual-base-offset, linkage, and devirtualized-destructor tests pass when all five locations are supported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100