Coverage Report

Created: 2020-09-22 08:39

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/APValue.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
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 implements the APValue class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/AST/APValue.h"
14
#include "clang/AST/ASTContext.h"
15
#include "clang/AST/CharUnits.h"
16
#include "clang/AST/DeclCXX.h"
17
#include "clang/AST/Expr.h"
18
#include "clang/AST/Type.h"
19
#include "llvm/Support/ErrorHandling.h"
20
#include "llvm/Support/raw_ostream.h"
21
using namespace clang;
22
23
/// The identity of a type_info object depends on the canonical unqualified
24
/// type only.
25
TypeInfoLValue::TypeInfoLValue(const Type *T)
26
681
    : T(T->getCanonicalTypeUnqualified().getTypePtr()) {}
27
28
void TypeInfoLValue::print(llvm::raw_ostream &Out,
29
45
                           const PrintingPolicy &Policy) const {
30
45
  Out << "typeid(";
31
45
  QualType(getType(), 0).print(Out, Policy);
32
45
  Out << ")";
33
45
}
34
35
static_assert(
36
    1 << llvm::PointerLikeTypeTraits<TypeInfoLValue>::NumLowBitsAvailable <=
37
        alignof(Type),
38
    "Type is insufficiently aligned");
39
40
APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)
41
28.0M
    : Ptr(P ? cast<ValueDecl>(P->getCanonicalDecl()) : nullptr), Local{I, V} {}
42
APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
43
139k
    : Ptr(P), Local{I, V} {}
44
45
APValue::LValueBase APValue::LValueBase::getDynamicAlloc(DynamicAllocLValue LV,
46
623
                                                         QualType Type) {
47
623
  LValueBase Base;
48
623
  Base.Ptr = LV;
49
623
  Base.DynamicAllocType = Type.getAsOpaquePtr();
50
623
  return Base;
51
623
}
52
53
APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV,
54
681
                                                     QualType TypeInfo) {
55
681
  LValueBase Base;
56
681
  Base.Ptr = LV;
57
681
  Base.TypeInfoType = TypeInfo.getAsOpaquePtr();
58
681
  return Base;
59
681
}
60
61
8.30M
unsigned APValue::LValueBase::getCallIndex() const {
62
8.30M
  return (is<TypeInfoLValue>() || 
is<DynamicAllocLValue>()8.30M
) ?
02.98k
63
8.30M
                                                            : Local.CallIndex;
64
8.30M
}
65
66
200k
unsigned APValue::LValueBase::getVersion() const {
67
200k
  return (is<TypeInfoLValue>() || 
is<DynamicAllocLValue>()200k
) ?
052
:
Local.Version200k
;
68
200k
}
69
70
1.52k
QualType APValue::LValueBase::getTypeInfoType() const {
71
1.52k
  assert(is<TypeInfoLValue>() && "not a type_info lvalue");
72
1.52k
  return QualType::getFromOpaquePtr(TypeInfoType);
73
1.52k
}
74
75
8.24k
QualType APValue::LValueBase::getDynamicAllocType() const {
76
8.24k
  assert(is<DynamicAllocLValue>() && "not a dynamic allocation lvalue");
77
8.24k
  return QualType::getFromOpaquePtr(DynamicAllocType);
78
8.24k
}
79
80
namespace clang {
81
bool operator==(const APValue::LValueBase &LHS,
82
1.50M
                const APValue::LValueBase &RHS) {
83
1.50M
  if (LHS.Ptr != RHS.Ptr)
84
355k
    return false;
85
1.14M
  if (LHS.is<TypeInfoLValue>() || LHS.is<DynamicAllocLValue>())
86
448
    return true;
87
1.14M
  return LHS.Local.CallIndex == RHS.Local.CallIndex &&
88
1.14M
         LHS.Local.Version == RHS.Local.Version;
89
1.14M
}
90
}
91
92
141k
APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType BaseOrMember) {
93
141k
  if (const Decl *D = BaseOrMember.getPointer())
94
141k
    BaseOrMember.setPointer(D->getCanonicalDecl());
95
141k
  Value = reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue());
