|  | //===-- Address.h - An aligned address -------------------------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This class provides a simple wrapper for a pair of a pointer and an | 
|  | // alignment. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H | 
|  | #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H | 
|  |  | 
|  | #include "llvm/IR/Constants.h" | 
|  | #include "clang/AST/CharUnits.h" | 
|  |  | 
|  | namespace clang { | 
|  | namespace CodeGen { | 
|  |  | 
|  | /// An aligned address. | 
|  | class Address { | 
|  | llvm::Value *Pointer; | 
|  | CharUnits Alignment; | 
|  | public: | 
|  | Address(llvm::Value *pointer, CharUnits alignment) | 
|  | : Pointer(pointer), Alignment(alignment) { | 
|  | assert((!alignment.isZero() || pointer == nullptr) && | 
|  | "creating valid address with invalid alignment"); | 
|  | } | 
|  |  | 
|  | static Address invalid() { return Address(nullptr, CharUnits()); } | 
|  | bool isValid() const { return Pointer != nullptr; } | 
|  |  | 
|  | llvm::Value *getPointer() const { | 
|  | assert(isValid()); | 
|  | return Pointer; | 
|  | } | 
|  |  | 
|  | /// Return the type of the pointer value. | 
|  | llvm::PointerType *getType() const { | 
|  | return llvm::cast<llvm::PointerType>(getPointer()->getType()); | 
|  | } | 
|  |  | 
|  | /// Return the type of the values stored in this address. | 
|  | /// | 
|  | /// When IR pointer types lose their element type, we should simply | 
|  | /// store it in Address instead for the convenience of writing code. | 
|  | llvm::Type *getElementType() const { | 
|  | return getType()->getElementType(); | 
|  | } | 
|  |  | 
|  | /// Return the address space that this address resides in. | 
|  | unsigned getAddressSpace() const { | 
|  | return getType()->getAddressSpace(); | 
|  | } | 
|  |  | 
|  | /// Return the IR name of the pointer value. | 
|  | llvm::StringRef getName() const { | 
|  | return getPointer()->getName(); | 
|  | } | 
|  |  | 
|  | /// Return the alignment of this pointer. | 
|  | CharUnits getAlignment() const { | 
|  | assert(isValid()); | 
|  | return Alignment; | 
|  | } | 
|  | }; | 
|  |  | 
|  | /// A specialization of Address that requires the address to be an | 
|  | /// LLVM Constant. | 
|  | class ConstantAddress : public Address { | 
|  | public: | 
|  | ConstantAddress(llvm::Constant *pointer, CharUnits alignment) | 
|  | : Address(pointer, alignment) {} | 
|  |  | 
|  | static ConstantAddress invalid() { | 
|  | return ConstantAddress(nullptr, CharUnits()); | 
|  | } | 
|  |  | 
|  | llvm::Constant *getPointer() const { | 
|  | return llvm::cast<llvm::Constant>(Address::getPointer()); | 
|  | } | 
|  |  | 
|  | ConstantAddress getBitCast(llvm::Type *ty) const { | 
|  | return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty), | 
|  | getAlignment()); | 
|  | } | 
|  |  | 
|  | ConstantAddress getElementBitCast(llvm::Type *ty) const { | 
|  | return getBitCast(ty->getPointerTo(getAddressSpace())); | 
|  | } | 
|  |  | 
|  | static bool isaImpl(Address addr) { | 
|  | return llvm::isa<llvm::Constant>(addr.getPointer()); | 
|  | } | 
|  | static ConstantAddress castImpl(Address addr) { | 
|  | return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()), | 
|  | addr.getAlignment()); | 
|  | } | 
|  | }; | 
|  |  | 
|  | } | 
|  |  | 
|  | // Present a minimal LLVM-like casting interface. | 
|  | template <class U> inline U cast(CodeGen::Address addr) { | 
|  | return U::castImpl(addr); | 
|  | } | 
|  | template <class U> inline bool isa(CodeGen::Address addr) { | 
|  | return U::isaImpl(addr); | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | #endif |