1 //===-- Address.h - An aligned address -------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This class provides a simple wrapper for a pair of a pointer and an 11 // alignment. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H 16 #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H 17 18 #include "llvm/IR/Constants.h" 19 #include "clang/AST/CharUnits.h" 20 21 namespace clang { 22 namespace CodeGen { 23 24 /// An aligned address. 25 class Address { 26 llvm::Value *Pointer; 27 CharUnits Alignment; 28 public: Address(llvm::Value * pointer,CharUnits alignment)29 Address(llvm::Value *pointer, CharUnits alignment) 30 : Pointer(pointer), Alignment(alignment) { 31 assert((!alignment.isZero() || pointer == nullptr) && 32 "creating valid address with invalid alignment"); 33 } 34 invalid()35 static Address invalid() { return Address(nullptr, CharUnits()); } isValid()36 bool isValid() const { return Pointer != nullptr; } 37 getPointer()38 llvm::Value *getPointer() const { 39 assert(isValid()); 40 return Pointer; 41 } 42 43 /// Return the type of the pointer value. getType()44 llvm::PointerType *getType() const { 45 return llvm::cast<llvm::PointerType>(getPointer()->getType()); 46 } 47 48 /// Return the type of the values stored in this address. 49 /// 50 /// When IR pointer types lose their element type, we should simply 51 /// store it in Address instead for the convenience of writing code. getElementType()52 llvm::Type *getElementType() const { 53 return getType()->getElementType(); 54 } 55 56 /// Return the address space that this address resides in. getAddressSpace()57 unsigned getAddressSpace() const { 58 return getType()->getAddressSpace(); 59 } 60 61 /// Return the IR name of the pointer value. getName()62 llvm::StringRef getName() const { 63 return getPointer()->getName(); 64 } 65 66 /// Return the alignment of this pointer. getAlignment()67 CharUnits getAlignment() const { 68 assert(isValid()); 69 return Alignment; 70 } 71 }; 72 73 /// A specialization of Address that requires the address to be an 74 /// LLVM Constant. 75 class ConstantAddress : public Address { 76 public: ConstantAddress(llvm::Constant * pointer,CharUnits alignment)77 ConstantAddress(llvm::Constant *pointer, CharUnits alignment) 78 : Address(pointer, alignment) {} 79 invalid()80 static ConstantAddress invalid() { 81 return ConstantAddress(nullptr, CharUnits()); 82 } 83 getPointer()84 llvm::Constant *getPointer() const { 85 return llvm::cast<llvm::Constant>(Address::getPointer()); 86 } 87 getBitCast(llvm::Type * ty)88 ConstantAddress getBitCast(llvm::Type *ty) const { 89 return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty), 90 getAlignment()); 91 } 92 getElementBitCast(llvm::Type * ty)93 ConstantAddress getElementBitCast(llvm::Type *ty) const { 94 return getBitCast(ty->getPointerTo(getAddressSpace())); 95 } 96 isaImpl(Address addr)97 static bool isaImpl(Address addr) { 98 return llvm::isa<llvm::Constant>(addr.getPointer()); 99 } castImpl(Address addr)100 static ConstantAddress castImpl(Address addr) { 101 return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()), 102 addr.getAlignment()); 103 } 104 }; 105 106 } 107 } 108 109 namespace llvm { 110 // Present a minimal LLVM-like casting interface. cast(clang::CodeGen::Address addr)111 template <class U> inline U cast(clang::CodeGen::Address addr) { 112 return U::castImpl(addr); 113 } isa(clang::CodeGen::Address addr)114 template <class U> inline bool isa(clang::CodeGen::Address addr) { 115 return U::isaImpl(addr); 116 } 117 } 118 119 namespace clang { 120 // Make our custom isa and cast available in namespace clang, to mirror 121 // what we do for LLVM's versions in Basic/LLVM.h. 122 using llvm::isa; 123 using llvm::cast; 124 } 125 126 #endif 127