Skip to content

Commit

Permalink
Fix codegen with forward declaration.
Browse files Browse the repository at this point in the history
If forward declaration has different parameter name
then code gen does not working
  • Loading branch information
kant2002 committed Nov 18, 2023
1 parent 929ab30 commit abcf509
Show file tree
Hide file tree
Showing 13 changed files with 45 additions and 27 deletions.
12 changes: 12 additions & 0 deletions Cesium.CodeGen.Tests/CodeGenMethodTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,18 @@ int main()
return fooptr(123);
}", "Attempted to call non-function pointer");

[Fact]
public Task StructParameters() => DoTest(@"
struct struct1 {
int x;
};
int console_read(struct struct1* __s);
int console_read(struct struct1* s) {
return s->x;
}");

// TODO [#196]
/* [Fact]
public Task VarargFunctionPointerCallTest() => DoTest(@"int foo(int a, ...) { return a; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
System.Int32 <Module>::console_read(struct1* __s)
IL_0000: ldarg.0
IL_0001: ldfld System.Int32 struct1::x
IL_0006: ret
2 changes: 1 addition & 1 deletion Cesium.CodeGen/Contexts/BlockScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public VariableDefinition ResolveVariable(string identifier)
return variableDefinition;
}

public ParameterDefinition ResolveParameter(string name) => Parent.ResolveParameter(name);
public ParameterDefinition ResolveParameter(int index) => Parent.ResolveParameter(index);
public ParameterInfo? GetParameterInfo(string name) => ((IDeclarationScope)Parent).GetParameterInfo(name);

/// <inheritdoc />
Expand Down
9 changes: 2 additions & 7 deletions Cesium.CodeGen/Contexts/FunctionScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,9 @@ public VariableDefinition ResolveVariable(string identifier)
public ParameterInfo? GetParameterInfo(string name) => FunctionInfo.Parameters?.Parameters.FirstOrDefault(p => p.Name == name);

private readonly Dictionary<string, ParameterDefinition> _parameterCache = new();
public ParameterDefinition ResolveParameter(string name)
public ParameterDefinition ResolveParameter(int index)
{
if (_parameterCache.TryGetValue(name, out var parameter))
return parameter;

parameter = Method.Parameters.FirstOrDefault(p => p.Name == name) ?? throw new AssertException($"Cannot resolve parameter with name name {name}");
_parameterCache.Add(name, parameter);
return parameter;
return Method.Parameters[index];
}
/// <inheritdoc />
public IType ResolveType(IType type) => Context.ResolveType(type);
Expand Down
2 changes: 1 addition & 1 deletion Cesium.CodeGen/Contexts/GlobalConstructorScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public VariableDefinition ResolveVariable(string identifier) =>
throw new AssertException("Cannot add a variable into a global constructor scope");

public ParameterInfo? GetParameterInfo(string name) => null;
public ParameterDefinition ResolveParameter(string name) =>
public ParameterDefinition ResolveParameter(int index) =>
throw new AssertException("Cannot resolve parameter from the global constructor scope");

/// <inheritdoc />
Expand Down
2 changes: 1 addition & 1 deletion Cesium.CodeGen/Contexts/IEmitScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal interface IEmitScope
ModuleDefinition Module { get; }
TranslationUnitContext Context { get; }
VariableDefinition ResolveVariable(string identifier);
ParameterDefinition ResolveParameter(string name);
ParameterDefinition ResolveParameter(int index);

/// <summary>
/// Resolves instruction to which label pointed.
Expand Down
3 changes: 3 additions & 0 deletions Cesium.CodeGen/Contexts/Meta/FunctionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ internal record FunctionInfo(
StorageClass StorageClass,
bool IsDefined)
{
public ParametersInfo? Parameters { get; set; } = Parameters;
public StorageClass StorageClass { get; set; } = StorageClass;
public bool IsDefined { get; set; } = IsDefined;
public MethodReference? MethodReference { get; set; }
public string? CliImportMember { get; set; }

Expand Down
23 changes: 13 additions & 10 deletions Cesium.CodeGen/Contexts/TranslationUnitContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,20 @@ internal void DeclareFunction(string identifier, FunctionInfo functionInfo)
if (functionInfo.CliImportMember is not null && existingDeclaration.CliImportMember is not null)
{
var method = this.MethodLookup(functionInfo.CliImportMember, functionInfo.Parameters!, functionInfo.ReturnType);
if (!method.FullName.Equals(existingDeclaration.MethodReference!.FullName))
var methodReference = existingDeclaration.MethodReference!;
if (!method.FullName.Equals(methodReference.FullName))
{
throw new CompilationException($"Function {identifier} already defined as as CLI-import with {existingDeclaration.MethodReference.FullName}.");
throw new CompilationException($"Function {identifier} already defined as as CLI-import with {methodReference.FullName}.");
}
}

var mergedStorageClass = existingDeclaration.StorageClass != StorageClass.Auto
? existingDeclaration.StorageClass
: functionInfo.StorageClass;
var mergedIsDefined = existingDeclaration.IsDefined || functionInfo.IsDefined;
Functions[identifier] = existingDeclaration with { StorageClass = mergedStorageClass, IsDefined = mergedIsDefined };
existingDeclaration.Parameters = functionInfo.Parameters;
existingDeclaration.IsDefined = mergedIsDefined;
existingDeclaration.StorageClass = mergedStorageClass;
}
}

Expand All @@ -73,16 +76,16 @@ internal MethodDefinition DefineMethod(
IType returnType,
ParametersInfo? parameters)
{
var owningType = storageClass == StorageClass.Auto ? GlobalType : GetOrCreateTranslationUnitType();
var method = owningType.DefineMethod(
this,
name,
returnType.Resolve(this),
parameters);
var owningType = storageClass == StorageClass.Auto ? GlobalType : GetOrCreateTranslationUnitType();
var method = owningType.DefineMethod(
this,
name,
returnType.Resolve(this),
parameters);
var existingDeclaration = Functions.GetValueOrDefault(name);
Debug.Assert(existingDeclaration is not null, $"Attempt to define method for undeclared function {name}");
Functions[name] = existingDeclaration with { MethodReference = method };
return method;
return method;
}

private readonly Dictionary<IGeneratedType, TypeReference> _generatedTypes = new();
Expand Down
2 changes: 1 addition & 1 deletion Cesium.CodeGen/Extensions/TypeDefinitionEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private static void AddParameters(

foreach (var parameter in parameters)
{
var (type, name) = parameter;
var (type, name, _) = parameter;
var parameterDefinition = new ParameterDefinition(type.Resolve(context))
{
Name = name
Expand Down
2 changes: 2 additions & 0 deletions Cesium.CodeGen/Ir/BlockItems/FunctionDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using System.Diagnostics;
using PointerType = Cesium.CodeGen.Ir.Types.PointerType;

namespace Cesium.CodeGen.Ir.BlockItems;
Expand Down Expand Up @@ -65,6 +66,7 @@ public void EmitCode(IEmitScope scope)
var (parameters, returnType) = FunctionType;

var declaration = context.GetFunctionInfo(Name);
Debug.Assert(declaration != null, $"Function {Name} does not declared.");

var method = declaration switch
{
Expand Down
3 changes: 1 addition & 2 deletions Cesium.CodeGen/Ir/Expressions/Values/LValueParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ private ParameterDefinition GetParameterDefinition(IEmitScope scope)
return _definition;
}

var parameterName = _parameterInfo.Name ?? throw new AssertException("Name of parameter does not specified");
_definition = scope.ResolveParameter(parameterName);
_definition = scope.ResolveParameter(_parameterInfo.Index);
return _definition;
}

Expand Down
6 changes: 3 additions & 3 deletions Cesium.CodeGen/Ir/ParametersInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ internal record ParametersInfo(IList<ParameterInfo> Parameters, bool IsVoid, boo
}
}

internal record ParameterInfo(IType Type, string? Name)
internal record ParameterInfo(IType Type, string? Name, int Index)
{
public static ParameterInfo Of(ParameterDeclaration declaration)
public static ParameterInfo Of(ParameterDeclaration declaration, int index)
{
var (specifiers, declarator, abstractDeclarator) = declaration;
var (type, identifier, cliImportMemberName) = (declarator, abstractDeclarator) switch
Expand All @@ -55,6 +55,6 @@ public static ParameterInfo Of(ParameterDeclaration declaration)
if (cliImportMemberName != null)
throw new CompilationException("CLI import specifier isn't supported for a parameter.");

return new ParameterInfo(type, identifier);
return new ParameterInfo(type, identifier, index);
}
}
2 changes: 1 addition & 1 deletion Cesium.CodeGen/Ir/Types/FunctionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public TypeReference ResolvePointer(TranslationUnitContext context)
if (isVarArg)
throw new WipException(196, $"A pointer to a vararg function is not implemented, yet: {this}.");

foreach (var (type, name) in parameterInfos)
foreach (var (type, name, index) in parameterInfos)
{
pointer.Parameters.Add(new ParameterDefinition(type.Resolve(context))
{
Expand Down

0 comments on commit abcf509

Please sign in to comment.