Coverage Report

Created: 2020-09-19 12:23

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/APValue.h
Line
Count
Source (jump to first uncovered line)
1
//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file defines the APValue class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_CLANG_AST_APVALUE_H
14
#define LLVM_CLANG_AST_APVALUE_H
15
16
#include "clang/Basic/LLVM.h"
17
#include "llvm/ADT/APFixedPoint.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 CXXRecordDecl;
28
  class Decl;
29
  class DiagnosticBuilder;
30
  class Expr;
31
  class FieldDecl;
32
  struct PrintingPolicy;
33
  class Type;
34
  class ValueDecl;
35
  class QualType;
36
37
/// Symbolic representation of typeid(T) for some type T.
38
class TypeInfoLValue {
39
  const Type *T;
40
41
public:
42
5.07k
  TypeInfoLValue() : T() {}
43
  explicit TypeInfoLValue(const Type *T);
44
45
187
  const Type *getType() const { return T; }
46
4.37k
  explicit operator bool() const { return T; }
47
48
681
  void *getOpaqueValue() { return const_cast<Type*>(T); }
49
187
  static TypeInfoLValue getFromOpaqueValue(void *Value) {
50
187
    TypeInfoLValue V;
51
187
    V.T = reinterpret_cast<const Type*>(Value);
52
187
    return V;
53
187
  }
54
55
  void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
56
};
57
58
/// Symbolic representation of a dynamic allocation.
59
class DynamicAllocLValue {
60
  unsigned Index;
61
62
public:
63
37.4k
  DynamicAllocLValue() : Index(0) {}
64
623
  explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
65
18.6k
  unsigned getIndex() { return Index - 1; }
66
67
37.3k
  explicit operator bool() const { return Index != 0; }
68
69
623
  void *getOpaqueValue() {
70
623
    return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
71
623
                                    << NumLowBitsAvailable);
72
623
  }
73
2.71k
  static DynamicAllocLValue getFromOpaqueValue(void *Value) {
74
2.71k
    DynamicAllocLValue V;
75
2.71k
    V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
76
2.71k
    return V;
77
2.71k
  }
78
79
623
  static unsigned getMaxIndex() {
80
623
    return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
81
623
  }
82
83
  static constexpr int NumLowBitsAvailable = 3;
84
};
85
}
86
87
namespace llvm {
88
template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
89
681
  static void *getAsVoidPointer(clang::TypeInfoLValue V) {
90
681
    return V.getOpaqueValue();
91
681
  }
92
187
  static clang::TypeInfoLValue getFromVoidPointer(void *P) {
93
187
    return clang::TypeInfoLValue::getFromOpaqueValue(P);
94
187
  }
95
  // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
96
  // to include Type.h.
97
  static constexpr int NumLowBitsAvailable = 3;
98
};
99
100
template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
101
623
  static void *getAsVoidPointer(clang::DynamicAllocLValue V) {
102
623
    return V.getOpaqueValue();
103
623
  }
104
2.71k
  static clang::DynamicAllocLValue getFromVoidPointer(void *P) {
105
2.71k
    return clang::DynamicAllocLValue::getFromOpaqueValue(P);
106
2.71k
  }
107
  static constexpr int NumLowBitsAvailable =
108
      clang::DynamicAllocLValue::NumLowBitsAvailable;
