@@ -46,6 +46,7 @@ class ScopeManager {
4646 struct Frame {
4747 enum class Kind : std::uint8_t {
4848 kRegular ,
49+ kTemporaries ,
4950 kLoop ,
5051 };
5152
@@ -57,7 +58,7 @@ class ScopeManager {
5758 Kind kind;
5859 };
5960
60- void Enter (Frame::Kind kind = Frame::Kind:: kRegular ) {
61+ void Enter (Frame::Kind kind) {
6162 frame_stack_.emplace_back (Frame{
6263 .begin = u_.builder .GetInsertPoint (),
6364 .kind = kind,
@@ -192,6 +193,17 @@ class ScopeManager {
192193 llvm::Function* fn_;
193194};
194195
196+ class ScopeGuard {
197+ public:
198+ ScopeGuard (ScopeManager& m) : m_(m) {}
199+ ~ScopeGuard () {
200+ m_.Exit ();
201+ }
202+
203+ private:
204+ ScopeManager& m_;
205+ };
206+
195207class FunctionCodegen {
196208 public:
197209 FunctionCodegen (CodegenUnit& u) : u_(u) {}
@@ -251,6 +263,11 @@ class FunctionCodegen {
251263 return u_.sf .Text (n);
252264 }
253265
266+ [[nodiscard]] ScopeGuard EnterStackFrame (ScopeManager::Frame::Kind kind = ScopeManager::Frame::Kind::kRegular ) {
267+ scope_->Enter (kind);
268+ return *scope_;
269+ }
270+
254271 void CodegenStmt (const ast::nodes::Stmt*);
255272 void CodegenDecl (const ast::nodes::Decl*);
256273 llvm::Value* CodegenExpr (const ast::nodes::Expr*, llvm::Value* dest = nullptr );
@@ -295,11 +312,10 @@ void FunctionCodegen::CodegenStmt(const ast::nodes::Stmt* n) {
295312 switch (n->nkind ) {
296313 case ast::NodeKind::BlockStmt: {
297314 const auto * m = n->As <ast::nodes::BlockStmt>();
298- scope_-> Enter () ;
315+ auto stack_frame{ EnterStackFrame ()} ;
299316 for (const auto * stmt : m->stmts ) {
300317 CodegenStmt (stmt);
301318 }
302- scope_->Exit ();
303319 break ;
304320 }
305321
@@ -337,7 +353,7 @@ void FunctionCodegen::CodegenStmt(const ast::nodes::Stmt* n) {
337353 case ast::NodeKind::ForStmt: {
338354 const auto * m = n->As <ast::nodes::ForStmt>();
339355
340- scope_-> Enter () ; // fake scope to drop loop variable after ForStmt end
356+ auto for_frame{ EnterStackFrame ()} ; // fake scope to drop loop variable after ForStmt end
341357 //
342358 CodegenStmt (m->init );
343359
@@ -355,21 +371,19 @@ void FunctionCodegen::CodegenStmt(const ast::nodes::Stmt* n) {
355371 u_.builder .CreateBr (cond_bb);
356372
357373 u_.builder .SetInsertPoint (body_bb);
358- scope_->Enter (ScopeManager::Frame::Kind::kLoop );
359374 {
360- lib::ScopedValue loop_ctx_guard (loop_ctx_, {.post = post_bb, .end = end_bb});
361- CodegenStmt (m->body );
362- }
363- if (!u_.builder .GetInsertBlock ()->getTerminator ()) {
364- u_.builder .CreateBr (post_bb);
375+ auto loop_frame{EnterStackFrame (ScopeManager::Frame::Kind::kLoop )};
376+ {
377+ lib::ScopedValue loop_ctx_guard (loop_ctx_, {.post = post_bb, .end = end_bb});
378+ CodegenStmt (m->body );
379+ }
380+ if (!u_.builder .GetInsertBlock ()->getTerminator ()) {
381+ u_.builder .CreateBr (post_bb);
382+ }
365383 }
366- scope_->Exit ();
367384
368385 u_.builder .SetInsertPoint (end_bb);
369386
370- //
371- scope_->Exit ();
372-
373387 break ;
374388 }
375389
@@ -385,15 +399,16 @@ void FunctionCodegen::CodegenStmt(const ast::nodes::Stmt* n) {
385399 u_.builder .CreateCondBr (CodegenExprAsBool (m->cond ), body_bb, end_bb);
386400
387401 u_.builder .SetInsertPoint (body_bb);
388- scope_->Enter (ScopeManager::Frame::Kind::kLoop );
389402 {
390- lib::ScopedValue loop_ctx_guard (loop_ctx_, {.post = body_bb, .end = end_bb});
391- CodegenStmt (m->body );
392- }
393- if (!u_.builder .GetInsertBlock ()->getTerminator ()) {
394- u_.builder .CreateBr (cond_bb);
403+ auto loop_frame{EnterStackFrame (ScopeManager::Frame::Kind::kLoop )};
404+ {
405+ lib::ScopedValue loop_ctx_guard (loop_ctx_, {.post = body_bb, .end = end_bb});
406+ CodegenStmt (m->body );
407+ }
408+ if (!u_.builder .GetInsertBlock ()->getTerminator ()) {
409+ u_.builder .CreateBr (cond_bb);
410+ }
395411 }
396- scope_->Exit ();
397412
398413 u_.builder .SetInsertPoint (end_bb);
399414
@@ -408,15 +423,16 @@ void FunctionCodegen::CodegenStmt(const ast::nodes::Stmt* n) {
408423 auto * end_bb = llvm::BasicBlock::Create (u_.ctx , " do.end" , fn_);
409424
410425 u_.builder .SetInsertPoint (body_bb);
411- scope_->Enter (ScopeManager::Frame::Kind::kLoop );
412426 {
413- lib::ScopedValue loop_ctx_guard (loop_ctx_, {.post = body_bb, .end = end_bb});
414- CodegenStmt (m->body );
415- }
416- if (!u_.builder .GetInsertBlock ()->getTerminator ()) {
417- u_.builder .CreateBr (cond_bb);
427+ auto loop_frame{EnterStackFrame (ScopeManager::Frame::Kind::kLoop )};
428+ {
429+ lib::ScopedValue loop_ctx_guard (loop_ctx_, {.post = body_bb, .end = end_bb});
430+ CodegenStmt (m->body );
431+ }
432+ if (!u_.builder .GetInsertBlock ()->getTerminator ()) {
433+ u_.builder .CreateBr (cond_bb);
434+ }
418435 }
419- scope_->Exit ();
420436
421437 u_.builder .CreateBr (cond_bb);
422438 u_.builder .SetInsertPoint (cond_bb);
@@ -485,7 +501,11 @@ void FunctionCodegen::CodegenDecl(const ast::nodes::Decl* n) {
485501 for (auto * decl : m->decls ) {
486502 auto * alloca = scope_->Alloc (Lit (decl->name ), itype.sym );
487503 if (decl->value ) {
488- auto * v = CodegenExpr (decl->value , alloca);
504+ llvm::Value* v;
505+ {
506+ auto tmp_frame{EnterStackFrame (ScopeManager::Frame::Kind::kTemporaries )};
507+ v = CodegenExpr (decl->value , alloca);
508+ }
489509 if (IsTrivial (v->getType ())) {
490510 u_.builder .CreateStore (v, alloca);
491511 }
@@ -654,6 +674,8 @@ llvm::Value* FunctionCodegen::CodegenExpr(const ast::nodes::Expr* expr, llvm::Va
654674 case ast::NodeKind::CallExpr: {
655675 const auto * m = expr->As <ast::nodes::CallExpr>();
656676
677+ auto tmp_frame{EnterStackFrame (ScopeManager::Frame::Kind::kTemporaries )};
678+
657679 const auto * func_sym = core::checker::ResolveExprSymbol (&u_.sf , u_.sf .module ->scope , m->fun ).sym ;
658680 assert (func_sym->Flags () & core::semantic::SymbolFlags::kFunction );
659681
@@ -695,7 +717,9 @@ llvm::Value* FunctionCodegen::CodegenExpr(const ast::nodes::Expr* expr, llvm::Va
695717 VANADIUM_DEBUG_ASSERT (av != nullptr , " Unknown argument expr type: {}" , magic_enum::enum_name (argnode->nkind ))
696718 }
697719
698- return u_.builder .CreateCall (callee, args);
720+ auto * res = u_.builder .CreateCall (callee, args);
721+
722+ return res;
699723 }
700724
701725 case ast::NodeKind::ParenExpr: {
0 commit comments