diff options
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.h')
-rw-r--r-- | clang/lib/AST/ByteCode/Compiler.h | 59 |
1 files changed, 33 insertions, 26 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index 56a972f..ac3ad84 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -102,6 +102,8 @@ struct VarCreationState { bool notCreated() const { return !S; } }; +enum class ScopeKind { Call, Block }; + /// Compilation context for expressions. template <class Emitter> class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, @@ -305,17 +307,19 @@ protected: const Expr *E); bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init, std::optional<PrimType> InitT); + bool visitCallArgs(ArrayRef<const Expr *> Args, const FunctionDecl *FuncDecl); /// Creates a local primitive value. unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, const ValueDecl *ExtendingDecl = nullptr, + ScopeKind SC = ScopeKind::Block, bool IsConstexprUnknown = false); /// Allocates a space storing a local given its type. std::optional<unsigned> allocateLocal(DeclTy &&Decl, QualType Ty = QualType(), const ValueDecl *ExtendingDecl = nullptr, - bool IsConstexprUnknown = false); + ScopeKind = ScopeKind::Block, bool IsConstexprUnknown = false); std::optional<unsigned> allocateTemporary(const Expr *E); private: @@ -451,28 +455,16 @@ extern template class Compiler<EvalEmitter>; /// Scope chain managing the variable lifetimes. template <class Emitter> class VariableScope { public: - VariableScope(Compiler<Emitter> *Ctx, const ValueDecl *VD) - : Ctx(Ctx), Parent(Ctx->VarScope), ValDecl(VD) { + VariableScope(Compiler<Emitter> *Ctx, const ValueDecl *VD, + ScopeKind Kind = ScopeKind::Block) + : Ctx(Ctx), Parent(Ctx->VarScope), ValDecl(VD), Kind(Kind) { Ctx->VarScope = this; } virtual ~VariableScope() { Ctx->VarScope = this->Parent; } - void add(const Scope::Local &Local, bool IsExtended) { - if (IsExtended) - this->addExtended(Local); - else - this->addLocal(Local); - } - virtual void addLocal(const Scope::Local &Local) { - if (this->Parent) - this->Parent->addLocal(Local); - } - - virtual void addExtended(const Scope::Local &Local) { - if (this->Parent) - this->Parent->addExtended(Local); + llvm_unreachable("Shouldn't be called"); } void addExtended(const Scope::Local &Local, const ValueDecl *ExtendingDecl) { @@ -496,10 +488,28 @@ public: this->addLocal(Local); } + /// Like addExtended, but adds to the nearest scope of the given kind. + void addForScopeKind(const Scope::Local &Local, ScopeKind Kind) { + VariableScope *P = this; + while (P) { + if (P->Kind == Kind) { + P->addLocal(Local); + return; + } + P = P->Parent; + if (!P) + break; + } + + // Add to this scope. + this->addLocal(Local); + } + virtual void emitDestruction() {} virtual bool emitDestructors(const Expr *E = nullptr) { return true; } virtual bool destroyLocals(const Expr *E = nullptr) { return true; } VariableScope *getParent() const { return Parent; } + ScopeKind getKind() const { return Kind; } protected: /// Compiler instance. @@ -507,12 +517,14 @@ protected: /// Link to the parent scope. VariableScope *Parent; const ValueDecl *ValDecl = nullptr; + ScopeKind Kind; }; /// Generic scope for local variables. template <class Emitter> class LocalScope : public VariableScope<Emitter> { public: - LocalScope(Compiler<Emitter> *Ctx) : VariableScope<Emitter>(Ctx, nullptr) {} + LocalScope(Compiler<Emitter> *Ctx, ScopeKind Kind = ScopeKind::Block) + : VariableScope<Emitter>(Ctx, nullptr, Kind) {} LocalScope(Compiler<Emitter> *Ctx, const ValueDecl *VD) : VariableScope<Emitter>(Ctx, VD) {} @@ -599,16 +611,11 @@ public: }; /// Scope for storage declared in a compound statement. +// FIXME: Remove? template <class Emitter> class BlockScope final : public LocalScope<Emitter> { public: - BlockScope(Compiler<Emitter> *Ctx) : LocalScope<Emitter>(Ctx) {} - - void addExtended(const Scope::Local &Local) override { - // If we to this point, just add the variable as a normal local - // variable. It will be destroyed at the end of the block just - // like all others. - this->addLocal(Local); - } + BlockScope(Compiler<Emitter> *Ctx, ScopeKind Kind = ScopeKind::Block) + : LocalScope<Emitter>(Ctx, Kind) {} }; template <class Emitter> class ArrayIndexScope final { |