109
};
110
}
111
112
namespace clang {
113
/// APValue - This class implements a discriminated union of [uninitialized]
114
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
115
/// [Vector: N * APValue], [Array: N * APValue]
116
class APValue {
117
  typedef llvm::APFixedPoint APFixedPoint;
118
  typedef llvm::APSInt APSInt;
119
  typedef llvm::APFloat APFloat;
120
public:
121
  enum ValueKind {
122
    /// There is no such object (it's outside its lifetime).
123
    None,
124
    /// This object has an indeterminate value (C++ [basic.indet]).
125
    Indeterminate,
126
    Int,
127
    Float,
128
    FixedPoint,
129
    ComplexInt,
130
    ComplexFloat,
131
    LValue,
132
    Vector,
133
    Array,
134
    Struct,
135
    Union,
136
    MemberPointer,
137
    AddrLabelDiff
138
  };
139
140
  class LValueBase {
141
    typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
142
                               DynamicAllocLValue>
143
        PtrTy;
144
145
  public:
146
16.2M
    LValueBase() : Local{} {}
147
    LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
148
    LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
149
    static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
150
    static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
151
152
    template <class T>
153
19.9M
    bool is() const { return Ptr.is<T>(); }
bool clang::APValue::LValueBase::is<clang::TypeInfoLValue>() const
Line
Count
Source
153
9.95M
    bool is() const { return Ptr.is<T>(); }
bool clang::APValue::LValueBase::is<clang::DynamicAllocLValue>() const
Line
Count
Source
153
9.98M
    bool is() const { return Ptr.is<T>(); }
bool clang::APValue::LValueBase::is<clang::ValueDecl const*>() const
Line
Count
Source
153
13
    bool is() const { return Ptr.is<T>(); }
154
155
    template <class T>
156
206k
    T get() const { return Ptr.get<T>(); }
clang::Expr const* clang::APValue::LValueBase::get<clang::Expr const*>() const
Line
Count
Source
156
206k
    T get() const { return Ptr.get<T>(); }
clang::DynamicAllocLValue clang::APValue::LValueBase::get<clang::DynamicAllocLValue>() const
Line
Count
Source
156
9
    T get() const { return Ptr.get<T>(); }
157
158
    template <class T>
159
37.0M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::ValueDecl const* clang::APValue::LValueBase::dyn_cast<clang::ValueDecl const*>() const
Line
Count
Source
159
24.3M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::TypeInfoLValue clang::APValue::LValueBase::dyn_cast<clang::TypeInfoLValue>() const
Line
Count
Source
159
4.37k
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::DynamicAllocLValue clang::APValue::LValueBase::dyn_cast<clang::DynamicAllocLValue>() const
Line
Count
Source
159
37.4k
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
clang::Expr const* clang::APValue::LValueBase::dyn_cast<clang::Expr const*>() const
Line
Count
Source
159
12.6M
    T dyn_cast() const { return Ptr.dyn_cast<T>(); }
160
161
    void *getOpaqueValue() const;
162
163
    bool isNull() const;
164
165
    explicit operator bool() const;
166
167
    unsigned getCallIndex() const;
168
    unsigned getVersion() const;
169
    QualType getTypeInfoType() const;
170
    QualType getDynamicAllocType() const;
171
172
    friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
173
0
    friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
174
0
      return !(LHS == RHS);
175
0
    }
176
    friend llvm::hash_code hash_value(const LValueBase &Base);
177
    friend struct llvm::DenseMapInfo<LValueBase>;
178
179
  private:
180
    PtrTy Ptr;
181
    struct LocalState {
182
      unsigned CallIndex, Version;
183
    };
184
    union {
185
      LocalState Local;
186
      /// The type std::type_info, if this is a TypeInfoLValue.
187
      void *TypeInfoType;
188
      /// The QualType, if this is a DynamicAllocLValue.
189
      void *DynamicAllocType;
190
    };
191
  };
192
193
  /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
194
  /// mean a virtual or non-virtual base class subobject.
195
  typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
196
197
  /// A non-discriminated union of a base, field, or array index.
198
  class LValuePathEntry {
199
    static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
200
                  "pointer doesn't fit in 64 bits?");
201
    uint64_t Value;
202
203
  public:
204
142k
    LValuePathEntry() : Value() {}
205
    LValuePathEntry(BaseOrMemberType BaseOrMember);
206
142k
    static LValuePathEntry ArrayIndex(uint64_t Index) {
207
142k
      LValuePathEntry Result;
208
142k
      Result.Value = Index;
209
142k
      return Result;
210
142k
    }
211
212
39.3k
    BaseOrMemberType getAsBaseOrMember() const {
213
39.3k
      return BaseOrMemberType::getFromOpaqueValue(
214
39.3k
          reinterpret_cast<void *>(Value));
215
39.3k
    }
216
147k
    uint64_t getAsArrayIndex() const { return Value; }
217
218
10.7k
    friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
219
10.7k
      return A.Value == B.Value;
220
10.7k
    }
