@@ -1906,6 +1906,70 @@ def CIR_VTableGetVirtualFnAddrOp : CIR_Op<"vtable.get_virtual_fn_addr", [
1906
1906
}];
1907
1907
}
1908
1908
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
+
1909
1973
//===----------------------------------------------------------------------===//
1910
1974
// SetBitfieldOp
1911
1975
//===----------------------------------------------------------------------===//
0 commit comments