Newer
Older
//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// These classes implement wrappers around llvm::Value in order to
// fully represent the range of values for C L- and R- values.
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_CODEGEN_CGVALUE_H
#define CLANG_CODEGEN_CGVALUE_H
#include "clang/AST/Type.h"
namespace llvm {
class Constant;
class Value;
}
class ObjCPropertyRefExpr;
class ObjCKVCRefExpr;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
namespace CodeGen {
/// RValue - This trivial value class is used to represent the result of an
/// expression that is evaluated. It can be one of three things: either a
/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
/// address of an aggregate value in memory.
class RValue {
llvm::Value *V1, *V2;
// TODO: Encode this into the low bit of pointer for more efficient
// return-by-value.
enum { Scalar, Complex, Aggregate } Flavor;
// FIXME: Aggregate rvalues need to retain information about whether they are
// volatile or not.
public:
bool isScalar() const { return Flavor == Scalar; }
bool isComplex() const { return Flavor == Complex; }
bool isAggregate() const { return Flavor == Aggregate; }
/// getScalar() - Return the Value* of this scalar value.
llvm::Value *getScalarVal() const {
assert(isScalar() && "Not a scalar!");
return V1;
}
/// getComplexVal - Return the real/imag components of this complex value.
///
std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
return std::pair<llvm::Value *, llvm::Value *>(V1, V2);
}
/// getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value *getAggregateAddr() const {
assert(isAggregate() && "Not an aggregate!");
return V1;
}
static RValue get(llvm::Value *V) {
RValue ER;
ER.V1 = V;
ER.Flavor = Scalar;
return ER;
}
static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
RValue ER;
ER.V1 = V1;
ER.V2 = V2;
ER.Flavor = Complex;
return ER;
}
static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
RValue ER;
ER.V1 = C.first;
ER.V2 = C.second;
ER.Flavor = Complex;
return ER;
}
static RValue getAggregate(llvm::Value *V) {
RValue ER;
ER.V1 = V;
ER.Flavor = Aggregate;
return ER;
}
};
/// LValue - This represents an lvalue references. Because C/C++ allow
/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
/// bitrange.
class LValue {
// FIXME: alignment?
enum {
Simple, // This is a normal l-value, use getAddress().
VectorElt, // This is a vector element l-value (V[i]), use getVector*
BitField, // This is a bitfield l-value, use getBitfield*.
ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
PropertyRef, // This is an Objective-C property reference, use
// getPropertyRefExpr
KVCRef // This is an objective-c 'implicit' property ref,
// use getKVCRefExpr
enum ObjCType {
None = 0, // object with no gc attribute.
Weak, // __weak object expression
Strong // __strong object expression
llvm::Value *V;
union {
// Index into a vector subscript: V[i]
llvm::Value *VectorIdx;
// ExtVector element subset: V.xyx
llvm::Constant *VectorElts;
// BitField start bit and size
struct {
unsigned short StartBit;
unsigned short Size;
bool IsSigned;
} BitfieldData;
// Obj-C property reference expression
const ObjCPropertyRefExpr *PropertyRefExpr;
// ObjC 'implicit' property reference expression
const ObjCKVCRefExpr *KVCRefExpr;
};
bool Volatile:1;
// FIXME: set but never used, what effect should it have?
bool Restrict:1;
// objective-c's ivar
bool Ivar:1;
// objective-c's gc attributes
unsigned ObjCType : 2;
private:
static void SetQualifiers(unsigned Qualifiers, LValue& R) {
R.Volatile = (Qualifiers&QualType::Volatile)!=0;
R.Restrict = (Qualifiers&QualType::Restrict)!=0;
// FIXME: Convenient place to set objc flags to 0. This
// should really be done in a user-defined constructor instead.
R.ObjCType = None;
public:
bool isSimple() const { return LVType == Simple; }
bool isVectorElt() const { return LVType == VectorElt; }
bool isBitfield() const { return LVType == BitField; }
bool isExtVectorElt() const { return LVType == ExtVectorElt; }
bool isPropertyRef() const { return LVType == PropertyRef; }
bool isKVCRef() const { return LVType == KVCRef; }
bool isVolatileQualified() const { return Volatile; }
bool isRestrictQualified() const { return Restrict; }
unsigned getQualifiers() const {
return (Volatile ? QualType::Volatile : 0) |
(Restrict ? QualType::Restrict : 0);
}
bool isObjCIvar() const { return Ivar; }
bool isObjCWeak() const { return ObjCType == Weak; }
bool isObjCStrong() const { return ObjCType == Strong; }
static void SetObjCIvar(LValue& R, bool iValue) {
R.Ivar = iValue;
static void SetObjCType(QualType::GCAttrTypes GCAttrs, LValue& R) {
if (GCAttrs == QualType::Weak)
R.ObjCType = Weak;
else if (GCAttrs == QualType::Strong)
R.ObjCType = Strong;
// simple lvalue
llvm::Value *getAddress() const { assert(isSimple()); return V; }
// vector elt lvalue
llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
// extended vector elements.
llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
llvm::Constant *getExtVectorElts() const {
assert(isExtVectorElt());
return VectorElts;
}
// bitfield lvalue
llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
unsigned short getBitfieldStartBit() const {
assert(isBitfield());
return BitfieldData.StartBit;
}
unsigned short getBitfieldSize() const {
assert(isBitfield());
return BitfieldData.Size;
}
bool isBitfieldSigned() const {
assert(isBitfield());
return BitfieldData.IsSigned;
}
// property ref lvalue
const ObjCPropertyRefExpr *getPropertyRefExpr() const {
assert(isPropertyRef());
return PropertyRefExpr;
}
// 'implicit' property ref lvalue
const ObjCKVCRefExpr *getKVCRefExpr() const {
assert(isKVCRef());
return KVCRefExpr;
}
static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers,
QualType::GCAttrTypes GCAttrs = QualType::GCNone) {
LValue R;
R.LVType = Simple;
R.V = V;
SetQualifiers(Qualifiers,R);
SetObjCType(GCAttrs, R);
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
return R;
}
static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
unsigned Qualifiers) {
LValue R;
R.LVType = VectorElt;
R.V = Vec;
R.VectorIdx = Idx;
SetQualifiers(Qualifiers,R);
return R;
}
static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
unsigned Qualifiers) {
LValue R;
R.LVType = ExtVectorElt;
R.V = Vec;
R.VectorElts = Elts;
SetQualifiers(Qualifiers,R);
return R;
}
static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
unsigned short Size, bool IsSigned,
unsigned Qualifiers) {
LValue R;
R.LVType = BitField;
R.V = V;
R.BitfieldData.StartBit = StartBit;
R.BitfieldData.Size = Size;
R.BitfieldData.IsSigned = IsSigned;
SetQualifiers(Qualifiers,R);
return R;
}
// FIXME: It is probably bad that we aren't emitting the target when
// we build the lvalue. However, this complicates the code a bit,
// and I haven't figured out how to make it go wrong yet.
static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
unsigned Qualifiers) {
LValue R;
R.LVType = PropertyRef;
R.PropertyRefExpr = E;
SetQualifiers(Qualifiers,R);
return R;
}
static LValue MakeKVCRef(const ObjCKVCRefExpr *E, unsigned Qualifiers) {
LValue R;
R.LVType = KVCRef;
R.KVCRefExpr = E;
SetQualifiers(Qualifiers,R);
return R;
}
};
} // end namespace CodeGen
} // end namespace clang
#endif