CGValue.h revision 46f45b9bec4a265ad8400a538e5ec3a5683617f1
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
134private:
135  static void SetQualifiers(unsigned Qualifiers, LValue& R) {
136    R.Volatile = (Qualifiers&QualType::Volatile)!=0;
137    R.Restrict = (Qualifiers&QualType::Restrict)!=0;
138  }
139
140public:
141  bool isSimple() const { return LVType == Simple; }
142  bool isVectorElt() const { return LVType == VectorElt; }
143  bool isBitfield() const { return LVType == BitField; }
144  bool isExtVectorElt() const { return LVType == ExtVectorElt; }
145  bool isPropertyRef() const { return LVType == PropertyRef; }
146
147  bool isVolatileQualified() const { return Volatile; }
148  bool isRestrictQualified() const { return Restrict; }
149
150  // simple lvalue
151  llvm::Value *getAddress() const { assert(isSimple()); return V; }
152  // vector elt lvalue
153  llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
154  llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
155  // extended vector elements.
156  llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
157  llvm::Constant *getExtVectorElts() const {
158    assert(isExtVectorElt());
159    return VectorElts;
160  }
161  // bitfield lvalue
162  llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
163  unsigned short getBitfieldStartBit() const {
164    assert(isBitfield());
165    return BitfieldData.StartBit;
166  }
167  unsigned short getBitfieldSize() const {
168    assert(isBitfield());
169    return BitfieldData.Size;
170  }
171  bool isBitfieldSigned() const {
172    assert(isBitfield());
173    return BitfieldData.IsSigned;
174  }
175  // property ref lvalue
176  const ObjCPropertyRefExpr *getPropertyRefExpr() const {
177    assert(isPropertyRef());
178    return PropertyRefExpr;
179  }
180
181  static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers) {
182    LValue R;
183    R.LVType = Simple;
184    R.V = V;
185    SetQualifiers(Qualifiers,R);
186    return R;
187  }
188
189  static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
190                              unsigned Qualifiers) {
191    LValue R;
192    R.LVType = VectorElt;
193    R.V = Vec;
194    R.VectorIdx = Idx;
195    SetQualifiers(Qualifiers,R);
196    return R;
197  }
198
199  static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
200                                 unsigned Qualifiers) {
201    LValue R;
202    R.LVType = ExtVectorElt;
203    R.V = Vec;
204    R.VectorElts = Elts;
205    SetQualifiers(Qualifiers,R);
206    return R;
207  }
208
209  static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
210                             unsigned short Size, bool IsSigned,
211                             unsigned Qualifiers) {
212    LValue R;
213    R.LVType = BitField;
214    R.V = V;
215    R.BitfieldData.StartBit = StartBit;
216    R.BitfieldData.Size = Size;
217    R.BitfieldData.IsSigned = IsSigned;
218    SetQualifiers(Qualifiers,R);
219    return R;
220  }
221
222  static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
223                                unsigned Qualifiers) {
224    LValue R;
225    R.LVType = PropertyRef;
226    R.PropertyRefExpr = E;
227    SetQualifiers(Qualifiers,R);
228    return R;
229  }
230};
231
232}  // end namespace CodeGen
233}  // end namespace clang
234
235#endif
236