CGValue.h revision 6dc2317b59cb1180a59f6c283d96b7a5dfeb5307
1//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- 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// These classes implement wrappers around llvm::Value in order to
11// fully represent the range of values for C L- and R- values.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef CLANG_CODEGEN_CGVALUE_H
16#define CLANG_CODEGEN_CGVALUE_H
17
18#include "clang/AST/Type.h"
19
20namespace llvm {
21  class Constant;
22  class Value;
23}
24
25namespace clang {
26  class ObjCPropertyRefExpr;
27
28namespace CodeGen {
29
30/// RValue - This trivial value class is used to represent the result of an
31/// expression that is evaluated.  It can be one of three things: either a
32/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
33/// address of an aggregate value in memory.
34class RValue {
35  llvm::Value *V1, *V2;
36  // TODO: Encode this into the low bit of pointer for more efficient
37  // return-by-value.
38  enum { Scalar, Complex, Aggregate } Flavor;
39
40  // FIXME: Aggregate rvalues need to retain information about whether they are
41  // volatile or not.
42public:
43
44  bool isScalar() const { return Flavor == Scalar; }
45  bool isComplex() const { return Flavor == Complex; }
46  bool isAggregate() const { return Flavor == Aggregate; }
47
48  /// getScalar() - Return the Value* of this scalar value.
49  llvm::Value *getScalarVal() const {
50    assert(isScalar() && "Not a scalar!");
51    return V1;
52  }
53
54  /// getComplexVal - Return the real/imag components of this complex value.
55  ///
56  std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
57    return std::pair<llvm::Value *, llvm::Value *>(V1, V2);
58  }
59
60  /// getAggregateAddr() - Return the Value* of the address of the aggregate.
61  llvm::Value *getAggregateAddr() const {
62    assert(isAggregate() && "Not an aggregate!");
63    return V1;
64  }
65
66  static RValue get(llvm::Value *V) {
67    RValue ER;
68    ER.V1 = V;
69    ER.Flavor = Scalar;
70    return ER;
71  }
72  static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
73    RValue ER;
74    ER.V1 = V1;
75    ER.V2 = V2;
76    ER.Flavor = Complex;
77    return ER;
78  }
79  static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
80    RValue ER;
81    ER.V1 = C.first;
82    ER.V2 = C.second;
83    ER.Flavor = Complex;
84    return ER;
85  }
86  static RValue getAggregate(llvm::Value *V) {
87    RValue ER;
88    ER.V1 = V;
89    ER.Flavor = Aggregate;
90    return ER;
91  }
92};
93
94
95/// LValue - This represents an lvalue references.  Because C/C++ allow
96/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
97/// bitrange.
98class LValue {
99  // FIXME: alignment?
100
101  enum {
102    Simple,       // This is a normal l-value, use getAddress().
103    VectorElt,    // This is a vector element l-value (V[i]), use getVector*
104    BitField,     // This is a bitfield l-value, use getBitfield*.
105    ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
106    PropertyRef   // This is an Objective-C property reference, use
107                  // getPropertyRefExpr
108  } LVType;
109
110  llvm::Value *V;
111
112  union {
113    // Index into a vector subscript: V[i]
114    llvm::Value *VectorIdx;
115
116    // ExtVector element subset: V.xyx
117    llvm::Constant *VectorElts;
118
119    // BitField start bit and size
120    struct {
121      unsigned short StartBit;
122      unsigned short Size;
123      bool IsSigned;
124    } BitfieldData;
125
126    // Obj-C property reference expression
127    const ObjCPropertyRefExpr *PropertyRefExpr;
128  };
129
130  bool Volatile:1;
131  // FIXME: set but never used, what effect should it have?
132  bool Restrict:1;
133
134  bool ObjcWeak:1;
135  bool ObjcStrong:1;
136
137private:
138  static void SetQualifiers(unsigned Qualifiers, LValue& R) {
139    R.Volatile = (Qualifiers&QualType::Volatile)!=0;
140    R.Restrict = (Qualifiers&QualType::Restrict)!=0;
141    // FIXME: Convenient place to set objc flags to 0. This
142    // should really be done in a user-defined constructor instead.
143    R.ObjcWeak = 0;
144    R.ObjcStrong = 0;
145  }
146
147public:
148  bool isSimple() const { return LVType == Simple; }
149  bool isVectorElt() const { return LVType == VectorElt; }
150  bool isBitfield() const { return LVType == BitField; }
151  bool isExtVectorElt() const { return LVType == ExtVectorElt; }
152  bool isPropertyRef() const { return LVType == PropertyRef; }
153
154  bool isVolatileQualified() const { return Volatile; }
155  bool isRestrictQualified() const { return Restrict; }
156
157  bool isObjcWeak() const { return ObjcWeak; }
158  bool isObjcStrong() const { return ObjcStrong; }
159
160  static void SetObjCGCAttrs(unsigned Weak, unsigned Strong, LValue& R) {
161    R.ObjcWeak = Weak;
162    R.ObjcStrong = Strong;
163  }
164
165  // simple lvalue
166  llvm::Value *getAddress() const { assert(isSimple()); return V; }
167  // vector elt lvalue
168  llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
169  llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
170  // extended vector elements.
171  llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
172  llvm::Constant *getExtVectorElts() const {
173    assert(isExtVectorElt());
174    return VectorElts;
175  }
176  // bitfield lvalue
177  llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
178  unsigned short getBitfieldStartBit() const {
179    assert(isBitfield());
180    return BitfieldData.StartBit;
181  }
182  unsigned short getBitfieldSize() const {
183    assert(isBitfield());
184    return BitfieldData.Size;
185  }
186  bool isBitfieldSigned() const {
187    assert(isBitfield());
188    return BitfieldData.IsSigned;
189  }
190  // property ref lvalue
191  const ObjCPropertyRefExpr *getPropertyRefExpr() const {
192    assert(isPropertyRef());
193    return PropertyRefExpr;
194  }
195
196  static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers) {
197    LValue R;
198    R.LVType = Simple;
199    R.V = V;
200    SetQualifiers(Qualifiers,R);
201    return R;
202  }
203
204  static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
205                              unsigned Qualifiers) {
206    LValue R;
207    R.LVType = VectorElt;
208    R.V = Vec;
209    R.VectorIdx = Idx;
210    SetQualifiers(Qualifiers,R);
211    return R;
212  }
213
214  static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
215                                 unsigned Qualifiers) {
216    LValue R;
217    R.LVType = ExtVectorElt;
218    R.V = Vec;
219    R.VectorElts = Elts;
220    SetQualifiers(Qualifiers,R);
221    return R;
222  }
223
224  static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
225                             unsigned short Size, bool IsSigned,
226                             unsigned Qualifiers) {
227    LValue R;
228    R.LVType = BitField;
229    R.V = V;
230    R.BitfieldData.StartBit = StartBit;
231    R.BitfieldData.Size = Size;
232    R.BitfieldData.IsSigned = IsSigned;
233    SetQualifiers(Qualifiers,R);
234    return R;
235  }
236
237  // FIXME: It is probably bad that we aren't emitting the target when
238  // we build the lvalue. However, this complicates the code a bit,
239  // and I haven't figured out how to make it go wrong yet.
240  static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
241                                unsigned Qualifiers) {
242    LValue R;
243    R.LVType = PropertyRef;
244    R.PropertyRefExpr = E;
245    SetQualifiers(Qualifiers,R);
246    return R;
247  }
248};
249
250}  // end namespace CodeGen
251}  // end namespace clang
252
253#endif
254