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