sun::codegen::scopes::ScopeManager

sun::codegen::scopes::ScopeManager

class · Source (opens in a new tab)

class sun::codegen::scopes::ScopeManager

Owns 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

ScopeManager(const ScopeManager &)=delete

public · function · Source (opens in a new tab)

sun::codegen::scopes::ScopeManager::ScopeManager(const ScopeManager &)=delete

Creates 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() const

Reports 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() const

Index 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) const

True 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) const

True 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 &)=delete

Disallows 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() const

Returns 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

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::ctx

No 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