blob: 334308081ff3c5b418bed169f591746a371d2dd6 [file] [log] [blame]
Pirama Arumuga Nainar87d948e2016-03-03 15:49:35 -08001//===-- 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}
Pirama Arumuga Nainar4967a712016-09-19 22:19:55 -0700107
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);
Pirama Arumuga Nainar87d948e2016-03-03 15:49:35 -0800114}
115
Pirama Arumuga Nainar87d948e2016-03-03 15:49:35 -0800116}
117
118#endif