Coverage Report

Created: 2020-02-15 09:57

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- ByteCodeExprGen.cpp - Code generator for expressions ---*- 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
#include "ByteCodeExprGen.h"
10
#include "ByteCodeEmitter.h"
11
#include "ByteCodeGenError.h"
12
#include "Context.h"
13
#include "Function.h"
14
#include "PrimType.h"
15
#include "Program.h"
16
#include "State.h"
17
18
using namespace clang;
19
using namespace clang::interp;
20
21
using APSInt = llvm::APSInt;
22
template <typename T> using Expected = llvm::Expected<T>;
23
template <typename T> using Optional = llvm::Optional<T>;
24
25
namespace clang {
26
namespace interp {
27
28
/// Scope used to handle temporaries in toplevel variable declarations.
29
template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
30
public:
31
  DeclScope(ByteCodeExprGen<Emitter> *Ctx, const VarDecl *VD)
32
0
      : LocalScope<Emitter>(Ctx), Scope(Ctx->P, VD) {}
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::ByteCodeEmitter>::DeclScope(clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>*, clang::VarDecl const*)
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::EvalEmitter>::DeclScope(clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>*, clang::VarDecl const*)
33
34
0
  void addExtended(const Scope::Local &Local) override {
35
0
    return this->addLocal(Local);
36
0
  }
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::ByteCodeEmitter>::addExtended(clang::interp::Scope::Local const&)
Unexecuted instantiation: clang::interp::DeclScope<clang::interp::EvalEmitter>::addExtended(clang::interp::Scope::Local const&)
37
38
private:
39
  Program::DeclScope Scope;
40
};
41
42
/// Scope used to handle initialization methods.
43
template <class Emitter> class OptionScope {
44
public:
45
  using InitFnRef = typename ByteCodeExprGen<Emitter>::InitFnRef;
46
  using ChainedInitFnRef = std::function<bool(InitFnRef)>;
47
48
  /// Root constructor, compiling or discarding primitives.
49
  OptionScope(ByteCodeExprGen<Emitter> *Ctx, bool NewDiscardResult)
50
      : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
51
28
        OldInitFn(std::move(Ctx->InitFn)) {
52
28
    Ctx->DiscardResult = NewDiscardResult;
53
28
    Ctx->InitFn = llvm::Optional<InitFnRef>{};
54
28
  }
clang::interp::OptionScope<clang::interp::ByteCodeEmitter>::OptionScope(clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>*, bool)
Line
Count
Source
51
9
        OldInitFn(std::move(Ctx->InitFn)) {
52
9
    Ctx->DiscardResult = NewDiscardResult;
53
9
    Ctx->InitFn = llvm::Optional<InitFnRef>{};
54
9
  }
clang::interp::OptionScope<clang::interp::EvalEmitter>::OptionScope(clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>*, bool)
Line
Count
Source
51
19
        OldInitFn(std::move(Ctx->InitFn)) {
52
19
    Ctx->DiscardResult = NewDiscardResult;
53
19
    Ctx->InitFn = llvm::Optional<InitFnRef>{};
54
19
  }
55
56
  /// Root constructor, setting up compilation state.
57
  OptionScope(ByteCodeExprGen<Emitter> *Ctx, InitFnRef NewInitFn)
58
      : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
59
0
        OldInitFn(std::move(Ctx->InitFn)) {
60
0
    Ctx->DiscardResult = true;
61
0
    Ctx->InitFn = NewInitFn;
62
0
  }
Unexecuted instantiation: clang::interp::OptionScope<clang::interp::ByteCodeEmitter>::OptionScope(clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>*, std::__1::function<bool ()>)
Unexecuted instantiation: clang::interp::OptionScope<clang::interp::EvalEmitter>::OptionScope(clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>*, std::__1::function<bool ()>)
63
64
  /// Extends the chain of initialisation pointers.
65
  OptionScope(ByteCodeExprGen<Emitter> *Ctx, ChainedInitFnRef NewInitFn)
66
      : Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
67
        OldInitFn(std::move(Ctx->InitFn)) {
68
    assert(OldInitFn && "missing initializer");
69
    Ctx->InitFn = [this, NewInitFn] { return NewInitFn(*OldInitFn); };
70
  }
71
72
28
  ~OptionScope() {
73
28
    Ctx->DiscardResult = OldDiscardResult;
74
28
    Ctx->InitFn = std::move(OldInitFn);
75
28
  }
clang::interp::OptionScope<clang::interp::ByteCodeEmitter>::~OptionScope()
Line
Count
Source
72
9
  ~OptionScope() {
73
9
    Ctx->DiscardResult = OldDiscardResult;
74
9
    Ctx->InitFn = std::move(OldInitFn);
75
9
  }
clang::interp::OptionScope<clang::interp::EvalEmitter>::~OptionScope()
Line
Count
Source
72
19
  ~OptionScope() {
73
19
    Ctx->DiscardResult = OldDiscardResult;
74
19
    Ctx->InitFn = std::move(OldInitFn);
75
19
  }
76
77
private:
78
  /// Parent context.
79
  ByteCodeExprGen<Emitter> *Ctx;
80
  /// Old discard flag to restore.
81
  bool OldDiscardResult;
82
  /// Old pointer emitter to restore.
83
  llvm::Optional<InitFnRef> OldInitFn;
84
};
85
86
} // namespace interp
87
} // namespace clang
88
89
template <class Emitter>
90
13
bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
91
13
  auto *SubExpr = CE->getSubExpr();
