Skip to content

Commit

Permalink
(#72) IR: resolve types for typedefs
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Feb 16, 2022
1 parent ee70a14 commit af00de4
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Cesium.CodeGen.Tests/CodeGenTypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ void foo(void)
}");

[Fact]
public Task EmptyStructDefinition() => DoTest("typedef struct { int x; } foo;");
public Task SingleFieldStructDefinition() => DoTest("typedef struct { int x; } foo;");
}
1 change: 1 addition & 0 deletions Cesium.CodeGen/Contexts/TranslationUnitContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ public record TranslationUnitContext(AssemblyContext AssemblyContext)
public TypeSystem TypeSystem => Module.TypeSystem;
public TypeDefinition ModuleType => Module.GetType("<Module>");
internal Dictionary<string, FunctionInfo> Functions => AssemblyContext.Functions;
internal Dictionary<string, TypeReference> Types { get; } = new();
}
4 changes: 2 additions & 2 deletions Cesium.CodeGen/Ir/Declarations/LocalDeclarationInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal record LocalDeclarationInfo(
ParametersInfo? Parameters,
string? CliImportMemberName)
{
public static LocalDeclarationInfo Of(IList<IDeclarationSpecifier> specifiers, Declarator? declarator)
public static LocalDeclarationInfo Of(ICollection<IDeclarationSpecifier> specifiers, Declarator? declarator)
{
var (type, cliImportMemberName) = ProcessSpecifiers(specifiers);
if (declarator == null)
Expand Down Expand Up @@ -85,7 +85,7 @@ public static LocalDeclarationInfo Of(IList<IDeclarationSpecifier> specifiers, D
}

private static (IType, string? cliImportMemberName) ProcessSpecifiers(
IList<IDeclarationSpecifier> specifiers)
ICollection<IDeclarationSpecifier> specifiers)
{
IType? type = null;
var isConst = false;
Expand Down
45 changes: 30 additions & 15 deletions Cesium.CodeGen/Ir/Declarations/ScopedDeclarationInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,41 @@ public static IScopedDeclarationInfo Of(Declaration declaration)

if (specifiers.Length > 0 && specifiers[0] is StorageClassSpecifier { Name: "typedef" })
{
return TypeDefDeclaration.Of(specifiers.Skip(1), initDeclarators);
return TypeDefOf(specifiers.RemoveAt(0), initDeclarators);
}

var initializableDeclarations = initDeclarators
.Select<InitDeclarator, InitializableDeclarationInfo>(id => Of(specifiers, id))
return IdentifierOf(specifiers, initDeclarators);
}

private static TypeDefDeclaration TypeDefOf(
ICollection<IDeclarationSpecifier> specifiers,
IEnumerable<InitDeclarator> initDeclarators)
{
var declarations = initDeclarators.Select(d =>
{
var (declarator, initializer) = d;
if (initializer != null)
throw new NotSupportedException($"Initializer is not supported for a typedef.");
return LocalDeclarationInfo.Of(specifiers, declarator);
}).ToList();

return new TypeDefDeclaration(declarations);
}

private static ScopedIdentifierDeclaration IdentifierOf(
ICollection<IDeclarationSpecifier> specifiers,
IEnumerable<InitDeclarator> initDeclarators)
{
var declarations = initDeclarators
.Select(id => IdentifierOf(specifiers, id))
.ToList();

return new ScopedIdentifierDeclaration(initializableDeclarations);
return new ScopedIdentifierDeclaration(declarations);
}

private static InitializableDeclarationInfo Of(
IList<IDeclarationSpecifier> specifiers,
private static InitializableDeclarationInfo IdentifierOf(
ICollection<IDeclarationSpecifier> specifiers,
InitDeclarator initDeclarator)
{
var (declarator, initializer) = initDeclarator;
Expand All @@ -44,14 +67,6 @@ private static InitializableDeclarationInfo Of(
}
}

internal record TypeDefDeclaration : IScopedDeclarationInfo
{
internal static TypeDefDeclaration Of(
IEnumerable<IDeclarationSpecifier> specifiers,
IEnumerable<InitDeclarator> initDeclarators)
{
throw new NotSupportedException("typedef not supported, yet.");
}
}
internal record TypeDefDeclaration(ICollection<LocalDeclarationInfo> Types) : IScopedDeclarationInfo;
internal record ScopedIdentifierDeclaration(ICollection<InitializableDeclarationInfo> Items) : IScopedDeclarationInfo;
internal record InitializableDeclarationInfo(LocalDeclarationInfo Declaration, IExpression? Initializer);
22 changes: 19 additions & 3 deletions Cesium.CodeGen/Ir/TopLevel/TopLevelDeclaration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public void EmitTo(TranslationUnitContext context)
EmitScopedIdentifier(context, declaration);
break;
case TypeDefDeclaration declaration:
EmitTypeDef(declaration);
EmitTypeDef(context, declaration);
break;
default:
throw new ArgumentOutOfRangeException(nameof(_declaration));
Expand Down Expand Up @@ -113,6 +113,22 @@ private static void EmitFunctionDeclaration(
context.Functions.Add(identifier, new FunctionInfo(parametersInfo, returnType, method));
}

private static void EmitTypeDef(TypeDefDeclaration declaration) =>
throw new NotImplementedException($"typedef is not supported at block level, yet: {declaration}.");
private static void EmitTypeDef(TranslationUnitContext context, TypeDefDeclaration declaration)
{
declaration.Deconstruct(out var types);
foreach (var typeDef in types)
{
var (type, identifier, parametersInfo, cliImportMemberName) = typeDef;
if (identifier == null)
throw new NotSupportedException($"Anonymous typedef not supported: {type}.");

if (parametersInfo != null)
throw new NotImplementedException($"Function typedef not supported, yet: {identifier}.");

if (cliImportMemberName != null)
throw new NotSupportedException($"typedef for CLI import not supported: {cliImportMemberName}.");

context.Types.Add(identifier, type.Resolve(context.TypeSystem));
}
}
}

0 comments on commit af00de4

Please sign in to comment.