sun::codegen::scopes::ScopeManager
class · Source (opens in a new tab)
class sun::codegen::scopes::ScopeManagerOwns the scope stack for the function being emitted and writes the drop code for everything in it.
The stack itself is reachable through the container-shaped accessors (back(), size(), empty(), operator[]) because callers legitimately register a variable in the innermost scope or record how deep they are. Everything else — finding a variable, taking ownership of a value, giving it up, releasing what is left — goes through a named method.
Public Functions
- ScopeManager
- back
- compoundStorageAddress
- emitArrayDrop
- emitCleanupForScope
- emitCleanupToDepth
- emitDeinitCall
- emitDropInPlace
- emitFieldCleanup
- emitFieldDeinit
- emitScopeCleanup
- empty
- findVariable
- functionBoundaryDepth
- hasLiveOwners
- isIndirectBinding
- markClassAllocationAsDeinited
- markInitialized
- operator=
- operator[]
- pop
- push
- releaseBlockResult
- size
- trackCallTemporary
- trackClassAllocation
- trackOwnedAllocation
- trackOwnedParam
ScopeManager
ScopeManager(const ScopeManager &)=delete
public · function · Source (opens in a new tab)
sun::codegen::scopes::ScopeManager::ScopeManager(const ScopeManager &)=deleteCreates the manager that tracks generated scopes and their cleanup.
ScopeManager(sun::codegen::CodegenState &state, sun::codegen::CodegenVisitor &gen)
public · function · Source (opens in a new tab)
sun::codegen::scopes::ScopeManager::ScopeManager(sun::codegen::CodegenState &state, sun::codegen::CodegenVisitor &gen)Creates the manager that tracks generated scopes and their cleanup.
Related: sun::codegen::CodegenState, sun::codegen::CodegenVisitor
back
public · function · Source (opens in a new tab)
CodegenScope & sun::codegen::scopes::ScopeManager::back()Provides access to the most recently entered scope.
Related: CodegenScope
compoundStorageAddress
public · function · Source (opens in a new tab)
Value * sun::codegen::scopes::ScopeManager::compoundStorageAddress(DeclarationId id)Storage address of a compound local: the alloca itself, or for an indirect binding the pointer it holds.
Related: DeclarationId
emitArrayDrop
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitArrayDrop(sun::types::ArrayType &arrayType, llvm::Value *storagePtr, const std::string &name)Drop every element of a sized array's inline storage.
Drops every initialized element of a sized array's inline storage.
Safe code cannot move individual elements out of an array.
Related: sun::types::ArrayType
emitCleanupForScope
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitCleanupForScope(CodegenScope &scope, bool unwinding=false)Emit cleanup for a single scope's allocations (LIFO), without popping it.
Related: CodegenScope
emitCleanupToDepth
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitCleanupToDepth(size_t depth, bool unwinding=false)Emit cleanup for all scopes from the innermost down to index depth (inclusive), without popping any.
Used by break/continue/throw paths that jump out of several scopes at once.
emitDeinitCall
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitDeinitCall(const ClassType *classType, llvm::Value *receiver)Call classType's deinit() on receiver if it defines one (declares the external on demand).
Related: ClassType
emitDropInPlace
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitDropInPlace(const TypePtr &type, llvm::Value *ptr, const std::string &name="drop")Drop the concrete value at ptr in place, including class fields, enum payloads, and array elements.
Borrowed views need no cleanup.
Related: TypePtr
emitFieldCleanup
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitFieldCleanup(llvm::Value *objectPtr, const ClassType *classType, const std::string &baseName, llvm::FunctionCallee freeFunc)Emit cleanup code for raw_ptr<T> fields in a class, recursively freeing pointer fields before the containing object is freed.
Related: ClassType
emitFieldDeinit
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitFieldDeinit(llvm::Value *objectPtr, const ClassType *classType, const std::string &baseName)Emit deinit calls for class fields that have deinit methods.
Recursively deinits nested class fields; enum-typed fields with owning payloads are dropped through their synthesized drop function.
Related: ClassType
emitScopeCleanup
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitScopeCleanup()Emit cleanup for every scope from the innermost down to the innermost function boundary.
Used by return paths and function ends.
empty
public · function · Source (opens in a new tab)
bool sun::codegen::scopes::ScopeManager::empty() constReports whether this object contains no entries.
findVariable
public · function · Source (opens in a new tab)
AllocaInst * sun::codegen::scopes::ScopeManager::findVariable(DeclarationId id)Finds a variable in the current scope chain.
Respects function boundaries - doesn't search past outer function scopes. Variables from outer functions should be accessed via closures instead.
Related: DeclarationId
functionBoundaryDepth
public · function · Source (opens in a new tab)
size_t sun::codegen::scopes::ScopeManager::functionBoundaryDepth() constIndex of the innermost function-boundary scope.
Falls back to the innermost scope (old single-scope cleanup behavior) if none is marked, so an unmarked context can never emit references into another function.
hasLiveOwners
public · function · Source (opens in a new tab)
bool sun::codegen::scopes::ScopeManager::hasLiveOwners(size_t depth) constTrue if any scope at or above depth holds an owner or an active catch — i.e.
unwinding past this point would need cleanup
isIndirectBinding
public · function · Source (opens in a new tab)
bool sun::codegen::scopes::ScopeManager::isIndirectBinding(DeclarationId id) constTrue if this declaration has indirect storage in the current function — its alloca holds the value's address, not the value.
Related: DeclarationId
markClassAllocationAsDeinited
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::markClassAllocationAsDeinited(llvm::Value *alloca, TypePtr type=nullptr)Give up ownership and track later reassignment with a drop flag.
Related: TypePtr
markInitialized
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::markInitialized(llvm::Value *ptr, const TypePtr &type)Restore ownership after storing a new value into a moved location.
Related: TypePtr
operator=
public · function · Source (opens in a new tab)
ScopeManager & sun::codegen::scopes::ScopeManager::operator=(const ScopeManager &)=deleteDisallows assignment so ownership and object identity cannot be duplicated.
Related: ScopeManager
operator[]
public · function · Source (opens in a new tab)
CodegenScope & sun::codegen::scopes::ScopeManager::operator[](size_t i)Provides indexed access to the stored elements.
Related: CodegenScope
pop
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::pop()Close the innermost scope, dropping whatever it still owns.
push
push()
public · function · Source (opens in a new tab)
CodegenScope & sun::codegen::scopes::ScopeManager::push()Open a scope that holds no source block of its own.
Related: CodegenScope
push(const sun::support::Position &loc)
public · function · Source (opens in a new tab)
CodegenScope & sun::codegen::scopes::ScopeManager::push(const sun::support::Position &loc)Open a scope for a source block (if/else, loop, try/catch).
Also opens a DILexicalBlock so debuggers see block-accurate variable visibility (no-op without -g); pop() closes it symmetrically.
Related: CodegenScope, sun::support::Position, pop()
releaseBlockResult
public · function · Source (opens in a new tab)
std::optional< std::string > sun::codegen::scopes::ScopeManager::releaseBlockResult(llvm::Value *result)A block used as a value hands its result to the enclosing expression, and ownership goes with it — the block's own scope must not drop it.
Marks the result moved out of the innermost scope and hands back the name it was tracked under, so the caller can re-track it in the scope that owns it now without losing the name its drop blocks are labelled with. Nothing means that scope did not own it and there is nothing to hand on. Call this after generating the body and before popping its scope.
size
public · function · Source (opens in a new tab)
size_t sun::codegen::scopes::ScopeManager::size() constReturns the number of stored entries.
trackCallTemporary
public · function · Source (opens in a new tab)
llvm::Value * sun::codegen::scopes::ScopeManager::trackCallTemporary(llvm::Value *result, const TypePtr &resultType)A call that hands back a compound by value hands back something the caller now owns.
var x = f(); adopts the very same slot and trackClassAllocation de-duplicates by alloca, and moving the result on marks it deinited, so this only decides what happens when nobody takes it: the temporary is dropped at the end of the scope that made it, rather than leaked. Only a materialized return (an alloca) is a temporary — a borrow handed back by a peek accessor is a pointer into storage someone else owns, and typeNeedsDrop already says no to ref T.
Related: TypePtr
trackClassAllocation
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::trackClassAllocation(llvm::Value *alloca, const std::string &name, TypePtr type, bool unwindOnly=false)Track a class or payload-enum allocation in the current scope for automatic drop at scope exit.
Enums are tracked only when they actually need drop code. An alloca already tracked (e.g. a constructor temporary later adopted by a variable) keeps its single entry — double-tracking would double-drop.
Related: TypePtr
trackOwnedAllocation
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::trackOwnedAllocation(llvm::Value *ptrAlloca, const std::string &name, TypePtr pointeeType=nullptr)Track a new owned allocation in the current scope.
Related: TypePtr
trackOwnedParam
public · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::trackOwnedParam(llvm::Value *alloca, const std::string &name, const TypePtr &type)A by-value compound parameter arrives moved: the caller gave up its ownership at the call, so this frame is the one that drops it.
Passing it on — into another call, a field, a container slot, a return — marks the slot deinited, so this only decides what happens when the body keeps it to the end. A ref T parameter is a borrow and answers false here.
Related: TypePtr
Private Functions
- emitFlaggedDrop
- emitUnconditionalDrop
- ensureDropFlag
- findAllocation
- setOwnership
- trackFieldAllocation
emitFlaggedDrop
private · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitFlaggedDrop(const ClassAllocation &alloc)Drop alloc only if its drop flag says this frame still owns it, then clear the flag.
Related: ClassAllocation
emitUnconditionalDrop
private · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::emitUnconditionalDrop(const TypePtr &type, llvm::Value *ptr, const std::string &name)Emit destruction after the caller has checked ownership.
Related: TypePtr
ensureDropFlag
private · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::ensureDropFlag(ClassAllocation &alloc)Give alloc a drop flag if it has none: an i1 slot that starts false in the entry block and is set where the value became owned, so it is true exactly when this frame still owns the value.
Related: ClassAllocation
findAllocation
private · function · Source (opens in a new tab)
ClassAllocation * sun::codegen::scopes::ScopeManager::findAllocation(llvm::Value *ptr, const TypePtr &type)Find ownership information for a local or one of its fields.
Related: ClassAllocation, TypePtr
setOwnership
private · function · Source (opens in a new tab)
void sun::codegen::scopes::ScopeManager::setOwnership(ClassAllocation &alloc, bool owned)Update static ownership and an existing runtime flag together.
Related: ClassAllocation
trackFieldAllocation
private · function · Source (opens in a new tab)
ClassAllocation * sun::codegen::scopes::ScopeManager::trackFieldAllocation(llvm::Value *ptr, const TypePtr &type)Track a moved field in its containing local's scope.
Related: ClassAllocation, TypePtr
Private Fields
ctx
private · variable · Source (opens in a new tab)
sun::codegen::CodegenContext& sun::codegen::scopes::ScopeManager::ctxNo documentation comment.
Related: sun::codegen::CodegenContext
gen_
private · variable · Source (opens in a new tab)
sun::codegen::CodegenVisitor& sun::codegen::scopes::ScopeManager::gen_No documentation comment.
Related: sun::codegen::CodegenVisitor
scopes_
private · variable · Source (opens in a new tab)
std::vector<CodegenScope> sun::codegen::scopes::ScopeManager::scopes_No documentation comment.
Related: CodegenScope
state_
private · variable · Source (opens in a new tab)
sun::codegen::CodegenState& sun::codegen::scopes::ScopeManager::state_No documentation comment.
Related: sun::codegen::CodegenState