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