aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Compiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.h')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.h59
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 {