Home | History | Annotate | Line # | Download | only in CodeGen
      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