Skip to content

Commit 41968d3

Browse files
authored
feat(init): struct support (#1281)
* add support for struct initializers * add initializer functions for each POU * fix global default initializers * improve struct lit test
1 parent 8c97777 commit 41968d3

File tree

454 files changed

+14346
-1948
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

454 files changed

+14346
-1948
lines changed

compiler/plc_ast/src/ast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,7 +1521,7 @@ impl AstFactory {
15211521
parameters: Some(Box::new(AstNode::new(
15221522
AstStatement::ExpressionList(parameters),
15231523
parameter_list_id,
1524-
SourceLocation::undefined(), //TODO: get real location
1524+
SourceLocation::internal(), //TODO: get real location
15251525
))),
15261526
}),
15271527
location: location.clone(),
@@ -1566,7 +1566,7 @@ impl AstFactory {
15661566
)),
15671567
parameters: Some(Box::new(AstFactory::create_expression_list(
15681568
parameters,
1569-
SourceLocation::undefined(),
1569+
SourceLocation::internal(),
15701570
id_provider.next_id(),
15711571
))),
15721572
}),

compiler/plc_ast/src/pre_processor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub fn pre_process(unit: &mut CompilationUnit, mut id_provider: IdProvider) {
6767
let type_name = internal_type_name("", name);
6868
let type_ref = DataTypeDeclaration::DataTypeReference {
6969
referenced_type: type_name.clone(),
70-
location: SourceLocation::undefined(), //return_type.get_location(),
70+
location: SourceLocation::internal(), //return_type.get_location(),
7171
};
7272
let datatype = std::mem::replace(referenced_type, Box::new(type_ref));
7373
if let DataTypeDeclaration::DataTypeDefinition { mut data_type, location, scope } =

compiler/plc_driver/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ fn generate(
363363
targets: Vec<Target>,
364364
annotated_project: AnnotatedProject<PathBuf>,
365365
) -> Result<(), Diagnostic> {
366-
let res = if compile_options.single_module {
366+
let res = if compile_options.single_module || matches!(linker_options.format, FormatOption::Object) {
367367
log::info!("Using single module mode");
368368
annotated_project.codegen_single_module(compile_options, &targets)?
369369
} else {

compiler/plc_driver/src/pipelines.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ impl<T: SourceContainer + Sync> ParsedProject<T> {
126126
// import builtin functions
127127
let builtins = plc::builtins::parse_built_ins(id_provider);
128128
global_index.import(plc::index::visitor::visit(&builtins));
129-
global_index.register_global_init_function();
130129

131130
IndexedProject { project: ParsedProject { project: self.project, units }, index: global_index }
132131
}
@@ -146,9 +145,10 @@ pub struct IndexedProject<T: SourceContainer + Sync> {
146145
impl<T: SourceContainer + Sync> IndexedProject<T> {
147146
/// Creates annotations on the project in order to facilitate codegen and validation
148147
pub fn annotate(self, mut id_provider: IdProvider) -> AnnotatedProject<T> {
148+
let init_name = self.get_project().get_init_symbol_name();
149149
//Resolve constants
150-
//TODO: Not sure what we are currently doing with unresolvables
151150
let (mut full_index, unresolvables) = plc::resolver::const_evaluator::evaluate_constants(self.index);
151+
full_index.register_global_init_function(&init_name);
152152

153153
//Create and call the annotator
154154
let mut annotated_units = Vec::new();
@@ -173,6 +173,7 @@ impl<T: SourceContainer + Sync> IndexedProject<T> {
173173
full_index.import(std::mem::take(&mut all_annotations.new_index));
174174

175175
TypeAnnotator::lower_init_functions(
176+
&init_name,
176177
unresolvables,
177178
&mut all_annotations,
178179
&mut full_index,
@@ -479,7 +480,7 @@ impl GeneratedProject {
479480
})??;
480481
codegen.persist_to_ir(output_location)
481482
}
482-
FormatOption::Object if self.objects.len() == 1 && objects.is_empty() => {
483+
FormatOption::Object if objects.is_empty() => {
483484
//Just copy over the object file, no need for a linker
484485
if let [obj] = &self.objects[..] {
485486
if obj.get_path() != output_location {

compiler/plc_driver/src/tests/multi_files.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn multiple_source_files_generated() {
3333
);
3434
//When the are generated
3535
let results = compile_with_root(vec![src1, src2], vec![], "root", DebugLevel::None).unwrap();
36-
assert_eq!(results.len(), 2);
36+
assert_eq!(results.len(), 4);
3737
//The datatypes do not conflics
3838
//The functions are defined correctly
3939
insta::assert_snapshot!(results.join("\n"));
@@ -72,7 +72,7 @@ fn multiple_files_with_debug_info() {
7272
let results =
7373
compile_with_root(vec![src1, src2], vec![], "root", DebugLevel::Full(plc::DEFAULT_DWARF_VERSION))
7474
.unwrap();
75-
assert_eq!(results.len(), 2);
75+
assert_eq!(results.len(), 4);
7676
//The datatypes do not conflics
7777
//The functions are defined correctly
7878
insta::assert_snapshot!(results.join("\n"));
@@ -111,7 +111,7 @@ fn multiple_files_in_different_locations_with_debug_info() {
111111
let results =
112112
compile_with_root(vec![src1, src2], vec![], "root", DebugLevel::Full(plc::DEFAULT_DWARF_VERSION))
113113
.unwrap();
114-
assert_eq!(results.len(), 2);
114+
assert_eq!(results.len(), 4);
115115
//The datatypes do not conflics
116116
//The functions are defined correctly
117117
insta::assert_snapshot!(results.join("\n"));

compiler/plc_driver/src/tests/snapshots/plc_driver__tests__external_files__external_file_function_call.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,11 @@ declare i16 @external() section "fn-$RUSTY$external:i16"
2020
source_filename = "external.st"
2121

2222
declare i16 @external() section "fn-$RUSTY$external:i16"
23+
24+
; ModuleID = '__init___TestProject'
25+
source_filename = "__init___TestProject"
26+
27+
define void @__init___TestProject() section "fn-$RUSTY$__init___TestProject:v" {
28+
entry:
29+
ret void
30+
}

compiler/plc_driver/src/tests/snapshots/plc_driver__tests__external_files__external_file_global_var.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,11 @@ source_filename = "external.st"
2828
@y = external global i16, section "var-$RUSTY$y:i16"
2929

3030
declare i16 @external() section "fn-$RUSTY$external:i16"
31+
32+
; ModuleID = '__init___TestProject'
33+
source_filename = "__init___TestProject"
34+
35+
define void @__init___TestProject() section "fn-$RUSTY$__init___TestProject:v" {
36+
entry:
37+
ret void
38+
}

compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_in_different_locations_with_debug_info.snap

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,89 @@ attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
8585
!12 = !{null}
8686
!13 = !DILocalVariable(name: "mainProg", scope: !10, file: !2, line: 2, type: !3)
8787
!14 = !DILocation(line: 5, column: 4, scope: !10)
88+
89+
; ModuleID = '__initializers'
90+
source_filename = "__initializers"
91+
92+
%mainProg = type {}
93+
94+
@mainProg_instance = external global %mainProg, section "var-$RUSTY$mainProg_instance:r0", !dbg !0
95+
96+
define void @__init_mainprog(%mainProg* %0) section "fn-$RUSTY$__init_mainprog:v[pr0]" !dbg !10 {
97+
entry:
98+
%self = alloca %mainProg*, align 8, !dbg !14
99+
call void @llvm.dbg.declare(metadata %mainProg** %self, metadata !15, metadata !DIExpression()), !dbg !14
100+
store %mainProg* %0, %mainProg** %self, align 8, !dbg !14
101+
ret void, !dbg !14
102+
}
103+
104+
declare !dbg !16 void @mainProg(%mainProg*) section "fn-$RUSTY$mainProg:v"
105+
106+
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
107+
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
108+
109+
attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
110+
111+
!llvm.module.flags = !{!5, !6}
112+
!llvm.dbg.cu = !{!7}
113+
114+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
115+
!1 = distinct !DIGlobalVariable(name: "mainProg", scope: !2, file: !2, line: 2, type: !3, isLocal: false, isDefinition: true)
116+
!2 = !DIFile(filename: "file2.st", directory: "lib")
117+
!3 = !DICompositeType(tag: DW_TAG_structure_type, name: "mainprog", scope: !2, file: !2, line: 2, align: 64, flags: DIFlagPublic, elements: !4, identifier: "mainprog")
118+
!4 = !{}
119+
!5 = !{i32 2, !"Dwarf Version", i32 5}
120+
!6 = !{i32 2, !"Debug Info Version", i32 3}
121+
!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false)
122+
!8 = !DIFile(filename: "__initializers", directory: "root")
123+
!9 = !{!0}
124+
!10 = distinct !DISubprogram(name: "__init_mainprog", linkageName: "__init_mainprog", scope: !2, file: !2, line: 2, type: !11, scopeLine: 2, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)
125+
!11 = !DISubroutineType(flags: DIFlagPublic, types: !12)
126+
!12 = !{null, !13}
127+
!13 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__auto_pointer_to_mainProg", baseType: !3, size: 64, align: 64, dwarfAddressSpace: 1)
128+
!14 = !DILocation(line: 2, column: 12, scope: !10)
129+
!15 = !DILocalVariable(name: "self", scope: !10, file: !2, line: 2, type: !13)
130+
!16 = distinct !DISubprogram(name: "mainProg", linkageName: "mainProg", scope: !2, file: !2, line: 2, type: !17, scopeLine: 5, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)
131+
!17 = !DISubroutineType(flags: DIFlagPublic, types: !18)
132+
!18 = !{null}
133+
134+
; ModuleID = '__init___TestProject'
135+
source_filename = "__init___TestProject"
136+
137+
%mainProg = type {}
138+
139+
@mainProg_instance = external global %mainProg, section "var-$RUSTY$mainProg_instance:r0", !dbg !0
140+
141+
define void @__init___TestProject() section "fn-$RUSTY$__init___TestProject:v" !dbg !10 {
142+
entry:
143+
call void @__init_mainprog(%mainProg* @mainProg_instance), !dbg !14
144+
ret void, !dbg !14
145+
}
146+
147+
declare !dbg !15 void @__init_mainprog(%mainProg*) section "fn-$RUSTY$__init_mainprog:v[pr0]"
148+
149+
declare !dbg !19 void @mainProg(%mainProg*) section "fn-$RUSTY$mainProg:v"
150+
151+
!llvm.module.flags = !{!5, !6}
152+
!llvm.dbg.cu = !{!7}
153+
154+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
155+
!1 = distinct !DIGlobalVariable(name: "mainProg", scope: !2, file: !2, line: 2, type: !3, isLocal: false, isDefinition: true)
156+
!2 = !DIFile(filename: "file2.st", directory: "lib")
157+
!3 = !DICompositeType(tag: DW_TAG_structure_type, name: "mainprog", scope: !2, file: !2, line: 2, align: 64, flags: DIFlagPublic, elements: !4, identifier: "mainprog")
158+
!4 = !{}
159+
!5 = !{i32 2, !"Dwarf Version", i32 5}
160+
!6 = !{i32 2, !"Debug Info Version", i32 3}
161+
!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false)
162+
!8 = !DIFile(filename: "__init___TestProject", directory: "root")
163+
!9 = !{!0}
164+
!10 = distinct !DISubprogram(name: "__init___TestProject", linkageName: "__init___TestProject", scope: !11, file: !11, type: !12, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)
165+
!11 = !DIFile(filename: "<internal>", directory: "")
166+
!12 = !DISubroutineType(flags: DIFlagPublic, types: !13)
167+
!13 = !{null}
168+
!14 = !DILocation(line: 0, scope: !10)
169+
!15 = distinct !DISubprogram(name: "__init_mainprog", linkageName: "__init_mainprog", scope: !2, file: !2, line: 2, type: !16, scopeLine: 2, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)
170+
!16 = !DISubroutineType(flags: DIFlagPublic, types: !17)
171+
!17 = !{null, !18}
172+
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__auto_pointer_to_mainProg", baseType: !3, size: 64, align: 64, dwarfAddressSpace: 1)
173+
!19 = distinct !DISubprogram(name: "mainProg", linkageName: "mainProg", scope: !2, file: !2, line: 2, type: !12, scopeLine: 5, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)

compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_with_debug_info.snap

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,89 @@ attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
8585
!12 = !{null}
8686
!13 = !DILocalVariable(name: "mainProg", scope: !10, file: !2, line: 2, type: !3)
8787
!14 = !DILocation(line: 5, column: 4, scope: !10)
88+
89+
; ModuleID = '__initializers'
90+
source_filename = "__initializers"
91+
92+
%mainProg = type {}
93+
94+
@mainProg_instance = external global %mainProg, section "var-$RUSTY$mainProg_instance:r0", !dbg !0
95+
96+
define void @__init_mainprog(%mainProg* %0) section "fn-$RUSTY$__init_mainprog:v[pr0]" !dbg !10 {
97+
entry:
98+
%self = alloca %mainProg*, align 8, !dbg !14
99+
call void @llvm.dbg.declare(metadata %mainProg** %self, metadata !15, metadata !DIExpression()), !dbg !14
100+
store %mainProg* %0, %mainProg** %self, align 8, !dbg !14
101+
ret void, !dbg !14
102+
}
103+
104+
declare !dbg !16 void @mainProg(%mainProg*) section "fn-$RUSTY$mainProg:v"
105+
106+
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
107+
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
108+
109+
attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
110+
111+
!llvm.module.flags = !{!5, !6}
112+
!llvm.dbg.cu = !{!7}
113+
114+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
115+
!1 = distinct !DIGlobalVariable(name: "mainProg", scope: !2, file: !2, line: 2, type: !3, isLocal: false, isDefinition: true)
116+
!2 = !DIFile(filename: "file2.st", directory: "")
117+
!3 = !DICompositeType(tag: DW_TAG_structure_type, name: "mainprog", scope: !2, file: !2, line: 2, align: 64, flags: DIFlagPublic, elements: !4, identifier: "mainprog")
118+
!4 = !{}
119+
!5 = !{i32 2, !"Dwarf Version", i32 5}
120+
!6 = !{i32 2, !"Debug Info Version", i32 3}
121+
!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false)
122+
!8 = !DIFile(filename: "__initializers", directory: "root")
123+
!9 = !{!0}
124+
!10 = distinct !DISubprogram(name: "__init_mainprog", linkageName: "__init_mainprog", scope: !2, file: !2, line: 2, type: !11, scopeLine: 2, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)
125+
!11 = !DISubroutineType(flags: DIFlagPublic, types: !12)
126+
!12 = !{null, !13}
127+
!13 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__auto_pointer_to_mainProg", baseType: !3, size: 64, align: 64, dwarfAddressSpace: 1)
128+
!14 = !DILocation(line: 2, column: 12, scope: !10)
129+
!15 = !DILocalVariable(name: "self", scope: !10, file: !2, line: 2, type: !13)
130+
!16 = distinct !DISubprogram(name: "mainProg", linkageName: "mainProg", scope: !2, file: !2, line: 2, type: !17, scopeLine: 5, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)
131+
!17 = !DISubroutineType(flags: DIFlagPublic, types: !18)
132+
!18 = !{null}
133+
134+
; ModuleID = '__init___TestProject'
135+
source_filename = "__init___TestProject"
136+
137+
%mainProg = type {}
138+
139+
@mainProg_instance = external global %mainProg, section "var-$RUSTY$mainProg_instance:r0", !dbg !0
140+
141+
define void @__init___TestProject() section "fn-$RUSTY$__init___TestProject:v" !dbg !10 {
142+
entry:
143+
call void @__init_mainprog(%mainProg* @mainProg_instance), !dbg !14
144+
ret void, !dbg !14
145+
}
146+
147+
declare !dbg !15 void @__init_mainprog(%mainProg*) section "fn-$RUSTY$__init_mainprog:v[pr0]"
148+
149+
declare !dbg !19 void @mainProg(%mainProg*) section "fn-$RUSTY$mainProg:v"
150+
151+
!llvm.module.flags = !{!5, !6}
152+
!llvm.dbg.cu = !{!7}
153+
154+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
155+
!1 = distinct !DIGlobalVariable(name: "mainProg", scope: !2, file: !2, line: 2, type: !3, isLocal: false, isDefinition: true)
156+
!2 = !DIFile(filename: "file2.st", directory: "")
157+
!3 = !DICompositeType(tag: DW_TAG_structure_type, name: "mainprog", scope: !2, file: !2, line: 2, align: 64, flags: DIFlagPublic, elements: !4, identifier: "mainprog")
158+
!4 = !{}
159+
!5 = !{i32 2, !"Dwarf Version", i32 5}
160+
!6 = !{i32 2, !"Debug Info Version", i32 3}
161+
!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false)
162+
!8 = !DIFile(filename: "__init___TestProject", directory: "root")
163+
!9 = !{!0}
164+
!10 = distinct !DISubprogram(name: "__init___TestProject", linkageName: "__init___TestProject", scope: !11, file: !11, type: !12, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)
165+
!11 = !DIFile(filename: "<internal>", directory: "")
166+
!12 = !DISubroutineType(flags: DIFlagPublic, types: !13)
167+
!13 = !{null}
168+
!14 = !DILocation(line: 0, scope: !10)
169+
!15 = distinct !DISubprogram(name: "__init_mainprog", linkageName: "__init_mainprog", scope: !2, file: !2, line: 2, type: !16, scopeLine: 2, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)
170+
!16 = !DISubroutineType(flags: DIFlagPublic, types: !17)
171+
!17 = !{null, !18}
172+
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__auto_pointer_to_mainProg", baseType: !3, size: 64, align: 64, dwarfAddressSpace: 1)
173+
!19 = distinct !DISubprogram(name: "mainProg", linkageName: "mainProg", scope: !2, file: !2, line: 2, type: !12, scopeLine: 5, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4)

compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_source_files_generated.snap

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,36 @@ define void @mainProg(%mainProg* %0) section "fn-$RUSTY$mainProg:v" {
3131
entry:
3232
ret void
3333
}
34+
35+
; ModuleID = '__initializers'
36+
source_filename = "__initializers"
37+
38+
%mainProg = type {}
39+
40+
@mainProg_instance = external global %mainProg, section "var-$RUSTY$mainProg_instance:r0"
41+
42+
define void @__init_mainprog(%mainProg* %0) section "fn-$RUSTY$__init_mainprog:v[pr0]" {
43+
entry:
44+
%self = alloca %mainProg*, align 8
45+
store %mainProg* %0, %mainProg** %self, align 8
46+
ret void
47+
}
48+
49+
declare void @mainProg(%mainProg*) section "fn-$RUSTY$mainProg:v"
50+
51+
; ModuleID = '__init___TestProject'
52+
source_filename = "__init___TestProject"
53+
54+
%mainProg = type {}
55+
56+
@mainProg_instance = external global %mainProg, section "var-$RUSTY$mainProg_instance:r0"
57+
58+
define void @__init___TestProject() section "fn-$RUSTY$__init___TestProject:v" {
59+
entry:
60+
call void @__init_mainprog(%mainProg* @mainProg_instance)
61+
ret void
62+
}
63+
64+
declare void @__init_mainprog(%mainProg*) section "fn-$RUSTY$__init_mainprog:v[pr0]"
65+
66+
declare void @mainProg(%mainProg*) section "fn-$RUSTY$mainProg:v"

0 commit comments

Comments
 (0)