92
13
  switch (CE->getCastKind()) {
93
0
94
13
  case CK_LValueToRValue: {
95
13
    return dereference(
96
13
        CE->getSubExpr(), DerefKind::Read,
97
13
        [](PrimType) {
98
0
          // Value loaded - nothing to do here.
99
0
          return true;
100
0
        },
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCastExpr(clang::CastExpr const*)::'lambda'(clang::interp::PrimType)::operator()(clang::interp::PrimType) const
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCastExpr(clang::CastExpr const*)::'lambda'(clang::interp::PrimType)::operator()(clang::interp::PrimType) const
101
13
        [this, CE](PrimType T) {
102
0
          // Pointer on stack - dereference it.
103
0
          if (!this->emitLoadPop(T, CE))
104
0
            return false;
105
0
          return DiscardResult ? this->emitPop(T, CE) : true;
106
0
        });
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCastExpr(clang::CastExpr const*)::'lambda0'(clang::interp::PrimType)::operator()(clang::interp::PrimType) const
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCastExpr(clang::CastExpr const*)::'lambda0'(clang::interp::PrimType)::operator()(clang::interp::PrimType) const
107
0
  }
108
0
109
0
  case CK_ArrayToPointerDecay:
110
0
  case CK_AtomicToNonAtomic:
111
0
  case CK_ConstructorConversion:
112
0
  case CK_FunctionToPointerDecay:
113
0
  case CK_NonAtomicToAtomic:
114
0
  case CK_NoOp:
115
0
  case CK_UserDefinedConversion:
116
0
    return this->Visit(SubExpr);
117
0
118
0
  case CK_ToVoid:
119
0
    return discard(SubExpr);
120
0
121
0
  default: {
122
0
    // TODO: implement other casts.
123
0
    return this->bail(CE);
124
0
  }
125
13
  }
126
13
}
clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitCastExpr(clang::CastExpr const*)
Line
Count
Source
90
6
bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
91
6
  auto *SubExpr = CE->getSubExpr();
92
6
  switch (CE->getCastKind()) {
93
0
94
6
  case CK_LValueToRValue: {
95
6
    return dereference(
96
6
        CE->getSubExpr(), DerefKind::Read,
97
6
        [](PrimType) {
98
6
          // Value loaded - nothing to do here.
99
6
          return true;
100
6
        },
101
6
        [this, CE](PrimType T) {
102
6
          // Pointer on stack - dereference it.
103
6
          if (!this->emitLoadPop(T, CE))
104
6
            return false;
105
6
          return DiscardResult ? this->emitPop(T, CE) : true;
106
6
        });
107
0
  }
108
0
109
0
  case CK_ArrayToPointerDecay:
110
0
  case CK_AtomicToNonAtomic:
111
0
  case CK_ConstructorConversion:
112
0
  case CK_FunctionToPointerDecay:
113
0
  case CK_NonAtomicToAtomic:
114
0
  case CK_NoOp:
115
0
  case CK_UserDefinedConversion:
116
0
    return this->Visit(SubExpr);
117
0
118
0
  case CK_ToVoid:
119
0
    return discard(SubExpr);
120
0
121
0
  default: {
122
0
    // TODO: implement other casts.
123
0
    return this->bail(CE);
124
0
  }
125
6
  }
126
6
}
clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitCastExpr(clang::CastExpr const*)
Line
Count
Source
90
7
bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
91
7
  auto *SubExpr = CE->getSubExpr();
92
7
  switch (CE->getCastKind()) {
93
0
94
7
  case CK_LValueToRValue: {
95
7
    return dereference(
96
7
        CE->getSubExpr(), DerefKind::Read,
97
7
        [](PrimType) {
98
7
          // Value loaded - nothing to do here.
99
7
          return true;
100
7
        },
101
7
        [this, CE](PrimType T) {
102
7
          // Pointer on stack - dereference it.
103
7
          if (!this->emitLoadPop(T, CE))
104
7
            return false;
105
7
          return DiscardResult ? this->emitPop(T, CE) : true;
106
7
        });
107
0
  }
108
0
109
0
  case CK_ArrayToPointerDecay:
110
0
  case CK_AtomicToNonAtomic:
111
0
  case CK_ConstructorConversion:
112
0
  case CK_FunctionToPointerDecay:
113
0
  case CK_NonAtomicToAtomic:
114
0
  case CK_NoOp:
115
0
  case CK_UserDefinedConversion:
116
0
    return this->Visit(SubExpr);
117
0
118
0
  case CK_ToVoid:
119
0
    return discard(SubExpr);
120
0
121
0
  default: {
122
0
    // TODO: implement other casts.
123
0
    return this->bail(CE);
124
0
  }
125
7
  }
