1 //===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // These classes implement wrappers around llvm::Value in order to
11 // fully represent the range of values for C L- and R- values.
13 //===----------------------------------------------------------------------===//
15 #ifndef CLANG_CODEGEN_CGVALUE_H
16 #define CLANG_CODEGEN_CGVALUE_H
18 #include "clang/AST/Type.h"
26 class ObjCPropertyRefExpr
;
31 /// RValue - This trivial value class is used to represent the result of an
32 /// expression that is evaluated. It can be one of three things: either a
33 /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
34 /// address of an aggregate value in memory.
37 // TODO: Encode this into the low bit of pointer for more efficient
39 enum { Scalar
, Complex
, Aggregate
} Flavor
;
44 bool isScalar() const { return Flavor
== Scalar
; }
45 bool isComplex() const { return Flavor
== Complex
; }
46 bool isAggregate() const { return Flavor
== Aggregate
; }
48 bool isVolatileQualified() const { return Volatile
; }
50 /// getScalar() - Return the Value* of this scalar value.
51 llvm::Value
*getScalarVal() const {
52 assert(isScalar() && "Not a scalar!");
56 /// getComplexVal - Return the real/imag components of this complex value.
58 std::pair
<llvm::Value
*, llvm::Value
*> getComplexVal() const {
59 return std::pair
<llvm::Value
*, llvm::Value
*>(V1
, V2
);
62 /// getAggregateAddr() - Return the Value* of the address of the aggregate.
63 llvm::Value
*getAggregateAddr() const {
64 assert(isAggregate() && "Not an aggregate!");
68 static RValue
get(llvm::Value
*V
) {
75 static RValue
getComplex(llvm::Value
*V1
, llvm::Value
*V2
) {
83 static RValue
getComplex(const std::pair
<llvm::Value
*, llvm::Value
*> &C
) {
91 // FIXME: Aggregate rvalues need to retain information about whether they are
92 // volatile or not. Remove default to find all places that probably get this
94 static RValue
getAggregate(llvm::Value
*V
, bool Vol
= false) {
97 ER
.Flavor
= Aggregate
;
104 /// LValue - This represents an lvalue references. Because C/C++ allow
105 /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
111 Simple
, // This is a normal l-value, use getAddress().
112 VectorElt
, // This is a vector element l-value (V[i]), use getVector*
113 BitField
, // This is a bitfield l-value, use getBitfield*.
114 ExtVectorElt
, // This is an extended vector subset, use getExtVectorComp
115 PropertyRef
, // This is an Objective-C property reference, use
116 // getPropertyRefExpr
117 KVCRef
// This is an objective-c 'implicit' property ref,
122 None
= 0, // object with no gc attribute.
123 Weak
, // __weak object expression
124 Strong
// __strong object expression
130 // Index into a vector subscript: V[i]
131 llvm::Value
*VectorIdx
;
133 // ExtVector element subset: V.xyx
134 llvm::Constant
*VectorElts
;
136 // BitField start bit and size
138 unsigned short StartBit
;
143 // Obj-C property reference expression
144 const ObjCPropertyRefExpr
*PropertyRefExpr
;
145 // ObjC 'implicit' property reference expression
146 const ObjCKVCRefExpr
*KVCRefExpr
;
150 // FIXME: set but never used, what effect should it have?
153 // objective-c's ivar
156 // LValue is non-gc'able for any reason, including being a parameter or local
160 // Lvalue is a global reference of an objective-c object
161 bool GlobalObjCRef
: 1;
163 // objective-c's gc attributes
164 unsigned ObjCType
: 2;
169 static void SetQualifiers(unsigned Qualifiers
, LValue
& R
) {
170 R
.Volatile
= (Qualifiers
&QualType::Volatile
)!=0;
171 R
.Restrict
= (Qualifiers
&QualType::Restrict
)!=0;
172 // FIXME: Convenient place to set objc flags to 0. This should really be
173 // done in a user-defined constructor instead.
175 R
.Ivar
= R
.NonGC
= R
.GlobalObjCRef
= false;
179 bool isSimple() const { return LVType
== Simple
; }
180 bool isVectorElt() const { return LVType
== VectorElt
; }
181 bool isBitfield() const { return LVType
== BitField
; }
182 bool isExtVectorElt() const { return LVType
== ExtVectorElt
; }
183 bool isPropertyRef() const { return LVType
== PropertyRef
; }
184 bool isKVCRef() const { return LVType
== KVCRef
; }
186 bool isVolatileQualified() const { return Volatile
; }
187 bool isRestrictQualified() const { return Restrict
; }
188 unsigned getQualifiers() const {
189 return (Volatile
? QualType::Volatile
: 0) |
190 (Restrict
? QualType::Restrict
: 0);
193 bool isObjCIvar() const { return Ivar
; }
194 bool isNonGC () const { return NonGC
; }
195 bool isGlobalObjCRef() const { return GlobalObjCRef
; }
196 bool isObjCWeak() const { return ObjCType
== Weak
; }
197 bool isObjCStrong() const { return ObjCType
== Strong
; }
199 static void SetObjCIvar(LValue
& R
, bool iValue
) {
203 static void SetGlobalObjCRef(LValue
& R
, bool iValue
) {
204 R
.GlobalObjCRef
= iValue
;
207 static void SetObjCNonGC(LValue
& R
, bool iValue
) {
210 static void SetObjCType(QualType::GCAttrTypes GCAttrs
, LValue
& R
) {
211 if (GCAttrs
== QualType::Weak
)
213 else if (GCAttrs
== QualType::Strong
)
220 llvm::Value
*getAddress() const { assert(isSimple()); return V
; }
222 llvm::Value
*getVectorAddr() const { assert(isVectorElt()); return V
; }
223 llvm::Value
*getVectorIdx() const { assert(isVectorElt()); return VectorIdx
; }
224 // extended vector elements.
225 llvm::Value
*getExtVectorAddr() const { assert(isExtVectorElt()); return V
; }
226 llvm::Constant
*getExtVectorElts() const {
227 assert(isExtVectorElt());
231 llvm::Value
*getBitfieldAddr() const { assert(isBitfield()); return V
; }
232 unsigned short getBitfieldStartBit() const {
233 assert(isBitfield());
234 return BitfieldData
.StartBit
;
236 unsigned short getBitfieldSize() const {
237 assert(isBitfield());
238 return BitfieldData
.Size
;
240 bool isBitfieldSigned() const {
241 assert(isBitfield());
242 return BitfieldData
.IsSigned
;
244 // property ref lvalue
245 const ObjCPropertyRefExpr
*getPropertyRefExpr() const {
246 assert(isPropertyRef());
247 return PropertyRefExpr
;
250 // 'implicit' property ref lvalue
251 const ObjCKVCRefExpr
*getKVCRefExpr() const {
256 static LValue
MakeAddr(llvm::Value
*V
, unsigned Qualifiers
,
257 QualType::GCAttrTypes GCAttrs
= QualType::GCNone
) {
261 SetQualifiers(Qualifiers
,R
);
262 SetObjCType(GCAttrs
, R
);
266 static LValue
MakeVectorElt(llvm::Value
*Vec
, llvm::Value
*Idx
,
267 unsigned Qualifiers
) {
269 R
.LVType
= VectorElt
;
272 SetQualifiers(Qualifiers
,R
);
276 static LValue
MakeExtVectorElt(llvm::Value
*Vec
, llvm::Constant
*Elts
,
277 unsigned Qualifiers
) {
279 R
.LVType
= ExtVectorElt
;
282 SetQualifiers(Qualifiers
,R
);
286 static LValue
MakeBitfield(llvm::Value
*V
, unsigned short StartBit
,
287 unsigned short Size
, bool IsSigned
,
288 unsigned Qualifiers
) {
292 R
.BitfieldData
.StartBit
= StartBit
;
293 R
.BitfieldData
.Size
= Size
;
294 R
.BitfieldData
.IsSigned
= IsSigned
;
295 SetQualifiers(Qualifiers
,R
);
299 // FIXME: It is probably bad that we aren't emitting the target when we build
300 // the lvalue. However, this complicates the code a bit, and I haven't figured
301 // out how to make it go wrong yet.
302 static LValue
MakePropertyRef(const ObjCPropertyRefExpr
*E
,
303 unsigned Qualifiers
) {
305 R
.LVType
= PropertyRef
;
306 R
.PropertyRefExpr
= E
;
307 SetQualifiers(Qualifiers
,R
);
311 static LValue
MakeKVCRef(const ObjCKVCRefExpr
*E
, unsigned Qualifiers
) {
315 SetQualifiers(Qualifiers
,R
);
320 } // end namespace CodeGen
321 } // end namespace clang