221
0
    friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
222
0
      return A.Value != B.Value;
223
0
    }
224
18.1k
    friend llvm::hash_code hash_value(LValuePathEntry A) {
225
18.1k
      return llvm::hash_value(A.Value);
226
18.1k
    }
227
  };
228
  struct NoLValuePath {};
229
  struct UninitArray {};
230
  struct UninitStruct {};
231
232
  friend class ASTReader;
233
  friend class ASTWriter;
234
235
private:
236
  ValueKind Kind;
237
238
  struct ComplexAPSInt {
239
    APSInt Real, Imag;
240
188
    ComplexAPSInt() : Real(1), Imag(1) {}
241
  };
242
  struct ComplexAPFloat {
243
    APFloat Real, Imag;
244
289
    ComplexAPFloat() : Real(0.0), Imag(0.0) {}
245
  };
246
  struct LV;
247
  struct Vec {
248
    APValue *Elts;
249
    unsigned NumElts;
250
6.05k
    Vec() : Elts(nullptr), NumElts(0) {}
251
5.85k
    ~Vec() { delete[] Elts; }
252
  };
253
  struct Arr {
254
    APValue *Elts;
255
    unsigned NumElts, ArrSize;
256
    Arr(unsigned NumElts, unsigned ArrSize);
257
    ~Arr();
258
  };
259
  struct StructData {
260
    APValue *Elts;
261
    unsigned NumBases;
262
    unsigned NumFields;
263
    StructData(unsigned NumBases, unsigned NumFields);
264
    ~StructData();
265
  };
266
  struct UnionData {
267
    const FieldDecl *Field;
268
    APValue *Value;
269
    UnionData();
270
    ~UnionData();
271
  };
272
  struct AddrLabelDiffData {
273
    const AddrLabelExpr* LHSExpr;
274
    const AddrLabelExpr* RHSExpr;
275
  };
276
  struct MemberPointerData;
277
278
  // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
279
  typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
280
                                      ComplexAPFloat, Vec, Arr, StructData,
281
                                      UnionData, AddrLabelDiffData> DataType;
282
  static const size_t DataSize = sizeof(DataType);
283
284
  DataType Data;
285
286
public:
287
62.9M
  APValue() : Kind(None) {}
288
27.8M
  explicit APValue(APSInt I) : Kind(None) {
289
27.8M
    MakeInt(); setInt(std::move(I));
290
27.8M
  }
291
37.0k
  explicit APValue(APFloat F) : Kind(None) {
292
37.0k
    MakeFloat(); setFloat(std::move(F));
293
37.0k
  }
294
3.18k
  explicit APValue(APFixedPoint FX) : Kind(None) {
295
3.18k
    MakeFixedPoint(std::move(FX));
296
3.18k
  }
297
4.10k
  explicit APValue(const APValue *E, unsigned N) : Kind(None) {
298
4.10k
    MakeVector(); setVector(E, N);
299
4.10k
  }
300
87
  APValue(APSInt R, APSInt I) : Kind(None) {
301
87
    MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
302
87
  }
303
191
  APValue(APFloat R, APFloat I) : Kind(None) {
304
191
    MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
305
191
  }
306
  APValue(const APValue &RHS);
307
  APValue(APValue &&RHS);
308
  APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
309
          bool IsNullPtr = false)
310
5.24k
      : Kind(None) {
311
5.24k
    MakeLValue(); setLValue(B, O, N, IsNullPtr);
312
5.24k
  }
313
  APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
314
          bool OnePastTheEnd, bool IsNullPtr = false)
315
1.10M
      : Kind(None) {
316
1.10M
    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
317
1.10M
  }
318
7.25k
  APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
319
7.25k
    MakeArray(InitElts, Size);
320
7.25k
  }
321
28.5k
  APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
322
28.5k
    MakeStruct(B, M);
323
28.5k
  }