126
7
}
127
128
template <class Emitter>
129
0
bool ByteCodeExprGen<Emitter>::VisitIntegerLiteral(const IntegerLiteral *LE) {
130
0
  if (DiscardResult)
131
0
    return true;
132
0
133
0
  auto Val = LE->getValue();
134
0
  QualType LitTy = LE->getType();
135
0
  if (Optional<PrimType> T = classify(LitTy))
136
0
    return emitConst(*T, getIntWidth(LitTy), LE->getValue(), LE);
137
0
  return this->bail(LE);
138
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitIntegerLiteral(clang::IntegerLiteral const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitIntegerLiteral(clang::IntegerLiteral const*)
139
140
template <class Emitter>
141
0
bool ByteCodeExprGen<Emitter>::VisitParenExpr(const ParenExpr *PE) {
142
0
  return this->Visit(PE->getSubExpr());
143
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitParenExpr(clang::ParenExpr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitParenExpr(clang::ParenExpr const*)
144
145
template <class Emitter>
146
8
bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
147
8
  const Expr *LHS = BO->getLHS();
148
8
  const Expr *RHS = BO->getRHS();
149
8
150
8
  // Deal with operations which have composite or void types.
151
8
  switch (BO->getOpcode()) {
152
0
  case BO_Comma:
153
0
    if (!discard(LHS))
154
0
      return false;
155
0
    if (!this->Visit(RHS))
156
0
      return false;
157
0
    return true;
158
8
  default:
159
8
    break;
160
8
  }
161
8
162
8
  // Typecheck the args.
163
8
  Optional<PrimType> LT = classify(LHS->getType());
164
8
  Optional<PrimType> RT = classify(RHS->getType());
165
8
  if (!LT || !RT) {
166
0
    return this->bail(BO);
167
0
  }
168
8
169
8
  if (Optional<PrimType> T = classify(BO->getType())) {
170
8
    if (!visit(LHS))
171
5
      return false;
172
3
    if (!visit(RHS))
173
0
      return false;
174
3
175
3
    auto Discard = [this, T, BO](bool Result) {
176
3
      if (!Result)
177
0
        return false;
178
3
      return DiscardResult ? 
this->emitPop(*T, BO)0
: true;
179
3
    };
clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)::'lambda'(bool)::operator()(bool) const
Line
Count
Source
175
3
    auto Discard = [this, T, BO](bool Result) {
176
3
      if (!Result)
177
0
        return false;
178
3
      return DiscardResult ? 
this->emitPop(*T, BO)0
: true;
179
3
    };
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)::'lambda'(bool)::operator()(bool) const
180
3
181
3
    switch (BO->getOpcode()) {
182
0
    case BO_EQ:
183
0
      return Discard(this->emitEQ(*LT, BO));
184
0
    case BO_NE:
185
0
      return Discard(this->emitNE(*LT, BO));
186
1
    case BO_LT:
187
1
      return Discard(this->emitLT(*LT, BO));
188
0
    case BO_LE:
189
0
      return Discard(this->emitLE(*LT, BO));
190
0
    case BO_GT:
191
0
      return Discard(this->emitGT(*LT, BO));
192
0
    case BO_GE:
193
0
      return Discard(this->emitGE(*LT, BO));
194
2
    case BO_Sub:
195
2
      return Discard(this->emitSub(*T, BO));
196
0
    case BO_Add:
197
0
      return Discard(this->emitAdd(*T, BO));
198
0
    case BO_Mul:
199
0
      return Discard(this->emitMul(*T, BO));
200
0
    default:
201
0
      return this->bail(BO);
202
0
    }
203
0
  }
204
0
205
0
  return this->bail(BO);
206
0
}
clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)
Line
Count
Source
146
3
bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
147
3
  const Expr *LHS = BO->getLHS();
148
3
  const Expr *RHS = BO->getRHS();
149
3
150
3
  // Deal with operations which have composite or void types.
151
3
  switch (BO->getOpcode()) {
152
0
  case BO_Comma:
153
0
    if (!discard(LHS))
154
0
      return false;
155
0
    if (!this->Visit(RHS))
156
0
      return false;
157
0
    return true;
158
3
  default:
159
3
    break;
160
3
  }
161
3
162
3
  // Typecheck the args.
163
3
  Optional<PrimType> LT = classify(LHS->getType());
164
3
  Optional<PrimType> RT = classify(RHS->getType());
165
3
  if (!LT || !RT) {
166
0
    return this->bail(BO);
167
0
  }
168
3
169
3
  if (Optional<PrimType> T = classify(BO->getType())) {
170
3
    if (!visit(LHS))
171
0
      return false;
172
3
    if (!visit(RHS))
173
0
      return false;
174
3
175
3
    auto Discard = [this, T, BO](bool Result) {
176
3
      if (!Result)
177
3
        return false;
178
3
      return DiscardResult ? this->emitPop(*T, BO) : true;
179
3
    };
180
3
181
3
    switch (BO->getOpcode()) {
182
0
    case BO_EQ:
183
0
      return Discard(this->emitEQ(*LT, BO));
184
0
    case BO_NE:
185
0
      return Discard(this->emitNE(*LT, BO));
186
1
    case BO_LT:
187
1
      return Discard(this->emitLT(*LT, BO));
188
0
    case BO_LE:
189
0
      return Discard(this->emitLE(*LT, BO));
190
0
    case BO_GT:
191
0
      return Discard(this->emitGT(*LT, BO));
192
0
    case BO_GE:
193
0
      return Discard(this->emitGE(*LT, BO));
194
2
    case BO_Sub:
195
2
      return Discard(this->emitSub(*T, BO));
196
0
    case BO_Add:
197
0
      return Discard(this->emitAdd(*T, BO));
198
0
    case BO_Mul:
199
0
      return Discard(this->emitMul(*T, BO));
200
0
    default:
201
0
      return this->bail(BO);
202
0
    }
203
0
  }
