1 //===--- ByteCodeStmtGen.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 "ByteCodeStmtGen.h"
10 #include "ByteCodeEmitter.h"
11 #include "ByteCodeGenError.h"
12 #include "Context.h"
13 #include "Function.h"
14 #include "PrimType.h"
15 
16 using namespace clang;
17 using namespace clang::interp;
18 
19 namespace clang {
20 namespace interp {
21 
22 /// Scope managing label targets.
23 template <class Emitter> class LabelScope {
24 public:
~LabelScope()25   virtual ~LabelScope() {  }
26 
27 protected:
LabelScope(ByteCodeStmtGen<Emitter> * Ctx)28   LabelScope(ByteCodeStmtGen<Emitter> *Ctx) : Ctx(Ctx) {}
29   /// ByteCodeStmtGen instance.
30   ByteCodeStmtGen<Emitter> *Ctx;
31 };
32 
33 /// Sets the context for break/continue statements.
34 template <class Emitter> class LoopScope final : public LabelScope<Emitter> {
35 public:
36   using LabelTy = typename ByteCodeStmtGen<Emitter>::LabelTy;
37   using OptLabelTy = typename ByteCodeStmtGen<Emitter>::OptLabelTy;
38 
LoopScope(ByteCodeStmtGen<Emitter> * Ctx,LabelTy BreakLabel,LabelTy ContinueLabel)39   LoopScope(ByteCodeStmtGen<Emitter> *Ctx, LabelTy BreakLabel,
40             LabelTy ContinueLabel)
41       : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
42         OldContinueLabel(Ctx->ContinueLabel) {
43     this->Ctx->BreakLabel = BreakLabel;
44     this->Ctx->ContinueLabel = ContinueLabel;
45   }
46 
~LoopScope()47   ~LoopScope() {
48     this->Ctx->BreakLabel = OldBreakLabel;
49     this->Ctx->ContinueLabel = OldContinueLabel;
50   }
51 
52 private:
53   OptLabelTy OldBreakLabel;
54   OptLabelTy OldContinueLabel;
55 };
56 
57 // Sets the context for a switch scope, mapping labels.
58 template <class Emitter> class SwitchScope final : public LabelScope<Emitter> {
59 public:
60   using LabelTy = typename ByteCodeStmtGen<Emitter>::LabelTy;
61   using OptLabelTy = typename ByteCodeStmtGen<Emitter>::OptLabelTy;
62   using CaseMap = typename ByteCodeStmtGen<Emitter>::CaseMap;
63 
SwitchScope(ByteCodeStmtGen<Emitter> * Ctx,CaseMap && CaseLabels,LabelTy BreakLabel,OptLabelTy DefaultLabel)64   SwitchScope(ByteCodeStmtGen<Emitter> *Ctx, CaseMap &&CaseLabels,
65               LabelTy BreakLabel, OptLabelTy DefaultLabel)
66       : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
67         OldDefaultLabel(this->Ctx->DefaultLabel),
68         OldCaseLabels(std::move(this->Ctx->CaseLabels)) {
69     this->Ctx->BreakLabel = BreakLabel;
70     this->Ctx->DefaultLabel = DefaultLabel;
71     this->Ctx->CaseLabels = std::move(CaseLabels);
72   }
73 
~SwitchScope()74   ~SwitchScope() {
75     this->Ctx->BreakLabel = OldBreakLabel;
76     this->Ctx->DefaultLabel = OldDefaultLabel;
77     this->Ctx->CaseLabels = std::move(OldCaseLabels);
78   }
79 
80 private:
81   OptLabelTy OldBreakLabel;
82   OptLabelTy OldDefaultLabel;
83   CaseMap OldCaseLabels;
84 };
85 
86 } // namespace interp
87 } // namespace clang
88 
89 template <class Emitter>
emitLambdaStaticInvokerBody(const CXXMethodDecl * MD)90 bool ByteCodeStmtGen<Emitter>::emitLambdaStaticInvokerBody(
91     const CXXMethodDecl *MD) {
92   assert(MD->isLambdaStaticInvoker());
93   assert(MD->hasBody());
94   assert(cast<CompoundStmt>(MD->getBody())->body_empty());
95 
96   const CXXRecordDecl *ClosureClass = MD->getParent();
97   const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator();
98   assert(ClosureClass->captures_begin() == ClosureClass->captures_end());
99   const Function *Func = this->getFunction(LambdaCallOp);
100   if (!Func)
101     return false;
102   assert(Func->hasThisPointer());
103   assert(Func->getNumParams() == (MD->getNumParams() + 1 + Func->hasRVO()));
104 
105   if (Func->hasRVO()) {
106     if (!this->emitRVOPtr(MD))
107       return false;
108   }
109 
110   // The lambda call operator needs an instance pointer, but we don't have
111   // one here, and we don't need one either because the lambda cannot have
112   // any captures, as verified above. Emit a null pointer. This is then
113   // special-cased when interpreting to not emit any misleading diagnostics.
114   if (!this->emitNullPtr(MD))
115     return false;
116 
117   // Forward all arguments from the static invoker to the lambda call operator.
118   for (const ParmVarDecl *PVD : MD->parameters()) {
119     auto It = this->Params.find(PVD);
120     assert(It != this->Params.end());
121 
122     // We do the lvalue-to-rvalue conversion manually here, so no need
123     // to care about references.
124     PrimType ParamType = this->classify(PVD->getType()).value_or(PT_Ptr);
125     if (!this->emitGetParam(ParamType, It->second.Offset, MD))
126       return false;
127   }
128 
129   if (!this->emitCall(Func, LambdaCallOp))
130     return false;
131 
132   this->emitCleanup();
133   if (ReturnType)
134     return this->emitRet(*ReturnType, MD);
135 
136   // Nothing to do, since we emitted the RVO pointer above.
137   return this->emitRetVoid(MD);
138 }
139 
140 template <class Emitter>
visitFunc(const FunctionDecl * F)141 bool ByteCodeStmtGen<Emitter>::visitFunc(const FunctionDecl *F) {
142   // Classify the return type.
143   ReturnType = this->classify(F->getReturnType());
144 
145   auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
146                                   const Expr *InitExpr) -> bool {
147     if (std::optional<PrimType> T = this->classify(InitExpr)) {
148       if (!this->visit(InitExpr))
149         return false;
150 
151       if (F->isBitField())
152         return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);
153       return this->emitInitThisField(*T, FieldOffset, InitExpr);
154     }
155     // Non-primitive case. Get a pointer to the field-to-initialize
156     // on the stack and call visitInitialzer() for it.
157     if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
158       return false;
159 
160     if (!this->visitInitializer(InitExpr))
161       return false;
162 
163     return this->emitPopPtr(InitExpr);
164   };
165 
166   // Emit custom code if this is a lambda static invoker.
167   if (const auto *MD = dyn_cast<CXXMethodDecl>(F);
168       MD && MD->isLambdaStaticInvoker())
169     return this->emitLambdaStaticInvokerBody(MD);
170 
171   // Constructor. Set up field initializers.
172   if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F)) {
173     const RecordDecl *RD = Ctor->getParent();
174     const Record *R = this->getRecord(RD);
175     if (!R)
176       return false;
177 
178     for (const auto *Init : Ctor->inits()) {
179       // Scope needed for the initializers.
180       BlockScope<Emitter> Scope(this);
181 
182       const Expr *InitExpr = Init->getInit();
183       if (const FieldDecl *Member = Init->getMember()) {
184         const Record::Field *F = R->getField(Member);
185 
186         if (!emitFieldInitializer(F, F->Offset, InitExpr))
187           return false;
188       } else if (const Type *Base = Init->getBaseClass()) {
189         // Base class initializer.
190         // Get This Base and call initializer on it.
191         const auto *BaseDecl = Base->getAsCXXRecordDecl();
192         assert(BaseDecl);
193         const Record::Base *B = R->getBase(BaseDecl);
194         assert(B);
195         if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
196           return false;
197         if (!this->visitInitializer(InitExpr))
198           return false;
199         if (!this->emitInitPtrPop(InitExpr))
200           return false;
201       } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
202         assert(IFD->getChainingSize() >= 2);
203 
204         unsigned NestedFieldOffset = 0;
205         const Record::Field *NestedField = nullptr;
206         for (const NamedDecl *ND : IFD->chain()) {
207           const auto *FD = cast<FieldDecl>(ND);
208           const Record *FieldRecord =
209               this->P.getOrCreateRecord(FD->getParent());
210           assert(FieldRecord);
211 
212           NestedField = FieldRecord->getField(FD);
213           assert(NestedField);
214 
215           NestedFieldOffset += NestedField->Offset;
216         }
217         assert(NestedField);
218 
219         if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
220           return false;
221       } else {
222         assert(Init->isDelegatingInitializer());
223         if (!this->emitThis(InitExpr))
224           return false;
225         if (!this->visitInitializer(Init->getInit()))
226           return false;
227         if (!this->emitPopPtr(InitExpr))
228           return false;
229       }
230     }
231   }
232 
233   if (const auto *Body = F->getBody())
234     if (!visitStmt(Body))
235       return false;
236 
237   // Emit a guard return to protect against a code path missing one.
238   if (F->getReturnType()->isVoidType())
239     return this->emitRetVoid(SourceInfo{});
240   else
241     return this->emitNoRet(SourceInfo{});
242 }
243 
244 template <class Emitter>
visitStmt(const Stmt * S)245 bool ByteCodeStmtGen<Emitter>::visitStmt(const Stmt *S) {
246   switch (S->getStmtClass()) {
247   case Stmt::CompoundStmtClass:
248     return visitCompoundStmt(cast<CompoundStmt>(S));
249   case Stmt::DeclStmtClass:
250     return visitDeclStmt(cast<DeclStmt>(S));
251   case Stmt::ReturnStmtClass:
252     return visitReturnStmt(cast<ReturnStmt>(S));
253   case Stmt::IfStmtClass:
254     return visitIfStmt(cast<IfStmt>(S));
255   case Stmt::WhileStmtClass:
256     return visitWhileStmt(cast<WhileStmt>(S));
257   case Stmt::DoStmtClass:
258     return visitDoStmt(cast<DoStmt>(S));
259   case Stmt::ForStmtClass:
260     return visitForStmt(cast<ForStmt>(S));
261   case Stmt::CXXForRangeStmtClass:
262     return visitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
263   case Stmt::BreakStmtClass:
264     return visitBreakStmt(cast<BreakStmt>(S));
265   case Stmt::ContinueStmtClass:
266     return visitContinueStmt(cast<ContinueStmt>(S));
267   case Stmt::SwitchStmtClass:
268     return visitSwitchStmt(cast<SwitchStmt>(S));
269   case Stmt::CaseStmtClass:
270     return visitCaseStmt(cast<CaseStmt>(S));
271   case Stmt::DefaultStmtClass:
272     return visitDefaultStmt(cast<DefaultStmt>(S));
273   case Stmt::GCCAsmStmtClass:
274   case Stmt::MSAsmStmtClass:
275     return visitAsmStmt(cast<AsmStmt>(S));
276   case Stmt::AttributedStmtClass:
277     return visitAttributedStmt(cast<AttributedStmt>(S));
278   case Stmt::CXXTryStmtClass:
279     return visitCXXTryStmt(cast<CXXTryStmt>(S));
280   case Stmt::NullStmtClass:
281     return true;
282   default: {
283     if (auto *Exp = dyn_cast<Expr>(S))
284       return this->discard(Exp);
285     return false;
286   }
287   }
288 }
289 
290 /// Visits the given statment without creating a variable
291 /// scope for it in case it is a compound statement.
292 template <class Emitter>
visitLoopBody(const Stmt * S)293 bool ByteCodeStmtGen<Emitter>::visitLoopBody(const Stmt *S) {
294   if (isa<NullStmt>(S))
295     return true;
296 
297   if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
298     for (auto *InnerStmt : CS->body())
299       if (!visitStmt(InnerStmt))
300         return false;
301     return true;
302   }
303 
304   return this->visitStmt(S);
305 }
306 
307 template <class Emitter>
visitCompoundStmt(const CompoundStmt * CompoundStmt)308 bool ByteCodeStmtGen<Emitter>::visitCompoundStmt(
309     const CompoundStmt *CompoundStmt) {
310   BlockScope<Emitter> Scope(this);
311   for (auto *InnerStmt : CompoundStmt->body())
312     if (!visitStmt(InnerStmt))
313       return false;
314   return true;
315 }
316 
317 template <class Emitter>
visitDeclStmt(const DeclStmt * DS)318 bool ByteCodeStmtGen<Emitter>::visitDeclStmt(const DeclStmt *DS) {
319   for (auto *D : DS->decls()) {
320     if (isa<StaticAssertDecl, TagDecl, TypedefNameDecl>(D))
321       continue;
322 
323     const auto *VD = dyn_cast<VarDecl>(D);
324     if (!VD)
325       return false;
326     if (!this->visitVarDecl(VD))
327       return false;
328   }
329 
330   return true;
331 }
332 
333 template <class Emitter>
visitReturnStmt(const ReturnStmt * RS)334 bool ByteCodeStmtGen<Emitter>::visitReturnStmt(const ReturnStmt *RS) {
335   if (const Expr *RE = RS->getRetValue()) {
336     ExprScope<Emitter> RetScope(this);
337     if (ReturnType) {
338       // Primitive types are simply returned.
339       if (!this->visit(RE))
340         return false;
341       this->emitCleanup();
342       return this->emitRet(*ReturnType, RS);
343     } else if (RE->getType()->isVoidType()) {
344       if (!this->visit(RE))
345         return false;
346     } else {
347       // RVO - construct the value in the return location.
348       if (!this->emitRVOPtr(RE))
349         return false;
350       if (!this->visitInitializer(RE))
351         return false;
352       if (!this->emitPopPtr(RE))
353         return false;
354 
355       this->emitCleanup();
356       return this->emitRetVoid(RS);
357     }
358   }
359 
360   // Void return.
361   this->emitCleanup();
362   return this->emitRetVoid(RS);
363 }
364 
365 template <class Emitter>
visitIfStmt(const IfStmt * IS)366 bool ByteCodeStmtGen<Emitter>::visitIfStmt(const IfStmt *IS) {
367   BlockScope<Emitter> IfScope(this);
368 
369   if (IS->isNonNegatedConsteval())
370     return visitStmt(IS->getThen());
371   if (IS->isNegatedConsteval())
372     return IS->getElse() ? visitStmt(IS->getElse()) : true;
373 
374   if (auto *CondInit = IS->getInit())
375     if (!visitStmt(CondInit))
376       return false;
377 
378   if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt())
379     if (!visitDeclStmt(CondDecl))
380       return false;
381 
382   if (!this->visitBool(IS->getCond()))
383     return false;
384 
385   if (const Stmt *Else = IS->getElse()) {
386     LabelTy LabelElse = this->getLabel();
387     LabelTy LabelEnd = this->getLabel();
388     if (!this->jumpFalse(LabelElse))
389       return false;
390     if (!visitStmt(IS->getThen()))
391       return false;
392     if (!this->jump(LabelEnd))
393       return false;
394     this->emitLabel(LabelElse);
395     if (!visitStmt(Else))
396       return false;
397     this->emitLabel(LabelEnd);
398   } else {
399     LabelTy LabelEnd = this->getLabel();
400     if (!this->jumpFalse(LabelEnd))
401       return false;
402     if (!visitStmt(IS->getThen()))
403       return false;
404     this->emitLabel(LabelEnd);
405   }
406 
407   return true;
408 }
409 
410 template <class Emitter>
visitWhileStmt(const WhileStmt * S)411 bool ByteCodeStmtGen<Emitter>::visitWhileStmt(const WhileStmt *S) {
412   const Expr *Cond = S->getCond();
413   const Stmt *Body = S->getBody();
414 
415   LabelTy CondLabel = this->getLabel(); // Label before the condition.
416   LabelTy EndLabel = this->getLabel();  // Label after the loop.
417   LoopScope<Emitter> LS(this, EndLabel, CondLabel);
418 
419   this->emitLabel(CondLabel);
420   if (!this->visitBool(Cond))
421     return false;
422   if (!this->jumpFalse(EndLabel))
423     return false;
424 
425   LocalScope<Emitter> Scope(this);
426   {
427     DestructorScope<Emitter> DS(Scope);
428     if (!this->visitLoopBody(Body))
429       return false;
430   }
431 
432   if (!this->jump(CondLabel))
433     return false;
434   this->emitLabel(EndLabel);
435 
436   return true;
437 }
438 
439 template <class Emitter>
visitDoStmt(const DoStmt * S)440 bool ByteCodeStmtGen<Emitter>::visitDoStmt(const DoStmt *S) {
441   const Expr *Cond = S->getCond();
442   const Stmt *Body = S->getBody();
443 
444   LabelTy StartLabel = this->getLabel();
445   LabelTy EndLabel = this->getLabel();
446   LabelTy CondLabel = this->getLabel();
447   LoopScope<Emitter> LS(this, EndLabel, CondLabel);
448   LocalScope<Emitter> Scope(this);
449 
450   this->emitLabel(StartLabel);
451   {
452     DestructorScope<Emitter> DS(Scope);
453 
454     if (!this->visitLoopBody(Body))
455       return false;
456     this->emitLabel(CondLabel);
457     if (!this->visitBool(Cond))
458       return false;
459   }
460   if (!this->jumpTrue(StartLabel))
461     return false;
462 
463   this->emitLabel(EndLabel);
464   return true;
465 }
466 
467 template <class Emitter>
visitForStmt(const ForStmt * S)468 bool ByteCodeStmtGen<Emitter>::visitForStmt(const ForStmt *S) {
469   // for (Init; Cond; Inc) { Body }
470   const Stmt *Init = S->getInit();
471   const Expr *Cond = S->getCond();
472   const Expr *Inc = S->getInc();
473   const Stmt *Body = S->getBody();
474 
475   LabelTy EndLabel = this->getLabel();
476   LabelTy CondLabel = this->getLabel();
477   LabelTy IncLabel = this->getLabel();
478   LoopScope<Emitter> LS(this, EndLabel, IncLabel);
479   LocalScope<Emitter> Scope(this);
480 
481   if (Init && !this->visitStmt(Init))
482     return false;
483   this->emitLabel(CondLabel);
484   if (Cond) {
485     if (!this->visitBool(Cond))
486       return false;
487     if (!this->jumpFalse(EndLabel))
488       return false;
489   }
490 
491   {
492     DestructorScope<Emitter> DS(Scope);
493 
494     if (Body && !this->visitLoopBody(Body))
495       return false;
496     this->emitLabel(IncLabel);
497     if (Inc && !this->discard(Inc))
498       return false;
499   }
500 
501   if (!this->jump(CondLabel))
502     return false;
503   this->emitLabel(EndLabel);
504   return true;
505 }
506 
507 template <class Emitter>
visitCXXForRangeStmt(const CXXForRangeStmt * S)508 bool ByteCodeStmtGen<Emitter>::visitCXXForRangeStmt(const CXXForRangeStmt *S) {
509   const Stmt *Init = S->getInit();
510   const Expr *Cond = S->getCond();
511   const Expr *Inc = S->getInc();
512   const Stmt *Body = S->getBody();
513   const Stmt *BeginStmt = S->getBeginStmt();
514   const Stmt *RangeStmt = S->getRangeStmt();
515   const Stmt *EndStmt = S->getEndStmt();
516   const VarDecl *LoopVar = S->getLoopVariable();
517 
518   LabelTy EndLabel = this->getLabel();
519   LabelTy CondLabel = this->getLabel();
520   LabelTy IncLabel = this->getLabel();
521   LoopScope<Emitter> LS(this, EndLabel, IncLabel);
522 
523   // Emit declarations needed in the loop.
524   if (Init && !this->visitStmt(Init))
525     return false;
526   if (!this->visitStmt(RangeStmt))
527     return false;
528   if (!this->visitStmt(BeginStmt))
529     return false;
530   if (!this->visitStmt(EndStmt))
531     return false;
532 
533   // Now the condition as well as the loop variable assignment.
534   this->emitLabel(CondLabel);
535   if (!this->visitBool(Cond))
536     return false;
537   if (!this->jumpFalse(EndLabel))
538     return false;
539 
540   if (!this->visitVarDecl(LoopVar))
541     return false;
542 
543   // Body.
544   LocalScope<Emitter> Scope(this);
545   {
546     DestructorScope<Emitter> DS(Scope);
547 
548     if (!this->visitLoopBody(Body))
549       return false;
550     this->emitLabel(IncLabel);
551     if (!this->discard(Inc))
552       return false;
553   }
554   if (!this->jump(CondLabel))
555     return false;
556 
557   this->emitLabel(EndLabel);
558   return true;
559 }
560 
561 template <class Emitter>
visitBreakStmt(const BreakStmt * S)562 bool ByteCodeStmtGen<Emitter>::visitBreakStmt(const BreakStmt *S) {
563   if (!BreakLabel)
564     return false;
565 
566   this->VarScope->emitDestructors();
567   return this->jump(*BreakLabel);
568 }
569 
570 template <class Emitter>
visitContinueStmt(const ContinueStmt * S)571 bool ByteCodeStmtGen<Emitter>::visitContinueStmt(const ContinueStmt *S) {
572   if (!ContinueLabel)
573     return false;
574 
575   this->VarScope->emitDestructors();
576   return this->jump(*ContinueLabel);
577 }
578 
579 template <class Emitter>
visitSwitchStmt(const SwitchStmt * S)580 bool ByteCodeStmtGen<Emitter>::visitSwitchStmt(const SwitchStmt *S) {
581   const Expr *Cond = S->getCond();
582   PrimType CondT = this->classifyPrim(Cond->getType());
583 
584   LabelTy EndLabel = this->getLabel();
585   OptLabelTy DefaultLabel = std::nullopt;
586   unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT, true, false);
587 
588   if (const auto *CondInit = S->getInit())
589     if (!visitStmt(CondInit))
590       return false;
591 
592   // Initialize condition variable.
593   if (!this->visit(Cond))
594     return false;
595   if (!this->emitSetLocal(CondT, CondVar, S))
596     return false;
597 
598   CaseMap CaseLabels;
599   // Create labels and comparison ops for all case statements.
600   for (const SwitchCase *SC = S->getSwitchCaseList(); SC;
601        SC = SC->getNextSwitchCase()) {
602     if (const auto *CS = dyn_cast<CaseStmt>(SC)) {
603       // FIXME: Implement ranges.
604       if (CS->caseStmtIsGNURange())
605         return false;
606       CaseLabels[SC] = this->getLabel();
607 
608       const Expr *Value = CS->getLHS();
609       PrimType ValueT = this->classifyPrim(Value->getType());
610 
611       // Compare the case statement's value to the switch condition.
612       if (!this->emitGetLocal(CondT, CondVar, CS))
613         return false;
614       if (!this->visit(Value))
615         return false;
616 
617       // Compare and jump to the case label.
618       if (!this->emitEQ(ValueT, S))
619         return false;
620       if (!this->jumpTrue(CaseLabels[CS]))
621         return false;
622     } else {
623       assert(!DefaultLabel);
624       DefaultLabel = this->getLabel();
625     }
626   }
627 
628   // If none of the conditions above were true, fall through to the default
629   // statement or jump after the switch statement.
630   if (DefaultLabel) {
631     if (!this->jump(*DefaultLabel))
632       return false;
633   } else {
634     if (!this->jump(EndLabel))
635       return false;
636   }
637 
638   SwitchScope<Emitter> SS(this, std::move(CaseLabels), EndLabel, DefaultLabel);
639   if (!this->visitStmt(S->getBody()))
640     return false;
641   this->emitLabel(EndLabel);
642   return true;
643 }
644 
645 template <class Emitter>
visitCaseStmt(const CaseStmt * S)646 bool ByteCodeStmtGen<Emitter>::visitCaseStmt(const CaseStmt *S) {
647   this->emitLabel(CaseLabels[S]);
648   return this->visitStmt(S->getSubStmt());
649 }
650 
651 template <class Emitter>
visitDefaultStmt(const DefaultStmt * S)652 bool ByteCodeStmtGen<Emitter>::visitDefaultStmt(const DefaultStmt *S) {
653   this->emitLabel(*DefaultLabel);
654   return this->visitStmt(S->getSubStmt());
655 }
656 
657 template <class Emitter>
visitAsmStmt(const AsmStmt * S)658 bool ByteCodeStmtGen<Emitter>::visitAsmStmt(const AsmStmt *S) {
659   return this->emitInvalid(S);
660 }
661 
662 template <class Emitter>
visitAttributedStmt(const AttributedStmt * S)663 bool ByteCodeStmtGen<Emitter>::visitAttributedStmt(const AttributedStmt *S) {
664   // Ignore all attributes.
665   return this->visitStmt(S->getSubStmt());
666 }
667 
668 template <class Emitter>
visitCXXTryStmt(const CXXTryStmt * S)669 bool ByteCodeStmtGen<Emitter>::visitCXXTryStmt(const CXXTryStmt *S) {
670   // Ignore all handlers.
671   return this->visitStmt(S->getTryBlock());
672 }
673 
674 namespace clang {
675 namespace interp {
676 
677 template class ByteCodeStmtGen<ByteCodeEmitter>;
678 
679 } // namespace interp
680 } // namespace clang
681