@@ -1906,6 +1906,70 @@ def CIR_VTableGetVirtualFnAddrOp : CIR_Op<"vtable.get_virtual_fn_addr", [
19061906 }];
19071907}
19081908
1909+ //===----------------------------------------------------------------------===//
1910+ // VTTAddrPointOp
1911+ //===----------------------------------------------------------------------===//
1912+
1913+ def CIR_VTTAddrPointOp : CIR_Op<"vtt.address_point", [
1914+ Pure, DeclareOpInterfaceMethods<SymbolUserOpInterface>
1915+ ]> {
1916+ let summary = "Get the VTT address point";
1917+ let description = [{
1918+ The `vtt.address_point` operation retrieves an element from the virtual
1919+ table table (VTT), which is the address point of a C++ vtable. In virtual
1920+ inheritance, a set of internal `__vptr` members for an object are
1921+ initialized by this operation, which assigns an element from the VTT. The
1922+ initialization order is as follows:
1923+
1924+ The complete object constructors and destructors find the VTT,
1925+ via the mangled name of the VTT global variable. They pass the address of
1926+ the subobject's sub-VTT entry in the VTT as a second parameter
1927+ when calling the base object constructors and destructors.
1928+ The base object constructors and destructors use the address passed to
1929+ initialize the primary virtual pointer and virtual pointers that point to
1930+ the classes which either have virtual bases or override virtual functions
1931+ with a virtual step.
1932+
1933+ The first parameter is either the mangled name of VTT global variable
1934+ or the address of the subobject's sub-VTT entry in the VTT.
1935+ The second parameter `offset` provides a virtual step to adjust to
1936+ the actual address point of the vtable.
1937+
1938+ The return type is always a `!cir.ptr<!cir.ptr<void>>`.
1939+
1940+ Example:
1941+ ```mlir
1942+ cir.global linkonce_odr @_ZTV1B = ...
1943+ ...
1944+ %3 = cir.base_class_addr(%1 : !cir.ptr<!rec_D> nonnull) [0]
1945+ -> !cir.ptr<!rec_B>
1946+ %4 = cir.vtt.address_point @_ZTT1D, offset = 1
1947+ -> !cir.ptr<!cir.ptr<!void>>
1948+ cir.call @_ZN1BC2Ev(%3, %4)
1949+ ```
1950+ Or:
1951+ ```mlir
1952+ %7 = cir.vtt.address_point %3 : !cir.ptr<!cir.ptr<!void>>, offset = 1
1953+ -> !cir.ptr<!cir.ptr<!void>>
1954+ ```
1955+ }];
1956+
1957+ let arguments = (ins OptionalAttr<FlatSymbolRefAttr>:$name,
1958+ Optional<CIR_AnyType>:$sym_addr,
1959+ I32Attr:$offset);
1960+ let results = (outs CIR_PointerType:$addr);
1961+
1962+ let assemblyFormat = [{
1963+ ($name^)?
1964+ ($sym_addr^ `:` type($sym_addr))?
1965+ `,`
1966+ `offset` `=` $offset
1967+ `->` qualified(type($addr)) attr-dict
1968+ }];
1969+
1970+ let hasVerifier = 1;
1971+ }
1972+
19091973//===----------------------------------------------------------------------===//
19101974// SetBitfieldOp
19111975//===----------------------------------------------------------------------===//
0 commit comments