Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/include/clang/AST/APValue.h
Line
Count
Source
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 "clang/Basic/LLVM.h"
18
#include "llvm/ADT/APFloat.h"
19
#include "llvm/ADT/APSInt.h"
20
#include "llvm/ADT/PointerIntPair.h"
21
#include "llvm/ADT/PointerUnion.h"
22
23
namespace clang {
24
  class AddrLabelExpr;
25
  class ASTContext;
26
  class CharUnits;
27
  class DiagnosticBuilder;
28
  class Expr;
29
  class FieldDecl;
30
  class Decl;
31
  class ValueDecl;
32
  class CXXRecordDecl;
33
  class QualType;
34
35
/// APValue - This class implements a discriminated union of [uninitialized]
36
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
37
/// [Vector: N * APValue], [Array: N * APValue]
38
class APValue {
39
  typedef llvm::APSInt APSInt;
40
  typedef llvm::APFloat APFloat;
41
public:
42
  enum ValueKind {
43
    Uninitialized,
44
    Int,
45
    Float,
46
    ComplexInt,
47
    ComplexFloat,
48
    LValue,
49
    Vector,
50
    Array,
51
    Struct,
52
    Union,
53
    MemberPointer,
54
    AddrLabelDiff
55
  };
56
  typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
57
  typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
58
  union LValuePathEntry {
59
    /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
60
    /// in the path. An opaque value of type BaseOrMemberType.
61
    void *BaseOrMember;
62
    /// ArrayIndex - The array index of the next item in the path.
63
    uint64_t ArrayIndex;
64
  };
65
  struct NoLValuePath {};
66
  struct UninitArray {};
67
  struct UninitStruct {};
68
private:
69
  ValueKind Kind;
70
71
  struct ComplexAPSInt {
72
    APSInt Real, Imag;
73
44
    ComplexAPSInt() : Real(1), Imag(1) {}
74
  };
75
  struct ComplexAPFloat {
76
    APFloat Real, Imag;
77
135
    ComplexAPFloat() : Real(0.0), Imag(0.0) {}
78
  };
79
  struct LV;
80
  struct Vec {
81
    APValue *Elts;
82
    unsigned NumElts;
83
1.64k
    Vec() : Elts(nullptr), NumElts(0) {}
84
1.64k
    ~Vec() { delete[] Elts; }
85
  };
86
  struct Arr {
87
    APValue *Elts;
88
    unsigned NumElts, ArrSize;
89
    Arr(unsigned NumElts, unsigned ArrSize);
90
    ~Arr();
91
  };
92
  struct StructData {
93
    APValue *Elts;
94
    unsigned NumBases;
95
    unsigned NumFields;
96
    StructData(unsigned NumBases, unsigned NumFields);
97
    ~StructData();
98
  };
99
  struct UnionData {
100
    const FieldDecl *Field;
101
    APValue *Value;
102
    UnionData();
103
    ~UnionData();
104
  };
105
  struct AddrLabelDiffData {
106
    const AddrLabelExpr* LHSExpr;
107
    const AddrLabelExpr* RHSExpr;
108
  };
109
  struct MemberPointerData;
110
111
  // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
112
  typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
113
                                      ComplexAPFloat, Vec, Arr, StructData,
114
                                      UnionData, AddrLabelDiffData> DataType;
115
  static const size_t DataSize = sizeof(DataType);
116
117
  DataType Data;
118
119
public:
120
31.7M
  APValue() : Kind(Uninitialized) {}
121
12.7M
  explicit APValue(APSInt I) : Kind(Uninitialized) {
122
12.7M
    MakeInt(); setInt(std::move(I));
123
12.7M
  }
124
154k
  explicit APValue(APFloat F) : Kind(Uninitialized) {
125
154k
    MakeFloat(); setFloat(std::move(F));
126
154k
  }
127
1.26k
  explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
128
1.26k
    MakeVector(); setVector(E, N);
129
1.26k
  }
130
43
  APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
131
43
    MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
132
43
  }
133
125
  APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
134
125
    MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
135
125
  }
136
  APValue(const APValue &RHS);
137
38.8k
  APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
138
  APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
139
          bool IsNullPtr = false)
140
26.0k
      : Kind(Uninitialized) {
141
26.0k
    MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
142
26.0k
  }
143
  APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
144
          bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
145
933k
      : Kind(Uninitialized) {
146
933k
    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
147
933k
  }
148
3.41k
  APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
149
3.41k
    MakeArray(InitElts, Size);
150
3.41k
  }
151
6.34k
  APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
152
6.34k
    MakeStruct(B, M);
153
6.34k
  }
154
  explicit APValue(const FieldDecl *D, const APValue &V = APValue())