204
0
205
0
  return this->bail(BO);
206
0
}
clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::VisitBinaryOperator(clang::BinaryOperator const*)
Line
Count
Source
146
5
bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
147
5
  const Expr *LHS = BO->getLHS();
148
5
  const Expr *RHS = BO->getRHS();
149
5
150
5
  // Deal with operations which have composite or void types.
151
5
  switch (BO->getOpcode()) {
152
0
  case BO_Comma:
153
0
    if (!discard(LHS))
154
0
      return false;
155
0
    if (!this->Visit(RHS))
156
0
      return false;
157
0
    return true;
158
5
  default:
159
5
    break;
160
5
  }
161
5
162
5
  // Typecheck the args.
163
5
  Optional<PrimType> LT = classify(LHS->getType());
164
5
  Optional<PrimType> RT = classify(RHS->getType());
165
5
  if (!LT || !RT) {
166
0
    return this->bail(BO);
167
0
  }
168
5
169
5
  if (Optional<PrimType> T = classify(BO->getType())) {
170
5
    if (!visit(LHS))
171
5
      return false;
172
0
    if (!visit(RHS))
173
0
      return false;
174
0
175
0
    auto Discard = [this, T, BO](bool Result) {
176
0
      if (!Result)
177
0
        return false;
178
0
      return DiscardResult ? this->emitPop(*T, BO) : true;
179
0
    };
180
0
181
0
    switch (BO->getOpcode()) {
182
0
    case BO_EQ:
183
0
      return Discard(this->emitEQ(*LT, BO));
184
0
    case BO_NE:
185
0
      return Discard(this->emitNE(*LT, BO));
186
0
    case BO_LT:
187
0
      return Discard(this->emitLT(*LT, BO));
188
0
    case BO_LE:
189
0
      return Discard(this->emitLE(*LT, BO));
190
0
    case BO_GT:
191
0
      return Discard(this->emitGT(*LT, BO));
192
0
    case BO_GE:
193
0
      return Discard(this->emitGE(*LT, BO));
194
0
    case BO_Sub:
195
0
      return Discard(this->emitSub(*T, BO));
196
0
    case BO_Add:
197
0
      return Discard(this->emitAdd(*T, BO));
198
0
    case BO_Mul:
199
0
      return Discard(this->emitMul(*T, BO));
200
0
    default:
201
0
      return this->bail(BO);
202
0
    }
203
0
  }
204
0
205
0
  return this->bail(BO);
206
0
}
207
208
template <class Emitter>
209
0
bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
210
0
  OptionScope<Emitter> Scope(this, /*discardResult=*/true);
211
0
  return this->Visit(E);
