Home | History | Annotate | Download | only in CodeGen
      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:
     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 
     35   static Address invalid() { return Address(nullptr, CharUnits()); }
     36   bool isValid() const { return Pointer != nullptr; }
     37 
     38   llvm::Value *getPointer() const {
     39     assert(isValid());
     40     return Pointer;
     41   }
     42 
     43   /// Return the type of the pointer value.
     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.
     52   llvm::Type *getElementType() const {
     53     return getType()->getElementType();
     54   }
     55 
     56   /// Return the address space that this address resides in.
     57   unsigned getAddressSpace() const {
     58     return getType()->getAddressSpace();
     59   }
     60 
     61   /// Return the IR name of the pointer value.
     62   llvm::StringRef getName() const {
     63     return getPointer()->getName();
     64   }
     65 
     66   /// Return the alignment of this pointer.
     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:
     77   ConstantAddress(llvm::Constant *pointer, CharUnits alignment)
     78     : Address(pointer, alignment) {}
     79 
     80   static ConstantAddress invalid() {
     81     return ConstantAddress(nullptr, CharUnits());
     82   }
     83 
     84   llvm::Constant *getPointer() const {
     85     return llvm::cast<llvm::Constant>(Address::getPointer());
     86   }
     87 
     88   ConstantAddress getBitCast(llvm::Type *ty) const {
     89     return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty),
     90                            getAlignment());
     91   }
     92 
     93   ConstantAddress getElementBitCast(llvm::Type *ty) const {
     94     return getBitCast(ty->getPointerTo(getAddressSpace()));
     95   }
     96 
     97   static bool isaImpl(Address addr) {
     98     return llvm::isa<llvm::Constant>(addr.getPointer());
     99   }
    100   static ConstantAddress castImpl(Address addr) {
    101     return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()),
    102                            addr.getAlignment());
    103   }
    104 };
    105 
    106 }
    107 
    108 // Present a minimal LLVM-like casting interface.
    109 template <class U> inline U cast(CodeGen::Address addr) {
    110   return U::castImpl(addr);
    111 }
    112 template <class U> inline bool isa(CodeGen::Address addr) {
    113   return U::isaImpl(addr);
    114 }
    115 
    116 }
    117 
    118 #endif
    119