155
705
      : Kind(Uninitialized) {
156
705
    MakeUnion(); setUnion(D, V);
157
705
  }
158
  APValue(const ValueDecl *Member, bool IsDerivedMember,
159
1.26k
          ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
160
1.26k
    MakeMemberPointer(Member, IsDerivedMember, Path);
161
1.26k
  }
162
  APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
163
28
      : Kind(Uninitialized) {
164
28
    MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
165
28
  }
166
167
45.9M
  ~APValue() {
168
45.9M
    MakeUninit();
169
45.9M
  }
170
171
  /// \brief Returns whether the object performed allocations.
172
  ///
173
  /// If APValues are constructed via placement new, \c needsCleanup()
174
  /// indicates whether the destructor must be called in order to correctly
175
  /// free all allocated memory.
176
  bool needsCleanup() const;
177
178
  /// \brief Swaps the contents of this and the given APValue.
179
  void swap(APValue &RHS);
180
181
2.15M
  ValueKind getKind() const { return Kind; }
182
3.44M
  bool isUninit() const { return Kind == Uninitialized; }
183
8.70M
  bool isInt() const { return Kind == Int; }
184
25.4k
  bool isFloat() const { return Kind == Float; }
185
28
  bool isComplexInt() const { return Kind == ComplexInt; }
186
3
  bool isComplexFloat() const { return Kind == ComplexFloat; }
187
4.99M
  bool isLValue() const { return Kind == LValue; }
188
68
  bool isVector() const { return Kind == Vector; }
189
2.92M
  bool isArray() const { return Kind == Array; }
190
2.92M
  bool isStruct() const { return Kind == Struct; }
191
2.92M
  bool isUnion() const { return Kind == Union; }
192
2.76M
  bool isMemberPointer() const { return Kind == MemberPointer; }
193
232k
  bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
194
195
  void dump() const;
196
  void dump(raw_ostream &OS) const;
197
198
  void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
199
  std::string getAsString(ASTContext &Ctx, QualType Ty) const;
200
201
15.4M
  APSInt &getInt() {
202
15.4M
    assert(isInt() && "Invalid accessor");
203
15.4M
    return *(APSInt*)(char*)Data.buffer;
204
15.4M
  }
205
3.94M
  const APSInt &getInt() const {
206
3.94M
    return const_cast<APValue*>(this)->getInt();
207
3.94M
  }
208
209
91.9k
  APFloat &getFloat() {
210
91.9k
    assert(isFloat() && "Invalid accessor");
211
91.9k
    return *(APFloat*)(char*)Data.buffer;
212
91.9k
  }
213
89.9k
  const APFloat &getFloat() const {
214
89.9k
    return const_cast<APValue*>(this)->getFloat();
215
89.9k
  }
216
217
29
  APSInt &getComplexIntReal() {
218
29
    assert(isComplexInt() && "Invalid accessor");
219
29
    return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
220
29
  }
221
20
  const APSInt &getComplexIntReal() const {
222
20
    return const_cast<APValue*>(this)->getComplexIntReal();
223
20
  }
224
225
20
  APSInt &getComplexIntImag() {
226
20
    assert(isComplexInt() && "Invalid accessor");
227
20
    return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
228
20
  }
229
11
  const APSInt &getComplexIntImag() const {
230
11
    return const_cast<APValue*>(this)->getComplexIntImag();
231
11
  }
232
233
84
  APFloat &getComplexFloatReal() {
234
84
    assert(isComplexFloat() && "Invalid accessor");
235
84
    return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
236
84
  }
237
80
  const APFloat &getComplexFloatReal() const {
238
80
    return const_cast<APValue*>(this)->getComplexFloatReal();
239
80
  }
240
241
59
  APFloat &getComplexFloatImag() {
242
59
    assert(isComplexFloat() && "Invalid accessor");
243
59
    return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
244
59
  }
245
55
  const APFloat &getComplexFloatImag() const {
246
55
    return const_cast<APValue*>(this)->getComplexFloatImag();
247
55
  }
248
249
  const LValueBase getLValueBase() const;
250
  CharUnits &getLValueOffset();
251
818k
  const CharUnits &getLValueOffset() const {
252
818k
    return const_cast<APValue*>(this)->getLValueOffset();
253
818k
  }
254
  bool isLValueOnePastTheEnd() const;
255
  bool hasLValuePath() const;
256
  ArrayRef<LValuePathEntry> getLValuePath() const;
257
  unsigned getLValueCallIndex() const;
258
  bool isNullPointer() const;
