From ff864c8204b07962873777d25080270c54f2b35e Mon Sep 17 00:00:00 2001 From: LPeter1997 Date: Sun, 1 Sep 2024 19:16:30 +0200 Subject: [PATCH] Codegen simplification (#461) * Update FunctionBodyCodegen.cs * Move * Simplified literal handling * Update FunctionBodyCodegen.cs * Update FunctionBodyCodegen.cs * Update FunctionBodyCodegen.cs * Update FunctionBodyCodegen.cs * Update FunctionBodyCodegen.cs --- src/Draco.Compiler/Api/Compilation.cs | 1 + .../{ => Codegen}/AssemblyCodegen.cs | 2 +- .../{ => Codegen}/FunctionBodyCodegen.cs | 362 ++++++++---------- .../{ => Codegen}/ModuleCodegen.cs | 3 +- .../Internal/Symbols/FunctionSymbol.cs | 2 +- .../Internal/Symbols/GlobalSymbol.cs | 10 + .../Metadata/MetadataStaticFieldSymbol.cs | 19 +- .../Internal/Symbols/WellKnownTypes.cs | 2 +- 8 files changed, 185 insertions(+), 216 deletions(-) rename src/Draco.Compiler/Internal/OptimizingIr/{ => Codegen}/AssemblyCodegen.cs (96%) rename src/Draco.Compiler/Internal/OptimizingIr/{ => Codegen}/FunctionBodyCodegen.cs (83%) rename src/Draco.Compiler/Internal/OptimizingIr/{ => Codegen}/ModuleCodegen.cs (98%) diff --git a/src/Draco.Compiler/Api/Compilation.cs b/src/Draco.Compiler/Api/Compilation.cs index fc50aa9ae..b7fed944b 100644 --- a/src/Draco.Compiler/Api/Compilation.cs +++ b/src/Draco.Compiler/Api/Compilation.cs @@ -14,6 +14,7 @@ using Draco.Compiler.Internal.Declarations; using Draco.Compiler.Internal.Diagnostics; using Draco.Compiler.Internal.OptimizingIr; +using Draco.Compiler.Internal.OptimizingIr.Codegen; using Draco.Compiler.Internal.Symbols; using Draco.Compiler.Internal.Symbols.Metadata; using Draco.Compiler.Internal.Symbols.Script; diff --git a/src/Draco.Compiler/Internal/OptimizingIr/AssemblyCodegen.cs b/src/Draco.Compiler/Internal/OptimizingIr/Codegen/AssemblyCodegen.cs similarity index 96% rename from src/Draco.Compiler/Internal/OptimizingIr/AssemblyCodegen.cs rename to src/Draco.Compiler/Internal/OptimizingIr/Codegen/AssemblyCodegen.cs index 821344630..ce8fd5ea4 100644 --- a/src/Draco.Compiler/Internal/OptimizingIr/AssemblyCodegen.cs +++ b/src/Draco.Compiler/Internal/OptimizingIr/Codegen/AssemblyCodegen.cs @@ -2,7 +2,7 @@ using Draco.Compiler.Api; using Draco.Compiler.Internal.OptimizingIr.Model; -namespace Draco.Compiler.Internal.OptimizingIr; +namespace Draco.Compiler.Internal.OptimizingIr.Codegen; /// /// Generates IR code on top-level. diff --git a/src/Draco.Compiler/Internal/OptimizingIr/FunctionBodyCodegen.cs b/src/Draco.Compiler/Internal/OptimizingIr/Codegen/FunctionBodyCodegen.cs similarity index 83% rename from src/Draco.Compiler/Internal/OptimizingIr/FunctionBodyCodegen.cs rename to src/Draco.Compiler/Internal/OptimizingIr/Codegen/FunctionBodyCodegen.cs index f2619d365..6fbc2c842 100644 --- a/src/Draco.Compiler/Internal/OptimizingIr/FunctionBodyCodegen.cs +++ b/src/Draco.Compiler/Internal/OptimizingIr/Codegen/FunctionBodyCodegen.cs @@ -1,5 +1,4 @@ using System.Collections.Immutable; -using System.Diagnostics; using System.Linq; using Draco.Compiler.Api; using Draco.Compiler.Internal.Binding; @@ -7,14 +6,11 @@ using Draco.Compiler.Internal.OptimizingIr.Instructions; using Draco.Compiler.Internal.OptimizingIr.Model; using Draco.Compiler.Internal.Symbols; -using Draco.Compiler.Internal.Symbols.Generic; -using Draco.Compiler.Internal.Symbols.Metadata; using Draco.Compiler.Internal.Symbols.Source; -using Draco.Compiler.Internal.Symbols.Syntax; using Draco.Compiler.Internal.Symbols.Synthetized; using static Draco.Compiler.Internal.OptimizingIr.InstructionFactory; -namespace Draco.Compiler.Internal.OptimizingIr; +namespace Draco.Compiler.Internal.OptimizingIr.Codegen; /// /// Generates IR code on function-local level. @@ -61,33 +57,10 @@ public void Write(IInstruction instr) this.currentBasicBlock.InsertLast(instr); } - private Module GetDefiningModule(Symbol symbol) - { - var pathToSymbol = symbol.AncestorChain.OfType().First(); - return (Module)this.procedure.Assembly.Lookup(pathToSymbol); - } - - private Procedure DefineProcedure(FunctionSymbol function) => this.GetDefiningModule(function).DefineProcedure(function); private BasicBlock DefineBasicBlock(LabelSymbol label) => this.procedure.DefineBasicBlock(label); private int DefineLocal(LocalSymbol local) => this.procedure.DefineLocal(local); public Register DefineRegister(TypeSymbol type) => this.procedure.DefineRegister(type); - private FunctionSymbol SynthetizeProcedure(FunctionSymbol func) - { - Debug.Assert(func.Body is not null); - - // We handle synthetized functions a bit specially, as they are not part of our symbol - // tree, so we compile them, in case they have not yet been - var compiledAlready = this.procedure.DeclaringModule.Procedures.ContainsKey(func); - var proc = this.procedure.DeclaringModule.DefineProcedure(func); - if (!compiledAlready) - { - var codegen = new FunctionBodyCodegen(this.compilation, proc); - func.Body.Accept(codegen); - } - return func; - } - private static bool NeedsBoxing(TypeSymbol targetType, TypeSymbol sourceType) { var targetIsValueType = targetType.Substitution.IsValueType; @@ -125,6 +98,130 @@ public IOperand BoxIfNeeded(TypeSymbol targetType, IOperand source) return source; } + private void PatchLoadTarget(IInstruction loadInstr, Register target) + { + switch (loadInstr) + { + case LoadInstruction load: + load.Target = target; + break; + case LoadElementInstruction loadElement: + loadElement.Target = target; + break; + case LoadFieldInstruction loadField: + loadField.Target = target; + break; + default: + throw new System.ArgumentOutOfRangeException(nameof(loadInstr)); + } + } + + private void PatchStoreSource(IInstruction storeInstr, TypeSymbol targetType, IOperand source) + { + source = this.BoxIfNeeded(targetType, source); + switch (storeInstr) + { + case StoreInstruction store: + store.Source = source; + break; + case StoreElementInstruction storeElement: + storeElement.Source = source; + break; + case StoreFieldInstruction storeField: + storeField.Source = source; + break; + default: + throw new System.ArgumentOutOfRangeException(nameof(storeInstr)); + } + } + + // Manifesting an expression as an address + private IOperand CompileToAddress(BoundExpression expression) + { + switch (expression) + { + case BoundLocalExpression local: + { + var target = this.DefineRegister(new ReferenceTypeSymbol(local.TypeRequired)); + this.Write(AddressOf(target, local.Local)); + return target; + } + default: + { + // We allocate a local so we can take its address + var local = new SynthetizedLocalSymbol(expression.TypeRequired, false); + this.procedure.DefineLocal(local); + // Store the value in it + var value = this.Compile(expression); + this.Write(Store(local, value)); + // Take its address + var target = this.DefineRegister(new ReferenceTypeSymbol(expression.TypeRequired)); + this.Write(AddressOf(target, local)); + return target; + } + } + } + + private IOperand? CompileReceiver(BoundCallExpression call) + { + if (call.Receiver is null) return null; + // Box receiver, if needed + if (call.Method.ContainingSymbol is TypeSymbol methodContainer + && NeedsBoxing(methodContainer, call.Receiver.TypeRequired)) + { + var valueReceiver = this.Compile(call.Receiver); + var receiver = this.DefineRegister(methodContainer); + this.Write(Box(receiver, methodContainer, valueReceiver)); + return receiver; + } + else + { + return call.Receiver.TypeRequired.IsValueType + ? this.CompileToAddress(call.Receiver) + : this.Compile(call.Receiver); + } + } + + private (IInstruction Load, IInstruction Store) CompileLvalue(BoundLvalue lvalue) + { + switch (lvalue) + { + case BoundLocalLvalue local: + { + return (Load: Load(default!, local.Local), Store: Store(local.Local, default!)); + } + case BoundGlobalLvalue global: + { + return (Load: Load(default!, global.Global), Store: Store(global.Global, default!)); + } + case BoundFieldLvalue field: + { + var receiver = field.Receiver is null ? null : this.Compile(field.Receiver); + if (receiver is null) + { + var src = field.Field; + return (Load: Load(default!, src), Store: Store(src, default!)); + } + else + { + return ( + Load: LoadField(default!, receiver, field.Field), + Store: StoreField(receiver, field.Field, default!)); + } + } + case BoundArrayAccessLvalue arrayAccess: + { + var array = this.Compile(arrayAccess.Array); + var indices = arrayAccess.Indices + .Select(this.Compile) + .ToList(); + return (Load: LoadElement(default!, array, indices), Store: StoreElement(array, indices, default!)); + } + default: + throw new System.ArgumentOutOfRangeException(nameof(lvalue)); + } + } + // Statements ////////////////////////////////////////////////////////////// public override IOperand VisitSequencePointStatement(BoundSequencePointStatement node) @@ -185,75 +282,6 @@ public override IOperand VisitConditionalGotoStatement(BoundConditionalGotoState return default!; } - // Lvalues ///////////////////////////////////////////////////////////////// - - private (IInstruction Load, IInstruction Store) CompileLvalue(BoundLvalue lvalue) - { - switch (lvalue) - { - case BoundLocalLvalue local: - { - return (Load: Load(default!, local.Local), Store: Store(local.Local, default!)); - } - case BoundGlobalLvalue global: - { - return (Load: Load(default!, global.Global), Store: Store(global.Global, default!)); - } - case BoundFieldLvalue field: - { - var receiver = field.Receiver is null ? null : this.Compile(field.Receiver); - if (receiver is null) - { - var src = field.Field; - return (Load: Load(default!, src), Store: Store(src, default!)); - } - else - { - return ( - Load: LoadField(default!, receiver, field.Field), - Store: StoreField(receiver, field.Field, default!)); - } - } - case BoundArrayAccessLvalue arrayAccess: - { - var array = this.Compile(arrayAccess.Array); - var indices = arrayAccess.Indices - .Select(this.Compile) - .ToList(); - return (Load: LoadElement(default!, array, indices), Store: StoreElement(array, indices, default!)); - } - default: - throw new System.ArgumentOutOfRangeException(nameof(lvalue)); - } - } - - // Manifesting an expression as an address - private IOperand CompileToAddress(BoundExpression expression) - { - switch (expression) - { - case BoundLocalExpression local: - { - var target = this.DefineRegister(new ReferenceTypeSymbol(local.TypeRequired)); - this.Write(AddressOf(target, local.Local)); - return target; - } - default: - { - // We allocate a local so we can take its address - var local = new SynthetizedLocalSymbol(expression.TypeRequired, false); - this.procedure.DefineLocal(local); - // Store the value in it - var value = this.Compile(expression); - this.Write(Store(local, value)); - // Take its address - var target = this.DefineRegister(new ReferenceTypeSymbol(expression.TypeRequired)); - this.Write(AddressOf(target, local)); - return target; - } - } - } - // Expressions ///////////////////////////////////////////////////////////// public override IOperand VisitStringExpression(BoundStringExpression node) => @@ -279,7 +307,7 @@ public override IOperand VisitCallExpression(BoundCallExpression node) .Select(pair => this.BoxIfNeeded(pair.Second.Type, this.Compile(pair.First))) .ToImmutableArray(); - var proc = this.TranslateFunctionSymbol(node.Method); + var proc = node.Method; if (proc.Codegen is { } codegen) { if (receiver is not null) @@ -296,29 +324,9 @@ public override IOperand VisitCallExpression(BoundCallExpression node) } } - private IOperand? CompileReceiver(BoundCallExpression call) - { - if (call.Receiver is null) return null; - // Box receiver, if needed - if (call.Method.ContainingSymbol is TypeSymbol methodContainer - && NeedsBoxing(methodContainer, call.Receiver.TypeRequired)) - { - var valueReceiver = this.Compile(call.Receiver); - var receiver = this.DefineRegister(methodContainer); - this.Write(Box(receiver, methodContainer, valueReceiver)); - return receiver; - } - else - { - return call.Receiver.TypeRequired.IsValueType - ? this.CompileToAddress(call.Receiver) - : this.Compile(call.Receiver); - } - } - public override IOperand VisitObjectCreationExpression(BoundObjectCreationExpression node) { - var ctor = this.TranslateFunctionSymbol(node.Constructor); + var ctor = node.Constructor; var args = node.Arguments.Select(this.Compile).ToList(); var result = this.DefineRegister(node.TypeRequired); this.Write(NewObject(result, ctor, args)); @@ -328,8 +336,8 @@ public override IOperand VisitObjectCreationExpression(BoundObjectCreationExpres public override IOperand VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { var receiver = node.Receiver is null ? null : this.Compile(node.Receiver); - var function = this.TranslateFunctionSymbol(node.Method); - var delegateCtor = this.TranslateFunctionSymbol(node.DelegateConstructor); + var function = node.Method; + var delegateCtor = node.DelegateConstructor; var result = this.DefineRegister(node.TypeRequired); this.Write(NewDelegate(result, receiver, function, delegateCtor)); return result; @@ -402,7 +410,7 @@ public override IOperand VisitAssignmentExpression(BoundAssignmentExpression nod { var leftValue = this.DefineRegister(node.Left.Type); // Patch - PatchLoadTarget(leftLoad, leftValue); + this.PatchLoadTarget(leftLoad, leftValue); this.Write(leftLoad); if (node.CompoundOperator.Codegen is { } codegen) { @@ -421,43 +429,6 @@ public override IOperand VisitAssignmentExpression(BoundAssignmentExpression nod return toStore; } - private static void PatchLoadTarget(IInstruction loadInstr, Register target) - { - switch (loadInstr) - { - case LoadInstruction load: - load.Target = target; - break; - case LoadElementInstruction loadElement: - loadElement.Target = target; - break; - case LoadFieldInstruction loadField: - loadField.Target = target; - break; - default: - throw new System.ArgumentOutOfRangeException(nameof(loadInstr)); - } - } - - private void PatchStoreSource(IInstruction storeInstr, TypeSymbol targetType, IOperand source) - { - source = this.BoxIfNeeded(targetType, source); - switch (storeInstr) - { - case StoreInstruction store: - store.Source = source; - break; - case StoreElementInstruction storeElement: - storeElement.Source = source; - break; - case StoreFieldInstruction storeField: - storeField.Source = source; - break; - default: - throw new System.ArgumentOutOfRangeException(nameof(storeInstr)); - } - } - public override IOperand VisitReturnExpression(BoundReturnExpression node) { var operand = this.Compile(node.Value); @@ -470,11 +441,10 @@ public override IOperand VisitReturnExpression(BoundReturnExpression node) public override IOperand VisitGlobalExpression(BoundGlobalExpression node) { // Check, if constant literal that has to be inlined - var metadataGlobal = ExtractMetadataStaticField(node.Global); - if (metadataGlobal is not null && metadataGlobal.IsLiteral) + if (node.Global.IsLiteral) { - var defaultValue = metadataGlobal.DefaultValue; // NOTE: Literals possibly have a different type than the signature of the global + var defaultValue = node.Global.LiteralValue; if (!BinderFacts.TryGetLiteralType(defaultValue, this.compilation.WellKnownTypes, out var literalType)) { throw new System.InvalidOperationException(); @@ -502,32 +472,6 @@ public override IOperand VisitParameterExpression(BoundParameterExpression node) return result; } - public override IOperand VisitFunctionGroupExpression(BoundFunctionGroupExpression node) => - // TODO - throw new System.NotImplementedException(); - - private FunctionSymbol TranslateFunctionSymbol(FunctionSymbol symbol) => symbol switch - { - // Generic functions - FunctionInstanceSymbol i => this.TranslateFunctionInstanceSymbol(i), - // Functions with synthetized body - FunctionSymbol f when f.DeclaringSyntax is null && f.Body is not null => this.SynthetizeProcedure(f), - // Functions with inline codegen - FunctionSymbol f when f.Codegen is not null => f, - // Source functions - SyntaxFunctionSymbol func => this.DefineProcedure(func).Symbol, - // Metadata functions - MetadataMethodSymbol m => m, - _ => throw new System.ArgumentOutOfRangeException(nameof(symbol)), - }; - - private FunctionInstanceSymbol TranslateFunctionInstanceSymbol(FunctionInstanceSymbol i) - { - // NOTE: We visit the underlying instantiated symbol in case it's synthetized by us - this.TranslateFunctionSymbol(i.GenericDefinition); - return i; - } - public override IOperand VisitLiteralExpression(BoundLiteralExpression node) => new Constant(node.Value, node.TypeRequired); public override IOperand VisitUnitExpression(BoundUnitExpression node) => default(Void); @@ -540,17 +484,37 @@ public override IOperand VisitFieldExpression(BoundFieldExpression node) return result; } - public override IOperand VisitUnaryExpression(BoundUnaryExpression node) => - throw new System.InvalidOperationException(); + // Lowered nodes ////////////////////////////////////////////////////////// - public override IOperand VisitBinaryExpression(BoundBinaryExpression node) => - throw new System.InvalidOperationException(); + public override IOperand VisitAndExpression(BoundAndExpression node) => ShouldHaveBeenLowered(node); + public override IOperand VisitOrExpression(BoundOrExpression node) => ShouldHaveBeenLowered(node); - // TODO: This will likely disappear once all globals can have a constant value - private static MetadataStaticFieldSymbol? ExtractMetadataStaticField(GlobalSymbol global) => global switch - { - MetadataStaticFieldSymbol m => m, - // TODO: Global instances? - _ => null, - }; + public override IOperand VisitIfExpression(BoundIfExpression node) => ShouldHaveBeenLowered(node); + public override IOperand VisitWhileExpression(BoundWhileExpression node) => ShouldHaveBeenLowered(node); + public override IOperand VisitForExpression(BoundForExpression node) => ShouldHaveBeenLowered(node); + + public override IOperand VisitIndexGetExpression(BoundIndexGetExpression node) => ShouldHaveBeenLowered(node); + public override IOperand VisitIndexSetExpression(BoundIndexSetExpression node) => ShouldHaveBeenLowered(node); + public override IOperand VisitPropertyGetExpression(BoundPropertyGetExpression node) => ShouldHaveBeenLowered(node); + public override IOperand VisitPropertySetExpression(BoundPropertySetExpression node) => ShouldHaveBeenLowered(node); + + public override IOperand VisitIndirectCallExpression(BoundIndirectCallExpression node) => ShouldHaveBeenLowered(node); + + public override IOperand VisitRelationalExpression(BoundRelationalExpression node) => ShouldHaveBeenLowered(node); + public override IOperand VisitUnaryExpression(BoundUnaryExpression node) => ShouldHaveBeenLowered(node); + public override IOperand VisitBinaryExpression(BoundBinaryExpression node) => ShouldHaveBeenLowered(node); + + // Illegal nodes ////////////////////////////////////////////////////////// + + public override IOperand VisitFunctionGroupExpression(BoundFunctionGroupExpression node) => Illegal(node); + public override IOperand VisitTypeExpression(BoundTypeExpression node) => Illegal(node); + public override IOperand VisitModuleExpression(BoundModuleExpression node) => Illegal(node); + + // Error utils //////////////////////////////////////////////////////////// + + private static IOperand ShouldHaveBeenLowered(BoundNode node) => + throw new System.InvalidOperationException($"node {node.GetType().Name} should have been lowered"); + + private static IOperand Illegal(BoundNode node) => + throw new System.InvalidOperationException($"illegal node {node.GetType().Name} in code generation"); } diff --git a/src/Draco.Compiler/Internal/OptimizingIr/ModuleCodegen.cs b/src/Draco.Compiler/Internal/OptimizingIr/Codegen/ModuleCodegen.cs similarity index 98% rename from src/Draco.Compiler/Internal/OptimizingIr/ModuleCodegen.cs rename to src/Draco.Compiler/Internal/OptimizingIr/Codegen/ModuleCodegen.cs index d33d3513e..7e0531fcf 100644 --- a/src/Draco.Compiler/Internal/OptimizingIr/ModuleCodegen.cs +++ b/src/Draco.Compiler/Internal/OptimizingIr/Codegen/ModuleCodegen.cs @@ -8,7 +8,7 @@ using Draco.Compiler.Internal.Symbols.Syntax; using static Draco.Compiler.Internal.OptimizingIr.InstructionFactory; -namespace Draco.Compiler.Internal.OptimizingIr; +namespace Draco.Compiler.Internal.OptimizingIr.Codegen; /// /// Generates IR code on module-level. @@ -100,6 +100,7 @@ public override void VisitModule(ModuleSymbol moduleSymbol) { member.Accept(this); } + this.Complete(); } diff --git a/src/Draco.Compiler/Internal/Symbols/FunctionSymbol.cs b/src/Draco.Compiler/Internal/Symbols/FunctionSymbol.cs index beda51cfb..6f35431d1 100644 --- a/src/Draco.Compiler/Internal/Symbols/FunctionSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/FunctionSymbol.cs @@ -4,7 +4,7 @@ using System.Threading; using Draco.Compiler.Api.Syntax; using Draco.Compiler.Internal.BoundTree; -using Draco.Compiler.Internal.OptimizingIr; +using Draco.Compiler.Internal.OptimizingIr.Codegen; using Draco.Compiler.Internal.OptimizingIr.Model; using Draco.Compiler.Internal.Symbols.Generic; diff --git a/src/Draco.Compiler/Internal/Symbols/GlobalSymbol.cs b/src/Draco.Compiler/Internal/Symbols/GlobalSymbol.cs index fc65757cc..96ff9846c 100644 --- a/src/Draco.Compiler/Internal/Symbols/GlobalSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/GlobalSymbol.cs @@ -15,6 +15,16 @@ internal abstract partial class GlobalSymbol : VariableSymbol, IMemberSymbol // NOTE: Override for covariant return type public override GlobalSymbol? GenericDefinition => null; + /// + /// True, if this global is a literal, meaning its value is known at compile-time and has to be inlined. + /// + public virtual bool IsLiteral => false; + + /// + /// The literal value of this global, if it is a literal. + /// + public virtual object? LiteralValue => null; + public override ISymbol ToApiSymbol() => new Api.Semantics.GlobalSymbol(this); public override GlobalSymbol GenericInstantiate(Symbol? containingSymbol, ImmutableArray arguments) => diff --git a/src/Draco.Compiler/Internal/Symbols/Metadata/MetadataStaticFieldSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Metadata/MetadataStaticFieldSymbol.cs index b0c4f2ddf..9c4de2e4b 100644 --- a/src/Draco.Compiler/Internal/Symbols/Metadata/MetadataStaticFieldSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Metadata/MetadataStaticFieldSymbol.cs @@ -42,6 +42,11 @@ public override Api.Semantics.Visibility Visibility internal override string RawDocumentation => LazyInitializer.EnsureInitialized(ref this.rawDocumentation, this.BuildRawDocumentation); private string? rawDocumentation; + public override bool IsLiteral => this.fieldDefinition.Attributes.HasFlag(FieldAttributes.Literal); + + public override object? LiteralValue => InterlockedUtils.InitializeMaybeNull(ref this.literalValue, this.BuildLiteralValue); + private object? literalValue; + public override Symbol? ContainingSymbol { get; } /// @@ -56,18 +61,6 @@ public override Api.Semantics.Visibility Visibility /// public MetadataReader MetadataReader => this.Assembly.MetadataReader; - /// - /// True, if this is a literal that cannot be referenced as a field, but needs to be inlined as a value. - /// This is the case for enum members. - /// - public bool IsLiteral => this.fieldDefinition.Attributes.HasFlag(FieldAttributes.Literal); - - /// - /// The default value of this field. - /// - public object? DefaultValue => InterlockedUtils.InitializeMaybeNull(ref this.defaultValue, this.BuildDefaultValue); - private object? defaultValue; - private readonly FieldDefinition fieldDefinition; public MetadataStaticFieldSymbol(Symbol containingSymbol, FieldDefinition fieldDefinition) @@ -84,7 +77,7 @@ public MetadataStaticFieldSymbol(Symbol containingSymbol, FieldDefinition fieldD private TypeSymbol BuildType() => this.fieldDefinition.DecodeSignature(this.Assembly.Compilation.TypeProvider, this); - private object? BuildDefaultValue() + private object? BuildLiteralValue() { var constantHandle = this.fieldDefinition.GetDefaultValue(); if (constantHandle.IsNil) return null; diff --git a/src/Draco.Compiler/Internal/Symbols/WellKnownTypes.cs b/src/Draco.Compiler/Internal/Symbols/WellKnownTypes.cs index 6eed87a1f..f27ee9939 100644 --- a/src/Draco.Compiler/Internal/Symbols/WellKnownTypes.cs +++ b/src/Draco.Compiler/Internal/Symbols/WellKnownTypes.cs @@ -6,7 +6,7 @@ using System.Threading; using Draco.Compiler.Api; using Draco.Compiler.Api.Syntax; -using Draco.Compiler.Internal.OptimizingIr; +using Draco.Compiler.Internal.OptimizingIr.Codegen; using Draco.Compiler.Internal.OptimizingIr.Model; using Draco.Compiler.Internal.Symbols.Error; using Draco.Compiler.Internal.Symbols.Generic;