1919
2020#include " llvm/IR/Constants.h"
2121
22+ #include " CIRGenPointerAuthInfo.h"
23+
2224#include " mlir/IR/Value.h"
2325
2426namespace clang ::CIRGen {
@@ -29,10 +31,24 @@ enum KnownNonNull_t { NotKnownNonNull, KnownNonNull };
2931// / Like RawAddress, an abstract representation of an aligned address, but the
3032// / pointer contained in this class is possibly signed.
3133class Address {
34+
35+ // The boolean flag indicates whether the pointer is known to be non-null.
3236 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.
3341 mlir::Type ElementType;
42+
3443 clang::CharUnits Alignment;
3544
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+
3652protected:
3753 Address (std::nullptr_t ) : ElementType(nullptr ) {}
3854
@@ -49,6 +65,14 @@ class Address {
4965 assert (elementType && " Element type cannot be null" );
5066 assert (!alignment.isZero () && " Alignment cannot be zero" );
5167 }
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+
5276 Address (mlir::Value pointer, clang::CharUnits alignment)
5377 : Address(pointer,
5478 mlir::cast<cir::PointerType>(pointer.getType()).getPointee(),
@@ -78,10 +102,15 @@ class Address {
78102 isKnownNonNull ());
79103 }
80104
105+ bool hasOffset () const { return bool (offset); }
106+
81107 // / Return address with different element type, but same pointer and
82108 // / alignment.
83109 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 ());
85114 return Address (getPointer (), ElemTy, getAlignment (), isKnownNonNull ());
86115 }
87116
@@ -121,6 +150,10 @@ class Address {
121150 return ElementType;
122151 }
123152
153+ const cir::CIRGenPointerAuthInfo &getPointerAuthInfo () const {
154+ return ptrAuthInfo;
155+ }
156+
124157 // / Whether the pointer is known not to be null.
125158 KnownNonNull_t isKnownNonNull () const {
126159 assert (isValid ());
0 commit comments