96
141k
}
97
98
namespace {
99
  struct LVBase {
100
    APValue::LValueBase Base;
101
    CharUnits Offset;
102
    unsigned PathLength;
103
    bool IsNullPtr : 1;
104
    bool IsOnePastTheEnd : 1;
105
  };
106
}
107
108
91.8k
void *APValue::LValueBase::getOpaqueValue() const {
109
91.8k
  return Ptr.getOpaqueValue();
110
91.8k
}
111
112
5.19k
bool APValue::LValueBase::isNull() const {
113
5.19k
  return Ptr.isNull();
114
5.19k
}
115
116
21.4M
APValue::LValueBase::operator bool () const {
117
21.4M
  return static_cast<bool>(Ptr);
118
21.4M
}
119
120
clang::APValue::LValueBase
121
139k
llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
122
139k
  clang::APValue::LValueBase B;
123
139k
  B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey();
124
139k
  return B;
125
139k
}
126
127
clang::APValue::LValueBase
128
124k
llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
129
124k
  clang::APValue::LValueBase B;
130
124k
  B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey();
131
124k
  return B;
132
124k
}
133
134
namespace clang {
135
87.2k
llvm::hash_code hash_value(const APValue::LValueBase &Base) {
136
87.2k
  if (Base.is<TypeInfoLValue>() || Base.is<DynamicAllocLValue>())
137
687
    return llvm::hash_value(Base.getOpaqueValue());
138
86.6k
  return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(),
139
86.6k
                            Base.getVersion());
140
86.6k
}
141
}
142
143
unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(
144
0
    const clang::APValue::LValueBase &Base) {
145
0
  return hash_value(Base);
146
0
}
147
148
bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(
149
    const clang::APValue::LValueBase &LHS,
150
0
    const clang::APValue::LValueBase &RHS) {
151
0
  return LHS == RHS;
152
0
}
153
154
struct APValue::LV : LVBase {
155
  static const unsigned InlinePathSpace =
156
      (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
157
158
  /// Path - The sequence of base classes, fields and array indices to follow to
159
  /// walk from Base to the subobject. When performing GCC-style folding, there
160
  /// may not be such a path.
161
  union {
162
    LValuePathEntry Path[InlinePathSpace];
163
    LValuePathEntry *PathPtr;
164
  };
165
166
1.13M
  LV() { PathLength = (unsigned)-1; }
167
1.12M
  ~LV() { resizePath(0); }
168
169
2.25M
  void resizePath(unsigned Length) {
170
2.25M
    if (Length == PathLength)
171
1.06M
      return;
172
1.19M
    if (hasPathPtr())
173
55
      delete [] PathPtr;
174
1.19M
    PathLength = Length;
175
1.19M
    if (hasPathPtr())
176
55
      PathPtr = new LValuePathEntry[Length];
177
1.19M
  }
178
179
6.82M
  bool hasPath() const { return PathLength != (unsigned)-1; }
180
4.83M
  bool hasPathPtr() const { return hasPath() && 
PathLength > InlinePathSpace3.69M
; }
181
182
1.12M
  LValuePathEntry *getPath() { return hasPathPtr() ? 
PathPtr55
:
Path1.12M
; }
183
1.31M
  const LValuePathEntry *getPath() const {
184
1.31M
    return hasPathPtr() ? 
PathPtr118
: Path;
185
1.31M
  }
186
};
187
188
namespace {
189
  struct MemberPointerBase {
190
    llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
191
    unsigned PathLength;
192
  };
193
}
194
195
struct APValue::MemberPointerData : MemberPointerBase {
196
  static const unsigned InlinePathSpace =
197
      (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
198
  typedef const CXXRecordDecl *PathElem;
199
  union {
200
    PathElem Path[InlinePathSpace];
201
    PathElem *PathPtr;
202
  };
203
204
1.37k
  MemberPointerData() { PathLength = 0; }
205
1.11k
  ~MemberPointerData() { resizePath(0); }
206
207
2.49k
  void resizePath(unsigned Length) {
208
2.49k
    if (Length == PathLength)
209
2.08k
      return;
210
403
    if (hasPathPtr())
211
19
      delete [] PathPtr;
212
403
    PathLength = Length;
213
403
    if (hasPathPtr())
214
19
      PathPtr = new PathElem[Length];
215
403
  }
216
217
2.19k
  bool hasPathPtr() const { return PathLength > InlinePathSpace; }
218
219
539
  PathElem *getPath() { return hasPathPtr() ? 
PathPtr275
:
Path264
; }
220
579
  const PathElem *getPath() const {
221
547
    return hasPathPtr() ? 
PathPtr32
: Path;
222
579
  }
223
};
224
225
// FIXME: Reduce the malloc traffic here.
226
227
APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
228
  Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
229
8.34k
  NumElts(NumElts), ArrSize(Size) {}
230
7.21k
APValue::Arr::~Arr() { delete [] Elts; }
231
232
APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
233
  Elts(new APValue[NumBases+NumFields]),
234
32.7k
  NumBases(NumBases), NumFields(NumFields) {}
235
24.7k
APValue::StructData::~StructData() {
236
24.7k
  delete [] Elts;
237
24.7k
}
238
239
2.23k
APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
240
1.93k
APValue::UnionData::~UnionData () {
241
1.93k
  delete Value;
242
1.93k
}
243
244
5.92M
APValue::APValue(const APValue &RHS) : Kind(None) {
245
5.92M
  switch (RHS.getKind()) {
246
125k
  case None:
247
125k
  case Indeterminate:
248
125k
    Kind = RHS.getKind();
249
125k
    break;
250
5.75M
  case Int:
251
5.75M
    MakeInt();
252
5.75M
    setInt(RHS.getInt());
253
5.75M
    break;
254
12.1k
  case Float:
255
12.1k
    MakeFloat();
256
12.1k
    setFloat(RHS.getFloat());
257
12.1k
    break;
258
6
  case FixedPoint: {
259
6
    APFixedPoint FXCopy = RHS.getFixedPoint();
260
6
    MakeFixedPoint(std::move(FXCopy));
261
6
    break;
262
125k
  }
263
1.95k
  case Vector:
264
1.95k
    MakeVector();
265
1.95k
    setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
266
1.95k
              RHS.getVectorLength());
267
1.95k
    break;
268
105
  case ComplexInt:
269
105
    MakeComplexInt();
270
105
    setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
271
105
    break;
272
102
  case ComplexFloat:
273
102
    MakeComplexFloat();
274
102
    setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
275
102
    break;
276
25.0k
  case LValue:
277
25.0k
    MakeLValue();
278
25.0k
    if (RHS.hasLValuePath())
279
24.7k
      setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
280
24.7k
                RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
281
317
    else
282
317
      setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
283
317
                RHS.isNullPointer());
284
25.0k
    break;
285
1.09k
  case Array:
286
1.09k
    MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
287
6.17k
    for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; 
++I5.07k
)
288
5.07k
      getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
289
1.09k
    if (RHS.hasArrayFiller())
290
210
      getArrayFiller() = RHS.getArrayFiller();
291
1.09k
    break;
292
4.25k
  case Struct:
293
4.25k
    MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
294
4.62k
    for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; 
++I369
)
295
369
      getStructBase(I) = RHS.getStructBase(I);
