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