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::TypedAttr lowerDataMemberConstant(
43 cir::DataMemberAttr attr, const mlir::DataLayout &layout,
44 const mlir::TypeConverter &typeConverter) const override;
45
46 mlir::Operation *
47 lowerGetRuntimeMember(cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
48 mlir::Value loweredAddr, mlir::Value loweredMember,
49 mlir::OpBuilder &builder) const override;
50};
51
52} // namespace
53
54std::unique_ptr<CIRCXXABI> createItaniumCXXABI(LowerModule &lm) {
55 return std::make_unique<LowerItaniumCXXABI>(lm);
56}
57
58static cir::IntType getPtrDiffCIRTy(LowerModule &lm) {
59 const clang::TargetInfo &target = lm.getTarget();
62 return cir::IntType::get(lm.getMLIRContext(), target.getTypeWidth(ptrdiffTy),
63 target.isTypeSigned(ptrdiffTy));
64}
65
66mlir::Type LowerItaniumCXXABI::lowerDataMemberType(
67 cir::DataMemberType type, const mlir::TypeConverter &typeConverter) const {
68 // Itanium C++ ABI 2.3.1:
69 // A data member pointer is represented as the data member's offset in bytes
70 // from the address point of an object of the base type, as a ptrdiff_t.
71 return getPtrDiffCIRTy(lm);
72}
73
74mlir::TypedAttr LowerItaniumCXXABI::lowerDataMemberConstant(
75 cir::DataMemberAttr attr, const mlir::DataLayout &layout,
76 const mlir::TypeConverter &typeConverter) const {
77 uint64_t memberOffset;
78 if (attr.isNullPtr()) {
79 // Itanium C++ ABI 2.3:
80 // A NULL pointer is represented as -1.
81 memberOffset = -1ull;
82 } else {
83 // Itanium C++ ABI 2.3:
84 // A pointer to data member is an offset from the base address of
85 // the class object containing it, represented as a ptrdiff_t
86 unsigned memberIndex = attr.getMemberIndex().value();
87 memberOffset =
88 attr.getType().getClassTy().getElementOffset(layout, memberIndex);
89 }
90
91 mlir::Type abiTy = lowerDataMemberType(attr.getType(), typeConverter);
92 return cir::IntAttr::get(abiTy, memberOffset);
93}
94
95mlir::Operation *LowerItaniumCXXABI::lowerGetRuntimeMember(
96 cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
97 mlir::Value loweredAddr, mlir::Value loweredMember,
98 mlir::OpBuilder &builder) const {
99 auto byteTy = cir::IntType::get(op.getContext(), 8, true);
100 auto bytePtrTy = cir::PointerType::get(
101 byteTy,
102 mlir::cast<cir::PointerType>(op.getAddr().getType()).getAddrSpace());
103 auto objectBytesPtr = cir::CastOp::create(
104 builder, op.getLoc(), bytePtrTy, cir::CastKind::bitcast, op.getAddr());
105 auto memberBytesPtr = cir::PtrStrideOp::create(
106 builder, op.getLoc(), bytePtrTy, objectBytesPtr, loweredMember);
107 return cir::CastOp::create(builder, op.getLoc(), op.getType(),
108 cir::CastKind::bitcast, memberBytesPtr);
109}
110
111} // 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
unsigned long uint64_t
IntType
===-— Target Data Type Query Methods ----------------------------—===//
Definition TargetInfo.h:146