296
10.2k
    for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; 
++I5.97k
)
297
5.97k
      getStructField(I) = RHS.getStructField(I);
298
4.25k
    break;
299
394
  case Union:
300
394
    MakeUnion();
301
394
    setUnion(RHS.getUnionField(), RHS.getUnionValue());
302
394
    break;
303
186
  case MemberPointer:
304
186
    MakeMemberPointer(RHS.getMemberPointerDecl(),
305
186
                      RHS.isMemberPointerToDerivedMember(),
306
186
                      RHS.getMemberPointerPath());
307
186
    break;
308
19
  case AddrLabelDiff:
309
19
    MakeAddrLabelDiff();
310
19
    setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());
311
19
    break;
312
5.92M
  }
313
5.92M
}
314
315
48.0k
APValue::APValue(APValue &&RHS) : Kind(RHS.Kind), Data(RHS.Data) {
316
48.0k
  RHS.Kind = None;
317
48.0k
}
318
319
3.37M
APValue &APValue::operator=(const APValue &RHS) {
320
3.37M
  if (this != &RHS)
321
3.37M
    *this = APValue(RHS);
322
3.37M
  return *this;
323
3.37M
}
324
325
35.0M
APValue &APValue::operator=(APValue &&RHS) {
326
35.0M
  if (Kind != None && 
Kind != Indeterminate2.44M
)
327
2.44M
    DestroyDataAndMakeUninit();
328
35.0M
  Kind = RHS.Kind;
329
35.0M
  Data = RHS.Data;
330
35.0M
  RHS.Kind = None;
331
35.0M
  return *this;
332
35.0M
}
333
334
34.5M
void APValue::DestroyDataAndMakeUninit() {
335
34.5M
  if (Kind == Int)
336
33.3M
    ((APSInt*)(char*)Data.buffer)->~APSInt();
337
1.21M
  else if (Kind == Float)
338
47.9k
    ((APFloat*)(char*)Data.buffer)->~APFloat();
339
1.16M
  else if (Kind == FixedPoint)
340
2.86k
    ((APFixedPoint *)(char *)Data.buffer)->~APFixedPoint();
341
1.16M
  else if (Kind == Vector)
342
5.85k
    ((Vec*)(char*)Data.buffer)->~Vec();
343
1.16M
  else if (Kind == ComplexInt)
344
178
    ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
345
1.16M
  else if (Kind == ComplexFloat)
346
271
    ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
347
1.15M
  else if (Kind == LValue)
348
1.12M
    ((LV*)(char*)Data.buffer)->~LV();
349
35.0k
  else if (Kind == Array)
350
7.21k
    ((Arr*)(char*)Data.buffer)->~Arr();
351
27.8k
  else if (Kind == Struct)
352
24.7k
    ((StructData*)(char*)Data.buffer)->~StructData();
353
3.09k
  else if (Kind == Union)
354
1.93k
    ((UnionData*)(char*)Data.buffer)->~UnionData();
355
1.16k
  else if (Kind == MemberPointer)
356
1.11k
    ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
357
49
  else if (Kind == AddrLabelDiff)
358
49
    ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
359
34.5M
  Kind = None;
360
34.5M
}
361
362
316k
bool APValue::needsCleanup() const {
363
316k
  switch (getKind()) {
364
10
  case None:
365
10
  case Indeterminate:
366
10
  case AddrLabelDiff:
367
10
    return false;
368
11.8k
  case Struct:
369
11.8k
  case Union:
370
11.8k
  case Array:
371
11.8k
  case Vector:
372
11.8k
    return true;
373
296k
  case Int:
374
296k
    return getInt().needsCleanup();
375
595
  case Float:
376
595
    return getFloat().needsCleanup();
377
334
  case FixedPoint:
378
334
    return getFixedPoint().getValue().needsCleanup();
379
34
  case ComplexFloat:
380
34
    assert(getComplexFloatImag().needsCleanup() ==
381
34
               getComplexFloatReal().needsCleanup() &&
382
34
           "In _Complex float types, real and imaginary values always have the "
383
34
           "same size.");
384
34
    return getComplexFloatReal().needsCleanup();
385
16
  case ComplexInt:
386
16
    assert(getComplexIntImag().needsCleanup() ==
387
16
               getComplexIntReal().needsCleanup() &&
388
16
           "In _Complex int types, real and imaginary values must have the "
389
16
           "same size.");
390
16
    return getComplexIntReal().needsCleanup();
391
7.42k
  case LValue:
392
7.42k
    return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
393
267
  case MemberPointer:
394
267
    return reinterpret_cast<const MemberPointerData *>(Data.buffer)
395
267
        ->hasPathPtr();
396
0
  }
397
0
  llvm_unreachable("Unknown APValue kind!");
398
0
}
399
400
12.8M
void APValue::swap(APValue &RHS) {
401
12.8M
  std::swap(Kind, RHS.Kind);
402
12.8M
  std::swap(Data, RHS.Data);
403
12.8M
}
404
405
27
static double GetApproxValue(const llvm::APFloat &F) {
406
27
  llvm::APFloat V = F;
407
27
  bool ignored;
408
27
  V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
409
27
            &ignored);