324
  explicit APValue(const FieldDecl *D, const APValue &V = APValue())
325
1.84k
      : Kind(None) {
326
1.84k
    MakeUnion(); setUnion(D, V);
327
1.84k
  }
328
  APValue(const ValueDecl *Member, bool IsDerivedMember,
329
1.19k
          ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
330
1.19k
    MakeMemberPointer(Member, IsDerivedMember, Path);
331
1.19k
  }
332
  APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
333
37
      : Kind(None) {
334
37
    MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
335
37
  }
336
1.26k
  static APValue IndeterminateValue() {
337
1.26k
    APValue Result;
338
1.26k
    Result.Kind = Indeterminate;
339
1.26k
    return Result;
340
1.26k
  }
341
342
  APValue &operator=(const APValue &RHS);
343
  APValue &operator=(APValue &&RHS);
344
345
97.5M
  ~APValue() {
346
97.5M
    if (Kind != None && 
Kind != Indeterminate32.0M
)
347
32.0M
      DestroyDataAndMakeUninit();
348
97.5M
  }
349
350
  /// Returns whether the object performed allocations.
351
  ///
352
  /// If APValues are constructed via placement new, \c needsCleanup()
353
  /// indicates whether the destructor must be called in order to correctly
354
  /// free all allocated memory.
355
  bool needsCleanup() const;
356
357
  /// Swaps the contents of this and the given APValue.
358
  void swap(APValue &RHS);
359
360
14.9M
  ValueKind getKind() const { return Kind; }
361
362
37.9M
  bool isAbsent() const { return Kind == None; }
363
3.19M
  bool isIndeterminate() const { return Kind == Indeterminate; }
364
11.5M
  bool hasValue() const { return Kind != None && 
Kind != Indeterminate11.4M
; }
365
366
113M
  bool isInt() const { return Kind == Int; }
367
126k
  bool isFloat() const { return Kind == Float; }
368
4.86k
  bool isFixedPoint() const { return Kind == FixedPoint; }
369
1.21k
  bool isComplexInt() const { return Kind == ComplexInt; }
370
806
  bool isComplexFloat() const { return Kind == ComplexFloat; }
371
28.3M
  bool isLValue() const { return Kind == LValue; }
372
34.1k
  bool isVector() const { return Kind == Vector; }
373
11.7M
  bool isArray() const { return Kind == Array; }
374
11.5M
  bool isStruct() const { return Kind == Struct; }
375
11.4M
  bool isUnion() const { return Kind == Union; }
376
11.3M
  bool isMemberPointer() const { return Kind == MemberPointer; }
377
1.59M
  bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
378
379
  void dump() const;
380
  void dump(raw_ostream &OS, const ASTContext &Context) const;
381
382
  void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
383
  std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
384
385
55.8M
  APSInt &getInt() {
386
55.8M
    assert(isInt() && "Invalid accessor");
387
55.8M
    return *(APSInt*)(char*)Data.buffer;
388
55.8M
  }
389
21.8M
  const APSInt &getInt() const {
390
21.8M
    return const_cast<APValue*>(this)->getInt();
391
21.8M
  }
392
393
  /// Try to convert this value to an integral constant. This works if it's an
394
  /// integer, null pointer, or offset from a null pointer. Returns true on
395
  /// success.
396
  bool toIntegralConstant(APSInt &Result, QualType SrcTy,
397
                          const ASTContext &Ctx) const;
398
399
33.6k
  APFloat &getFloat() {
400
33.6k
    assert(isFloat() && "Invalid accessor");
401
33.6k
    return *(APFloat*)(char*)Data.buffer;
402
33.6k
  }
403
29.1k
  const APFloat &getFloat() const {
404
29.1k
    return const_cast<APValue*>(this)->getFloat();
405
29.1k
  }
406
407
2.77k
  APFixedPoint &getFixedPoint() {
408
2.77k
    assert(isFixedPoint() && "Invalid accessor");
409
2.77k
    return *(APFixedPoint *)(char *)Data.buffer;
410
2.77k
  }
