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 CharUnits Alignment; 27 28 protected: 29 Address(std::nullptr_t) : Pointer(nullptr) {} 30 31 public: 32 Address(llvm::Value *pointer, CharUnits alignment) 33 : Pointer(pointer), Alignment(alignment) { 34 assert(pointer != nullptr && "Pointer cannot be null"); 35 assert(!alignment.isZero() && "Alignment cannot be zero"); 36 } 37 38 static Address invalid() { return Address(nullptr); } 39 bool isValid() const { return Pointer != nullptr; } 40 41 llvm::Value *getPointer() const { 42 assert(isValid()); 43 return Pointer; 44 } 45 46 /// Return the type of the pointer value. 47 llvm::PointerType *getType() const { 48 return llvm::cast<llvm::PointerType>(getPointer()->getType()); 49 } 50 51 /// Return the type of the values stored in this address. 52 /// 53 /// When IR pointer types lose their element type, we should simply 54 /// store it in Address instead for the convenience of writing code. 55 llvm::Type *getElementType() const { 56 return getType()->getElementType(); 57 } 58 59 /// Return the address space that this address resides in. 60 unsigned getAddressSpace() const { 61 return getType()->getAddressSpace(); 62 } 63 64 /// Return the IR name of the pointer value. 65 llvm::StringRef getName() const { 66 return getPointer()->getName(); 67 } 68 69 /// Return the alignment of this pointer. 70 CharUnits getAlignment() const { 71 assert(isValid()); 72 return Alignment; 73 } 74 }; 75 76 /// A specialization of Address that requires the address to be an 77 /// LLVM Constant. 78 class ConstantAddress : public Address { 79 ConstantAddress(std::nullptr_t) : Address(nullptr) {} 80 81 public: 82 ConstantAddress(llvm::Constant *pointer, CharUnits alignment) 83 : Address(pointer, alignment) {} 84 85 static ConstantAddress invalid() { 86 return ConstantAddress(nullptr); 87 } 88 89 llvm::Constant *getPointer() const { 90 return llvm::cast<llvm::Constant>(Address::getPointer()); 91 } 92 93 ConstantAddress getBitCast(llvm::Type *ty) const { 94 return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty), 95 getAlignment()); 96 } 97 98 ConstantAddress getElementBitCast(llvm::Type *ty) const { 99 return getBitCast(ty->getPointerTo(getAddressSpace())); 100 } 101 102 static bool isaImpl(Address addr) { 103 return llvm::isa<llvm::Constant>(addr.getPointer()); 104 } 105 static ConstantAddress castImpl(Address addr) { 106 return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()), 107 addr.getAlignment()); 108 } 109 }; 110 111 } 112 113 // Present a minimal LLVM-like casting interface. 114 template <class U> inline U cast(CodeGen::Address addr) { 115 return U::castImpl(addr); 116 } 117 template <class U> inline bool isa(CodeGen::Address addr) { 118 return U::isaImpl(addr); 119 } 120 121 } 122 123 #endif 124