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