clang 22.0.0git
Address.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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 class provides a simple wrapper for a pair of a pointer and an
10// alignment.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CLANG_LIB_CIR_ADDRESS_H
15#define CLANG_LIB_CIR_ADDRESS_H
16
17#include "mlir/IR/Value.h"
18#include "clang/AST/CharUnits.h"
20#include "llvm/ADT/PointerIntPair.h"
21
22namespace clang::CIRGen {
23
24// Forward declaration to avoid a circular dependency
25class CIRGenBuilderTy;
26
27class Address {
28
29 // The boolean flag indicates whether the pointer is known to be non-null.
30 llvm::PointerIntPair<mlir::Value, 1, bool> pointerAndKnownNonNull;
31
32 /// The expected CIR type of the pointer. Carrying accurate element type
33 /// information in Address makes it more convenient to work with Address
34 /// values and allows frontend assertions to catch simple mistakes.
35 mlir::Type elementType;
36
37 clang::CharUnits alignment;
38
39protected:
40 Address(std::nullptr_t) : elementType(nullptr) {}
41
42public:
43 Address(mlir::Value pointer, mlir::Type elementType,
44 clang::CharUnits alignment)
45 : pointerAndKnownNonNull(pointer, false), elementType(elementType),
46 alignment(alignment) {
47 assert(mlir::isa<cir::PointerType>(pointer.getType()) &&
48 "Expected cir.ptr type");
49
50 assert(pointer && "Pointer cannot be null");
51 assert(elementType && "Element type cannot be null");
52 assert(!alignment.isZero() && "Alignment cannot be zero");
53
54 assert(mlir::cast<cir::PointerType>(pointer.getType()).getPointee() ==
55 elementType);
56 }
57
58 Address(mlir::Value pointer, clang::CharUnits alignment)
59 : Address(pointer,
60 mlir::cast<cir::PointerType>(pointer.getType()).getPointee(),
61 alignment) {
62 assert((!alignment.isZero() || pointer == nullptr) &&
63 "creating valid address with invalid alignment");
64 }
65
66 static Address invalid() { return Address(nullptr); }
67 bool isValid() const {
68 return pointerAndKnownNonNull.getPointer() != nullptr;
69 }
70
71 /// Return address with different pointer, but same element type and
72 /// alignment.
73 Address withPointer(mlir::Value newPtr) const {
74 return Address(newPtr, getElementType(), getAlignment());
75 }
76
77 /// Return address with different element type, a bitcast pointer, and
78 /// the same alignment.
79 Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const;
80
81 mlir::Value getPointer() const {
82 assert(isValid());
83 return pointerAndKnownNonNull.getPointer();
84 }
85
86 mlir::Value getBasePointer() const {
87 // TODO(cir): Remove the version above when we catchup with OG codegen on
88 // ptr auth.
89 assert(isValid() && "pointer isn't valid");
90 return getPointer();
91 }
92
93 mlir::Type getType() const {
94 assert(mlir::cast<cir::PointerType>(
95 pointerAndKnownNonNull.getPointer().getType())
96 .getPointee() == elementType);
97
98 return mlir::cast<cir::PointerType>(getPointer().getType());
99 }
100
101 mlir::Type getElementType() const {
102 assert(isValid());
103 assert(mlir::cast<cir::PointerType>(
104 pointerAndKnownNonNull.getPointer().getType())
105 .getPointee() == elementType);
106 return elementType;
107 }
108
109 clang::CharUnits getAlignment() const { return alignment; }
110
111 /// Get the operation which defines this address.
112 mlir::Operation *getDefiningOp() const {
113 if (!isValid())
114 return nullptr;
115 return getPointer().getDefiningOp();
116 }
117
118 template <typename OpTy> OpTy getDefiningOp() const {
119 return mlir::dyn_cast_or_null<OpTy>(getDefiningOp());
120 }
121};
122
123} // namespace clang::CIRGen
124
125#endif // CLANG_LIB_CIR_ADDRESS_H
Address withPointer(mlir::Value newPtr) const
Return address with different pointer, but same element type and alignment.
Definition: Address.h:73
mlir::Value getPointer() const
Definition: Address.h:81
Address(mlir::Value pointer, clang::CharUnits alignment)
Definition: Address.h:58
mlir::Type getElementType() const
Definition: Address.h:101
static Address invalid()
Definition: Address.h:66
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
clang::CharUnits getAlignment() const
Definition: Address.h:109
mlir::Value getBasePointer() const
Definition: Address.h:86
mlir::Type getType() const
Definition: Address.h:93
Address(std::nullptr_t)
Definition: Address.h:40
bool isValid() const
Definition: Address.h:67
Address(mlir::Value pointer, mlir::Type elementType, clang::CharUnits alignment)
Definition: Address.h:43
OpTy getDefiningOp() const
Definition: Address.h:118
mlir::Operation * getDefiningOp() const
Get the operation which defines this address.
Definition: Address.h:112
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:122
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: TypeBase.h:3346
Definition: ABIArgInfo.h:22
U cast(CodeGen::Address addr)
Definition: Address.h:327
#define false
Definition: stdbool.h:26