259
260
5.53k
  APValue &getVectorElt(unsigned I) {
261
5.53k
    assert(isVector() && "Invalid accessor");
262
5.53k
    assert(I < getVectorLength() && "Index out of range");
263
5.53k
    return ((Vec*)(char*)Data.buffer)->Elts[I];
264
5.53k
  }
265
5.03k
  const APValue &getVectorElt(unsigned I) const {
266
5.03k
    return const_cast<APValue*>(this)->getVectorElt(I);
267
5.03k
  }
268
1.67k
  unsigned getVectorLength() const {
269
1.67k
    assert(isVector() && "Invalid accessor");
270
1.67k
    return ((const Vec*)(const void *)Data.buffer)->NumElts;
271
1.67k
  }
272
273
20.4k
  APValue &getArrayInitializedElt(unsigned I) {
274
20.4k
    assert(isArray() && "Invalid accessor");
275
20.4k
    assert(I < getArrayInitializedElts() && "Index out of range");
276
20.4k
    return ((Arr*)(char*)Data.buffer)->Elts[I];
277
20.4k
  }
278
4.05k
  const APValue &getArrayInitializedElt(unsigned I) const {
279
4.05k
    return const_cast<APValue*>(this)->getArrayInitializedElt(I);
280
4.05k
  }
281
7.50k
  bool hasArrayFiller() const {
282
7.50k
    return getArrayInitializedElts() != getArraySize();
283
7.50k
  }
284
11.6k
  APValue &getArrayFiller() {
285
11.6k
    assert(isArray() && "Invalid accessor");
286
11.6k
    assert(hasArrayFiller() && "No array filler");
287
11.6k
    return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
288
11.6k
  }
289
1.68k
  const APValue &getArrayFiller() const {
290
1.68k
    return const_cast<APValue*>(this)->getArrayFiller();
291
1.68k
  }
292
26.9k
  unsigned getArrayInitializedElts() const {
293
26.9k
    assert(isArray() && "Invalid accessor");
294
26.9k
    return ((const Arr*)(const void *)Data.buffer)->NumElts;
295
26.9k
  }
296
8.80k
  unsigned getArraySize() const {
297
8.80k
    assert(isArray() && "Invalid accessor");
298
8.80k
    return ((const Arr*)(const void *)Data.buffer)->ArrSize;
299
8.80k
  }
300
301
35.7k
  unsigned getStructNumBases() const {
302
35.7k
    assert(isStruct() && "Invalid accessor");
303
35.7k
    return ((const StructData*)(const char*)Data.buffer)->NumBases;
304
35.7k
  }
305
5.13k
  unsigned getStructNumFields() const {
306
5.13k
    assert(isStruct() && "Invalid accessor");
307
5.13k
    return ((const StructData*)(const char*)Data.buffer)->NumFields;
308
5.13k
  }
309
1.81k
  APValue &getStructBase(unsigned i) {
310
1.81k
    assert(isStruct() && "Invalid accessor");
311
1.81k
    return ((StructData*)(char*)Data.buffer)->Elts[i];
312
1.81k
  }
313
30.6k
  APValue &getStructField(unsigned i) {
314
30.6k
    assert(isStruct() && "Invalid accessor");
315
30.6k
    return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
316
30.6k
  }
317
422
  const APValue &getStructBase(unsigned i) const {
318
422
    return const_cast<APValue*>(this)->getStructBase(i);
319
422
  }
320
6.06k
  const APValue &getStructField(unsigned i) const {
321
6.06k
    return const_cast<APValue*>(this)->getStructField(i);
322
6.06k
  }
323
324
586
  const FieldDecl *getUnionField() const {
325
586
    assert(isUnion() && "Invalid accessor");
326
586
    return ((const UnionData*)(const char*)Data.buffer)->Field;
327
586
  }
328
959
  APValue &getUnionValue() {
329
959
    assert(isUnion() && "Invalid accessor");
330
959
    return *((UnionData*)(char*)Data.buffer)->Value;
331
959
  }
332
125
  const APValue &getUnionValue() const {
333
125
    return const_cast<APValue*>(this)->getUnionValue();
334
125
  }
335
336
  const ValueDecl *getMemberPointerDecl() const;
337
  bool isMemberPointerToDerivedMember() const;
338
  ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
339
340
17
  const AddrLabelExpr* getAddrLabelDiffLHS() const {
341
17
    assert(isAddrLabelDiff() && "Invalid accessor");
342
17
    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
343
17
  }
344
17
  const AddrLabelExpr* getAddrLabelDiffRHS() const {
345
17
    assert(isAddrLabelDiff() && "Invalid accessor");
346
17
    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
347
17
  }
348
349
13.0M
  void setInt(APSInt I) {
350
13.0M
    assert(isInt() && "Invalid accessor");
351
13.0M
    *(APSInt *)(char *)Data.buffer = std::move(I);
352
13.0M
  }