411
668
  const APFixedPoint &getFixedPoint() const {
412
668
    return const_cast<APValue *>(this)->getFixedPoint();
413
668
  }
414
415
196
  APSInt &getComplexIntReal() {
416
196
    assert(isComplexInt() && "Invalid accessor");
417
196
    return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
418
196
  }
419
175
  const APSInt &getComplexIntReal() const {
420
175
    return const_cast<APValue*>(this)->getComplexIntReal();
421
175
  }
422
423
181
  APSInt &getComplexIntImag() {
424
181
    assert(isComplexInt() && "Invalid accessor");
425
181
    return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
426
181
  }
427
160
  const APSInt &getComplexIntImag() const {
428
160
    return const_cast<APValue*>(this)->getComplexIntImag();
429
160
  }
430
431
239
  APFloat &getComplexFloatReal() {
432
239
    assert(isComplexFloat() && "Invalid accessor");
433
239
    return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
434
239
  }
435
237
  const APFloat &getComplexFloatReal() const {
436
237
    return const_cast<APValue*>(this)->getComplexFloatReal();
437
237
  }
438
439
205
  APFloat &getComplexFloatImag() {
440
205
    assert(isComplexFloat() && "Invalid accessor");
441
205
    return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
442
205
  }
443
203
  const APFloat &getComplexFloatImag() const {
444
203
    return const_cast<APValue*>(this)->getComplexFloatImag();
445
203
  }
446
447
  const LValueBase getLValueBase() const;
448
  CharUnits &getLValueOffset();
449
685k
  const CharUnits &getLValueOffset() const {
450
685k
    return const_cast<APValue*>(this)->getLValueOffset();
451
685k
  }
452
  bool isLValueOnePastTheEnd() const;
453
  bool hasLValuePath() const;
454
  ArrayRef<LValuePathEntry> getLValuePath() const;
455
  unsigned getLValueCallIndex() const;
456
  unsigned getLValueVersion() const;
457
  bool isNullPointer() const;
458
459
10.5k
  APValue &getVectorElt(unsigned I) {
460
10.5k
    assert(isVector() && "Invalid accessor");
461
10.5k
    assert(I < getVectorLength() && "Index out of range");
462
10.5k
    return ((Vec*)(char*)Data.buffer)->Elts[I];
463
10.5k
  }
464
9.05k
  const APValue &getVectorElt(unsigned I) const {
465
9.05k
    return const_cast<APValue*>(this)->getVectorElt(I);
466
9.05k
  }
467
15.1k
  unsigned getVectorLength() const {
468
15.1k
    assert(isVector() && "Invalid accessor");
469
15.1k
    return ((const Vec*)(const void *)Data.buffer)->NumElts;
470
15.1k
  }
471
472
90.5k
  APValue &getArrayInitializedElt(unsigned I) {
473
90.5k
    assert(isArray() && "Invalid accessor");
474
90.5k
    assert(I < getArrayInitializedElts() && "Index out of range");
475
90.5k
    return ((Arr*)(char*)Data.buffer)->Elts[I];
476
90.5k
  }
477
27.5k
  const APValue &getArrayInitializedElt(unsigned I) const {
478
27.5k
    return const_cast<APValue*>(this)->getArrayInitializedElt(I);
479
27.5k
  }
480
27.7k
  bool hasArrayFiller() const {
481
27.7k
    return getArrayInitializedElts() != getArraySize();
482
27.7k
  }
483
15.1k
  APValue &getArrayFiller() {
484
15.1k
    assert(isArray() && "Invalid accessor");
485
15.1k
    assert(hasArrayFiller() && "No array filler");
486
15.1k
    return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
487
15.1k
  }
488
1.41k
  const APValue &getArrayFiller() const {
489
1.41k
    return const_cast<APValue*>(this)->getArrayFiller();
490
1.41k
  }
491
155k
  unsigned getArrayInitializedElts() const {
492
155k
    assert(isArray() && "Invalid accessor");
493
155k
    return ((const Arr*)(const void *)Data.buffer)->NumElts;
494
155k
  }
