 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
52.6% |
30 / 57 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
96.5% |
55 / 57 |
| |
|
Line Coverage: |
97.7% |
127 / 130 |
| |
 |
|
 |
1 : //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- 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 file defines the APValue class.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_CLANG_AST_APVALUE_H
15 : #define LLVM_CLANG_AST_APVALUE_H
16 :
17 : #include "llvm/ADT/APSInt.h"
18 : #include "llvm/ADT/APFloat.h"
19 :
20 : namespace clang {
21 : class CharUnits;
22 : class Expr;
23 :
24 : /// APValue - This class implements a discriminated union of [uninitialized]
25 : /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset].
26 : class APValue {
27 : typedef llvm::APSInt APSInt;
28 : typedef llvm::APFloat APFloat;
29 : public:
30 : enum ValueKind {
31 : Uninitialized,
32 : Int,
33 : Float,
34 : ComplexInt,
35 : ComplexFloat,
36 : LValue,
37 : Vector
38 : };
39 : private:
40 : ValueKind Kind;
41 :
42 173: struct ComplexAPSInt {
43 : APSInt Real, Imag;
44 173: ComplexAPSInt() : Real(1), Imag(1) {}
45 : };
46 186: struct ComplexAPFloat {
47 : APFloat Real, Imag;
48 186: ComplexAPFloat() : Real(0.0), Imag(0.0) {}
49 : };
50 :
51 : struct Vec {
52 : APValue *Elts;
53 : unsigned NumElts;
54 24: Vec() : Elts(0), NumElts(0) {}
24: branch 0 taken
0: branch 1 not taken
96: branch 2 taken
24: branch 3 taken
55 24: ~Vec() { delete[] Elts; }
56 : };
57 :
58 : enum {
59 : MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
60 : sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
61 : };
62 :
63 : union {
64 : void *Aligner;
65 : char Data[MaxSize];
66 : };
67 :
68 : public:
69 35639: APValue() : Kind(Uninitialized) {}
70 25173: explicit APValue(const APSInt &I) : Kind(Uninitialized) {
71 25173: MakeInt(); setInt(I);
72 25173: }
73 424: explicit APValue(const APFloat &F) : Kind(Uninitialized) {
74 424: MakeFloat(); setFloat(F);
75 424: }
76 11: explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
77 11: MakeVector(); setVector(E, N);
78 11: }
79 54: APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
80 54: MakeComplexInt(); setComplexInt(R, I);
81 54: }
82 60: APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
83 60: MakeComplexFloat(); setComplexFloat(R, I);
84 60: }
85 1189: APValue(const APValue &RHS) : Kind(Uninitialized) {
86 1189: *this = RHS;
87 1189: }
88 243: APValue(Expr* B, const CharUnits &O) : Kind(Uninitialized) {
89 243: MakeLValue(); setLValue(B, O);
90 243: }
91 : APValue(Expr* B);
92 :
93 63331: ~APValue() {
94 63331: MakeUninit();
95 63331: }
96 :
97 500: ValueKind getKind() const { return Kind; }
98 52371: bool isUninit() const { return Kind == Uninitialized; }
99 199656: bool isInt() const { return Kind == Int; }
100 12105: bool isFloat() const { return Kind == Float; }
101 10256: bool isComplexInt() const { return Kind == ComplexInt; }
102 10756: bool isComplexFloat() const { return Kind == ComplexFloat; }
103 26538: bool isLValue() const { return Kind == LValue; }
104 9568: bool isVector() const { return Kind == Vector; }
105 :
106 : void print(llvm::raw_ostream &OS) const;
107 : void dump() const;
108 :
109 67748: APSInt &getInt() {
67748: branch 1 taken
0: branch 2 not taken
110 67748: assert(isInt() && "Invalid accessor");
111 67748: return *(APSInt*)(char*)Data;
112 : }
113 25530: const APSInt &getInt() const {
114 25530: return const_cast<APValue*>(this)->getInt();
115 : }
116 :
117 656: APFloat &getFloat() {
0: branch 2 not taken
118 656: assert(isFloat() && "Invalid accessor");
119 656: return *(APFloat*)(char*)Data;
120 : }
121 588: const APFloat &getFloat() const {
122 588: return const_cast<APValue*>(this)->getFloat();
123 : }
124 :
125 16: APValue &getVectorElt(unsigned i) const {
0: branch 2 not taken
0: branch 2 not taken
126 16: assert(isVector() && "Invalid accessor");
127 16: return ((Vec*)(char*)Data)->Elts[i];
128 : }
129 17: unsigned getVectorLength() const {
17: branch 1 taken
0: branch 2 not taken
130 17: assert(isVector() && "Invalid accessor");
131 17: return ((Vec*)(void *)Data)->NumElts;
132 : }
133 :
134 219: APSInt &getComplexIntReal() {
219: branch 1 taken
0: branch 2 not taken
135 219: assert(isComplexInt() && "Invalid accessor");
136 219: return ((ComplexAPSInt*)(char*)Data)->Real;
137 : }
138 119: const APSInt &getComplexIntReal() const {
139 119: return const_cast<APValue*>(this)->getComplexIntReal();
140 : }
141 :
142 214: APSInt &getComplexIntImag() {
214: branch 1 taken
0: branch 2 not taken
143 214: assert(isComplexInt() && "Invalid accessor");
144 214: return ((ComplexAPSInt*)(char*)Data)->Imag;
145 : }
146 119: const APSInt &getComplexIntImag() const {
147 119: return const_cast<APValue*>(this)->getComplexIntImag();
148 : }
149 :
150 312: APFloat &getComplexFloatReal() {
312: branch 1 taken
0: branch 2 not taken
151 312: assert(isComplexFloat() && "Invalid accessor");
152 312: return ((ComplexAPFloat*)(char*)Data)->Real;
153 : }
154 130: const APFloat &getComplexFloatReal() const {
155 130: return const_cast<APValue*>(this)->getComplexFloatReal();
156 : }
157 :
158 310: APFloat &getComplexFloatImag() {
310: branch 1 taken
0: branch 2 not taken
159 310: assert(isComplexFloat() && "Invalid accessor");
160 310: return ((ComplexAPFloat*)(char*)Data)->Imag;
161 : }
162 130: const APFloat &getComplexFloatImag() const {
163 130: return const_cast<APValue*>(this)->getComplexFloatImag();
164 : }
165 :
166 : Expr* getLValueBase() const;
167 : CharUnits getLValueOffset() const;
168 :
169 50703: void setInt(const APSInt &I) {
50703: branch 1 taken
0: branch 2 not taken
170 50703: assert(isInt() && "Invalid accessor");
171 50703: *(APSInt*)(char*)Data = I;
172 50703: }
173 884: void setFloat(const APFloat &F) {
884: branch 1 taken
0: branch 2 not taken
174 884: assert(isFloat() && "Invalid accessor");
175 884: *(APFloat*)(char*)Data = F;
176 884: }
177 24: void setVector(const APValue *E, unsigned N) {
24: branch 1 taken
0: branch 2 not taken
178 24: assert(isVector() && "Invalid accessor");
96: branch 2 taken
24: branch 3 taken
179 120: ((Vec*)(char*)Data)->Elts = new APValue[N];
180 24: ((Vec*)(char*)Data)->NumElts = N;
96: branch 0 taken
24: branch 1 taken
181 120: for (unsigned i = 0; i != N; ++i)
182 96: ((Vec*)(char*)Data)->Elts[i] = E[i];
183 24: }
184 173: void setComplexInt(const APSInt &R, const APSInt &I) {
185 : assert(R.getBitWidth() == I.getBitWidth() &&
173: branch 2 taken
0: branch 3 not taken
186 173: "Invalid complex int (type mismatch).");
173: branch 1 taken
0: branch 2 not taken
187 173: assert(isComplexInt() && "Invalid accessor");
188 173: ((ComplexAPSInt*)(char*)Data)->Real = R;
189 173: ((ComplexAPSInt*)(char*)Data)->Imag = I;
190 173: }
191 186: void setComplexFloat(const APFloat &R, const APFloat &I) {
192 : assert(&R.getSemantics() == &I.getSemantics() &&
186: branch 2 taken
0: branch 3 not taken
193 186: "Invalid complex float (type mismatch).");
186: branch 1 taken
0: branch 2 not taken
194 186: assert(isComplexFloat() && "Invalid accessor");
195 186: ((ComplexAPFloat*)(char*)Data)->Real = R;
196 186: ((ComplexAPFloat*)(char*)Data)->Imag = I;
197 186: }
198 : void setLValue(Expr *B, const CharUnits &O);
199 :
200 : const APValue &operator=(const APValue &RHS);
201 :
202 : private:
203 : void MakeUninit();
204 45916: void MakeInt() {
45916: branch 1 taken
0: branch 2 not taken
205 45916: assert(isUninit() && "Bad state change");
45916: branch 1 taken
0: branch 2 not taken
206 91832: new ((void*)Data) APSInt(1);
207 45916: Kind = Int;
208 45916: }
209 883: void MakeFloat() {
883: branch 1 taken
0: branch 2 not taken
210 883: assert(isUninit() && "Bad state change");
883: branch 1 taken
0: branch 2 not taken
211 1766: new ((void*)(char*)Data) APFloat(0.0);
212 883: Kind = Float;
213 883: }
214 24: void MakeVector() {
24: branch 1 taken
0: branch 2 not taken
215 24: assert(isUninit() && "Bad state change");
24: branch 1 taken
0: branch 2 not taken
216 48: new ((void*)(char*)Data) Vec();
217 24: Kind = Vector;
218 24: }
219 173: void MakeComplexInt() {
173: branch 1 taken
0: branch 2 not taken
220 173: assert(isUninit() && "Bad state change");
173: branch 1 taken
0: branch 2 not taken
221 346: new ((void*)(char*)Data) ComplexAPSInt();
222 173: Kind = ComplexInt;
223 173: }
224 186: void MakeComplexFloat() {
186: branch 1 taken
0: branch 2 not taken
225 186: assert(isUninit() && "Bad state change");
186: branch 1 taken
0: branch 2 not taken
226 372: new ((void*)(char*)Data) ComplexAPFloat();
227 186: Kind = ComplexFloat;
228 186: }
229 : void MakeLValue();
230 : };
231 :
232 0: inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) {
233 0: V.print(OS);
234 0: return OS;
235 : }
236 :
237 : } // end namespace clang.
238 :
239 : #endif
Generated: 2010-02-10 01:31 by zcov