summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Interp/ByteCodeStmtGen.cpp')
-rw-r--r--clang/lib/AST/Interp/ByteCodeStmtGen.cpp265
1 files changed, 0 insertions, 265 deletions
diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
deleted file mode 100644
index 25d9cadf6d3..00000000000
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-//===--- ByteCodeStmtGen.cpp - Code generator for expressions ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "ByteCodeStmtGen.h"
-#include "ByteCodeEmitter.h"
-#include "ByteCodeGenError.h"
-#include "Context.h"
-#include "Function.h"
-#include "Program.h"
-#include "State.h"
-#include "Type.h"
-
-using namespace clang;
-using namespace clang::interp;
-
-template <typename T> using Expected = llvm::Expected<T>;
-template <typename T> using Optional = llvm::Optional<T>;
-
-namespace clang {
-namespace interp {
-
-/// Scope managing label targets.
-template <class Emitter> class LabelScope {
-public:
- virtual ~LabelScope() { }
-
-protected:
- LabelScope(ByteCodeStmtGen<Emitter> *Ctx) : Ctx(Ctx) {}
- /// ByteCodeStmtGen instance.
- ByteCodeStmtGen<Emitter> *Ctx;
-};
-
-/// Sets the context for break/continue statements.
-template <class Emitter> class LoopScope final : public LabelScope<Emitter> {
-public:
- using LabelTy = typename ByteCodeStmtGen<Emitter>::LabelTy;
- using OptLabelTy = typename ByteCodeStmtGen<Emitter>::OptLabelTy;
-
- LoopScope(ByteCodeStmtGen<Emitter> *Ctx, LabelTy BreakLabel,
- LabelTy ContinueLabel)
- : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
- OldContinueLabel(Ctx->ContinueLabel) {
- this->Ctx->BreakLabel = BreakLabel;
- this->Ctx->ContinueLabel = ContinueLabel;
- }
-
- ~LoopScope() {
- this->Ctx->BreakLabel = OldBreakLabel;
- this->Ctx->ContinueLabel = OldContinueLabel;
- }
-
-private:
- OptLabelTy OldBreakLabel;
- OptLabelTy OldContinueLabel;
-};
-
-// Sets the context for a switch scope, mapping labels.
-template <class Emitter> class SwitchScope final : public LabelScope<Emitter> {
-public:
- using LabelTy = typename ByteCodeStmtGen<Emitter>::LabelTy;
- using OptLabelTy = typename ByteCodeStmtGen<Emitter>::OptLabelTy;
- using CaseMap = typename ByteCodeStmtGen<Emitter>::CaseMap;
-
- SwitchScope(ByteCodeStmtGen<Emitter> *Ctx, CaseMap &&CaseLabels,
- LabelTy BreakLabel, OptLabelTy DefaultLabel)
- : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
- OldDefaultLabel(this->Ctx->DefaultLabel),
- OldCaseLabels(std::move(this->Ctx->CaseLabels)) {
- this->Ctx->BreakLabel = BreakLabel;
- this->Ctx->DefaultLabel = DefaultLabel;
- this->Ctx->CaseLabels = std::move(CaseLabels);
- }
-
- ~SwitchScope() {
- this->Ctx->BreakLabel = OldBreakLabel;
- this->Ctx->DefaultLabel = OldDefaultLabel;
- this->Ctx->CaseLabels = std::move(OldCaseLabels);
- }
-
-private:
- OptLabelTy OldBreakLabel;
- OptLabelTy OldDefaultLabel;
- CaseMap OldCaseLabels;
-};
-
-} // namespace interp
-} // namespace clang
-
-template <class Emitter>
-bool ByteCodeStmtGen<Emitter>::visitFunc(const FunctionDecl *F) {
- // Classify the return type.
- ReturnType = this->classify(F->getReturnType());
-
- // Set up fields and context if a constructor.
- if (auto *MD = dyn_cast<CXXMethodDecl>(F))
- return this->bail(MD);
-
- if (auto *Body = F->getBody())
- if (!visitStmt(Body))
- return false;
-
- // Emit a guard return to protect against a code path missing one.
- if (F->getReturnType()->isVoidType())
- return this->emitRetVoid(SourceInfo{});
- else
- return this->emitNoRet(SourceInfo{});
-}
-
-template <class Emitter>
-bool ByteCodeStmtGen<Emitter>::visitStmt(const Stmt *S) {
- switch (S->getStmtClass()) {
- case Stmt::CompoundStmtClass:
- return visitCompoundStmt(cast<CompoundStmt>(S));
- case Stmt::DeclStmtClass:
- return visitDeclStmt(cast<DeclStmt>(S));
- case Stmt::ReturnStmtClass:
- return visitReturnStmt(cast<ReturnStmt>(S));
- case Stmt::IfStmtClass:
- return visitIfStmt(cast<IfStmt>(S));
- case Stmt::NullStmtClass:
- return true;
- default: {
- if (auto *Exp = dyn_cast<Expr>(S))
- return this->discard(Exp);
- return this->bail(S);
- }
- }
-}
-
-template <class Emitter>
-bool ByteCodeStmtGen<Emitter>::visitCompoundStmt(
- const CompoundStmt *CompoundStmt) {
- BlockScope<Emitter> Scope(this);
- for (auto *InnerStmt : CompoundStmt->body())
- if (!visitStmt(InnerStmt))
- return false;
- return true;
-}
-
-template <class Emitter>
-bool ByteCodeStmtGen<Emitter>::visitDeclStmt(const DeclStmt *DS) {
- for (auto *D : DS->decls()) {
- // Variable declarator.
- if (auto *VD = dyn_cast<VarDecl>(D)) {
- if (!visitVarDecl(VD))
- return false;
- continue;
- }
-
- // Decomposition declarator.
- if (auto *DD = dyn_cast<DecompositionDecl>(D)) {
- return this->bail(DD);
- }
- }
-
- return true;
-}
-
-template <class Emitter>
-bool ByteCodeStmtGen<Emitter>::visitReturnStmt(const ReturnStmt *RS) {
- if (const Expr *RE = RS->getRetValue()) {
- ExprScope<Emitter> RetScope(this);
- if (ReturnType) {
- // Primitive types are simply returned.
- if (!this->visit(RE))
- return false;
- this->emitCleanup();
- return this->emitRet(*ReturnType, RS);
- } else {
- // RVO - construct the value in the return location.
- auto ReturnLocation = [this, RE] { return this->emitGetParamPtr(0, RE); };
- if (!this->visitInitializer(RE, ReturnLocation))
- return false;
- this->emitCleanup();
- return this->emitRetVoid(RS);
- }
- } else {
- this->emitCleanup();
- if (!this->emitRetVoid(RS))
- return false;
- return true;
- }
-}
-
-template <class Emitter>
-bool ByteCodeStmtGen<Emitter>::visitIfStmt(const IfStmt *IS) {
- BlockScope<Emitter> IfScope(this);
- if (auto *CondInit = IS->getInit())
- if (!visitStmt(IS->getInit()))
- return false;
-
- if (const DeclStmt *CondDecl = IS->getConditionVariableDeclStmt())
- if (!visitDeclStmt(CondDecl))
- return false;
-
- if (!this->visitBool(IS->getCond()))
- return false;
-
- if (const Stmt *Else = IS->getElse()) {
- LabelTy LabelElse = this->getLabel();
- LabelTy LabelEnd = this->getLabel();
- if (!this->jumpFalse(LabelElse))
- return false;
- if (!visitStmt(IS->getThen()))
- return false;
- if (!this->jump(LabelEnd))
- return false;
- this->emitLabel(LabelElse);
- if (!visitStmt(Else))
- return false;
- this->emitLabel(LabelEnd);
- } else {
- LabelTy LabelEnd = this->getLabel();
- if (!this->jumpFalse(LabelEnd))
- return false;
- if (!visitStmt(IS->getThen()))
- return false;
- this->emitLabel(LabelEnd);
- }
-
- return true;
-}
-
-template <class Emitter>
-bool ByteCodeStmtGen<Emitter>::visitVarDecl(const VarDecl *VD) {
- auto DT = VD->getType();
-
- if (!VD->hasLocalStorage()) {
- // No code generation required.
- return true;
- }
-
- // Integers, pointers, primitives.
- if (Optional<PrimType> T = this->classify(DT)) {
- auto Off = this->allocateLocalPrimitive(VD, *T, DT.isConstQualified());
- // Compile the initialiser in its own scope.
- {
- ExprScope<Emitter> Scope(this);
- if (!this->visit(VD->getInit()))
- return false;
- }
- // Set the value.
- return this->emitSetLocal(*T, Off, VD);
- } else {
- // Composite types - allocate storage and initialize it.
- if (auto Off = this->allocateLocal(VD)) {
- return this->visitLocalInitializer(VD->getInit(), *Off);
- } else {
- return this->bail(VD);
- }
- }
-}
-
-namespace clang {
-namespace interp {
-
-template class ByteCodeStmtGen<ByteCodeEmitter>;
-
-} // namespace interp
-} // namespace clang
OpenPOWER on IntegriCloud