495
32.1k
  unsigned getArraySize() const {
496
32.1k
    assert(isArray() && "Invalid accessor");
497
32.1k
    return ((const Arr*)(const void *)Data.buffer)->ArrSize;
498
32.1k
  }
499
500
82.7k
  unsigned getStructNumBases() const {
501
82.7k
    assert(isStruct() && "Invalid accessor");
502
82.7k
    return ((const StructData*)(const char*)Data.buffer)->NumBases;
503
82.7k
  }
504
8.54k
  unsigned getStructNumFields() const {
505
8.54k
    assert(isStruct() && "Invalid accessor");
506
8.54k
    return ((const StructData*)(const char*)Data.buffer)->NumFields;
507
8.54k
  }
508
4.58k
  APValue &getStructBase(unsigned i) {
509
4.58k
    assert(isStruct() && "Invalid accessor");
510
4.58k
    return ((StructData*)(char*)Data.buffer)->Elts[i];
511
4.58k
  }
512
74.2k
  APValue &getStructField(unsigned i) {
513
74.2k
    assert(isStruct() && "Invalid accessor");
514
74.2k
    return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
515
74.2k
  }
516
1.55k
  const APValue &getStructBase(unsigned i) const {
517
1.55k
    return const_cast<APValue*>(this)->getStructBase(i);
518
1.55k
  }
519
22.7k
  const APValue &getStructField(unsigned i) const {
520
22.7k
    return const_cast<APValue*>(this)->getStructField(i);
521
22.7k
  }
522
523
4.15k
  const FieldDecl *getUnionField() const {
524
4.15k
    assert(isUnion() && "Invalid accessor");
525
4.15k
    return ((const UnionData*)(const char*)Data.buffer)->Field;
526
4.15k
  }
527
3.60k
  APValue &getUnionValue() {
528
3.60k
    assert(isUnion() && "Invalid accessor");
529
3.60k
    return *((UnionData*)(char*)Data.buffer)->Value;
530
3.60k
  }
531
1.56k
  const APValue &getUnionValue() const {
532
1.56k
    return const_cast<APValue*>(this)->getUnionValue();
533
1.56k
  }
534
535
  const ValueDecl *getMemberPointerDecl() const;
536
  bool isMemberPointerToDerivedMember() const;
537
  ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
538
539
26
  const AddrLabelExpr* getAddrLabelDiffLHS() const {
540
26
    assert(isAddrLabelDiff() && "Invalid accessor");
541
26
    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
542
26
  }
543
26
  const AddrLabelExpr* getAddrLabelDiffRHS() const {
544
26
    assert(isAddrLabelDiff() && "Invalid accessor");
545
26
    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
546
26
  }
547
548
33.6M
  void setInt(APSInt I) {
549
33.6M
    assert(isInt() && "Invalid accessor");
550
33.6M
    *(APSInt *)(char *)Data.buffer = std::move(I);
551
33.6M
  }
552
49.2k
  void setFloat(APFloat F) {
553
49.2k
    assert(isFloat() && "Invalid accessor");
554
49.2k
    *(APFloat *)(char *)Data.buffer = std::move(F);
555
49.2k
  }
556
0
  void setFixedPoint(APFixedPoint FX) {
557
0
    assert(isFixedPoint() && "Invalid accessor");
558
0
    *(APFixedPoint *)(char *)Data.buffer = std::move(FX);
559
0
  }
560
6.05k
  void setVector(const APValue *E, unsigned N) {
561
6.05k
    assert(isVector() && "Invalid accessor");
562
6.05k
    ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
563
6.05k
    ((Vec*)(char*)Data.buffer)->NumElts = N;
564
38.8k
    for (unsigned i = 0; i != N; 
++i32.8k
)
565
32.8k
      ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
566
6.05k
  }
567
188
  void setComplexInt(APSInt R, APSInt I) {
568
188
    assert(R.getBitWidth() == I.getBitWidth() &&
569
188
           "Invalid complex int (type mismatch).");
570
188
    assert(isComplexInt() && "Invalid accessor");
571
188
    ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
572
188
    ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
573
188
  }
