003 File Manager
Current Path:
/usr/src/contrib/llvm-project/clang/lib/AST/Interp
usr
/
src
/
contrib
/
llvm-project
/
clang
/
lib
/
AST
/
Interp
/
📁
..
📄
Boolean.h
(4.12 KB)
📄
ByteCodeEmitter.cpp
(5.38 KB)
📄
ByteCodeEmitter.h
(3.13 KB)
📄
ByteCodeExprGen.cpp
(16.6 KB)
📄
ByteCodeExprGen.h
(10.2 KB)
📄
ByteCodeGenError.cpp
(483 B)
📄
ByteCodeGenError.h
(1.36 KB)
📄
ByteCodeStmtGen.cpp
(7.21 KB)
📄
ByteCodeStmtGen.h
(2.39 KB)
📄
Context.cpp
(3.28 KB)
📄
Context.h
(2.39 KB)
📄
Descriptor.cpp
(10.31 KB)
📄
Descriptor.h
(7.82 KB)
📄
Disasm.cpp
(1.95 KB)
📄
EvalEmitter.cpp
(7.6 KB)
📄
EvalEmitter.h
(3.7 KB)
📄
Frame.cpp
(464 B)
📄
Frame.h
(1.28 KB)
📄
Function.cpp
(1.73 KB)
📄
Function.h
(4.91 KB)
📄
Integral.h
(8.38 KB)
📄
Interp.cpp
(11.54 KB)
📄
Interp.h
(30.64 KB)
📄
InterpBlock.cpp
(1.91 KB)
📄
InterpBlock.h
(4.11 KB)
📄
InterpFrame.cpp
(5.32 KB)
📄
InterpFrame.h
(4.54 KB)
📄
InterpStack.cpp
(1.81 KB)
📄
InterpStack.h
(3.43 KB)
📄
InterpState.cpp
(2.03 KB)
📄
InterpState.h
(3.29 KB)
📄
Opcode.h
(817 B)
📄
Opcodes.td
(11.02 KB)
📄
Pointer.cpp
(4.97 KB)
📄
Pointer.h
(11.08 KB)
📄
PrimType.cpp
(648 B)
📄
PrimType.h
(4.66 KB)
📄
Program.cpp
(11.29 KB)
📄
Program.h
(6.66 KB)
📄
Record.cpp
(1.54 KB)
📄
Record.h
(3.76 KB)
📄
Source.cpp
(1.15 KB)
📄
Source.h
(3.25 KB)
📄
State.cpp
(5.34 KB)
📄
State.h
(4.01 KB)
Editing: ByteCodeStmtGen.cpp
//===--- 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 "PrimType.h" #include "Program.h" #include "State.h" #include "clang/Basic/LLVM.h" using namespace clang; using namespace clang::interp; 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
Upload File
Create Folder