clang 22.0.0git
LowerItaniumCXXABI.cpp
Go to the documentation of this file.
1//===---- LowerItaniumCXXABI.cpp - Emit CIR code Itanium-specific code ---===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This provides CIR lowering logic targeting the Itanium C++ ABI. The class in
10// this file generates records that follow the Itanium C++ ABI, which is
11// documented at:
12// https://itanium-cxx-abi.github.io/cxx-abi/abi.html
13// https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
14//
15// It also supports the closely-related ARM ABI, documented at:
16// https://developer.arm.com/documentation/ihi0041/g/
17//
18// This file partially mimics clang/lib/CodeGen/ItaniumCXXABI.cpp. The queries
19// are adapted to operate on the CIR dialect, however.
20//
21//===----------------------------------------------------------------------===//
22
23#include "CIRCXXABI.h"
24#include "LowerModule.h"
25#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
26#include "llvm/Support/ErrorHandling.h"
27
28namespace cir {
29
30namespace {
31
32class LowerItaniumCXXABI : public CIRCXXABI {
33public:
34 LowerItaniumCXXABI(LowerModule &lm) : CIRCXXABI(lm) {}
35
36 /// Lower the given data member pointer type to its ABI type. The returned
37 /// type is also a CIR type.
38 virtual mlir::Type
39 lowerDataMemberType(cir::DataMemberType type,
40 const mlir::TypeConverter &typeConverter) const override;
41
42 mlir::Type
43 lowerMethodType(cir::MethodType type,
44 const mlir::TypeConverter &typeConverter) const override;
45
46 mlir::TypedAttr lowerDataMemberConstant(
47 cir::DataMemberAttr attr, const mlir::DataLayout &layout,
48 const mlir::TypeConverter &typeConverter) const override;
49
50 mlir::Operation *
51 lowerGetRuntimeMember(cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
52 mlir::Value loweredAddr, mlir::Value loweredMember,
53 mlir::OpBuilder &builder) const override;
54};
55
56} // namespace
57
58std::unique_ptr<CIRCXXABI> createItaniumCXXABI(LowerModule &lm) {
59 return std::make_unique<LowerItaniumCXXABI>(lm);
60}
61
62static cir::IntType getPtrDiffCIRTy(LowerModule &lm) {
63 const clang::TargetInfo &target = lm.getTarget();
66 return cir::IntType::get(lm.getMLIRContext(), target.getTypeWidth(ptrdiffTy),
67 target.isTypeSigned(ptrdiffTy));
68}
69
70mlir::Type LowerItaniumCXXABI::lowerDataMemberType(
71 cir::DataMemberType type, const mlir::TypeConverter &typeConverter) const {
72 // Itanium C++ ABI 2.3.1:
73 // A data member pointer is represented as the data member's offset in bytes
74 // from the address point of an object of the base type, as a ptrdiff_t.
75 return getPtrDiffCIRTy(lm);
76}
77
78mlir::Type LowerItaniumCXXABI::lowerMethodType(
79 cir::MethodType type, const mlir::TypeConverter &typeConverter) const {
80 // Itanium C++ ABI 2.3.2:
81 // In all representations, the basic ABI properties of member function
82 // pointer types are those of the following class, where fnptr_t is the
83 // appropriate function-pointer type for a member function of this type:
84 //
85 // struct {
86 // fnptr_t ptr;
87 // ptrdiff_t adj;
88 // };
89
90 cir::IntType ptrdiffCIRTy = getPtrDiffCIRTy(lm);
91
92 // Note that clang CodeGen emits struct{ptrdiff_t, ptrdiff_t} for member
93 // function pointers. Let's follow this approach.
94 return cir::RecordType::get(type.getContext(), {ptrdiffCIRTy, ptrdiffCIRTy},
95 /*packed=*/false, /*padded=*/false,
96 cir::RecordType::Struct);
97}
98
99mlir::TypedAttr LowerItaniumCXXABI::lowerDataMemberConstant(
100 cir::DataMemberAttr attr, const mlir::DataLayout &layout,
101 const mlir::TypeConverter &typeConverter) const {
102 uint64_t memberOffset;
103 if (attr.isNullPtr()) {
104 // Itanium C++ ABI 2.3:
105 // A NULL pointer is represented as -1.
106 memberOffset = -1ull;
107 } else {
108 // Itanium C++ ABI 2.3:
109 // A pointer to data member is an offset from the base address of
110 // the class object containing it, represented as a ptrdiff_t
111 unsigned memberIndex = attr.getMemberIndex().value();
112 memberOffset =
113 attr.getType().getClassTy().getElementOffset(layout, memberIndex);
114 }
115
116 mlir::Type abiTy = lowerDataMemberType(attr.getType(), typeConverter);
117 return cir::IntAttr::get(abiTy, memberOffset);
118}
119
120mlir::Operation *LowerItaniumCXXABI::lowerGetRuntimeMember(
121 cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
122 mlir::Value loweredAddr, mlir::Value loweredMember,
123 mlir::OpBuilder &builder) const {
124 auto byteTy = cir::IntType::get(op.getContext(), 8, true);
125 auto bytePtrTy = cir::PointerType::get(
126 byteTy,
127 mlir::cast<cir::PointerType>(op.getAddr().getType()).getAddrSpace());
128 auto objectBytesPtr = cir::CastOp::create(
129 builder, op.getLoc(), bytePtrTy, cir::CastKind::bitcast, op.getAddr());
130 auto memberBytesPtr = cir::PtrStrideOp::create(
131 builder, op.getLoc(), bytePtrTy, objectBytesPtr, loweredMember);
132 return cir::CastOp::create(builder, op.getLoc(), op.getType(),
133 cir::CastKind::bitcast, memberBytesPtr);
134}
135
136} // namespace cir
mlir::MLIRContext * getMLIRContext()
Definition LowerModule.h:47
const clang::TargetInfo & getTarget() const
Definition LowerModule.h:46
Exposes information about the current target.
Definition TargetInfo.h:226
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
static bool isTypeSigned(IntType T)
Returns true if the type is signed; false otherwise.
IntType getPtrDiffType(LangAS AddrSpace) const
Definition TargetInfo.h:407
std::unique_ptr< CIRCXXABI > createItaniumCXXABI(LowerModule &lm)
Creates an Itanium-family ABI.
static cir::IntType getPtrDiffCIRTy(LowerModule &lm)
const internal::VariadicAllOfMatcher< Attr > attr
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
unsigned long uint64_t
IntType
===-— Target Data Type Query Methods ----------------------------—===//
Definition TargetInfo.h:146