410
27
  return V.convertToDouble();
411
27
}
412
413
void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx,
414
2.33k
                          QualType Ty) const {
415
  // There are no objects of type 'void', but values of this type can be
416
  // returned from functions.
417
2.33k
  if (Ty->isVoidType()) {
418
0
    Out << "void()";
419
0
    return;
420
0
  }
421
422
2.33k
  switch (getKind()) {
423
0
  case APValue::None:
424
0
    Out << "<out of lifetime>";
425
0
    return;
426
4
  case APValue::Indeterminate:
427
4
    Out << "<uninitialized>";
428
4
    return;
429
1.17k
  case APValue::Int:
430
1.17k
    if (Ty->isBooleanType())
431
24
      Out << (getInt().getBoolValue() ? 
"true"14
:
"false"10
);
432
1.15k
    else
433
1.15k
      Out << getInt();
434
1.17k
    return;
435
23
  case APValue::Float:
436
23
    Out << GetApproxValue(getFloat());
437
23
    return;
438
0
  case APValue::FixedPoint:
439
0
    Out << getFixedPoint();
440
0
    return;
441
2
  case APValue::Vector: {
442
2
    Out << '{';
443
2
    QualType ElemTy = Ty->castAs<VectorType>()->getElementType();
444
2
    getVectorElt(0).printPretty(Out, Ctx, ElemTy);
445
8
    for (unsigned i = 1; i != getVectorLength(); 
++i6
) {
446
6
      Out << ", ";
447
6
      getVectorElt(i).printPretty(Out, Ctx, ElemTy);
448
6
    }
449
2
    Out << '}';
450
2
    return;
451
0
  }
452
2
  case APValue::ComplexInt:
453
2
    Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
454
2
    return;
455
2
  case APValue::ComplexFloat:
456
2
    Out << GetApproxValue(getComplexFloatReal()) << "+"
457
2
        << GetApproxValue(getComplexFloatImag()) << "i";
458
2
    return;
459
1.08k
  case APValue::LValue: {
460
1.08k
    bool IsReference = Ty->isReferenceType();
461
1.08k
    QualType InnerTy
462
738
      = IsReference ? 
Ty.getNonReferenceType()347
: Ty->getPointeeType();
463
1.08k
    if (InnerTy.isNull())
464
574
      InnerTy = Ty;
465
466
1.08k
    LValueBase Base = getLValueBase();
467
1.08k
    if (!Base) {
468
90
      if (isNullPointer()) {
469
74
        Out << (Ctx.getLangOpts().CPlusPlus11 ? "nullptr" : 
"0"0
);
470
16
      } else if (IsReference) {
471
0
        Out << "*(" << InnerTy.stream(Ctx.getPrintingPolicy()) << "*)"
472
0
            << getLValueOffset().getQuantity();
473
16
      } else {
474
16
        Out << "(" << Ty.stream(Ctx.getPrintingPolicy()) << ")"
475
16
            << getLValueOffset().getQuantity();
476
16
      }
477
90
      return;
478
90
    }
479
480
995
    if (!hasLValuePath()) {
481
      // No lvalue path: just print the offset.
482
0
      CharUnits O = getLValueOffset();
483
0
      CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
484
0
      if (!O.isZero()) {
485
0
        if (IsReference)
486
0
          Out << "*(";
487
0
        if (O % S) {
488
0
          Out << "(char*)";
489
0
          S = CharUnits::One();
490
0
        }
491
0
        Out << '&';
492
0
      } else if (!IsReference) {
493
0
        Out << '&';
494
0
      }
495
496
0
      if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
497
0
        Out << *VD;
498
0
      else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
499
0
        TI.print(Out, Ctx.getPrintingPolicy());
500
0
      } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {
501
0
        Out << "{*new "
502
0
            << Base.getDynamicAllocType().stream(Ctx.getPrintingPolicy()) << "#"
503
0
            << DA.getIndex() << "}";
504
0
      } else {
505
0
        assert(Base.get<const Expr *>() != nullptr &&
506
0
               "Expecting non-null Expr");
507
0
        Base.get<const Expr*>()->printPretty(Out, nullptr,
508
0
                                             Ctx.getPrintingPolicy());
509
0
      }
510
511
0
      if (!O.isZero()) {
512
0
        Out << " + " << (O / S);
513
0
        if (IsReference)
514
0
          Out << ')';
515
0
      }
516
0
      return;
517
0
    }
518
519
    // We have an lvalue path. Print it out nicely.
520
995
    if (!IsReference)
521
648
      Out << '&';
522
347
    else if (isLValueOnePastTheEnd())
523
0
      Out << "*(&";
524
525
995
    QualType ElemTy;
526
995
    if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
527
801
      Out << *VD;
528
801
      ElemTy = VD->getType();
529
194
    } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
530
45
      TI.print(Out, Ctx.getPrintingPolicy());
531
45
      ElemTy = Base.getTypeInfoType();
532
149
    } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {
533
17
      Out << "{*new "
534
17
          << Base.getDynamicAllocType().stream(Ctx.getPrintingPolicy()) << "#"
535
17
          << DA.getIndex() << "}";
536
17
      ElemTy = Base.getDynamicAllocType();
537
132
    } else {
538
132
      const Expr *E = Base.get<const Expr*>();
539
132
      assert(E != nullptr && "Expecting non-null Expr");
540
132
      E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
541
      // FIXME: This is wrong if E is a MaterializeTemporaryExpr with an lvalue
542
      // adjustment.
543
132
      ElemTy = E->getType();
544
132
    }
