summaryrefslogtreecommitdiff
path: root/source/slang/lower-to-ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/lower-to-ir.cpp')
-rw-r--r--source/slang/lower-to-ir.cpp91
1 files changed, 49 insertions, 42 deletions
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 24181c75a..57fa55741 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -1417,21 +1417,6 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
SLANG_UNIMPLEMENTED_X("codegen for aggregate type constructor expression");
}
- // Add arguments that appeared directly in an argument list
- // to the list of argument values for a call.
- void addDirectCallArgs(
- InvokeExpr* expr,
- List<IRInst*>* ioArgs)
- {
- for( auto arg : expr->Arguments )
- {
- // TODO: Need to handle case of l-value arguments,
- // when they are matched to `out` or `in out` parameters.
- auto loweredArg = lowerRValueExpr(context, arg);
- addArgs(context, ioArgs, loweredArg);
- }
- }
-
// After a call to a function with `out` or `in out`
// parameters, we may need to copy data back into
// the l-value locations used for output arguments.
@@ -1452,18 +1437,44 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
List<OutArgumentFixup>* ioFixups)
{
UInt argCount = expr->Arguments.Count();
- UInt argIndex = 0;
+ UInt argCounter = 0;
for (auto paramDeclRef : getMembersOfType<ParamDecl>(funcDeclRef))
{
- if (argIndex >= argCount)
- {
- // The remaining parameters must be defaulted...
- break;
- }
-
auto paramDecl = paramDeclRef.getDecl();
RefPtr<Type> paramType = lowerSimpleType(context, GetType(paramDeclRef));
- auto argExpr = expr->Arguments[argIndex++];
+
+ UInt argIndex = argCounter++;
+ RefPtr<Expr> argExpr;
+ if(argIndex < argCount)
+ {
+ argExpr = expr->Arguments[argIndex];
+ }
+ else
+ {
+ // We have run out of arguments supplied at the call site,
+ // but there are still parameters remaining. This must mean
+ // that these parameters have default argument expressions
+ // associated with them.
+ argExpr = getInitExpr(paramDeclRef);
+
+ // Assert that such an expression must have been present.
+ SLANG_ASSERT(argExpr);
+
+ // TODO: The approach we are taking here to default arguments
+ // is simplistic, and has consequences for the front-end as
+ // well as binary serializatiojn of modules.
+ //
+ // We could consider some more refined approaches where, e.g.,
+ // functions with default arguments generate multiple IR-level
+ // functions, that compute and provide the default values.
+ //
+ // Alternatively, each parameter with defaults could be generated
+ // into its own callable function that provides the default value,
+ // so that calling modules can call into a pre-generated function.
+ //
+ // Each of these options involves trade-offs, and we need to
+ // make a conscious decision at some point.
+ }
if (paramDecl->HasModifier<OutModifier>()
|| paramDecl->HasModifier<InOutModifier>())
@@ -1543,8 +1554,7 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
}
else
{
- SLANG_UNEXPECTED("shouldn't relaly happen");
- UNREACHABLE(addDirectCallArgs(expr, ioArgs));
+ SLANG_UNEXPECTED("callee was not a callable decl");
}
}
@@ -1696,24 +1706,21 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
return result;
}
- // The default case is to assume that we just have
- // an ordinary expression, and can lower it as such.
- LoweredValInfo funcVal = lowerRValueExpr(context, expr->FunctionExpr);
-
- // Now we add any direct arguments from the call expression itself.
- addDirectCallArgs(expr, &irArgs);
-
- // Delegate to the logic for invoking a value.
- auto result = emitCallToVal(context, type, funcVal, irArgs.Count(), irArgs.Buffer());
-
- // TODO: because of the nature of how the `emitCallToVal` case works
- // right now, we don't have information on in/out parameters, and
- // so we can't collect info to apply fixups.
+ // TODO: In this case we should be emitting code for the callee as
+ // an ordinary expression, then emitting the arguments according
+ // to the type information on the callee (e.g., which paameters
+ // are `out` or `inout`, and then finally emitting the `call`
+ // instruciton.
//
- // Once we have a better representation for function types, though,
- // this should be fixable.
-
- return result;
+ // We don't currently have the case of emitting arguments according
+ // to function type info (instead of declaration info), and really
+ // this case can't occur unless we start adding first-class functions
+ // to the source language.
+ //
+ // For now we just bail out with an error.
+ //
+ SLANG_UNEXPECTED("could not resolve target declaration for call");
+ UNREACHABLE_RETURN(LoweredValInfo());
}
LoweredValInfo subscriptValue(