From ead99d70d1eeb48d3b2ca7dc757fb68a6c94e64a Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 17 Jun 2023 19:27:40 +0100 Subject: Support external global definitions --- .../backends/llvm/LlvmCompilerContext.java | 2 +- .../backends/llvm/LlvmCompilerNamespaces.java | 5 +++-- .../backends/llvm/ir/LlvmIrSerializer.java | 9 ++++++-- .../backends/llvm/ir/ast/LlvmGlobalDefinition.java | 4 +++- .../backends/llvm/LlvmCompilerPushStringTests.java | 4 ++-- .../ir/LlvmIrSerializerGlobalDefinitionTests.java | 26 ++++++++++++++++++---- .../llvm/ir/LlvmIrSerializerModuleTests.java | 5 +++-- 7 files changed, 41 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java index 60e6515b..980249e2 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java @@ -123,7 +123,7 @@ public record LlvmCompilerContext( var globalDefinition = new LlvmGlobalDefinition( generateTopLevelEntityName(builder.namePrefix().orElseThrow()), builder.type().orElseThrow(), - builder.value().orElseThrow(), + builder.value(), builder.constant(), builder.isPrivate(), builder.unnamedAddr() diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java index 949ffa9c..5c0bbca5 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java @@ -12,6 +12,7 @@ import org.shedlang.compiler.types.NamespaceTypeInfo; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.IntStream; public class LlvmCompilerNamespaces { @@ -44,14 +45,14 @@ public class LlvmCompilerNamespaces { return new LlvmGlobalDefinition( globalNameNamespaceValue(namespaceName), typeNamespaceStruct(namespaceTypeInfo), - new LlvmOperandStructure( + Optional.of(new LlvmOperandStructure( IntStream.range(0, namespaceTypeInfo.fieldCount()) .mapToObj(ignored -> new LlvmTypedOperand( LlvmCompilerTypes.VALUE_TYPE, new LlvmOperandInt(0) )) .toList() - ), + )), false, false, false diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java index 5853fd6d..74a271ed 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializer.java @@ -207,11 +207,16 @@ public class LlvmIrSerializer { if (globalDefinition.unnamedAddr()) { builder.append("unnamed_addr "); } + if (globalDefinition.value().isEmpty()) { + builder.append("external "); + } builder.append(globalDefinition.constant() ? "constant" : "global"); builder.append(" "); serializeType(globalDefinition.type(), builder); - builder.append(" "); - serializeOperand(globalDefinition.value(), builder); + if (globalDefinition.value().isPresent()) { + builder.append(" "); + serializeOperand(globalDefinition.value().get(), builder); + } builder.append("\n"); } } diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmGlobalDefinition.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmGlobalDefinition.java index 68c9cd67..2f5f2e72 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmGlobalDefinition.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmGlobalDefinition.java @@ -3,10 +3,12 @@ package org.shedlang.compiler.backends.llvm.ir.ast; import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; +import java.util.Optional; + public record LlvmGlobalDefinition( String name, LlvmType type, - LlvmOperand value, + Optional value, boolean constant, boolean isPrivate, boolean unnamedAddr diff --git a/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerPushStringTests.java b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerPushStringTests.java index 9a6324a8..b62ac757 100644 --- a/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerPushStringTests.java +++ b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerPushStringTests.java @@ -36,7 +36,7 @@ public class LlvmCompilerPushStringTests { LlvmTypes.INT_64, LlvmTypes.array(5, LlvmTypes.INT_8) )))), - has("value", x -> x.value(), equalTo(LlvmIr.operandStructure(List.of( + has("value", x -> x.value(), isOptionalOf(equalTo(LlvmIr.operandStructure(List.of( LlvmIr.typedOperand(LlvmTypes.INT_64, LlvmIr.operandInt(5)), LlvmIr.typedOperand( LlvmTypes.array(5, LlvmTypes.INT_8), @@ -48,7 +48,7 @@ public class LlvmCompilerPushStringTests { LlvmIr.operandInt(111) )) ) - )))), + ))))), has("constant", x -> x.constant(), equalTo(true)), has("isPrivate", x -> x.isPrivate(), equalTo(true)), has("unnamedAddr", x -> x.unnamedAddr(), equalTo(true)) diff --git a/src/test/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializerGlobalDefinitionTests.java b/src/test/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializerGlobalDefinitionTests.java index c2460540..85d94127 100644 --- a/src/test/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializerGlobalDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializerGlobalDefinitionTests.java @@ -5,6 +5,8 @@ import org.shedlang.compiler.backends.llvm.ir.ast.LlvmGlobalDefinition; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmIr; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypes; +import java.util.Optional; + import static org.shedlang.compiler.backends.llvm.ir.LlvmIrSerializerTesting.serializeToString; import static org.zwobble.precisely.AssertThat.assertThat; import static org.zwobble.precisely.Matchers.equalTo; @@ -15,7 +17,7 @@ public class LlvmIrSerializerGlobalDefinitionTests { var definition = new LlvmGlobalDefinition( "x", LlvmTypes.INT_64, - LlvmIr.operandInt(42), + Optional.of(LlvmIr.operandInt(42)), false, false, false @@ -26,12 +28,28 @@ public class LlvmIrSerializerGlobalDefinitionTests { assertThat(result, equalTo("@x = global i64 42\n")); } + @Test + public void canSerializeExternal() { + var definition = new LlvmGlobalDefinition( + "x", + LlvmTypes.INT_64, + Optional.empty(), + false, + false, + false + ); + + var result = serializeToString(definition, LlvmIrSerializer::serializeTopLevelEntity); + + assertThat(result, equalTo("@x = external global i64\n")); + } + @Test public void canSerializeConstant() { var definition = new LlvmGlobalDefinition( "x", LlvmTypes.INT_64, - LlvmIr.operandInt(42), + Optional.of(LlvmIr.operandInt(42)), true, false, false @@ -47,7 +65,7 @@ public class LlvmIrSerializerGlobalDefinitionTests { var definition = new LlvmGlobalDefinition( "x", LlvmTypes.INT_64, - LlvmIr.operandInt(42), + Optional.of(LlvmIr.operandInt(42)), false, true, false @@ -63,7 +81,7 @@ public class LlvmIrSerializerGlobalDefinitionTests { var definition = new LlvmGlobalDefinition( "x", LlvmTypes.INT_64, - LlvmIr.operandInt(42), + Optional.of(LlvmIr.operandInt(42)), false, false, true diff --git a/src/test/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializerModuleTests.java b/src/test/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializerModuleTests.java index 1f32ddf3..c9cf5e95 100644 --- a/src/test/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializerModuleTests.java +++ b/src/test/java/org/shedlang/compiler/backends/llvm/ir/LlvmIrSerializerModuleTests.java @@ -6,6 +6,7 @@ import org.shedlang.compiler.backends.llvm.ir.ast.LlvmIr; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypes; import java.util.List; +import java.util.Optional; import static org.shedlang.compiler.backends.llvm.ir.LlvmIrSerializerTesting.serializeToString; import static org.zwobble.precisely.AssertThat.assertThat; @@ -18,7 +19,7 @@ public class LlvmIrSerializerModuleTests { new LlvmGlobalDefinition( "x", LlvmTypes.INT_64, - LlvmIr.operandInt(42), + Optional.of(LlvmIr.operandInt(42)), false, false, false @@ -26,7 +27,7 @@ public class LlvmIrSerializerModuleTests { new LlvmGlobalDefinition( "y", LlvmTypes.INT_64, - LlvmIr.operandInt(42), + Optional.of(LlvmIr.operandInt(42)), false, false, false -- cgit v1.2.3