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 "llvm/IR/Constants.h" 18 #include "clang/AST/CharUnits.h" 19 20 namespace clang { 21 namespace CodeGen { 22 23 /// An aligned address. 24 class Address { 25 llvm::Value *Pointer; 26 llvm::Type *ElementType; 27 CharUnits Alignment; 28 29 protected: 30 Address(std::nullptr_t) : Pointer(nullptr), ElementType(nullptr) {} 31 32 public: 33 Address(llvm::Value *pointer, llvm::Type *elementType, CharUnits alignment) 34 : Pointer(pointer), ElementType(elementType), Alignment(alignment) { 35 assert(pointer != nullptr && "Pointer cannot be null"); 36 assert(elementType != nullptr && "Element type cannot be null"); 37 assert(llvm::cast<llvm::PointerType>(pointer->getType()) 38 ->isOpaqueOrPointeeTypeMatches(elementType) && 39 "Incorrect pointer element type"); 40 assert(!alignment.isZero() && "Alignment cannot be zero"); 41 } 42 43 // Deprecated: Use constructor with explicit element type instead. 44 Address(llvm::Value *Pointer, CharUnits Alignment) 45 : Address(Pointer, Pointer->getType()->getPointerElementType(), 46 Alignment) {} 47 48 static Address invalid() { return Address(nullptr); } 49 bool isValid() const { return Pointer != nullptr; } 50 51 llvm::Value *getPointer() const { 52 assert(isValid()); 53 return Pointer; 54 } 55 56 /// Return the type of the pointer value. 57 llvm::PointerType *getType() const { 58 return llvm::cast<llvm::PointerType>(getPointer()->getType()); 59 } 60 61 /// Return the type of the values stored in this address. 62 llvm::Type *getElementType() const { 63 assert(isValid()); 64 return ElementType; 65 } 66 67 /// Return the address space that this address resides in. 68 unsigned getAddressSpace() const { 69 return getType()->getAddressSpace(); 70 } 71 72 /// Return the IR name of the pointer value. 73 llvm::StringRef getName() const { 74 return getPointer()->getName(); 75 } 76 77 /// Return the alignment of this pointer. 78 CharUnits getAlignment() const { 79 assert(isValid()); 80 return Alignment; 81 } 82 83 /// Return address with different pointer, but same element type and 84 /// alignment. 85 Address withPointer(llvm::Value *NewPointer) const { 86 return Address(NewPointer, ElementType, Alignment); 87 } 88 89 /// Return address with different alignment, but same pointer and element 90 /// type. 91 Address withAlignment(CharUnits NewAlignment) const { 92 return Address(Pointer, ElementType, NewAlignment); 93 } 94 }; 95 96 /// A specialization of Address that requires the address to be an 97 /// LLVM Constant. 98 class ConstantAddress : public Address { 99 ConstantAddress(std::nullptr_t) : Address(nullptr) {} 100 101 public: 102 ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType, 103 CharUnits alignment) 104 : Address(pointer, elementType, alignment) {} 105 106 static ConstantAddress invalid() { 107 return ConstantAddress(nullptr); 108 } 109 110 llvm::Constant *getPointer() const { 111 return llvm::cast<llvm::Constant>(Address::getPointer()); 112 } 113 114 ConstantAddress getElementBitCast(llvm::Type *ElemTy) const { 115 llvm::Constant *BitCast = llvm::ConstantExpr::getBitCast( 116 getPointer(), ElemTy->getPointerTo(getAddressSpace())); 117 return ConstantAddress(BitCast, ElemTy, getAlignment()); 118 } 119 120 static bool isaImpl(Address addr) { 121 return llvm::isa<llvm::Constant>(addr.getPointer()); 122 } 123 static ConstantAddress castImpl(Address addr) { 124 return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()), 125 addr.getElementType(), addr.getAlignment()); 126 } 127 }; 128 129 } 130 131 // Present a minimal LLVM-like casting interface. 132 template <class U> inline U cast(CodeGen::Address addr) { 133 return U::castImpl(addr); 134 } 135 template <class U> inline bool isa(CodeGen::Address addr) { 136 return U::isaImpl(addr); 137 } 138 139 } 140 141 #endif 142