Closed dkolsen-pgi closed 1 month ago
Ah, we've been discussing this in #379. This is great, I'll take a look soon :) CC @Lancern as well.
We're discussing the design of this in #379; it probably makes sense to keep the design discussion there, and then come back to this PR once that's done.
Implement derived-to-base address conversions for non-virtual base classes. The code gen for this situation was only implemented when the offset was zero, and it simply created a
cir.base_class_addr
op for which no lowering or other transformation existed.Conversion to a virtual base class is not yet implemented.
Two new fields are added to the
cir.base_class_addr
operation: the byte offset of the necessary adjustment, and a boolean flag indicating whether the source operand may be null. The offset is easy to compute in the front end while the entire path of intermediate classes is still available. It would be difficult for the back end to recompute the offset. So it is best to store it in the operation. The null-pointer check is best done late in the lowering process. But whether or not the null-pointer check is needed is only known by the front end; the back end can't figure that out. So that flag needs to be stored in the operation.CIRGenFunction::getAddressOfBaseClass
was largely rewritten. The code path no longer matches the equivalent function in the LLVM IR code gen, because the generated ClangIR is quite different from the generated LLVM IR.cir.base_class_addr
is lowered to LLVM IR as agetelementptr
operation. If a null-pointer check is needed, then that is wrapped in aselect
operation.When generating code for a constructor or destructor, an incorrect
cir.ptr_stride
op was used to convert the pointer to a base class. The code was assuming that the operand ofcir.ptr_stride
was measured in bytes; the operand is the number elements, not the number of bytes. So the base class constructor was being called on the wrong chunk of memory. Fix this by using acir.base_class_addr
op instead ofcir.ptr_stride
in this scenario.The use of
cir.ptr_stride
inApplyNonVirtualAndVirtualOffset
had the same problem. Continue usingcir.ptr_stride
here, but temporarily convert the pointer to typechar*
so the pointer is adjusted correctly.Adjust the expected results of three existing tests in response to these changes.
Add two new tests, one code gen and one lowering, to cover the case where a base class is at a non-zero offset.