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 /// Return address with different element type, but same pointer and
100 Address
withElementType(llvm::Type
*ElemTy
) const {
101 return Address(getPointer(), ElemTy
, getAlignment(), isKnownNonNull());
104 /// Whether the pointer is known not to be null.
105 KnownNonNull_t
isKnownNonNull() const {
107 return (KnownNonNull_t
)PointerAndKnownNonNull
.getInt();
110 /// Set the non-null bit.
111 Address
setKnownNonNull() {
113 PointerAndKnownNonNull
.setInt(true);
118 /// A specialization of Address that requires the address to be an
120 class ConstantAddress
: public Address
{
121 ConstantAddress(std::nullptr_t
) : Address(nullptr) {}
124 ConstantAddress(llvm::Constant
*pointer
, llvm::Type
*elementType
,
126 : Address(pointer
, elementType
, alignment
) {}
128 static ConstantAddress
invalid() {
129 return ConstantAddress(nullptr);
132 llvm::Constant
*getPointer() const {
133 return llvm::cast
<llvm::Constant
>(Address::getPointer());
136 ConstantAddress
withElementType(llvm::Type
*ElemTy
) const {
137 return ConstantAddress(getPointer(), ElemTy
, getAlignment());
140 static bool isaImpl(Address addr
) {
141 return llvm::isa
<llvm::Constant
>(addr
.getPointer());
143 static ConstantAddress
castImpl(Address addr
) {
144 return ConstantAddress(llvm::cast
<llvm::Constant
>(addr
.getPointer()),
145 addr
.getElementType(), addr
.getAlignment());
151 // Present a minimal LLVM-like casting interface.
152 template <class U
> inline U
cast(CodeGen::Address addr
) {
153 return U::castImpl(addr
);
155 template <class U
> inline bool isa(CodeGen::Address addr
) {
156 return U::isaImpl(addr
);