19
19
20
20
#include " llvm/IR/Constants.h"
21
21
22
+ #include " CIRGenPointerAuthInfo.h"
23
+
22
24
#include " mlir/IR/Value.h"
23
25
24
26
namespace clang ::CIRGen {
@@ -29,10 +31,24 @@ enum KnownNonNull_t { NotKnownNonNull, KnownNonNull };
29
31
// / Like RawAddress, an abstract representation of an aligned address, but the
30
32
// / pointer contained in this class is possibly signed.
31
33
class Address {
34
+
35
+ // The boolean flag indicates whether the pointer is known to be non-null.
32
36
llvm::PointerIntPair<mlir::Value, 1 , bool > PointerAndKnownNonNull;
37
+
38
+ // / The expected CIR type of the pointer. Carrying accurate element type
39
+ // / information in Address makes it more convenient to work with Address
40
+ // / values and allows frontend assertions to catch simple mistakes.
33
41
mlir::Type ElementType;
42
+
34
43
clang::CharUnits Alignment;
35
44
45
+ // / The ptrauth information needed to authenticate the base pointer.
46
+ cir::CIRGenPointerAuthInfo ptrAuthInfo;
47
+
48
+ // / Offset from the base pointer. This is non-null only when the base pointer
49
+ // / is signed.
50
+ mlir::Value offset = nullptr ;
51
+
36
52
protected:
37
53
Address (std::nullptr_t ) : ElementType(nullptr ) {}
38
54
@@ -49,6 +65,14 @@ class Address {
49
65
assert (elementType && " Element type cannot be null" );
50
66
assert (!alignment.isZero () && " Alignment cannot be zero" );
51
67
}
68
+
69
+ Address (mlir::Value basePtr, mlir::Type elementType,
70
+ clang::CharUnits alignment, cir::CIRGenPointerAuthInfo ptrAuthInfo,
71
+ mlir::Value offset, KnownNonNull_t isKnownNonNull = NotKnownNonNull)
72
+ : PointerAndKnownNonNull(basePtr, isKnownNonNull),
73
+ ElementType(elementType), Alignment(alignment),
74
+ ptrAuthInfo(ptrAuthInfo), offset(offset) {}
75
+
52
76
Address (mlir::Value pointer, clang::CharUnits alignment)
53
77
: Address(pointer,
54
78
mlir::cast<cir::PointerType>(pointer.getType()).getPointee(),
@@ -78,10 +102,15 @@ class Address {
78
102
isKnownNonNull ());
79
103
}
80
104
105
+ bool hasOffset () const { return bool (offset); }
106
+
81
107
// / Return address with different element type, but same pointer and
82
108
// / alignment.
83
109
Address withElementType (mlir::Type ElemTy) const {
84
- // TODO(cir): hasOffset() check
110
+ if (!hasOffset ())
111
+ return Address (getBasePointer (), ElemTy, getAlignment (),
112
+ getPointerAuthInfo (), /* Offset=*/ nullptr ,
113
+ isKnownNonNull ());
85
114
return Address (getPointer (), ElemTy, getAlignment (), isKnownNonNull ());
86
115
}
87
116
@@ -121,6 +150,10 @@ class Address {
121
150
return ElementType;
122
151
}
123
152
153
+ const cir::CIRGenPointerAuthInfo &getPointerAuthInfo () const {
154
+ return ptrAuthInfo;
155
+ }
156
+
124
157
// / Whether the pointer is known not to be null.
125
158
KnownNonNull_t isKnownNonNull () const {
126
159
assert (isValid ());
0 commit comments