/src/llvm-project/clang/lib/CodeGen/Address.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- Address.h - An aligned address -------------------------*- C++ -*-===// |
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 LLVM_CLANG_LIB_CODEGEN_ADDRESS_H |
15 | | #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H |
16 | | |
17 | | #include "clang/AST/CharUnits.h" |
18 | | #include "llvm/ADT/PointerIntPair.h" |
19 | | #include "llvm/IR/Constants.h" |
20 | | #include "llvm/Support/MathExtras.h" |
21 | | |
22 | | namespace clang { |
23 | | namespace CodeGen { |
24 | | |
25 | | // Indicates whether a pointer is known not to be null. |
26 | | enum KnownNonNull_t { NotKnownNonNull, KnownNonNull }; |
27 | | |
28 | | /// An aligned address. |
29 | | class Address { |
30 | | llvm::PointerIntPair<llvm::Value *, 1, bool> PointerAndKnownNonNull; |
31 | | llvm::Type *ElementType; |
32 | | CharUnits Alignment; |
33 | | |
34 | | protected: |
35 | 0 | Address(std::nullptr_t) : ElementType(nullptr) {} |
36 | | |
37 | | public: |
38 | | Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment, |
39 | | KnownNonNull_t IsKnownNonNull = NotKnownNonNull) |
40 | | : PointerAndKnownNonNull(Pointer, IsKnownNonNull), |
41 | 0 | ElementType(ElementType), Alignment(Alignment) { |
42 | 0 | assert(Pointer != nullptr && "Pointer cannot be null"); |
43 | 0 | assert(ElementType != nullptr && "Element type cannot be null"); |
44 | 0 | } |
45 | | |
46 | 0 | static Address invalid() { return Address(nullptr); } |
47 | 0 | bool isValid() const { |
48 | 0 | return PointerAndKnownNonNull.getPointer() != nullptr; |
49 | 0 | } |
50 | | |
51 | 0 | llvm::Value *getPointer() const { |
52 | 0 | assert(isValid()); |
53 | 0 | return PointerAndKnownNonNull.getPointer(); |
54 | 0 | } |
55 | | |
56 | | /// Return the type of the pointer value. |
57 | 0 | llvm::PointerType *getType() const { |
58 | 0 | return llvm::cast<llvm::PointerType>(getPointer()->getType()); |
59 | 0 | } |
60 | | |
61 | | /// Return the type of the values stored in this address. |
62 | 0 | llvm::Type *getElementType() const { |
63 | 0 | assert(isValid()); |
64 | 0 | return ElementType; |
65 | 0 | } |
66 | | |
67 | | /// Return the address space that this address resides in. |
68 | 0 | unsigned getAddressSpace() const { |
69 | 0 | return getType()->getAddressSpace(); |
70 | 0 | } |
71 | | |
72 | | /// Return the IR name of the pointer value. |
73 | 0 | llvm::StringRef getName() const { |
74 | 0 | return getPointer()->getName(); |
75 | 0 | } |
76 | | |
77 | | /// Return the alignment of this pointer. |
78 | 0 | CharUnits getAlignment() const { |
79 | 0 | assert(isValid()); |
80 | 0 | return Alignment; |
81 | 0 | } |
82 | | |
83 | | /// Return address with different pointer, but same element type and |
84 | | /// alignment. |
85 | | Address withPointer(llvm::Value *NewPointer, |
86 | 0 | KnownNonNull_t IsKnownNonNull) const { |
87 | 0 | return Address(NewPointer, getElementType(), getAlignment(), |
88 | 0 | IsKnownNonNull); |
89 | 0 | } |
90 | | |
91 | | /// Return address with different alignment, but same pointer and element |
92 | | /// type. |
93 | 0 | Address withAlignment(CharUnits NewAlignment) const { |
94 | 0 | return Address(getPointer(), getElementType(), NewAlignment, |
95 | 0 | isKnownNonNull()); |
96 | 0 | } |
97 | | |
98 | | /// Return address with different element type, but same pointer and |
99 | | /// alignment. |
100 | 0 | Address withElementType(llvm::Type *ElemTy) const { |
101 | 0 | return Address(getPointer(), ElemTy, getAlignment(), isKnownNonNull()); |
102 | 0 | } |
103 | | |
104 | | /// Whether the pointer is known not to be null. |
105 | 0 | KnownNonNull_t isKnownNonNull() const { |
106 | 0 | assert(isValid()); |
107 | 0 | return (KnownNonNull_t)PointerAndKnownNonNull.getInt(); |
108 | 0 | } |
109 | | |
110 | | /// Set the non-null bit. |
111 | 0 | Address setKnownNonNull() { |
112 | 0 | assert(isValid()); |
113 | 0 | PointerAndKnownNonNull.setInt(true); |
114 | 0 | return *this; |
115 | 0 | } |
116 | | }; |
117 | | |
118 | | /// A specialization of Address that requires the address to be an |
119 | | /// LLVM Constant. |
120 | | class ConstantAddress : public Address { |
121 | 0 | ConstantAddress(std::nullptr_t) : Address(nullptr) {} |
122 | | |
123 | | public: |
124 | | ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType, |
125 | | CharUnits alignment) |
126 | 0 | : Address(pointer, elementType, alignment) {} |
127 | | |
128 | 0 | static ConstantAddress invalid() { |
129 | 0 | return ConstantAddress(nullptr); |
130 | 0 | } |
131 | | |
132 | 0 | llvm::Constant *getPointer() const { |
133 | 0 | return llvm::cast<llvm::Constant>(Address::getPointer()); |
134 | 0 | } |
135 | | |
136 | 0 | ConstantAddress withElementType(llvm::Type *ElemTy) const { |
137 | 0 | return ConstantAddress(getPointer(), ElemTy, getAlignment()); |
138 | 0 | } |
139 | | |
140 | 0 | static bool isaImpl(Address addr) { |
141 | 0 | return llvm::isa<llvm::Constant>(addr.getPointer()); |
142 | 0 | } |
143 | 0 | static ConstantAddress castImpl(Address addr) { |
144 | 0 | return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()), |
145 | 0 | addr.getElementType(), addr.getAlignment()); |
146 | 0 | } |
147 | | }; |
148 | | |
149 | | } |
150 | | |
151 | | // Present a minimal LLVM-like casting interface. |
152 | | template <class U> inline U cast(CodeGen::Address addr) { |
153 | | return U::castImpl(addr); |
154 | | } |
155 | | template <class U> inline bool isa(CodeGen::Address addr) { |
156 | | return U::isaImpl(addr); |
157 | | } |
158 | | |
159 | | } |
160 | | |
161 | | #endif |