Code Map
module volt.lowerer.llvmlowerer;
//! Used by the composable string lowering code.
alias NodeConsumer = void delegate(ir.Node);
//! Calls the correct functions where they need to be called to lower a
//! module.
class LlvmLowerer : ScopeManager, Pass
{
public:
lp: LanguagePass;
thisModule: ir.Module;
V_P64: bool;
public:
this(lp: LanguagePass) { }
//! Perform all lower operations on a given module.
fn transform(m: ir.Module) { }
fn close() { }
fn enter(bs: ir.BlockStatement) Status { }
fn enter(func: ir.Function) Status { }
fn leave(t: ir.ThrowStatement) Status { }
fn enter(exp: ir.Exp, binOp: ir.BinOp) Status { }
fn enter(var: ir.Variable) Status { }
fn leave(exp: ir.Exp, binOp: ir.BinOp) Status { }
fn enter(exp: ir.Exp, builtin: ir.BuiltinExp) Status { }
fn leave(exp: ir.Exp, al: ir.ArrayLiteral) Status { }
fn leave(exp: ir.Exp, assocArray: ir.AssocArray) Status { }
fn leave(exp: ir.Exp, uexp: ir.Unary) Status { }
fn leave(exp: ir.Exp, postfix: ir.Postfix) Status { }
fn leave(exp: ir.Exp, prop: ir.PropertyExp) Status { }
fn leave(exp: ir.Exp, cs: ir.ComposableString) Status { }
fn enter(exp: ir.Exp, literal: ir.StructLiteral) Status { }
fn leave(exp: ir.Exp, ae: ir.AccessExp) Status { }
fn visit(exp: ir.Exp, eref: ir.ExpReference) Status { }
fn enter(exp: ir.Exp, simport: ir.StringImport) Status { }
}
//! Next stop, backend! The LlvmLowerer visitor (and supporting functions)
//! have a fairly simple job to describe -- change any structure that the
//! backend doesn't handle into something composed of things the backend
//! DOES know how to deal with. This can involve turning keywords into
//! function calls into the runtime, changing foreach statements to for
//! statements, and so on.
fn lowerAAInsert(loc: const(Location), lp: LanguagePass, thisModule: ir.Module, current: ir.Scope, statExp: ir.StatementExp, aa: ir.AAType, var: ir.Variable, key: ir.Exp, value: ir.Exp, lowerer: LlvmLowerer, buildif: bool, aaIsPointer: bool) { }
//! Build code to lookup a key in an AA and add it to a StatementExp.
fn lowerAALookup(loc: const(Location), lp: LanguagePass, thisModule: ir.Module, current: ir.Scope, statExp: ir.StatementExp, aa: ir.AAType, var: ir.Variable, key: ir.Exp, store: ir.Exp, lowerer: LlvmLowerer) { }
//! Given an AA key, cast in such a way that it could be given to a
//! runtime AA function.
fn lowerAAKeyCast(loc: const(Location), lp: LanguagePass, thisModule: ir.Module, current: ir.Scope, key: ir.Exp, aa: ir.AAType, lowerer: LlvmLowerer) ir.Exp { }
fn lowerAAValueCast(loc: const(Location), lp: LanguagePass, thisModule: ir.Module, current: ir.Scope, key: ir.Exp, aa: ir.AAType, lowerer: LlvmLowerer) ir.Exp { }
fn lowerAACast(loc: const(Location), lp: LanguagePass, thisModule: ir.Module, current: ir.Scope, key: ir.Exp, t: ir.Type, lowerer: LlvmLowerer) ir.Exp { }
fn lowerAggregateAACast(loc: const(Location), lp: LanguagePass, thisModule: ir.Module, current: ir.Scope, key: ir.Exp, st: ir.Aggregate) ir.Exp { }
//! Given an AA key that is a struct or an array, cast it in such a way
//! that it could be given to a runtime AA function.
fn lowerStructOrArrayAACast(loc: const(Location), lp: LanguagePass, thisModule: ir.Module, current: ir.Scope, key: ir.Exp, t: ir.Type, lowerer: LlvmLowerer) ir.Exp { }
//! Turn a PropertyExp into a call or member call as appropriate.
fn lowerProperty(lp: LanguagePass, exp: ir.Exp, prop: ir.PropertyExp) { }
//! Lower a composable string, either at compile time, or calling
//! formatting functions with a sink.
fn lowerComposableString(lp: LanguagePass, current: ir.Scope, func: ir.Function, exp: ir.Exp, cs: ir.ComposableString, lowerer: LlvmLowerer) { }
//! Dispatch a composable string component to the right function.
fn lowerComposableStringComponent(lp: LanguagePass, current: ir.Scope, e: ir.Exp, sexp: ir.StatementExp, sinkVar: ir.Variable, dgt: NodeConsumer, lowerer: LlvmLowerer) { }
//! Lower a primitive type component of a composable string.
fn lowerComposableStringPrimitiveComponent(lp: LanguagePass, current: ir.Scope, e: ir.Exp, pt: ir.PrimitiveType, sexp: ir.StatementExp, sinkVar: ir.Variable, dgt: NodeConsumer) { }
//! Lower an associative array component of a composable string.
fn lowerComposableStringAAComponent(lp: LanguagePass, current: ir.Scope, e: ir.Exp, aatype: ir.AAType, sexp: ir.StatementExp, sinkVar: ir.Variable, dgt: NodeConsumer, lowerer: LlvmLowerer) { }
//! Lower an array component of a composable string.
fn lowerComposableStringArrayComponent(lp: LanguagePass, current: ir.Scope, e: ir.Exp, sexp: ir.StatementExp, sinkVar: ir.Variable, dgt: NodeConsumer, lowerer: LlvmLowerer) { }
//! Lower a pointer component of a composable string.
fn lowerComposableStringPointerComponent(lp: LanguagePass, e: ir.Exp, sexp: ir.StatementExp, sinkVar: ir.Variable, dgt: NodeConsumer) { }
//! Lower an enum component of a composable string.
fn lowerComposableStringEnumComponent(lp: LanguagePass, current: ir.Scope, _enum: ir.Enum, e: ir.Exp, sexp: ir.StatementExp, sinkVar: ir.Variable, dgt: NodeConsumer) { }
//! Generate the function that fills in the toSink field on an Enum.
fn generateToSink(loc: const(Location), lp: LanguagePass, current: ir.Scope, _enum: ir.Enum) ir.Function { }
//! Lower a string component of a composable string.
fn lowerComposableStringStringComponent(e: ir.Exp, sexp: ir.StatementExp, sinkVar: ir.Variable) { }
//! Lower a string component of a composable string.
fn lowerComposableStringStringComponent(e: ir.Exp, sexp: ir.StatementExp, sinkVar: ir.Variable, dgt: NodeConsumer) { }
//! Build an if statement based on a runtime assert.
fn lowerAssertIf(lp: LanguagePass, current: ir.Scope, as: ir.AssertStatement) ir.IfStatement { }
//! Given a throw statement, turn its expression into a call into the RT.
fn lowerThrow(lp: LanguagePass, t: ir.ThrowStatement) { }
//! Replace a StringImport with the string in the file it points at, or
//! error.
fn lowerStringImport(driver: Driver, exp: ir.Exp, simport: ir.StringImport) { }
//! Turn Struct a = {1, "banana"}; into Struct a; a.firstField = 1;
//! b.secondField = "banana";.
fn lowerStructLiteral(lp: LanguagePass, current: ir.Scope, exp: ir.Exp, literal: ir.StructLiteral) { }
//! Lower a postfix index expression.
fn lowerIndex(lp: LanguagePass, current: ir.Scope, thisModule: ir.Module, exp: ir.Exp, postfix: ir.Postfix, lowerer: LlvmLowerer) { }
//! Lower a postfix index expression that operates on an AA.
fn lowerIndexAA(lp: LanguagePass, current: ir.Scope, thisModule: ir.Module, exp: ir.Exp, postfix: ir.Postfix, aa: ir.AAType, lowerer: LlvmLowerer) { }
//! Lower an assign if it needs it.
fn lowerAssign(lp: LanguagePass, thisModule: ir.Module, exp: ir.Exp, binOp: ir.BinOp) { }
//! Lower an assign to an array if it's being modified by a postfix.
fn lowerAssignArray(lp: LanguagePass, thisModule: ir.Module, exp: ir.Exp, binOp: ir.BinOp, asPostfix: ir.Postfix, leftType: ir.ArrayType) { }
//! Lower an assign to an AA.
fn lowerAssignAA(lp: LanguagePass, current: ir.Scope, thisModule: ir.Module, exp: ir.Exp, binOp: ir.BinOp, asPostfix: ir.Postfix, aa: ir.AAType, lowerer: LlvmLowerer) { }
//! Lower a +=, *=, etc assign to an AA.
fn lowerOpAssignAA(lp: LanguagePass, current: ir.Scope, thisModule: ir.Module, exp: ir.Exp, binOp: ir.BinOp, asPostfix: ir.Postfix, aa: ir.AAType, lowerer: LlvmLowerer) { }
//! Lower a concatenation operation. (A ~ B)
fn lowerCat(lp: LanguagePass, thisModule: ir.Module, exp: ir.Exp, binOp: ir.BinOp) { }
//! Lower a concatenation assign operation. (A ~= B)
fn lowerCatAssign(lp: LanguagePass, thisModule: ir.Module, exp: ir.Exp, binOp: ir.BinOp) { }
//! Lower a comparison operation, if it needs it.
fn lowerCmp(lp: LanguagePass, thisModule: ir.Module, exp: ir.Exp, binOp: ir.BinOp) { }
//! Lower an expression that casts to an interface.
fn lowerInterfaceCast(loc: const(Location), lp: LanguagePass, current: ir.Scope, uexp: ir.Unary, exp: ir.Exp) { }
//! Lower an expression that casts to an array.
fn lowerArrayCast(loc: const(Location), lp: LanguagePass, current: ir.Scope, uexp: ir.Unary, exp: ir.Exp) { }
//! Is a given postfix an interface pointer? If so, which one?
fn isInterfacePointer(lp: LanguagePass, pfix: ir.Postfix, current: ir.Scope, iface: ir._Interface) bool { }
//! If a postfix operates directly on a struct via a function call, put it
//! in a variable first.
fn lowerStructLookupViaFunctionCall(lp: LanguagePass, current: ir.Scope, exp: ir.Exp, ae: ir.AccessExp, type: ir.Type) { }
//! Rewrites a given foreach statement (fes) into a for statement.
fn lowerForeach(fes: ir.ForeachStatement, lp: LanguagePass, current: ir.Scope) ir.ForStatement { }
//! Lower an array literal to an internal array literal.
fn lowerArrayLiteral(lp: LanguagePass, current: ir.Scope, exp: ir.Exp, al: ir.ArrayLiteral) { }
//! Lower a builtin expression.
fn lowerBuiltin(lp: LanguagePass, current: ir.Scope, exp: ir.Exp, builtin: ir.BuiltinExp, lowerer: LlvmLowerer) { }
fn lowerVaArg(loc: const(Location), lp: LanguagePass, vaexp: ir.VaArgExp) ir.StatementExp { }
//! Lower an ExpReference, if needed.
fn lowerExpReference(functionStack: ir.Function[], exp: ir.Exp, eref: ir.ExpReference, func: ir.Function) { }
//! Lower a Postfix, if needed.
fn lowerPostfix(lp: LanguagePass, current: ir.Scope, thisModule: ir.Module, exp: ir.Exp, parentFunc: ir.Function, postfix: ir.Postfix, lowerer: LlvmLowerer) { }
//! Lower a call to a varargs function.
fn lowerVarargCall(lp: LanguagePass, current: ir.Scope, postfix: ir.Postfix, func: ir.Function, exp: ir.Exp) { }
fn lowerGlobalAALiteral(lp: LanguagePass, current: ir.Scope, mod: ir.Module, var: ir.Variable) { }
//! If postfix is slicing a static array from a non-lvalue expression,
//! lower it into a statement exp.
fn lowerStaticArraySliceNonLValue(lp: LanguagePass, current: ir.Scope, postfix: ir.Postfix, exp: ir.Exp) { }
//! Lower an AA literal.
fn lowerAA(lp: LanguagePass, current: ir.Scope, thisModule: ir.Module, exp: ir.Exp, assocArray: ir.AssocArray, lowerer: LlvmLowerer) { }
//! Rewrite Struct(args) to call their constructors.
fn lowerStructUnionConstructor(lp: LanguagePass, current: ir.Scope, exp: ir.Exp, builtin: ir.BuiltinExp) { }
fn zeroVariableIfNeeded(lp: LanguagePass, var: ir.Variable) ir.Exp { }
fn zeroVariablesIfNeeded(lp: LanguagePass, bs: ir.BlockStatement) { }
Next stop, backend! The LlvmLowerer visitor (and supporting functions) have a fairly simple job to describe -- change any structure that the backend doesn't handle into something composed of things the backend DOES know how to deal with. This can involve turning keywords into function calls into the runtime, changing foreach statements to for statements, and so on.
Build a function call that inserts a value with a given key into a given AA, and add it to a StatementExp.
Params: loc: Nodes created in this function will be given this location. lp: The LanguagePass. thisModule: The module that the call will be living in. current: The scope at the point of call. statExp: The StatementExp to add the call to. aa: The type of the that we're inserting into. var: The Variable containing the instance of the AA being inserted in to. key: The key to associate the value with. value: The value we are inserting. buildif: Generate code to initialise the AA if it's needed. aaIsPointer: Is the AA being held as a pointer?
Build code to lookup a key in an AA and add it to a StatementExp.
Params: loc: Any Nodes created will be given this Location. lp: The LanguagePass. thisModule: The Module that the lookup will take place in. current: The Scope at the time of the lookup. statExp: The StatementExp to add the lookup to. aa: The type of the AA that we're performing a lookup on. var: The Variable that holds the AA. key: The key to lookup in the AA. store: A reference to a Variable of AA.value type, to hold the result of the lookup.
Given an AA key, cast in such a way that it could be given to a runtime AA function.
Params: loc: Any Nodes created will be given this location. lp: The LanguagePass. thisModule: The Module that this code is taking place in. current: The Scope where this code takes place. key: An expression holding the key in its normal form. aa: The AA type that the key belongs to.
Returns: An expression casting the key.
Given an AA key that is a struct or an array, cast it in such a way that it could be given to a runtime AA function.
Params: loc: Any Nodes created will be given this location. lp: The LanguagePass. thisModule: The Module that this code is taking place in. current: The Scope where this code takes place. key: An expression holding the key/value in its normal form. t: The type of the key or value
Turn a PropertyExp into a call or member call as appropriate.
Params: lp: The LanguagePass. exp: The expression to write the new call to. prop: The PropertyExp to lower.
Lower a composable string, either at compile time, or calling formatting functions with a sink.
Used by the composable string lowering code.
Dispatch a composable string component to the right function.
Lower a primitive type component of a composable string.
Lower an associative array component of a composable string.
Lower an array component of a composable string.
Lower a pointer component of a composable string.
Lower an enum component of a composable string.
Generate the function that fills in the toSink
field on an Enum
.
Used by the composable string code to turn "${SomeEnum.Member}"
into "Member"
.
Lower a string component of a composable string.
Build an if statement based on a runtime assert.
Given a throw statement, turn its expression into a call into the RT.
Params: lp: The LanguagePass. t: The ThrowStatement to lower.
Replace a StringImport with the string in the file it points at, or error.
Params: lp: The LanguagePass. current: The scope at where the StringImport is. exp: The expression to write the new string into. simport: The StringImport to lower.
Turn Struct a = {1, "banana"};
into Struct a; a.firstField = 1; b.secondField = "banana";
.
Params: lp: The LanguagePass. current: The scope where the StructLiteral occurs. exp: The expression of the StructLiteral. literal: The StructLiteral to lower.
Lower a postfix index expression.
Params: lp: The LanguagePass. current: The Scope where this code takes place. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. postfix: The postfix expression to potentially lower.
Lower a postfix index expression that operates on an AA.
Params: lp: The LanguagePass. current: The Scope where this code takes place. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. postfix: The postfix expression to potentially lower. aa: The type of the AA being operated on.
Lower an assign if it needs it.
Params: lp: The LanguagePass. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. binOp: The BinOp with the assign to potentially lower.
Lower an assign to an array if it's being modified by a postfix.
Params: lp: The LanguagePass. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. binOp: The BinOp with the assign to potentially lower. asPostfix: The postfix operation modifying the array. leftType: The array type of the left hand side of the assign.
Lower an assign to an AA.
Params: lp: The LanguagePass. current: The Scope where this code takes place. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. binOp: The BinOp with the assign to potentially lower. asPostfix: The left hand side of the assign as a postfix. aa: The AA type that the expression is assigning to.
Lower a +=, *=, etc assign to an AA.
Params: lp: The LanguagePass. current: The Scope where this code takes place. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. binOp: The BinOp with the assign to potentially lower. asPostfix: The left hand side of the assign as a postfix. aa: The AA type that the expression is assigning to.
Lower a concatenation operation. (A ~ B)
Params: lp: The LanguagePass. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. binOp: The BinOp with the concatenation to lower.
Lower a concatenation assign operation. (A ~= B)
Params: lp: The LanguagePass. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. binOp: The BinOp with the concatenation assign to lower.
Lower a comparison operation, if it needs it.
Params: lp: The LanguagePass. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. binOp: The BinOp with the comparison operation to potentially lower.
Lower an expression that casts to an interface.
Params: loc: Nodes created in this function will be given this loc. lp: The LanguagePass. current: The Scope where this code takes place. uexp: The interface cast to lower. exp: A reference to the relevant expression.
Lower an expression that casts to an array.
Params: loc: Nodes created in this function will be given this loc. lp: The LanguagePass. current: The Scope where this code takes place. uexp: The array cast to lower. exp: A reference to the relevant expression.
Is a given postfix an interface pointer? If so, which one?
Params: lp: The LanguagePass. pfix: The Postfix to check. current: The scope where the postfix resides. iface: Will be filled in with the Interface if the postfix is a pointer to one.
Returns: true if pfix's type is an interface pointer, false otherwise.
If a postfix operates directly on a struct via a function call, put it in a variable first.
Params: lp: The LanguagePass. current: The Scope where this code takes place. exp: A reference to the relevant expression. ae: The AccessExp to check.
Rewrites a given foreach statement (fes) into a for statement.
The ForStatement created uses several of the fes's nodes directly; that is to say, the original foreach and the new for cannot coexist.
Params: fes: The ForeachStatement to lower. lp: The LanguagePass. current: The Scope where this code takes place.
Returns: The lowered ForStatement.
Lower an array literal to an internal array literal.
The backend will treat any ArrayLiteral as full of constants, so we can't pass most of them through.
Params: lp: The LanguagePass. current: The Scope where this code takes place. inFunction: Is this ArrayLiteral in a function or not? exp: A reference to the relevant expression. al: The ArrayLiteral to lower.
Lower a builtin expression.
These are comprised mostly of things that need calls to the RT to deal with them.
Params: lp: The LanguagePass. current: The Scope where this code takes place. exp: A reference to the relevant expression. builtin: The BuiltinExp to lower.
Lower an ExpReference, if needed.
This rewrites them to lookup through the nested struct, if needed.
Params: functionStack: A list of functions. Most recent at $-1, its parent at $-2, and so on. exp: A reference to the relevant expression. eref: The ExpReference to potentially lower.
Lower a Postfix, if needed.
This handles index operations, and interface pointers.
Params: lp: The LanguagePass. current: The Scope where this code takes place. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. parentFunc: The parent function where this postfix is held, or null. postfix: The Postfix to potentially lower.
Lower a call to a varargs function.
If postfix is slicing a static array from a non-lvalue expression, lower it into a statement exp.
Lower an AA literal.
Params: lp: The LanguagePass. current: The Scope where this code takes place. thisModule: The Module that this code is taking place in. exp: A reference to the relevant expression. assocArray: The AA literal to lower.
Rewrite Struct(args) to call their constructors.
Calls the correct functions where they need to be called to lower a module.
Perform all lower operations on a given module.
Params: m: The module to lower.