545
546
995
    ArrayRef<LValuePathEntry> Path = getLValuePath();
547
995
    const CXXRecordDecl *CastToBase = nullptr;
548
1.10k
    for (unsigned I = 0, N = Path.size(); I != N; 
++I109
) {
549
109
      if (ElemTy->getAs<RecordType>()) {
550
        // The lvalue refers to a class type, so the next path entry is a base
551
        // or member.
552
52
        const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();
553
52
        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
554
21
          CastToBase = RD;
555
21
          ElemTy = Ctx.getRecordType(RD);
556
31
        } else {
557
31
          const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
558
31
          Out << ".";
559
31
          if (CastToBase)
560
4
            Out << *CastToBase << "::";
561
31
          Out << *VD;
562
31
          ElemTy = VD->getType();
563
31
        }
564
57
      } else {
565
        // The lvalue must refer to an array.
566
57
        Out << '[' << Path[I].getAsArrayIndex() << ']';
567
57
        ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
568
57
      }
569
109
    }
570
571
    // Handle formatting of one-past-the-end lvalues.
572
995
    if (isLValueOnePastTheEnd()) {
573
      // FIXME: If CastToBase is non-0, we should prefix the output with
574
      // "(CastToBase*)".
575
4
      Out << " + 1";
576
4
      if (IsReference)
577
0
        Out << ')';
578
4
    }
