Skip to content

Commit

Permalink
Initialize using address of compound initializer (#718)
Browse files Browse the repository at this point in the history
  • Loading branch information
kant2002 authored Nov 22, 2024
1 parent f31e852 commit 03ebc93
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 26 deletions.
7 changes: 7 additions & 0 deletions Cesium.CodeGen.Tests/CodeGenEnumTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,12 @@ enum Colour { Red, Green, Blue };
public Task EnumUseValuesInDeclaration() => DoTest(@"
enum Colour { Red, Green, Blue = Green + 10 };
int x = {Blue};
");

[Fact]
public Task EnumUseValuesInStructPointerDeclaration() => DoTest(@"
enum Colour { Red, Green, Blue = Green + 10 };
typedef struct { int x; } TestStruct;
TestStruct *x = &(TestStruct){Blue};
");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
System.Void <Module>::.cctor()
Locals:
<typedef>TestStruct V_0
IL_0000: ldloca V_0
IL_0004: initobj <typedef>TestStruct
IL_000a: ldloca V_0
IL_000e: ldc.i4.s 11
IL_0010: stfld System.Int32 <typedef>TestStruct::x
IL_0015: ldloc V_0
IL_0019: stsfld <typedef>TestStruct <Module>::global_tmp_0
IL_001e: ldsflda <typedef>TestStruct <Module>::global_tmp_0
IL_0023: stsfld <typedef>TestStruct* <Module>::x
IL_0028: ret
3 changes: 3 additions & 0 deletions Cesium.CodeGen/Contexts/BlockScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,7 @@ public void PushPragma(IPragma blockItem) { }

/// <inheritdoc />
public void RemovePragma<T>(Predicate<T> predicate) where T : IPragma { }

/// <inheritdoc />
public string GetTmpVariable() => ((IDeclarationScope)Parent).GetTmpVariable();
}
8 changes: 8 additions & 0 deletions Cesium.CodeGen/Contexts/FunctionScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,12 @@ public void MergeScope(BlockScope scope)
_variableDefinition.Add(variableName, variableDefinition);
}
}

private int tempLocalIndex = 0;

/// <inheritdoc />
public string GetTmpVariable()
{
return "local_" + tempLocalIndex++;
}
}
8 changes: 8 additions & 0 deletions Cesium.CodeGen/Contexts/GlobalConstructorScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,12 @@ public void RemovePragma<T>(Predicate<T> predicate) where T : IPragma
}
}
}

private int tempLocalIndex = 0;

/// <inheritdoc />
public string GetTmpVariable()
{
return "global_tmp_" + tempLocalIndex++;
}
}
6 changes: 6 additions & 0 deletions Cesium.CodeGen/Contexts/IDeclarationScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,10 @@ internal interface IDeclarationScope
void RemovePragma<T>(Predicate<T> predicate) where T : IPragma;

List<SwitchCase>? SwitchCases { get; }

/// <summary>
/// Gets name of the new temp variable.
/// </summary>
/// <returns>Name of the new temporary variable, unique to the scope</returns>
string GetTmpVariable();
}
1 change: 1 addition & 0 deletions Cesium.CodeGen/Extensions/ExpressionEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ internal static class ExpressionEx
Ast.MemberAccessExpression e => new MemberAccessExpression(e),
Ast.PointerMemberAccessExpression e => new PointerMemberAccessExpression(e),
Ast.PostfixIncrementDecrementExpression e => new PostfixIncrementDecrementExpression(e),
Ast.CompoundLiteralExpression e => new CompoundObjectInitializationExpression(e),

Ast.CommaExpression e => new CommaExpression(e),

