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