Skip to content

Commit

Permalink
Support inline and noreturn in IR (#708)
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 authored Nov 11, 2024
1 parent a5e06d7 commit 00b2ff3
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 00b2ff3

Please sign in to comment.