579
995
    return;
580
995
  }
581
6
  case APValue::Array: {
582
6
    const ArrayType *AT = Ctx.getAsArrayType(Ty);
583
6
    QualType ElemTy = AT->getElementType();
584
6
    Out << '{';
585
6
    if (unsigned N = getArrayInitializedElts()) {
586
2
      getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy);
587
20
      for (unsigned I = 1; I != N; 
++I18
) {
588
20
        Out << ", ";
589
20
        if (I == 10) {
590
          // Avoid printing out the entire contents of large arrays.
591
2
          Out << "...";
592
2
          break;
593
2
        }
594
18
        getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy);
595
18
      }
596
2
    }
597
6
    Out << '}';
598
6
    return;
599
995
  }
600
23
  case APValue::Struct: {
601
23
    Out << '{';
602
23
    const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl();
603
23
    bool First = true;
604
23
    if (unsigned N = getStructNumBases()) {
605
2
      const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
606
2
      CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();
607
4
      for (unsigned I = 0; I != N; 
++I, ++BI2
) {
608
2
        assert(BI != CD->bases_end());
609
2
        if (!First)
610
0
          Out << ", ";
611
2
        getStructBase(I).printPretty(Out, Ctx, BI->getType());
612
2
        First = false;
613
2
      }
614
2
    }
615
22
    for (const auto *FI : RD->fields()) {
616
22
      if (!First)
617
8
        Out << ", ";
618
22
      if (FI->isUnnamedBitfield()) 
continue0
;
619
22
      getStructField(FI->getFieldIndex()).
620
22
        printPretty(Out, Ctx, FI->getType());
621
22
      First = false;
622
22
    }
623
23
    Out << '}';
624
23
    return;
625
995
  }