212
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::discard(clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::discard(clang::Expr const*)
213
214
template <class Emitter>
215
28
bool ByteCodeExprGen<Emitter>::visit(const Expr *E) {
216
28
  OptionScope<Emitter> Scope(this, /*discardResult=*/false);
217
28
  return this->Visit(E);
218
28
}
clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visit(clang::Expr const*)
Line
Count
Source
215
9
bool ByteCodeExprGen<Emitter>::visit(const Expr *E) {
216
9
  OptionScope<Emitter> Scope(this, /*discardResult=*/false);
217
9
  return this->Visit(E);
218
9
}
clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visit(clang::Expr const*)
Line
Count
Source
215
19
bool ByteCodeExprGen<Emitter>::visit(const Expr *E) {
216
19
  OptionScope<Emitter> Scope(this, /*discardResult=*/false);
217
19
  return this->Visit(E);
218
19
}
219
220
template <class Emitter>
221
1
bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) {
222
1
  if (Optional<PrimType> T = classify(E->getType())) {
223
1
    return visit(E);
224
1
  } else {
225
0
    return this->bail(E);
226
0
  }
227
1
}
clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitBool(clang::Expr const*)
Line
Count
Source
221
1
bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) {
222
1
  if (Optional<PrimType> T = classify(E->getType())) {
223
1
    return visit(E);
224
1
  } else {
225
0
    return this->bail(E);
226
0
  }
227
1
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitBool(clang::Expr const*)
228
229
template <class Emitter>
230
0
bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, const Expr *E) {
231
0
  switch (T) {
232
0
  case PT_Bool:
233
0
    return this->emitZeroBool(E);
234
0
  case PT_Sint8:
235
0
    return this->emitZeroSint8(E);
236
0
  case PT_Uint8:
237
0
    return this->emitZeroUint8(E);
238
0
  case PT_Sint16:
239
0
    return this->emitZeroSint16(E);
240
0
  case PT_Uint16:
241
0
    return this->emitZeroUint16(E);
242
0
  case PT_Sint32:
243
0
    return this->emitZeroSint32(E);
244
0
  case PT_Uint32:
245
0
    return this->emitZeroUint32(E);
246
0
  case PT_Sint64:
247
0
    return this->emitZeroSint64(E);
248
0
  case PT_Uint64:
249
0
    return this->emitZeroUint64(E);
250
0
  case PT_Ptr:
251
0
    return this->emitNullPtr(E);
252
0
  }
253
0
  llvm_unreachable("unknown primitive type");
254
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitZeroInitializer(clang::interp::PrimType, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitZeroInitializer(clang::interp::PrimType, clang::Expr const*)
255
256
template <class Emitter>
257
bool ByteCodeExprGen<Emitter>::dereference(
258
    const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
259
13
    llvm::function_ref<bool(PrimType)> Indirect) {
260
13
  if (Optional<PrimType> T = classify(LV->getType())) {
261
13
    if (!LV->refersToBitField()) {
262
13
      // Only primitive, non bit-field types can be dereferenced directly.
263
13
      if (auto *DE = dyn_cast<DeclRefExpr>(LV)) {
264
13
        if (!DE->getDecl()->getType()->isReferenceType()) {
265
13
          if (auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
266
13
            return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
267
0
          if (auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
268
0
            return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
269
0
        }
270
13
      }
271
13
    }
272
0
273
0
    if (!visit(LV))
274
0
      return false;
275
0
    return Indirect(*T);
276
0
  }
277
0
278
0
  return false;
279
0
}
clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::dereference(clang::Expr const*, clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
Line
Count
Source
259
6
    llvm::function_ref<bool(PrimType)> Indirect) {
260
6
  if (Optional<PrimType> T = classify(LV->getType())) {
261
6
    if (!LV->refersToBitField()) {
262
6
      // Only primitive, non bit-field types can be dereferenced directly.
263
6
      if (auto *DE = dyn_cast<DeclRefExpr>(LV)) {
264
6
        if (!DE->getDecl()->getType()->isReferenceType()) {
265
6
          if (auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
266
6
            return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
267
0
          if (auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
268
0
            return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
269
0
        }
270
6
      }
271
6
    }
272
0
273
0
    if (!visit(LV))
274
0
      return false;
275
0
    return Indirect(*T);
276
0
  }
277
0
278
0
  return false;
279
0
}
clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::dereference(clang::Expr const*, clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
Line
Count
Source
259
7
    llvm::function_ref<bool(PrimType)> Indirect) {
260
7
  if (Optional<PrimType> T = classify(LV->getType())) {
261
7
    if (!LV->refersToBitField()) {
262
7
      // Only primitive, non bit-field types can be dereferenced directly.
263
7
      if (auto *DE = dyn_cast<DeclRefExpr>(LV)) {
264
7
        if (!DE->getDecl()->getType()->isReferenceType()) {
265
7
          if (auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
266
7
            return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
267
0
          if (auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
268
0
            return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
269
0
        }
270
7
      }
271
7
    }
272
0
273
0
    if (!visit(LV))
274
0
      return false;
275
0
    return Indirect(*T);
276
0
  }
277
0
278
0
  return false;
279
0
}
280
281
template <class Emitter>
282
bool ByteCodeExprGen<Emitter>::dereferenceParam(
283
    const Expr *LV, PrimType T, const ParmVarDecl *PD, DerefKind AK,
284
    llvm::function_ref<bool(PrimType)> Direct,
285
13
    llvm::function_ref<bool(PrimType)> Indirect) {
286
13
  auto It = this->Params.find(PD);
287
13
  if (It != this->Params.end()) {
288
6
    unsigned Idx = It->second;
289
6
    switch (AK) {
290
6
    case DerefKind::Read:
291
6
      return DiscardResult ? 
true0
: this->emitGetParam(T, Idx, LV);
292
0
293
0
    case DerefKind::Write:
294
0
      if (!Direct(T))
295
0
        return false;
296
0
      if (!this->emitSetParam(T, Idx, LV))
297
0
        return false;
298
0
      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
299
0
300
0
    case DerefKind::ReadWrite:
301
0
      if (!this->emitGetParam(T, Idx, LV))
302
0
        return false;
303
0
      if (!Direct(T))
304
0
        return false;
305
0
      if (!this->emitSetParam(T, Idx, LV))
306
0
        return false;
307
0
      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
308
0
    }
309
0
    return true;
310
0
  }
311
7
312
7
  // If the param is a pointer, we can dereference a dummy value.
313
7
  if (!DiscardResult && T == PT_Ptr && 
AK == DerefKind::Read0
) {
314
0
    if (auto Idx = P.getOrCreateDummy(PD))
315
0
      return this->emitGetPtrGlobal(*Idx, PD);
316
0
    return false;
317
0
  }
318
7
319
7
  // Value cannot be produced - try to emit pointer and do stuff with it.
320
7
  return visit(LV) && 
Indirect(T)0
;
321
7
}
clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::dereferenceParam(clang::Expr const*, clang::interp::PrimType, clang::ParmVarDecl const*, clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
Line
Count
Source
285
6
    llvm::function_ref<bool(PrimType)> Indirect) {
286
6
  auto It = this->Params.find(PD);
287
6
  if (It != this->Params.end()) {
288
6
    unsigned Idx = It->second;
289
6
    switch (AK) {
290
6
    case DerefKind::Read:
291
6
      return DiscardResult ? 
true0
: this->emitGetParam(T, Idx, LV);
292
0
293
0
    case DerefKind::Write:
294
0
      if (!Direct(T))
295
0
        return false;
296
0
      if (!this->emitSetParam(T, Idx, LV))
297
0
        return false;
298
0
      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
299
0
300
0
    case DerefKind::ReadWrite:
301
0
      if (!this->emitGetParam(T, Idx, LV))
302
0
        return false;
303
0
      if (!Direct(T))
304
0
        return false;
305
0
      if (!this->emitSetParam(T, Idx, LV))
306
0
        return false;
307
0
      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
308
0
    }
309
0
    return true;
310
0
  }
311
0
312
0
  // If the param is a pointer, we can dereference a dummy value.
313
0
  if (!DiscardResult && T == PT_Ptr && AK == DerefKind::Read) {
314
0
    if (auto Idx = P.getOrCreateDummy(PD))
315
0
      return this->emitGetPtrGlobal(*Idx, PD);
316
0
    return false;
317
0
  }
318
0
319
0
  // Value cannot be produced - try to emit pointer and do stuff with it.
320
0
  return visit(LV) && Indirect(T);
321
0
}
clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::dereferenceParam(clang::Expr const*, clang::interp::PrimType, clang::ParmVarDecl const*, clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
Line
Count
Source
285
7
    llvm::function_ref<bool(PrimType)> Indirect) {
286
7
  auto It = this->Params.find(PD);
287
7
  if (It != this->Params.end()) {
288
0
    unsigned Idx = It->second;
289
0
    switch (AK) {
290
0
    case DerefKind::Read:
291
0
      return DiscardResult ? true : this->emitGetParam(T, Idx, LV);
292
0
293
0
    case DerefKind::Write:
294
0
      if (!Direct(T))
295
0
        return false;
296
0
      if (!this->emitSetParam(T, Idx, LV))
297
0
        return false;
298
0
      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
299
0
300
0
    case DerefKind::ReadWrite:
301
0
      if (!this->emitGetParam(T, Idx, LV))
302
0
        return false;
303
0
      if (!Direct(T))
304
0
        return false;
305
0
      if (!this->emitSetParam(T, Idx, LV))
306
0
        return false;
307
0
      return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
308
0
    }
309
0
    return true;
310
0
  }
311
7
312
7
  // If the param is a pointer, we can dereference a dummy value.
313
7
  if (!DiscardResult && T == PT_Ptr && 
AK == DerefKind::Read0
) {
314
0
    if (auto Idx = P.getOrCreateDummy(PD))
315
0
      return this->emitGetPtrGlobal(*Idx, PD);
316
0
    return false;
317
0
  }
318
7
319
7
  // Value cannot be produced - try to emit pointer and do stuff with it.
320
7
  return visit(LV) && 
Indirect(T)0
;
321
7
}
322
323
template <class Emitter>
324
bool ByteCodeExprGen<Emitter>::dereferenceVar(
325
    const Expr *LV, PrimType T, const VarDecl *VD, DerefKind AK,
326
    llvm::function_ref<bool(PrimType)> Direct,
327
0
    llvm::function_ref<bool(PrimType)> Indirect) {
328
0
  auto It = Locals.find(VD);
329
0
  if (It != Locals.end()) {
330
0
    const auto &L = It->second;
331
0
    switch (AK) {
332
0
    case DerefKind::Read:
333
0
      if (!this->emitGetLocal(T, L.Offset, LV))
334
0
        return false;
335
0
      return DiscardResult ? this->emitPop(T, LV) : true;
336
0
337
0
    case DerefKind::Write:
338
0
      if (!Direct(T))
339
0
        return false;
340
0
      if (!this->emitSetLocal(T, L.Offset, LV))
341
0
        return false;
342
0
      return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
343
0
344
0
    case DerefKind::ReadWrite:
345
0
      if (!this->emitGetLocal(T, L.Offset, LV))
346
0
        return false;
347
0
      if (!Direct(T))
348
0
        return false;
349
0
      if (!this->emitSetLocal(T, L.Offset, LV))
350
0
        return false;
351
0
      return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
352
0
    }
353
0
  } else if (auto Idx = getGlobalIdx(VD)) {
354
0
    switch (AK) {
355
0
    case DerefKind::Read:
356
0
      if (!this->emitGetGlobal(T, *Idx, LV))
357
0
        return false;
358
0
      return DiscardResult ? this->emitPop(T, LV) : true;
359
0
360
0
    case DerefKind::Write:
361
0
      if (!Direct(T))
362
0
        return false;
363
0
      if (!this->emitSetGlobal(T, *Idx, LV))
364
0
        return false;
365
0
      return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
366
0
367
0
    case DerefKind::ReadWrite:
368
0
      if (!this->emitGetGlobal(T, *Idx, LV))
369
0
        return false;
370
0
      if (!Direct(T))
371
0
        return false;
372
0
      if (!this->emitSetGlobal(T, *Idx, LV))
373
0
        return false;
374
0
      return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
375
0
    }
376
0
  }
377
0
378
0
  // If the declaration is a constant value, emit it here even
379
0
  // though the declaration was not evaluated in the current scope.
380
0
  // The access mode can only be read in this case.
381
0
  if (!DiscardResult && AK == DerefKind::Read) {
382
0
    if (VD->hasLocalStorage() && VD->hasInit() && !VD->isConstexpr()) {
383
0
      QualType VT = VD->getType();
384
0
      if (VT.isConstQualified() && VT->isFundamentalType())
385
0
        return this->Visit(VD->getInit());
386
0
    }
387
0
  }
388
0
389
0
  // Value cannot be produced - try to emit pointer.
390
0
  return visit(LV) && Indirect(T);
391
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::dereferenceVar(clang::Expr const*, clang::interp::PrimType, clang::VarDecl const*, clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::dereferenceVar(clang::Expr const*, clang::interp::PrimType, clang::VarDecl const*, clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::DerefKind, llvm::function_ref<bool (clang::interp::PrimType)>, llvm::function_ref<bool (clang::interp::PrimType)>)
392
393
template <class Emitter>
394
bool ByteCodeExprGen<Emitter>::emitConst(PrimType T, unsigned NumBits,
395
0
                                         const APInt &Value, const Expr *E) {
396
0
  switch (T) {
397
0
  case PT_Sint8:
398
0
    return this->emitConstSint8(Value.getSExtValue(), E);
399
0
  case PT_Uint8:
400
0
    return this->emitConstUint8(Value.getZExtValue(), E);
401
0
  case PT_Sint16:
402
0
    return this->emitConstSint16(Value.getSExtValue(), E);
403
0
  case PT_Uint16:
404
0
    return this->emitConstUint16(Value.getZExtValue(), E);
405
0
  case PT_Sint32:
406
0
    return this->emitConstSint32(Value.getSExtValue(), E);
407
0
  case PT_Uint32:
408
0
    return this->emitConstUint32(Value.getZExtValue(), E);
409
0
  case PT_Sint64:
410
0
    return this->emitConstSint64(Value.getSExtValue(), E);
411
0
  case PT_Uint64:
412
0
    return this->emitConstUint64(Value.getZExtValue(), E);
413
0
  case PT_Bool:
414
0
    return this->emitConstBool(Value.getBoolValue(), E);
415
0
  case PT_Ptr:
416
0
    llvm_unreachable("Invalid integral type");
417
0
    break;
418
0
  }
419
0
  llvm_unreachable("unknown primitive type");
420
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitConst(clang::interp::PrimType, unsigned int, llvm::APInt const&, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitConst(clang::interp::PrimType, unsigned int, llvm::APInt const&, clang::Expr const*)
421
422
template <class Emitter>
423
unsigned ByteCodeExprGen<Emitter>::allocateLocalPrimitive(DeclTy &&Src,
424
                                                          PrimType Ty,
425
                                                          bool IsConst,
426
0
                                                          bool IsExtended) {
427
0
  Descriptor *D = P.createDescriptor(Src, Ty, IsConst, Src.is<const Expr *>());
428
0
  Scope::Local Local = this->createLocal(D);
429
0
  if (auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<const Decl *>()))
430
0
    Locals.insert({VD, Local});
431
0
  VarScope->add(Local, IsExtended);
432
0
  return Local.Offset;
433
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::allocateLocalPrimitive(llvm::PointerUnion<clang::Decl const*, clang::Expr const*>&&, clang::interp::PrimType, bool, bool)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::allocateLocalPrimitive(llvm::PointerUnion<clang::Decl const*, clang::Expr const*>&&, clang::interp::PrimType, bool, bool)
434
435
template <class Emitter>
436
llvm::Optional<unsigned>
437
0
ByteCodeExprGen<Emitter>::allocateLocal(DeclTy &&Src, bool IsExtended) {
438
0
  QualType Ty;
439
0
440
0
  const ValueDecl *Key = nullptr;
441
0
  bool IsTemporary = false;
442
0
  if (auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<const Decl *>())) {
443
0
    Key = VD;
444
0
    Ty = VD->getType();
445
0
  }
446
0
  if (auto *E = Src.dyn_cast<const Expr *>()) {
447
0
    IsTemporary = true;
448
0
    Ty = E->getType();
449
0
  }
450
0
451
0
  Descriptor *D = P.createDescriptor(Src, Ty.getTypePtr(),
452
0
                                     Ty.isConstQualified(), IsTemporary);
453
0
  if (!D)
454
0
    return {};
455
0
456
0
  Scope::Local Local = this->createLocal(D);
457
0
  if (Key)
458
0
    Locals.insert({Key, Local});
459
0
  VarScope->add(Local, IsExtended);
460
0
  return Local.Offset;
461
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::allocateLocal(llvm::PointerUnion<clang::Decl const*, clang::Expr const*>&&, bool)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::allocateLocal(llvm::PointerUnion<clang::Decl const*, clang::Expr const*>&&, bool)
462
463
template <class Emitter>
464
bool ByteCodeExprGen<Emitter>::visitInitializer(
465
0
    const Expr *Init, InitFnRef InitFn) {
466
0
  OptionScope<Emitter> Scope(this, InitFn);
467
0
  return this->Visit(Init);
468
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitInitializer(clang::Expr const*, std::__1::function<bool ()>)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitInitializer(clang::Expr const*, std::__1::function<bool ()>)
469
470
template <class Emitter>
471
0
bool ByteCodeExprGen<Emitter>::getPtrVarDecl(const VarDecl *VD, const Expr *E) {
472
0
  // Generate a pointer to the local, loading refs.
473
0
  if (Optional<unsigned> Idx = getGlobalIdx(VD)) {
474
0
    if (VD->getType()->isReferenceType())
475
0
      return this->emitGetGlobalPtr(*Idx, E);
476
0
    else
477
0
      return this->emitGetPtrGlobal(*Idx, E);
478
0
  }
479
0
  return this->bail(VD);
480
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::getPtrVarDecl(clang::VarDecl const*, clang::Expr const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::getPtrVarDecl(clang::VarDecl const*, clang::Expr const*)
481
482
template <class Emitter>
483
llvm::Optional<unsigned>
484
0
ByteCodeExprGen<Emitter>::getGlobalIdx(const VarDecl *VD) {
485
0
  if (VD->isConstexpr()) {
486
0
    // Constexpr decl - it must have already been defined.
487
0
    return P.getGlobal(VD);
488
0
  }
489
0
  if (!VD->hasLocalStorage()) {
490
0
    // Not constexpr, but a global var - can have pointer taken.
491
0
    Program::DeclScope Scope(P, VD);
492
0
    return P.getOrCreateGlobal(VD);
493
0
  }
494
0
  return {};
495
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::getGlobalIdx(clang::VarDecl const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::getGlobalIdx(clang::VarDecl const*)
496
497
template <class Emitter>
498
0
const RecordType *ByteCodeExprGen<Emitter>::getRecordTy(QualType Ty) {
499
0
  if (auto *PT = dyn_cast<PointerType>(Ty))
500
0
    return PT->getPointeeType()->getAs<RecordType>();
501
0
  else
502
0
    return Ty->getAs<RecordType>();
503
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::getRecordTy(clang::QualType)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::getRecordTy(clang::QualType)
504
505
template <class Emitter>
506
0
Record *ByteCodeExprGen<Emitter>::getRecord(QualType Ty) {
507
0
  if (auto *RecordTy = getRecordTy(Ty)) {
508
0
    return getRecord(RecordTy->getDecl());
509
0
  }
510
0
  return nullptr;
511
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::getRecord(clang::QualType)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::getRecord(clang::QualType)
512
513
template <class Emitter>
514
0
Record *ByteCodeExprGen<Emitter>::getRecord(const RecordDecl *RD) {
515
0
  return P.getOrCreateRecord(RD);
516
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::getRecord(clang::RecordDecl const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::getRecord(clang::RecordDecl const*)
517
518
template <class Emitter>
519
7
bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *Exp) {
520
7
  ExprScope<Emitter> RootScope(this);
521
7
  if (!visit(Exp))
522
7
    return false;
523
0
524
0
  if (Optional<PrimType> T = classify(Exp))
525
0
    return this->emitRet(*T, Exp);
526
0
  else
527
0
    return this->emitRetValue(Exp);
528
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitExpr(clang::Expr const*)
clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitExpr(clang::Expr const*)
Line
Count
Source
519
7
bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *Exp) {
520
7
  ExprScope<Emitter> RootScope(this);
521
7
  if (!visit(Exp))
522
7
    return false;
523
0
524
0
  if (Optional<PrimType> T = classify(Exp))
525
0
    return this->emitRet(*T, Exp);
526
0
  else
527
0
    return this->emitRetValue(Exp);
528
0
}
529
530
template <class Emitter>
531
0
bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
532
0
  const Expr *Init = VD->getInit();
533
0
534
0
  if (Optional<unsigned> I = P.createGlobal(VD)) {
535
0
    if (Optional<PrimType> T = classify(VD->getType())) {
536
0
      {
537
0
        // Primitive declarations - compute the value and set it.
538
0
        DeclScope<Emitter> LocalScope(this, VD);
539
0
        if (!visit(Init))
540
0
          return false;
541
0
      }
542
0
543
0
      // If the declaration is global, save the value for later use.
544
0
      if (!this->emitDup(*T, VD))
545
0
        return false;
546
0
      if (!this->emitInitGlobal(*T, *I, VD))
547
0
        return false;
548
0
      return this->emitRet(*T, VD);
549
0
    } else {
550
0
      {
551
0
        // Composite declarations - allocate storage and initialize it.
552
0
        DeclScope<Emitter> LocalScope(this, VD);
553
0
        if (!visitGlobalInitializer(Init, *I))
554
0
          return false;
555
0
      }
556
0
557
0
      // Return a pointer to the global.
558
0
      if (!this->emitGetPtrGlobal(*I, VD))
559
0
        return false;
560
0
      return this->emitRetValue(VD);
561
0
    }
562
0
  }
563
0
564
0
  return this->bail(VD);
565
0
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::visitDecl(clang::VarDecl const*)
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::visitDecl(clang::VarDecl const*)
566
567
template <class Emitter>
568
2
void ByteCodeExprGen<Emitter>::emitCleanup() {
569
10
  for (VariableScope<Emitter> *C = VarScope; C; 
C = C->getParent()8
)
570
8
    C->emitDestruction();
571
2
}
clang::interp::ByteCodeExprGen<clang::interp::ByteCodeEmitter>::emitCleanup()
Line
Count
Source
568
2
void ByteCodeExprGen<Emitter>::emitCleanup() {
569
10
  for (VariableScope<Emitter> *C = VarScope; C; 
C = C->getParent()8
)
570
8
    C->emitDestruction();
571
2
}
Unexecuted instantiation: clang::interp::ByteCodeExprGen<clang::interp::EvalEmitter>::emitCleanup()
572
573
namespace clang {
574
namespace interp {
575
576
template class ByteCodeExprGen<ByteCodeEmitter>;
577
template class ByteCodeExprGen<EvalEmitter>;
578
579
} // namespace interp
580
} // namespace clang