Expand Down
19 changes: 18 additions & 1 deletion Cesium.CodeGen/Extensions/TranslationUnitEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,24 @@ private static IEnumerable<IBlockItem> GetTopLevelDeclarations(Ast.SymbolDeclara
if (initializer != null)
{
var variableIdentifier = new IdentifierExpression(identifier);
yield return new ExpressionStatement(new AssignmentExpression(variableIdentifier, AssignmentOperator.Assign, initializer, false));
if (initializer is UnaryOperatorExpression { Operator : UnaryOperator.AddressOf, Target: CompoundObjectInitializationExpression compoundInitializationExpression } unaryOperatorExpression)
{
var tempVariableName = scope.GetTmpVariable();
var tempVariableIdentifier = new IdentifierExpression(tempVariableName);
if (type is PointerType pointerType)
{
type = pointerType.Base;
}

var tempVariable = new GlobalVariableDefinition(storageClass, type, tempVariableName);
yield return tempVariable;
yield return new ExpressionStatement(new AssignmentExpression(tempVariableIdentifier, AssignmentOperator.Assign, compoundInitializationExpression, false));
yield return new ExpressionStatement(new AssignmentExpression(variableIdentifier, AssignmentOperator.Assign, new UnaryOperatorExpression(UnaryOperator.AddressOf, tempVariableIdentifier), false));
}
else
{
yield return new ExpressionStatement(new AssignmentExpression(variableIdentifier, AssignmentOperator.Assign, initializer, false));
}
}

continue;
Expand Down
2 changes: 1 addition & 1 deletion Cesium.CodeGen/Ir/Declarations/LocalDeclarationInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static LocalDeclarationInfo Of(
return new LocalDeclarationInfo(type, Identifier: null, cliImportMemberName);
}

private static (IType, string? CliImportMemberName) ProcessSpecifiers(
public static (IType, string? CliImportMemberName) ProcessSpecifiers(
IReadOnlyList<IDeclarationSpecifier> specifiers)
{
IType? type = null;
Expand Down
14 changes: 1 addition & 13 deletions Cesium.CodeGen/Ir/Declarations/ScopedDeclarationInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ private static ScopedIdentifierDeclaration[] IdentifierOf(
var declarations = initDeclarators
.Select(id =>
{
//return IdentifierOf(declarationSpecifiers, id);
var (declarator, initializer) = id;
var declarationInfo = LocalDeclarationInfo.Of(declarationSpecifiers, declarator, initializer);
var (type, _, _) = declarationInfo;
Expand All @@ -94,18 +93,7 @@ private static ScopedIdentifierDeclaration[] IdentifierOf(
return declarations;
}

private static InitializableDeclarationInfo IdentifierOf(
IReadOnlyList<IDeclarationSpecifier> specifiers,
InitDeclarator initDeclarator)
{
var (declarator, initializer) = initDeclarator;
var declarationInfo = LocalDeclarationInfo.Of(specifiers, declarator, initializer);
var (type, _, _) = declarationInfo;
var expression = ConvertInitializer(type, initializer);
return new InitializableDeclarationInfo(declarationInfo, expression);
}

private static IExpression? ConvertInitializer(Types.IType? type, Initializer? initializer)
public static IExpression? ConvertInitializer(Types.IType? type, Initializer? initializer)
{
if (initializer is null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ internal CompoundObjectFieldInitializer(AssignmentInitializer initializer)
Designation = initializer.Designation!;
}

internal CompoundObjectFieldInitializer(IExpression inner, Designation designation)
{
Inner = inner;
Designation = designation;
}

public void EmitTo(IEmitScope scope) => Inner.EmitTo(scope);

public IType GetExpressionType(IDeclarationScope scope) => Inner.GetExpressionType(scope);

public IExpression Lower(IDeclarationScope scope) => Inner.Lower(scope);
public IExpression Lower(IDeclarationScope scope) => new CompoundObjectFieldInitializer(Inner.Lower(scope), Designation);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Cesium.Ast;
using Cesium.CodeGen.Contexts;
using Cesium.CodeGen.Extensions;
using Cesium.CodeGen.Ir.Declarations;
using Cesium.CodeGen.Ir.Types;
using Cesium.Core;
using Mono.Cecil;
Expand All @@ -15,7 +16,6 @@ internal sealed class CompoundObjectInitializationExpression : IExpression
private Action? _prefixAction;
private Action? _postfixAction;
private readonly ImmutableArray<IExpression?> _initializers;
private IDeclarationScope? _scope;

public CompoundObjectInitializationExpression(IType type, ImmutableArray<IExpression?> initializers)
{
Expand All @@ -28,6 +28,13 @@ public CompoundObjectInitializationExpression(ImmutableArray<IExpression?> initi
_initializers = initializers;
}

public CompoundObjectInitializationExpression(Ast.CompoundLiteralExpression expression)
{
var (type, cliDescription) = LocalDeclarationInfo.ProcessSpecifiers(expression.TypeName.SpecifierQualifierList);
_type = type;
_initializers = expression.Initializers.Select(initializer => IScopedDeclarationInfo.ConvertInitializer(_type, initializer)).ToImmutableArray();
}

public void Hint(FieldDefinition type, Action prefixAction, Action postfixAction)
{
_typeDef = type;
Expand Down Expand Up @@ -271,14 +278,8 @@ static Instruction GetWriteInstruction(MetadataType type)

public IExpression Lower(IDeclarationScope scope)
{
_scope = scope;
if (_type != null) CheckIfResolved(scope);
return this;
}

private void CheckIfResolved(IDeclarationScope scope)
{
if (_type!.TypeKind == TypeKind.Unresolved)
_type = scope.ResolveType(_type);
var resolvedType = _type?.TypeKind == TypeKind.Unresolved ? scope.ResolveType(_type) : _type;
var initializers = _initializers.Select(_ => _?.Lower(scope)).ToImmutableArray();
return resolvedType == null ? new CompoundObjectInitializationExpression(initializers) : new CompoundObjectInitializationExpression(resolvedType, initializers);
}
}

0 comments on commit 03ebc93

Please sign in to comment.