Code Generation
The codegen stage walks the analyzed AST with a visitor
(codegen_visitor.h) and emits LLVM IR. It relies entirely on the types and
annotations stamped by the semantic analyzer — by this point every
expression already knows its resolved sun::Type, and generic
specializations have been recorded for it to emit as ordinary non-generic
code.
Key Conventions
- LLVM is accessed through a shared context:
ctx.builderandctx.context. - Sun types map to LLVM types via the type resolver:
typeResolver.resolve(type)for variables andtypeResolver.resolveForReturn(type)for function returns. - Classes are value types: functions returning a class return the struct by value, and callers materialize it on the stack for addressability.
- Arrays are fat pointers:
{ ptr data, i32 ndims, ptr dims }. - Throwing functions (
T, IError) return plainT; errors are native LLVM exceptions (__gxx_personality_v0, landing pads), sothrowunwinds andcatchselects a handler by the thrown class's type id. - Lambdas use closure structs; named functions use direct calls. Class
methods use the closure ABI: arg 0 is a ptr to
{ ptr func, ptr env }with the receiver inenv, andobj.methodin value position is a lambda-typed bound method{ methodFn, objPtr }. - Call arguments are never re-examined here. Semantic analysis records an
ArgConversionper argument on the call node, and every kind of call — plain, module-qualified, generic, method, lambda, interface, constructor, extern "C" — lowers its arguments through one loop,emitCallArguments, that switches on those tags (take the address for a borrow, zero the source for a move, build a fat pointer for an interface, extend a number, ...). Codegen does no semantic analysis of its own.
Source Layout
The code generation is split across multiple files under src/codegen/ by
expression type:
| File | Responsibility |
|---|---|
codegen_visitor.cpp | Main visitor dispatch, module initialization |
functions_lambdas.cpp | Function/lambda codegen with closure support |
classes.cpp | Class definitions, constructors, methods |
call_expressions.cpp | Function calls, method calls |
variable_creation.cpp | Variable declarations (var, let) |
variable_references.cpp | Variable loads, assignments |
if_expressions.cpp | Conditionals, ternary expressions |
loops.cpp | for, while, and for-in loops |
match_expressions.cpp | Pattern matching (match expressions) |
block_expressions.cpp | Block scoping |
return_statements.cpp | Return value handling |
error_handling.cpp | try/catch/throw codegen |
arrays.cpp | Array literals and indexing |
intrinsics.cpp | Compiler intrinsic codegen (_sizeof, _load, etc.) |
threads.cpp | OS thread spawning and joining |
thread_utils.cpp | Thread utility helpers |
Adding a New Expression Type
- Add an
ASTNodeTypeenum value and AST class. - Implement a
codegenmethod in the appropriatesrc/codegen/*.cppfile. - Update the
codegenExpression()dispatch switch.