574
289
  void setComplexFloat(APFloat R, APFloat I) {
575
289
    assert(&R.getSemantics() == &I.getSemantics() &&
576
289
           "Invalid complex float (type mismatch).");
577
289
    assert(isComplexFloat() && "Invalid accessor");
578
289
    ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
579
289
    ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
580
289
  }
581
  void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
582
                 bool IsNullPtr);
583
  void setLValue(LValueBase B, const CharUnits &O,
584
                 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
585
                 bool IsNullPtr);
586
2.29k
  void setUnion(const FieldDecl *Field, const APValue &Value) {
587
2.29k
    assert(isUnion() && "Invalid accessor");
588
2.29k
    ((UnionData*)(char*)Data.buffer)->Field = Field;
589
2.29k
    *((UnionData*)(char*)Data.buffer)->Value = Value;
590
2.29k
  }
591
  void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
592
56
                        const AddrLabelExpr* RHSExpr) {
593
56
    ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
594
56
    ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
595
56
  }
596
597
private:
598
  void DestroyDataAndMakeUninit();
599
33.6M
  void MakeInt() {
600
33.6M
    assert(isAbsent() && "Bad state change");
601
33.6M
    new ((void*)Data.buffer) APSInt(1);
602
33.6M
    Kind = Int;
603
33.6M
  }
604
49.2k
  void MakeFloat() {
605
49.2k
    assert(isAbsent() && "Bad state change");
606
49.2k
    new ((void*)(char*)Data.buffer) APFloat(0.0);
607
49.2k
    Kind = Float;
608
49.2k
  }
609
3.19k
  void MakeFixedPoint(APFixedPoint &&FX) {
610
3.19k
    assert(isAbsent() && "Bad state change");
611
3.19k
    new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
612
3.19k
    Kind = FixedPoint;
613
3.19k
  }
614
6.05k
  void MakeVector() {
615
6.05k
    assert(isAbsent() && "Bad state change");
616
6.05k
    new ((void*)(char*)Data.buffer) Vec();
617
6.05k
    Kind = Vector;
618
6.05k
  }
619
188
  void MakeComplexInt() {
620
188
    assert(isAbsent() && "Bad state change");
621
188
    new ((void*)(char*)Data.buffer) ComplexAPSInt();
622
188
    Kind = ComplexInt;
623
188
  }
624
289
  void MakeComplexFloat() {
625
289
    assert(isAbsent() && "Bad state change");
626
289
    new ((void*)(char*)Data.buffer) ComplexAPFloat();
627
289
    Kind = ComplexFloat;
628
289
  }
629
  void MakeLValue();
630
  void MakeArray(unsigned InitElts, unsigned Size);
631
32.7k
  void MakeStruct(unsigned B, unsigned M) {
632
32.7k
    assert(isAbsent() && "Bad state change");
633
32.7k
    new ((void*)(char*)Data.buffer) StructData(B, M);
634
32.7k
    Kind = Struct;
635
32.7k
  }
636
2.23k
  void MakeUnion() {
637
2.23k
    assert(isAbsent() && "Bad state change");
638
2.23k
    new ((void*)(char*)Data.buffer) UnionData();
639
2.23k
    Kind = Union;
640
2.23k
  }
641
  void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
642
                         ArrayRef<const CXXRecordDecl*> Path);
643
56
  void MakeAddrLabelDiff() {
644
56
    assert(isAbsent() && "Bad state change");
645
56
    new ((void*)(char*)Data.buffer) AddrLabelDiffData();
646
56
    Kind = AddrLabelDiff;
647
56
  }
648
};
649
650
} // end namespace clang.
651
652
namespace llvm {
653
template<> struct DenseMapInfo<clang::APValue::LValueBase> {
654
  static clang::APValue::LValueBase getEmptyKey();
655
  static clang::APValue::LValueBase getTombstoneKey();
656
  static unsigned getHashValue(const clang::APValue::LValueBase &Base);
657
  static bool isEqual(const clang::APValue::LValueBase &LHS,
658
                      const clang::APValue::LValueBase &RHS);
659
};
660
}
661
662
#endif