353
158k
  void setFloat(APFloat F) {
354
158k
    assert(isFloat() && "Invalid accessor");
355
158k
    *(APFloat *)(char *)Data.buffer = std::move(F);
356
158k
  }
357
1.64k
  void setVector(const APValue *E, unsigned N) {
358
1.64k
    assert(isVector() && "Invalid accessor");
359
1.64k
    ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
360
1.64k
    ((Vec*)(char*)Data.buffer)->NumElts = N;
361
11.2k
    for (unsigned i = 0; 
i != N11.2k
;
++i9.56k
)
362
9.56k
      ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
363
1.64k
  }
364
44
  void setComplexInt(APSInt R, APSInt I) {
365
44
    assert(R.getBitWidth() == I.getBitWidth() &&
366
44
           "Invalid complex int (type mismatch).");
367
44
    assert(isComplexInt() && "Invalid accessor");
368
44
    ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
369
44
    ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
370
44
  }
371
135
  void setComplexFloat(APFloat R, APFloat I) {
372
135
    assert(&R.getSemantics() == &I.getSemantics() &&
373
135
           "Invalid complex float (type mismatch).");
374
135
    assert(isComplexFloat() && "Invalid accessor");
375
135
    ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
376
135
    ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
377
135
  }
378
  void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
379
                 unsigned CallIndex, bool IsNullPtr);
380
  void setLValue(LValueBase B, const CharUnits &O,
381
                 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
382
                 unsigned CallIndex, bool IsNullPtr);
383
721
  void setUnion(const FieldDecl *Field, const APValue &Value) {
384
721
    assert(isUnion() && "Invalid accessor");
385
721
    ((UnionData*)(char*)Data.buffer)->Field = Field;
386
721
    *((UnionData*)(char*)Data.buffer)->Value = Value;
387
721
  }
388
  void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
389
39
                        const AddrLabelExpr* RHSExpr) {
390
39
    ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
391
39
    ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
392
39
  }
393
394
  /// Assign by swapping from a copy of the RHS.
395
16.3M
  APValue &operator=(APValue RHS) {
396
16.3M
    swap(RHS);
397
16.3M
    return *this;
398
16.3M
  }
399
400
private:
401
  void DestroyDataAndMakeUninit();
402
45.9M
  void MakeUninit() {
403
45.9M
    if (Kind != Uninitialized)
404
14.1M
      DestroyDataAndMakeUninit();
405
45.9M
  }
406
13.0M
  void MakeInt() {
407
13.0M
    assert(isUninit() && "Bad state change");
408
13.0M
    new ((void*)Data.buffer) APSInt(1);
409
13.0M
    Kind = Int;
410
13.0M
  }
411
158k
  void MakeFloat() {
412
158k
    assert(isUninit() && "Bad state change");
413
158k
    new ((void*)(char*)Data.buffer) APFloat(0.0);
414
158k
    Kind = Float;
415
158k
  }
416
1.64k
  void MakeVector() {
417
1.64k
    assert(isUninit() && "Bad state change");
418
1.64k
    new ((void*)(char*)Data.buffer) Vec();
419
1.64k
    Kind = Vector;
420
1.64k
  }
421
44
  void MakeComplexInt() {
422
44
    assert(isUninit() && "Bad state change");
423
44
    new ((void*)(char*)Data.buffer) ComplexAPSInt();
424
44
    Kind = ComplexInt;
425
44
  }
426
135
  void MakeComplexFloat() {
427
135
    assert(isUninit() && "Bad state change");
428
135
    new ((void*)(char*)Data.buffer) ComplexAPFloat();
429
135
    Kind = ComplexFloat;
430
135
  }
431
  void MakeLValue();
432
  void MakeArray(unsigned InitElts, unsigned Size);
433
8.90k
  void MakeStruct(unsigned B, unsigned M) {
434
8.90k
    assert(isUninit() && "Bad state change");
435
8.90k
    new ((void*)(char*)Data.buffer) StructData(B, M);
436
8.90k
    Kind = Struct;
437
8.90k
  }
438
721
  void MakeUnion() {
439
721
    assert(isUninit() && "Bad state change");
440
721
    new ((void*)(char*)Data.buffer) UnionData();
441
721
    Kind = Union;
442
721
  }
443
  void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
444
                         ArrayRef<const CXXRecordDecl*> Path);
445
39
  void MakeAddrLabelDiff() {
446
39
    assert(isUninit() && "Bad state change");
447
39
    new ((void*)(char*)Data.buffer) AddrLabelDiffData();
448
39
    Kind = AddrLabelDiff;
449
39
  }
450
};
451
452
} // end namespace clang.
453
454
#endif