626
4
  case APValue::Union:
627
4
    Out << '{';
628
4
    if (const FieldDecl *FD = getUnionField()) {
629
4
      Out << "." << *FD << " = ";
630
4
      getUnionValue().printPretty(Out, Ctx, FD->getType());
631
4
    }
632
4
    Out << '}';
633
4
    return;
634
2
  case APValue::MemberPointer:
635
    // FIXME: This is not enough to unambiguously identify the member in a
636
    // multiple-inheritance scenario.
637
2
    if (const ValueDecl *VD = getMemberPointerDecl()) {
638
2
      Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
639
2
      return;
640
2
    }
641
0
    Out << "0";
642
0
    return;
643
2
  case APValue::AddrLabelDiff:
644
2
    Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
645
2
    Out << " - ";
646
2
    Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
647
2
    return;
648
0
  }
649
0
  llvm_unreachable("Unknown APValue kind!");
650
0
}
651
652
471
std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const {
653
471
  std::string Result;
654
471
  llvm::raw_string_ostream Out(Result);
655
471
  printPretty(Out, Ctx, Ty);
656
471
  Out.flush();
657
471
  return Result;
658
471
}
659
660
bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy,
661
714
                                 const ASTContext &Ctx) const {
662
714
  if (isInt()) {
663
277
    Result = getInt();
664
277
    return true;
665
277
  }
666
667
437
  if (isLValue() && isNullPointer()) {
668
213
    Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy);
669
213
    return true;
670
213
  }
671
672
224
  if (isLValue() && !getLValueBase()) {
673
223
    Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy);
674
223
    return true;
675
223
  }
676
677
1
  return false;
678
1
}
679
680
1.98M
const APValue::LValueBase APValue::getLValueBase() const {
681
1.98M
  assert(isLValue() && "Invalid accessor");
682
1.98M
  return ((const LV*)(const void*)Data.buffer)->Base;
683
1.98M
}
684
685
672k
bool APValue::isLValueOnePastTheEnd() const {
686
672k
  assert(isLValue() && "Invalid accessor");
687
672k
  return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
688
672k
}
689
690
685k
CharUnits &APValue::getLValueOffset() {
691
685k
  assert(isLValue() && "Invalid accessor");
692
685k
  return ((LV*)(void*)Data.buffer)->Offset;
693
685k
}
694
695
1.98M
bool APValue::hasLValuePath() const {
696
1.98M
  assert(isLValue() && "Invalid accessor");
697
1.98M
  return ((const LV*)(const char*)Data.buffer)->hasPath();
698
1.98M
}
699
700
1.31M
ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
701
1.31M
  assert(isLValue() && hasLValuePath() && "Invalid accessor");
702
1.31M
  const LV &LVal = *((const LV*)(const char*)Data.buffer);
703
1.31M
  return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
