diff --git a/.goreleaser.yml b/.goreleaser.yml index 6fb45a2fd..0df98a0f7 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,3 +1,4 @@ +version: 2 project_name: spice builds: - main: ./.github/media/dummy.go diff --git a/.run/spice build.run.xml b/.run/spice build.run.xml index 9ab7a44bd..992d19dd6 100644 --- a/.run/spice build.run.xml +++ b/.run/spice build.run.xml @@ -1,5 +1,5 @@ - + diff --git a/.run/spice run.run.xml b/.run/spice run.run.xml index 6dcd146ad..f1152f57e 100644 --- a/.run/spice run.run.xml +++ b/.run/spice run.run.xml @@ -1,5 +1,5 @@ - + diff --git a/.run/spice test.run.xml b/.run/spice test.run.xml index 374fd189f..b68e00b77 100644 --- a/.run/spice test.run.xml +++ b/.run/spice test.run.xml @@ -1,5 +1,5 @@ - + diff --git a/media/test-project/test.spice b/media/test-project/test.spice index 206b0b8b1..aa139d993 100644 --- a/media/test-project/test.spice +++ b/media/test-project/test.spice @@ -1,5 +1,13 @@ -f main() { +int Test = 123; + +type TestStruct struct { + int a + TestStruct* b +} +f main() { + TestStruct testStruct = TestStruct{1, nil}; + TestStruct testCopy = testStruct; } /*import "std/os/env"; diff --git a/src/SourceFile.cpp b/src/SourceFile.cpp index 4c050ccec..2a4217b16 100644 --- a/src/SourceFile.cpp +++ b/src/SourceFile.cpp @@ -814,7 +814,7 @@ void SourceFile::visualizerOutput(std::string outputName, const std::string &out void SourceFile::printStatusMessage(const char *stage, const CompileStageIOType &in, const CompileStageIOType &out, uint64_t stageRuntime, unsigned short stageRuns) const { if (cliOptions.printDebugOutput) { - const char *const compilerStageIoTypeName[] = {"Code", "Tokens", "CST", "AST", "IR", "OBJECT_FILE"}; + const char *const compilerStageIoTypeName[6] = {"Code", "Tokens", "CST", "AST", "IR", "Obj"}; // Build output string std::stringstream outputStr; outputStr << "[" << stage << "] for " << fileName << ": "; diff --git a/src/irgenerator/IRGenerator.cpp b/src/irgenerator/IRGenerator.cpp index 8e522864e..353f01b86 100644 --- a/src/irgenerator/IRGenerator.cpp +++ b/src/irgenerator/IRGenerator.cpp @@ -243,11 +243,10 @@ llvm::Constant *IRGenerator::getDefaultValueForSymbolType(const QualType &symbol // Struct if (symbolType.is(TY_STRUCT)) { - // Retrieve struct type + // Retrieve field count Scope *structScope = symbolType.getBodyScope(); assert(structScope != nullptr); const size_t fieldCount = structScope->getFieldCount(); - auto structType = reinterpret_cast(symbolType.toLLVMType(sourceFile)); // Get default values for all fields of the struct std::vector fieldConstants; @@ -268,14 +267,14 @@ llvm::Constant *IRGenerator::getDefaultValueForSymbolType(const QualType &symbol fieldConstants.push_back(defaultFieldValue); } + + auto structType = reinterpret_cast(symbolType.toLLVMType(sourceFile)); return llvm::ConstantStruct::get(structType, fieldConstants); } // Interface if (symbolType.is(TY_INTERFACE)) { - // Retrieve struct type auto structType = reinterpret_cast(symbolType.toLLVMType(sourceFile)); - return llvm::ConstantStruct::get(structType, llvm::Constant::getNullValue(builder.getPtrTy())); } @@ -395,7 +394,7 @@ LLVMExprResult IRGenerator::doAssignment(llvm::Value *lhsAddress, SymbolTableEnt const QualType &rhsSType, bool isDecl) { // Deduce some information about the assignment const bool isRefAssign = lhsEntry != nullptr && lhsEntry->getQualType().isRef(); - const bool needsCopy = !isDecl && !isRefAssign && rhsSType.removeReferenceWrapper().is(TY_STRUCT) && !rhs.isTemporary(); + const bool needsCopy = !isRefAssign && rhsSType.removeReferenceWrapper().is(TY_STRUCT) && !rhs.isTemporary(); if (isRefAssign) { assert(lhsEntry != nullptr); diff --git a/test/test-files/irgenerator/structs/success-default-copy-ctor/ir-code.ll b/test/test-files/irgenerator/structs/success-default-copy-ctor/ir-code.ll index d18796869..576901198 100644 --- a/test/test-files/irgenerator/structs/success-default-copy-ctor/ir-code.ll +++ b/test/test-files/irgenerator/structs/success-default-copy-ctor/ir-code.ll @@ -31,21 +31,24 @@ define dso_local i32 @main() #1 { %2 = load i1, ptr %b_addr, align 1 %3 = zext i1 %2 to i32 %4 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.0, i32 %1, i32 %3) - %5 = load %struct.StructToCopy, ptr %stc, align 4 - store %struct.StructToCopy %5, ptr %stc2, align 4 + call void @llvm.memcpy.p0.p0.i64(ptr %stc2, ptr %stc, i64 8, i1 false) %a_addr1 = getelementptr inbounds %struct.StructToCopy, ptr %stc2, i64 0, i32 0 - %6 = load i32, ptr %a_addr1, align 4 + %5 = load i32, ptr %a_addr1, align 4 %b_addr2 = getelementptr inbounds %struct.StructToCopy, ptr %stc2, i64 0, i32 1 - %7 = load i1, ptr %b_addr2, align 1 - %8 = zext i1 %7 to i32 - %9 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.1, i32 %6, i32 %8) - %10 = load i32, ptr %result, align 4 - ret i32 %10 + %6 = load i1, ptr %b_addr2, align 1 + %7 = zext i1 %6 to i32 + %8 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.1, i32 %5, i32 %7) + %9 = load i32, ptr %result, align 4 + ret i32 %9 } ; Function Attrs: nofree nounwind declare noundef i32 @printf(ptr nocapture noundef readonly, ...) #2 +; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #3 + attributes #0 = { norecurse } attributes #1 = { noinline nounwind optnone uwtable } attributes #2 = { nofree nounwind } +attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } diff --git a/test/test-files/irgenerator/structs/success-external-nested-struct/ir-code.ll b/test/test-files/irgenerator/structs/success-external-nested-struct/ir-code.ll index b0c9e6fca..821eb78e2 100644 --- a/test/test-files/irgenerator/structs/success-external-nested-struct/ir-code.ll +++ b/test/test-files/irgenerator/structs/success-external-nested-struct/ir-code.ll @@ -16,22 +16,25 @@ define dso_local i32 @main() #0 { %1 = call %struct.Socket @_Z16openServerSockett(i16 8080) store %struct.Socket %1, ptr %s, align 8 %nested_addr = getelementptr inbounds %struct.Socket, ptr %s, i64 0, i32 2 - %2 = load %struct.NestedSocket, ptr %nested_addr, align 8 - store %struct.NestedSocket %2, ptr %n, align 8 + call void @llvm.memcpy.p0.p0.i64(ptr %n, ptr %nested_addr, i64 16, i1 false) %testString_addr = getelementptr inbounds %struct.NestedSocket, ptr %n, i64 0, i32 0 - %3 = load ptr, ptr %testString_addr, align 8 - %4 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.0, ptr %3) + %2 = load ptr, ptr %testString_addr, align 8 + %3 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.0, ptr %2) %sock_addr = getelementptr inbounds %struct.Socket, ptr %s, i64 0, i32 0 - %5 = load i32, ptr %sock_addr, align 4 - %6 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.1, i32 %5) - %7 = load i32, ptr %result, align 4 - ret i32 %7 + %4 = load i32, ptr %sock_addr, align 4 + %5 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.1, i32 %4) + %6 = load i32, ptr %result, align 4 + ret i32 %6 } declare %struct.Socket @_Z16openServerSockett(i16) +; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 + ; Function Attrs: nofree nounwind -declare noundef i32 @printf(ptr nocapture noundef readonly, ...) #1 +declare noundef i32 @printf(ptr nocapture noundef readonly, ...) #2 attributes #0 = { noinline nounwind optnone uwtable } -attributes #1 = { nofree nounwind } +attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +attributes #2 = { nofree nounwind } diff --git a/test/test-files/irgenerator/structs/success-struct/ir-code.ll b/test/test-files/irgenerator/structs/success-struct/ir-code.ll index 0a7ac3082..e68b63e3b 100644 --- a/test/test-files/irgenerator/structs/success-struct/ir-code.ll +++ b/test/test-files/irgenerator/structs/success-struct/ir-code.ll @@ -27,28 +27,31 @@ define dso_local i32 @main() #0 { store double 4.634000e+01, ptr %2, align 8 %3 = getelementptr inbounds %struct.TestStruct, ptr %instance, i32 0, i32 2 store ptr %nestedInstance, ptr %3, align 8 - %4 = load %struct.TestStruct, ptr %instance, align 8 - store %struct.TestStruct %4, ptr %instance1, align 8 + call void @llvm.memcpy.p0.p0.i64(ptr %instance1, ptr %instance, i64 24, i1 false) %nested_addr = getelementptr inbounds %struct.TestStruct, ptr %instance, i64 0, i32 2 - %5 = load ptr, ptr %nested_addr, align 8 - %nested2_addr = getelementptr inbounds %struct.Nested, ptr %5, i64 0, i32 1 - %6 = load ptr, ptr %nested2_addr, align 8 - %7 = load i1, ptr %6, align 1 - %8 = zext i1 %7 to i32 + %4 = load ptr, ptr %nested_addr, align 8 + %nested2_addr = getelementptr inbounds %struct.Nested, ptr %4, i64 0, i32 1 + %5 = load ptr, ptr %nested2_addr, align 8 + %6 = load i1, ptr %5, align 1 + %7 = zext i1 %6 to i32 %field2_addr = getelementptr inbounds %struct.TestStruct, ptr %instance1, i64 0, i32 1 - %9 = load double, ptr %field2_addr, align 8 - %10 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.0, i32 %8, double %9) + %8 = load double, ptr %field2_addr, align 8 + %9 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.0, i32 %7, double %8) %nested_addr1 = getelementptr inbounds %struct.TestStruct, ptr %instance1, i64 0, i32 2 - %11 = load ptr, ptr %nested_addr1, align 8 - %nested1_addr = getelementptr inbounds %struct.Nested, ptr %11, i64 0, i32 0 - %12 = load ptr, ptr %nested1_addr, align 8 - %13 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.1, ptr %12) - %14 = load i32, ptr %result, align 4 - ret i32 %14 + %10 = load ptr, ptr %nested_addr1, align 8 + %nested1_addr = getelementptr inbounds %struct.Nested, ptr %10, i64 0, i32 0 + %11 = load ptr, ptr %nested1_addr, align 8 + %12 = call i32 (ptr, ...) @printf(ptr noundef @printf.str.1, ptr %11) + %13 = load i32, ptr %result, align 4 + ret i32 %13 } +; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 + ; Function Attrs: nofree nounwind -declare noundef i32 @printf(ptr nocapture noundef readonly, ...) #1 +declare noundef i32 @printf(ptr nocapture noundef readonly, ...) #2 attributes #0 = { noinline nounwind optnone uwtable } -attributes #1 = { nofree nounwind } +attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +attributes #2 = { nofree nounwind }