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
21namespace clang {
22namespace CodeGen {
23
24/// An aligned address.
25class Address {
26  llvm::Value *Pointer;
27  CharUnits Alignment;
28public:
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.
75class ConstantAddress : public Address {
76public:
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.
109template <class U> inline U cast(CodeGen::Address addr) {
110  return U::castImpl(addr);
111}
112template <class U> inline bool isa(CodeGen::Address addr) {
113  return U::isaImpl(addr);
114}
115
116}
117
118#endif
119