1 //===-- Address.h - An aligned address -------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This class provides a simple wrapper for a pair of a pointer and an
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
15 #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
17 #include "clang/AST/CharUnits.h"
18 #include "llvm/ADT/PointerIntPair.h"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/Support/MathExtras.h"
25 // Indicates whether a pointer is known not to be null.
26 enum KnownNonNull_t
{ NotKnownNonNull
, KnownNonNull
};
28 /// An aligned address.
30 llvm::PointerIntPair
<llvm::Value
*, 1, bool> PointerAndKnownNonNull
;
31 llvm::Type
*ElementType
;
35 Address(std::nullptr_t
) : ElementType(nullptr) {}
38 Address(llvm::Value
*Pointer
, llvm::Type
*ElementType
, CharUnits Alignment
,
39 KnownNonNull_t IsKnownNonNull
= NotKnownNonNull
)
40 : PointerAndKnownNonNull(Pointer
, IsKnownNonNull
),
41 ElementType(ElementType
), Alignment(Alignment
) {
42 assert(Pointer
!= nullptr && "Pointer cannot be null");
43 assert(ElementType
!= nullptr && "Element type cannot be null");
46 static Address
invalid() { return Address(nullptr); }
47 bool isValid() const {
48 return PointerAndKnownNonNull
.getPointer() != nullptr;
51 llvm::Value
*getPointer() const {
53 return PointerAndKnownNonNull
.getPointer();
56 /// Return the type of the pointer value.
57 llvm::PointerType
*getType() const {
58 return llvm::cast
<llvm::PointerType
>(getPointer()->getType());
61 /// Return the type of the values stored in this address.
62 llvm::Type
*getElementType() const {
67 /// Return the address space that this address resides in.
68 unsigned getAddressSpace() const {
69 return getType()->getAddressSpace();
72 /// Return the IR name of the pointer value.
73 llvm::StringRef
getName() const {
74 return getPointer()->getName();
77 /// Return the alignment of this pointer.
78 CharUnits
getAlignment() const {
83 /// Return address with different pointer, but same element type and
85 Address
withPointer(llvm::Value
*NewPointer
,
86 KnownNonNull_t IsKnownNonNull
) const {
87 return Address(NewPointer
, getElementType(), getAlignment(),
91 /// Return address with different alignment, but same pointer and element
93 Address
withAlignment(CharUnits NewAlignment
) const {
94 return Address(getPointer(), getElementType(), NewAlignment
,
98 /// Whether the pointer is known not to be null.
99 KnownNonNull_t
isKnownNonNull() const {
101 return (KnownNonNull_t
)PointerAndKnownNonNull
.getInt();
104 /// Set the non-null bit.
105 Address
setKnownNonNull() {
107 PointerAndKnownNonNull
.setInt(true);
112 /// A specialization of Address that requires the address to be an
114 class ConstantAddress
: public Address
{
115 ConstantAddress(std::nullptr_t
) : Address(nullptr) {}
118 ConstantAddress(llvm::Constant
*pointer
, llvm::Type
*elementType
,
120 : Address(pointer
, elementType
, alignment
) {}
122 static ConstantAddress
invalid() {
123 return ConstantAddress(nullptr);
126 llvm::Constant
*getPointer() const {
127 return llvm::cast
<llvm::Constant
>(Address::getPointer());
130 ConstantAddress
withElementType(llvm::Type
*ElemTy
) const {
131 return ConstantAddress(getPointer(), ElemTy
, getAlignment());
134 static bool isaImpl(Address addr
) {
135 return llvm::isa
<llvm::Constant
>(addr
.getPointer());
137 static ConstantAddress
castImpl(Address addr
) {
138 return ConstantAddress(llvm::cast
<llvm::Constant
>(addr
.getPointer()),
139 addr
.getElementType(), addr
.getAlignment());
145 // Present a minimal LLVM-like casting interface.
146 template <class U
> inline U
cast(CodeGen::Address addr
) {
147 return U::castImpl(addr
);
149 template <class U
> inline bool isa(CodeGen::Address addr
) {
150 return U::isaImpl(addr
);