Skip to content

Commit

Permalink
Support inline and noreturn in IR
Browse files Browse the repository at this point in the history
Since codegen of inline functions was not working in #705, then instead of just removing specifiers, I put them into IR, and let somebody utilize it if needed.
  • Loading branch information
kant2002 committed Nov 11, 2024
1 parent 04485fc commit 573c557
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Cesium.CodeGen.Tests/CodeGenMethodTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -557,4 +557,7 @@ int main()
return 1;
}
}");

[Fact]
public Task InlineFunction() => DoTest(@"inline int test () {return 1;} int main() { return 0; }");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
System.Int32 <Module>::test()
IL_0000: ldc.i4.1
IL_0001: ret

System.Int32 <Module>::main()
IL_0000: ldc.i4.0
IL_0001: ret

System.Int32 <Module>::<SyntheticEntrypoint>()
Locals:
System.Int32 V_0
IL_0000: call System.Int32 <Module>::main()
IL_0005: stloc.s V_0
IL_0007: ldloc.s V_0
IL_0009: call System.Void Cesium.Runtime.RuntimeHelpers::Exit(System.Int32)
IL_000e: ldloc.s V_0
IL_0010: ret
20 changes: 19 additions & 1 deletion Cesium.CodeGen/Ir/BlockItems/FunctionDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ internal sealed class FunctionDefinition : IBlockItem

public bool IsMain => Name == MainFunctionName;

public bool Inline { get; private set; }

public bool NoReturn { get; private set; }

public FunctionDefinition(Ast.FunctionDefinition function)
{
var (specifiers, declarator, declarations, astStatement) = function;
Expand All @@ -37,6 +41,18 @@ public FunctionDefinition(Ast.FunctionDefinition function)
specifiers = specifiers.Remove(staticMarker);
}

var functionSpecifiers = specifiers.OfType<FunctionSpecifier>().ToList();
specifiers = specifiers.RemoveAll(_ => _ is FunctionSpecifier);
if (functionSpecifiers.Any(_ => _.SpecifierType == "inline"))
{
Inline = true;
}

if (functionSpecifiers.Any(_ => _.SpecifierType == "_Noreturn"))
{
NoReturn = true;
}

var (type, name, cliImportMemberName) = LocalDeclarationInfo.Of(specifiers, declarator);
FunctionType = type as FunctionType
?? throw new AssertException($"Function of not a function type: {type}.");
Expand All @@ -52,12 +68,14 @@ public FunctionDefinition(Ast.FunctionDefinition function)
Statement = astStatement.ToIntermediate();
}

public FunctionDefinition(string name, StorageClass storageClass, FunctionType functionType, IBlockItem statement)
public FunctionDefinition(string name, StorageClass storageClass, FunctionType functionType, IBlockItem statement, bool inline, bool noreturn)
{
StorageClass = storageClass;
Name = name;
FunctionType = functionType;
Statement = statement;
Inline = inline;
NoReturn = noreturn;
}

public void EmitCode(IEmitScope scope)
Expand Down
2 changes: 1 addition & 1 deletion Cesium.CodeGen/Ir/Lowering/BlockItemLowering.cs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ void ProcessCaseStatement(CaseStatement caseStatement, BlockScope switchBlock, s
var newDeclaration = new FunctionInfo(parameters, returnType, d.StorageClass, IsDefined: true);
scope.DeclareFunction(d.Name, newDeclaration);

return new FunctionDefinition(d.Name, d.StorageClass, resolvedFunctionType, d.Statement);
return new FunctionDefinition(d.Name, d.StorageClass, resolvedFunctionType, d.Statement, d.Inline, d.NoReturn);
}
case GlobalVariableDefinition d:
{
Expand Down

0 comments on commit 573c557

Please sign in to comment.