704
1.31M
}
705
706
0
unsigned APValue::getLValueCallIndex() const {
707
0
  assert(isLValue() && "Invalid accessor");
708
0
  return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
709
0
}
710
711
0
unsigned APValue::getLValueVersion() const {
712
0
  assert(isLValue() && "Invalid accessor");
713
0
  return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
714
0
}
715
716
677k
bool APValue::isNullPointer() const {
717
677k
  assert(isLValue() && "Invalid usage");
718
677k
  return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
719
677k
}
720
721
void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
722
5.55k
                        bool IsNullPtr) {
723
5.55k
  assert(isLValue() && "Invalid accessor");
724
5.55k
  LV &LVal = *((LV*)(char*)Data.buffer);
725
5.55k
  LVal.Base = B;
726
5.55k
  LVal.IsOnePastTheEnd = false;
727
5.55k
  LVal.Offset = O;
728
5.55k
  LVal.resizePath((unsigned)-1);
729
5.55k
  LVal.IsNullPtr = IsNullPtr;
730
5.55k
}
731
732
void APValue::setLValue(LValueBase B, const CharUnits &O,
733
                        ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
734
1.12M
                        bool IsNullPtr) {
735
1.12M
  assert(isLValue() && "Invalid accessor");
736
1.12M
  LV &LVal = *((LV*)(char*)Data.buffer);
737
1.12M
  LVal.Base = B;
738
1.12M
  LVal.IsOnePastTheEnd = IsOnePastTheEnd;
739
1.12M
  LVal.Offset = O;
740
1.12M
  LVal.resizePath(Path.size());
741
1.12M
  memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
742
1.12M
  LVal.IsNullPtr = IsNullPtr;
743
1.12M
}
744
745
1.93k
const ValueDecl *APValue::getMemberPointerDecl() const {
746
1.93k
  assert(isMemberPointer() && "Invalid accessor");
747
1.93k
  const MemberPointerData &MPD =
748
1.93k
      *((const MemberPointerData *)(const char *)Data.buffer);
749
1.93k
  return MPD.MemberAndIsDerivedMember.getPointer();
750
1.93k
}
751
752
514
bool APValue::isMemberPointerToDerivedMember() const {
753
514
  assert(isMemberPointer() && "Invalid accessor");
754
514
  const MemberPointerData &MPD =
755
514
      *((const MemberPointerData *)(const char *)Data.buffer);
756
514
  return MPD.MemberAndIsDerivedMember.getInt();
757
514
}
758
759
579
ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
760
579
  assert(isMemberPointer() && "Invalid accessor");
761
579
  const MemberPointerData &MPD =
762
579
      *((const MemberPointerData *)(const char *)Data.buffer);
763
579
  return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
764
579
}
765
766
1.13M
void APValue::MakeLValue() {
767
1.13M
  assert(isAbsent() && "Bad state change");
768
1.13M
  static_assert(sizeof(LV) <= DataSize, "LV too big");
769
1.13M
  new ((void*)(char*)Data.buffer) LV();
770
1.13M
  Kind = LValue;
771
1.13M
}
772
773
8.34k
void APValue::MakeArray(unsigned InitElts, unsigned Size) {
774
8.34k
  assert(isAbsent() && "Bad state change");
775
8.34k
  new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
776
8.34k
  Kind = Array;
777
8.34k
}
778
779
void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
780
1.37k
                                ArrayRef<const CXXRecordDecl*> Path) {
781
1.37k
  assert(isAbsent() && "Bad state change");
782
1.37k
  MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
783
1.37k
  Kind = MemberPointer;
784
1.37k
  MPD->MemberAndIsDerivedMember.setPointer(
785
1.19k
      Member ? cast<ValueDecl>(Member->getCanonicalDecl()) : 
nullptr181
);
786
1.37k
  MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
787
1.37k
  MPD->resizePath(Path.size());
788
1.91k
  for (unsigned I = 0; I != Path.size(); 
++I539
)
789
539
    MPD->getPath()[I] = Path[I]->getCanonicalDecl();
790
1.37k
}