diff --git a/compiler/plc_driver/src/cli.rs b/compiler/plc_driver/src/cli.rs index 06a8255ed10..10b9cb9140b 100644 --- a/compiler/plc_driver/src/cli.rs +++ b/compiler/plc_driver/src/cli.rs @@ -330,6 +330,14 @@ pub struct CompileParameters { )] pub gdwarf_varinfo_version: Option, + #[clap( + name = "gpubnames", + long, + help = "Enable .debug_names accelerator table emission (disabled by default for GDB compatibility)", + global = true + )] + pub gpubnames: bool, + #[clap( name = "threads", long, diff --git a/compiler/plc_driver/src/lib.rs b/compiler/plc_driver/src/lib.rs index 95d39dfc18d..fbd8cfde01c 100644 --- a/compiler/plc_driver/src/lib.rs +++ b/compiler/plc_driver/src/lib.rs @@ -57,6 +57,7 @@ pub struct CompileOptions { pub relocation_preference: RelocationPreference, pub error_format: ErrorFormat, pub debug_level: DebugLevel, + pub generate_pubnames: bool, pub single_module: bool, pub online_change: OnlineChange, pub constructors_only: bool, @@ -73,6 +74,7 @@ impl Default for CompileOptions { relocation_preference: RelocationPreference::Default, error_format: ErrorFormat::None, debug_level: DebugLevel::None, + generate_pubnames: false, single_module: false, online_change: OnlineChange::Disabled, constructors_only: false, diff --git a/compiler/plc_driver/src/pipelines.rs b/compiler/plc_driver/src/pipelines.rs index e8fa8da7a49..db42e2f2c50 100644 --- a/compiler/plc_driver/src/pipelines.rs +++ b/compiler/plc_driver/src/pipelines.rs @@ -203,6 +203,7 @@ impl BuildPipeline { relocation_preference, error_format: params.error_format, debug_level: params.debug_level(), + generate_pubnames: params.gpubnames, single_module: params.single_module, online_change: if params.online_change { OnlineChange::Enabled { @@ -916,6 +917,7 @@ impl AnnotatedProject { //FIXME don't clone here compile_options.online_change.clone(), target, + compile_options.generate_pubnames, ); //Create a types codegen, this contains all the type declarations //Associate the index type with LLVM types diff --git a/compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_in_different_locations_with_debug_info.snap b/compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_in_different_locations_with_debug_info.snap index 4d446d4e0bb..3b6c8441d61 100644 --- a/compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_in_different_locations_with_debug_info.snap +++ b/compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_in_different_locations_with_debug_info.snap @@ -33,7 +33,7 @@ declare void @mainProg(ptr) !4 = !{} !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} -!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false) +!7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None) !8 = !DIFile(filename: "app/file1.st", directory: "root") !9 = !{!0} !10 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !11, file: !11, line: 2, type: !12, scopeLine: 10, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4) @@ -71,7 +71,7 @@ entry: !4 = !{} !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} -!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false) +!7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None) !8 = !DIFile(filename: "lib/file2.st", directory: "root") !9 = !{!0} !10 = distinct !DISubprogram(name: "mainProg", linkageName: "mainProg", scope: !2, file: !2, line: 2, type: !11, scopeLine: 5, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4) diff --git a/compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_with_debug_info.snap b/compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_with_debug_info.snap index 90ff627c622..cf86bec989d 100644 --- a/compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_with_debug_info.snap +++ b/compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_with_debug_info.snap @@ -33,7 +33,7 @@ declare void @mainProg(ptr) !4 = !{} !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} -!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false) +!7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None) !8 = !DIFile(filename: "file1.st", directory: "root") !9 = !{!0} !10 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !11, file: !11, line: 2, type: !12, scopeLine: 10, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4) @@ -71,7 +71,7 @@ entry: !4 = !{} !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} -!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false) +!7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None) !8 = !DIFile(filename: "file2.st", directory: "root") !9 = !{!0} !10 = distinct !DISubprogram(name: "mainProg", linkageName: "mainProg", scope: !2, file: !2, line: 2, type: !11, scopeLine: 5, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4) diff --git a/compiler/plc_llvm/src/cpp/llvm_wrapper.cpp b/compiler/plc_llvm/src/cpp/llvm_wrapper.cpp index b29efa1d0af..f4abf477e18 100644 --- a/compiler/plc_llvm/src/cpp/llvm_wrapper.cpp +++ b/compiler/plc_llvm/src/cpp/llvm_wrapper.cpp @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include using namespace llvm; @@ -17,4 +20,62 @@ extern "C" { TargetOptions* options = &targetMachine->Options; options->UseInitArray = useInitArray ? 1 : 0; } + + // Create a DICompileUnit via the C++ DIBuilder API, which exposes the + // NameTableKind parameter that the LLVM C API does not. + // When enablePubnames is false, sets NameTableKind::None to suppress + // .debug_names emission (avoiding a GDB incompatibility with lld). + // + // The `lang` and `emissionKind` parameters use the LLVMDWARFSourceLanguage + // and LLVMDWARFEmissionKind C enum values (0-based sequential), which need + // to be mapped to their DWARF/C++ equivalents. + LLVMMetadataRef createCompileUnit( + LLVMDIBuilderRef builderRef, + LLVMMetadataRef fileRef, + unsigned lang, + const char *producer, size_t producerLen, + LLVMBool isOptimized, + unsigned runtimeVer, + unsigned emissionKind, + uint64_t dwoId, + LLVMBool splitDebugInlining, + LLVMBool debugInfoForProfiling, + LLVMBool enablePubnames, + const char *sysRoot, size_t sysRootLen, + const char *sdk, size_t sdkLen + ) { + auto *builder = unwrap(builderRef); + auto *file = cast(unwrap(fileRef)); + auto nameTableKind = enablePubnames + ? DICompileUnit::DebugNameTableKind::Default + : DICompileUnit::DebugNameTableKind::None; + + // The LLVM C API uses a 0-based sequential enum for source languages + // (LLVMDWARFSourceLanguageC89=0, C=1, ...) while the C++ API / DWARF + // spec uses the actual DWARF values (DW_LANG_C89=0x0001, C=0x0002, ...). + // Add 1 to convert from the C enum to the DWARF value. + unsigned dwarfLang = lang + 1; + + // Similarly, LLVMDWARFEmissionKind: None=0, Full=1, LineTablesOnly=2 + // maps to DICompileUnit::DebugEmissionKind where NoDebug=0, FullDebug=1, + // LineTablesOnly=2, DebugDirectivesOnly=3 — these happen to match directly. + + auto *cu = builder->createCompileUnit( + dwarfLang, file, + StringRef(producer, producerLen), + isOptimized, + /*Flags=*/"", + runtimeVer, + /*SplitName=*/"", + static_cast(emissionKind), + dwoId, + splitDebugInlining, + debugInfoForProfiling, + nameTableKind, + /*RangesBaseAddress=*/false, + StringRef(sysRoot, sysRootLen), + StringRef(sdk, sdkLen) + ); + return wrap(cu); + } } diff --git a/compiler/plc_llvm/src/lib.rs b/compiler/plc_llvm/src/lib.rs index 7677b2a55d7..d784a18fbc4 100644 --- a/compiler/plc_llvm/src/lib.rs +++ b/compiler/plc_llvm/src/lib.rs @@ -1,15 +1,50 @@ -//! This crate provides Rust bindings for LLVM Target Machine functionalities. +//! This crate provides Rust bindings for LLVM Target Machine functionalities +//! and extensions to inkwell's debug info API. +use std::ffi::c_void; +use std::marker::PhantomData; + +use inkwell::debug_info::{DICompileUnit, DIFile, DWARFEmissionKind, DWARFSourceLanguage, DebugInfoBuilder}; +use inkwell::llvm_sys::debuginfo::{LLVMDWARFEmissionKind, LLVMDWARFSourceLanguage}; use inkwell::llvm_sys::prelude::LLVMBool; +use inkwell::module::Module; use inkwell::targets::TargetMachine; +/// Opaque pointer matching LLVMDIBuilderRef (= *mut LLVMOpaqueDIBuilder). +/// We define our own alias to avoid depending on the private re-export path. +type LLVMDIBuilderRef = *mut c_void; + mod ffi { - use inkwell::llvm_sys::prelude::LLVMBool; + use std::ffi::c_void; + + use inkwell::llvm_sys::prelude::{LLVMBool, LLVMMetadataRef}; use inkwell::llvm_sys::target_machine::LLVMTargetMachineRef; + /// Opaque pointer matching LLVMDIBuilderRef. + type LLVMDIBuilderRef = *mut c_void; + #[link(name = "llvm_wrapper")] unsafe extern "C" { pub fn setUseInitArray(tm: LLVMTargetMachineRef, use_init_array: LLVMBool); + + pub fn createCompileUnit( + builder: LLVMDIBuilderRef, + file: LLVMMetadataRef, + lang: std::ffi::c_uint, + producer: *const std::ffi::c_char, + producer_len: usize, + is_optimized: LLVMBool, + runtime_ver: std::ffi::c_uint, + emission_kind: std::ffi::c_uint, + dwo_id: u64, + split_debug_inlining: LLVMBool, + debug_info_for_profiling: LLVMBool, + enable_pubnames: LLVMBool, + sys_root: *const std::ffi::c_char, + sys_root_len: usize, + sdk: *const std::ffi::c_char, + sdk_len: usize, + ) -> LLVMMetadataRef; } } @@ -31,3 +66,94 @@ impl TargetMachineExt for TargetMachine { } } } + +/// Creates a [`DebugInfoBuilder`] and [`DICompileUnit`] with control over `.debug_names` emission. +/// +/// This wraps LLVM's C++ `DIBuilder::createCompileUnit` which exposes the `NameTableKind` +/// parameter that the LLVM C API does not. When `generate_pubnames` is `false`, sets +/// `NameTableKind::None` to suppress `.debug_names` emission, avoiding a GDB incompatibility +/// when multiple compilation units are linked with `lld`. +#[allow(clippy::too_many_arguments)] +pub fn create_debug_info<'ctx>( + module: &Module<'ctx>, + allow_unresolved: bool, + language: DWARFSourceLanguage, + filename: &str, + directory: &str, + producer: &str, + is_optimized: bool, + runtime_ver: std::ffi::c_uint, + emission_kind: DWARFEmissionKind, + generate_pubnames: bool, +) -> (DebugInfoBuilder<'ctx>, DICompileUnit<'ctx>) { + use inkwell::llvm_sys::debuginfo::{ + LLVMCreateDIBuilder, LLVMCreateDIBuilderDisallowUnresolved, LLVMDIBuilderCreateFile, + }; + + unsafe { + let raw_module = module.as_mut_ptr(); + let builder_ref: LLVMDIBuilderRef = if allow_unresolved { + LLVMCreateDIBuilder(raw_module).cast() + } else { + LLVMCreateDIBuilderDisallowUnresolved(raw_module).cast() + }; + + let file_ref = LLVMDIBuilderCreateFile( + builder_ref.cast(), + filename.as_ptr().cast(), + filename.len(), + directory.as_ptr().cast(), + directory.len(), + ); + + let cu_ref = ffi::createCompileUnit( + builder_ref, + file_ref, + { + let lang: LLVMDWARFSourceLanguage = language.into(); + lang as std::ffi::c_uint + }, + producer.as_ptr().cast(), + producer.len(), + is_optimized as LLVMBool, + runtime_ver, + { + let kind: LLVMDWARFEmissionKind = emission_kind.into(); + kind as std::ffi::c_uint + }, + 0, // dwo_id + 0, // split_debug_inlining = false + 0, // debug_info_for_profiling = false + generate_pubnames as LLVMBool, + c"".as_ptr(), + 0, + c"".as_ptr(), + 0, + ); + + // Construct inkwell wrapper types from raw LLVM pointers. + // These types are thin wrappers with predictable layout: + // DebugInfoBuilder { builder: LLVMDIBuilderRef, _marker: PhantomData } + // DIFile { metadata_ref: LLVMMetadataRef, _marker: PhantomData } + // DICompileUnit { file: DIFile, metadata_ref: LLVMMetadataRef, _marker: PhantomData } + let debug_info: DebugInfoBuilder<'ctx> = std::mem::transmute(builder_ref); + let compile_unit: DICompileUnit<'ctx> = + std::mem::transmute((file_ref, cu_ref, PhantomData::<&'ctx ()>)); + + // Compile-time layout verification + const _: () = { + assert!(size_of::() == size_of::() + size_of::>()); + assert!( + size_of::() + == size_of::() + size_of::() + size_of::>() + ); + }; + + // Runtime verification in debug builds + debug_assert_eq!(debug_info.as_mut_ptr().cast::(), builder_ref); + debug_assert_eq!(compile_unit.as_mut_ptr(), cu_ref); + debug_assert_eq!(compile_unit.get_file().as_mut_ptr(), file_ref); + + (debug_info, compile_unit) + } +} diff --git a/src/codegen.rs b/src/codegen.rs index 0d705c124d5..4295661cedd 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -96,6 +96,7 @@ type MainEmptyFunction = unsafe extern "C" fn() -> U; impl<'ink> CodeGen<'ink> { /// constructs a new code-generator that generates CompilationUnits into a module with the given module_name + #[allow(clippy::too_many_arguments)] pub fn new( context: &'ink CodegenContext, root: Option<&Path>, @@ -104,6 +105,7 @@ impl<'ink> CodeGen<'ink> { debug_level: DebugLevel, online_change: OnlineChange, target: &Target, + generate_pubnames: bool, ) -> CodeGen<'ink> { let module_location = file_marker.get_name().unwrap_or_default(); let module = context.create_module(module_location); @@ -136,7 +138,14 @@ impl<'ink> CodeGen<'ink> { module.set_triple(&triple); let debug_level = if file_marker.is_internal() { DebugLevel::None } else { debug_level }; - let debug = debug::DebugBuilderEnum::new(context, &module, root, optimization_level, debug_level); + let debug = debug::DebugBuilderEnum::new( + context, + &module, + root, + optimization_level, + debug_level, + generate_pubnames, + ); CodeGen { module, debug, module_location: module_location.to_string(), online_change } } diff --git a/src/codegen/debug.rs b/src/codegen/debug.rs index d11ba86655c..c2e06ee238f 100644 --- a/src/codegen/debug.rs +++ b/src/codegen/debug.rs @@ -202,6 +202,7 @@ impl<'ink> DebugBuilderEnum<'ink> { root: Option<&Path>, optimization: OptimizationLevel, debug_level: DebugLevel, + generate_pubnames: bool, ) -> Self { match debug_level { DebugLevel::None => DebugBuilderEnum::None, @@ -229,22 +230,17 @@ impl<'ink> DebugBuilderEnum<'ink> { let path = Path::new(module.get_source_file_name().to_str().unwrap_or("")).to_path_buf(); let root = root.unwrap_or_else(|| Path::new("")); let filename = path.strip_prefix(root).unwrap_or(&path).to_str().unwrap_or_default(); - let (debug_info, compile_unit) = module.create_debug_info_builder( + let (debug_info, compile_unit) = plc_llvm::create_debug_info( + module, true, - inkwell::debug_info::DWARFSourceLanguage::C, //TODO: Own lang + inkwell::debug_info::DWARFSourceLanguage::Pascal83, filename, root.to_str().unwrap_or_default(), "RuSTy Structured text Compiler", optimization.is_optimized(), - "", 0, - "", debug_level.into(), - 0, - false, - false, - "", - "", + generate_pubnames, ); let data_layout = module.get_data_layout(); diff --git a/src/codegen/tests/debug_tests.rs b/src/codegen/tests/debug_tests.rs index f0e072e73bb..635bfaae582 100644 --- a/src/codegen/tests/debug_tests.rs +++ b/src/codegen/tests/debug_tests.rs @@ -114,7 +114,7 @@ fn test_global_var_enum_added_to_debug_info() { !8 = !DIEnumerator(name: "c", value: 2) !9 = !{i32 2, !"Dwarf Version", i32 5} !10 = !{i32 2, !"Debug Info Version", i32 3} - !11 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !12, globals: !21, splitDebugInlining: false) + !11 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !12, globals: !21, splitDebugInlining: false, nameTableKind: None) !12 = !{!3, !13, !15} !13 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "en1", scope: !2, file: !2, line: 2, baseType: !14, size: 32, align [filtered], elements: !5) !14 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic) @@ -225,7 +225,7 @@ fn test_global_var_enum_with_explicit_values_added_to_debug_info() { !25 = !DIEnumerator(name: "Execute", value: 16, isUnsigned: true) !26 = !{i32 2, !"Dwarf Version", i32 5} !27 = !{i32 2, !"Debug Info Version", i32 3} - !28 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !29, globals: !30, splitDebugInlining: false) + !28 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !29, globals: !30, splitDebugInlining: false, nameTableKind: None) !29 = !{!3, !11, !19} !30 = !{!0, !9, !17} "#) @@ -334,7 +334,7 @@ fn test_global_var_struct_with_enum_members_added_to_debug_info() { !25 = !DISubrange(count: 81, lowerBound: 0) !26 = !{i32 2, !"Dwarf Version", i32 5} !27 = !{i32 2, !"Debug Info Version", i32 3} - !28 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !29, globals: !30, splitDebugInlining: false) + !28 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !29, globals: !30, splitDebugInlining: false, nameTableKind: None) !29 = !{!8, !14} !30 = !{!0} "#) @@ -594,7 +594,7 @@ fn switch_case_debug_info() { !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !3, file: !3, line: 2, type: !5, scopeLine: 9, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !7) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -731,7 +731,7 @@ fn dbg_declare_has_valid_metadata_references_for_methods() { !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "fb", linkageName: "fb", scope: !3, file: !3, line: 2, type: !5, scopeLine: 5, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !13) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -843,7 +843,7 @@ fn action_with_var_temp() { !4 = !{} !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} - !7 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false) + !7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false, nameTableKind: None) !8 = !{!0} !9 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !2, file: !2, line: 2, type: !10, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4) !10 = !DISubroutineType(flags: DIFlagPublic, types: !11) @@ -1102,7 +1102,7 @@ END_FUNCTION !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !3, file: !3, line: 22, type: !5, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !7) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -1278,7 +1278,7 @@ fn constants_are_tagged_as_such() { !25 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !2, file: !2, line: 10, baseType: !3, size: 32, align [filtered], offset: 64, flags: DIFlagPublic) !26 = !{i32 2, !"Dwarf Version", i32 5} !27 = !{i32 2, !"Debug Info Version", i32 3} - !28 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !29, splitDebugInlining: false) + !28 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !29, splitDebugInlining: false, nameTableKind: None) !29 = !{!0, !5, !13, !19} !30 = distinct !DISubprogram(name: "prog", linkageName: "prog", scope: !2, file: !2, line: 8, type: !31, scopeLine: 12, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !28, retainedNodes: !33) !31 = !DISubroutineType(flags: DIFlagPublic, types: !32) @@ -1413,7 +1413,7 @@ fn test_debug_info_regular_pointer_types() { !30 = !DISubrange(count: 81, lowerBound: 0) !31 = !{i32 2, !"Dwarf Version", i32 5} !32 = !{i32 2, !"Debug Info Version", i32 3} - !33 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !34, splitDebugInlining: false) + !33 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !34, splitDebugInlining: false, nameTableKind: None) !34 = !{!0, !6, !13, !22} "#) } @@ -1544,7 +1544,7 @@ fn test_debug_info_auto_deref_parameters() { !33 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__test_with_ref_params_local_ref", baseType: !17, size: 64, align [filtered], dwarfAddressSpace: 1) !34 = !{i32 2, !"Dwarf Version", i32 5} !35 = !{i32 2, !"Debug Info Version", i32 3} - !36 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !37, splitDebugInlining: false) + !36 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !37, splitDebugInlining: false, nameTableKind: None) !37 = !{!0} !38 = distinct !DISubprogram(name: "test_with_ref_params", linkageName: "test_with_ref_params", scope: !2, file: !2, line: 2, type: !39, scopeLine: 14, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !36, retainedNodes: !41) !39 = !DISubroutineType(flags: DIFlagPublic, types: !40) @@ -1645,7 +1645,7 @@ fn test_debug_info_auto_deref_alias_pointers() { !18 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__global_alias_struct", baseType: !10, size: 64, align [filtered], dwarfAddressSpace: 1) !19 = !{i32 2, !"Dwarf Version", i32 5} !20 = !{i32 2, !"Debug Info Version", i32 3} - !21 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !22, splitDebugInlining: false) + !21 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !22, splitDebugInlining: false, nameTableKind: None) !22 = !{!0, !4, !8, !15} "#) } @@ -1793,7 +1793,7 @@ fn test_debug_info_mixed_pointer_types() { !33 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__mixed_ptr_local_ref", baseType: !30, size: 64, align [filtered], dwarfAddressSpace: 1) !34 = !{i32 2, !"Dwarf Version", i32 5} !35 = !{i32 2, !"Debug Info Version", i32 3} - !36 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !37, splitDebugInlining: false) + !36 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !37, splitDebugInlining: false, nameTableKind: None) !37 = !{!0, !6, !12} !38 = distinct !DISubprogram(name: "mixed_ptr", linkageName: "mixed_ptr", scope: !2, file: !2, line: 7, type: !39, scopeLine: 18, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !36, retainedNodes: !41) !39 = !DISubroutineType(flags: DIFlagPublic, types: !40) @@ -2010,7 +2010,7 @@ fn test_debug_info_auto_deref_reference_to_pointers() { !46 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__test_with_reference_params_local_reference", baseType: !17, size: 64, align [filtered], dwarfAddressSpace: 1) !47 = !{i32 2, !"Dwarf Version", i32 5} !48 = !{i32 2, !"Debug Info Version", i32 3} - !49 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !50, splitDebugInlining: false) + !49 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !50, splitDebugInlining: false, nameTableKind: None) !50 = !{!0, !6, !13, !22, !31} !51 = distinct !DISubprogram(name: "test_with_reference_params", linkageName: "test_with_reference_params", scope: !2, file: !2, line: 9, type: !52, scopeLine: 17, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !49, retainedNodes: !54) !52 = !DISubroutineType(flags: DIFlagPublic, types: !53) @@ -2074,7 +2074,7 @@ fn range_datatype_debug() { !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !3, file: !3, line: 6, type: !5, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !7) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -2157,7 +2157,7 @@ fn range_datatype_reference_expr_bounds_debug() { !4 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic) !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} - !7 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false) + !7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false, nameTableKind: None) !8 = !{!0} !9 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !2, file: !2, line: 10, type: !10, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !12) !10 = !DISubroutineType(flags: DIFlagPublic, types: !11) @@ -2252,7 +2252,7 @@ fn range_datatype_fqn_reference_bounds_debug() { !9 = !DIDerivedType(tag: DW_TAG_typedef, name: "__SUBRANGE_10_103__DINT", scope: !2, file: !2, line: 2, baseType: !7, align [filtered]) !10 = !{i32 2, !"Dwarf Version", i32 5} !11 = !{i32 2, !"Debug Info Version", i32 3} - !12 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !13, splitDebugInlining: false) + !12 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !13, splitDebugInlining: false, nameTableKind: None) !13 = !{!0} !14 = distinct !DISubprogram(name: "prog", linkageName: "prog", scope: !2, file: !2, line: 6, type: !15, scopeLine: 13, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !12, retainedNodes: !17) !15 = !DISubroutineType(flags: DIFlagPublic, types: !16) @@ -2359,7 +2359,7 @@ fn range_datatype_debug_alias_reused() { !11 = !DIDerivedType(tag: DW_TAG_member, name: "w", scope: !2, file: !2, line: 13, baseType: !9, size: 32, align [filtered], offset: 96, flags: DIFlagPublic) !12 = !{i32 2, !"Dwarf Version", i32 5} !13 = !{i32 2, !"Debug Info Version", i32 3} - !14 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !15, splitDebugInlining: false) + !14 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !15, splitDebugInlining: false, nameTableKind: None) !15 = !{!0} !16 = distinct !DISubprogram(name: "prog", linkageName: "prog", scope: !2, file: !2, line: 6, type: !17, scopeLine: 15, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !14, retainedNodes: !19) !17 = !DISubroutineType(flags: DIFlagPublic, types: !18) diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__aggregate_return_value_variable_in_function.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__aggregate_return_value_variable_in_function.snap index 7a5c35f82b3..40eb9b310cb 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__aggregate_return_value_variable_in_function.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__aggregate_return_value_variable_in_function.snap @@ -29,7 +29,7 @@ attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__array_size_correctly_set_in_dwarf_info.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__array_size_correctly_set_in_dwarf_info.snap index 87e37d577f5..321d5c1cff8 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__array_size_correctly_set_in_dwarf_info.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__array_size_correctly_set_in_dwarf_info.snap @@ -29,7 +29,7 @@ attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !5, file: !5, line: 2, type: !6, scopeLine: 6, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__assignment_statement_have_location.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__assignment_statement_have_location.snap index bbc5a9a541f..e3978232939 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__assignment_statement_have_location.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__assignment_statement_have_location.snap @@ -22,7 +22,7 @@ entry: !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__case_conditions_location_marked.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__case_conditions_location_marked.snap index 5195e265e48..081ffd38dab 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__case_conditions_location_marked.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__case_conditions_location_marked.snap @@ -41,7 +41,7 @@ continue: ; preds = %else, %case1, %case !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__exit_statement_have_location.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__exit_statement_have_location.snap index d63674be26b..d690aabf22a 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__exit_statement_have_location.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__exit_statement_have_location.snap @@ -40,7 +40,7 @@ buffer_block2: ; No predecessors! !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__external_impl_is_not_added_as_external_subroutine.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__external_impl_is_not_added_as_external_subroutine.snap index dd2c3baea5d..35ced484fdc 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__external_impl_is_not_added_as_external_subroutine.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__external_impl_is_not_added_as_external_subroutine.snap @@ -27,6 +27,6 @@ declare void @myFb(ptr) !4 = !{} !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} -!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false) +!7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None) !8 = !DIFile(filename: "", directory: "src") !9 = !{!0} diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__for_conditions_location_marked.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__for_conditions_location_marked.snap index 8370554065a..df30db27c35 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__for_conditions_location_marked.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__for_conditions_location_marked.snap @@ -83,7 +83,7 @@ continue8: ; preds = %buffer_block12, %el !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__function_calls_have_location.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__function_calls_have_location.snap index f6bb2924c47..16fce67c630 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__function_calls_have_location.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__function_calls_have_location.snap @@ -22,7 +22,7 @@ entry: !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__function_calls_in_expressions_have_location.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__function_calls_in_expressions_have_location.snap index 99af008522a..afb6b7d8fe5 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__function_calls_in_expressions_have_location.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__function_calls_in_expressions_have_location.snap @@ -23,7 +23,7 @@ entry: !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__if_conditions_location_marked.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__if_conditions_location_marked.snap index 8df976bbe53..2517faab96d 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__if_conditions_location_marked.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__if_conditions_location_marked.snap @@ -43,7 +43,7 @@ continue2: ; preds = %else1, %condition_b !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__implementation_added_as_subroutine.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__implementation_added_as_subroutine.snap index e80391e22a7..0d4b97acc3c 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__implementation_added_as_subroutine.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__implementation_added_as_subroutine.snap @@ -44,7 +44,7 @@ entry: !4 = !{} !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} -!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false) +!7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None) !8 = !DIFile(filename: "", directory: "src") !9 = !{!0} !10 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !2, file: !2, line: 2, type: !11, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4) diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__nested_function_calls_get_location.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__nested_function_calls_get_location.snap index b4a77479465..c4228c047ea 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__nested_function_calls_get_location.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__nested_function_calls_get_location.snap @@ -26,7 +26,7 @@ entry: !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 4, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !9) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__non_callable_expressions_have_no_location.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__non_callable_expressions_have_no_location.snap index 02fd44286df..af476c5c311 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__non_callable_expressions_have_no_location.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__non_callable_expressions_have_no_location.snap @@ -22,7 +22,7 @@ entry: !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__non_function_pous_have_struct_as_param.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__non_function_pous_have_struct_as_param.snap index d909685ebc8..70216799e28 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__non_function_pous_have_struct_as_param.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__non_function_pous_have_struct_as_param.snap @@ -46,7 +46,7 @@ entry: !6 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic) !7 = !{i32 2, !"Dwarf Version", i32 5} !8 = !{i32 2, !"Debug Info Version", i32 3} -!9 = distinct !DICompileUnit(language: DW_LANG_C, file: !10, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !11, splitDebugInlining: false) +!9 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !10, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !11, splitDebugInlining: false, nameTableKind: None) !10 = !DIFile(filename: "", directory: "src") !11 = !{!0} !12 = distinct !DISubprogram(name: "myProg", linkageName: "myProg", scope: !2, file: !2, line: 2, type: !13, scopeLine: 6, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !9, retainedNodes: !15) diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__repeat_conditions_location_marked.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__repeat_conditions_location_marked.snap index d5c5b8b9166..149bd13bad0 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__repeat_conditions_location_marked.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__repeat_conditions_location_marked.snap @@ -53,7 +53,7 @@ continue2: ; preds = %buffer_block, %cond !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__return_statement_have_location.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__return_statement_have_location.snap index 46cdf41f5c4..dbebc9a7b6b 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__return_statement_have_location.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__return_statement_have_location.snap @@ -25,7 +25,7 @@ buffer_block: ; No predecessors! !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__string_size_correctly_set_in_dwarf_info.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__string_size_correctly_set_in_dwarf_info.snap index e73141e62dd..fc5a5c94bd6 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__string_size_correctly_set_in_dwarf_info.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__string_size_correctly_set_in_dwarf_info.snap @@ -23,5 +23,5 @@ target triple = "[filtered]" !8 = !DISubrange(count: 65, lowerBound: 0) !9 = !{i32 2, !"Dwarf Version", i32 5} !10 = !{i32 2, !"Debug Info Version", i32 3} -!11 = distinct !DICompileUnit(language: DW_LANG_C, file: !4, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !12, splitDebugInlining: false) +!11 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !4, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !12, splitDebugInlining: false, nameTableKind: None) !12 = !{!0} diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__var_and_vartemp_variables_in_pous_added_as_local.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__var_and_vartemp_variables_in_pous_added_as_local.snap index b9474180b44..e4dd9619dd1 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__var_and_vartemp_variables_in_pous_added_as_local.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__var_and_vartemp_variables_in_pous_added_as_local.snap @@ -71,7 +71,7 @@ entry: !4 = !{} !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} -!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false) +!7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !8, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None) !8 = !DIFile(filename: "", directory: "src") !9 = !{!0} !10 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !2, file: !2, line: 2, type: !11, scopeLine: 4, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !4) diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__var_in_out_inout_in_function_added_as_params.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__var_in_out_inout_in_function_added_as_params.snap index 8c42519373c..e12bbfc1c94 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__var_in_out_inout_in_function_added_as_params.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__var_in_out_inout_in_function_added_as_params.snap @@ -29,7 +29,7 @@ entry: !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 6, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !11) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__while_conditions_location_marked.snap b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__while_conditions_location_marked.snap index ee41cc78630..a60f78c83b8 100644 --- a/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__while_conditions_location_marked.snap +++ b/src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__while_conditions_location_marked.snap @@ -43,7 +43,7 @@ continue1: ; preds = %buffer_block, %whil !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "src") !4 = distinct !DISubprogram(name: "myFunc", linkageName: "myFunc", scope: !5, file: !5, line: 2, type: !6, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DIFile(filename: "", directory: "") diff --git a/src/codegen/tests/directaccess_test.rs b/src/codegen/tests/directaccess_test.rs index 2425262d3b3..89bb859ab83 100644 --- a/src/codegen/tests/directaccess_test.rs +++ b/src/codegen/tests/directaccess_test.rs @@ -513,3 +513,67 @@ fn direct_acess_in_output_assignment_with_complexe_expression() { attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } "#); } + +#[test] +fn direct_access_in_output_assignment_of_function() { + let ir = codegen( + r" + FUNCTION FLIP + VAR_INPUT + in: BYTE; + END_VAR + VAR_OUTPUT + out : BYTE; + END_VAR + out := NOT(in); + END_FUNCTION + + FUNCTION main + VAR + wordVar : WORD; + END_VAR + + wordVar := 0; + FLIP(2#01010101, wordVar.%b0); + END_FUNCTION + ", + ); + + filtered_assert_snapshot!(ir, @r#" + ; ModuleID = '' + source_filename = "" + target datalayout = "[filtered]" + target triple = "[filtered]" + + define void @FLIP(i8 %0, ptr %1) { + entry: + %in = alloca i8, align [filtered] + store i8 %0, ptr %in, align [filtered] + %out = alloca ptr, align [filtered] + store ptr %1, ptr %out, align [filtered] + %deref = load ptr, ptr %out, align [filtered] + %2 = load i8, ptr %in, align [filtered] + %tmpVar = xor i8 %2, -1 + store i8 %tmpVar, ptr %deref, align [filtered] + ret void + } + + define void @main() { + entry: + %wordVar = alloca i16, align [filtered] + store i16 0, ptr %wordVar, align [filtered] + store i16 0, ptr %wordVar, align [filtered] + %__FLIP_out0 = alloca i8, align [filtered] + store i8 0, ptr %__FLIP_out0, align [filtered] + call void @FLIP(i8 85, ptr %__FLIP_out0) + %0 = load i16, ptr %wordVar, align [filtered] + %load___FLIP_out0 = load i8, ptr %__FLIP_out0, align [filtered] + %erase = and i16 %0, -256 + %1 = zext i8 %load___FLIP_out0 to i16 + %value = shl i16 %1, 0 + %or = or i16 %erase, %value + store i16 %or, ptr %wordVar, align [filtered] + ret void + } + "#); +} diff --git a/src/codegen/tests/oop_tests/debug_tests.rs b/src/codegen/tests/oop_tests/debug_tests.rs index eb3c2442871..923384fc064 100644 --- a/src/codegen/tests/oop_tests/debug_tests.rs +++ b/src/codegen/tests/oop_tests/debug_tests.rs @@ -152,7 +152,7 @@ fn members_from_base_class_are_available_in_subclasses() { !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !3, file: !3, line: 2, type: !5, scopeLine: 8, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !25) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -396,7 +396,7 @@ fn write_to_parent_variable_qualified_access() { !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "fb", linkageName: "fb", scope: !3, file: !3, line: 2, type: !5, scopeLine: 7, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !16) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -651,7 +651,7 @@ fn write_to_parent_variable_in_instance() { !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !3, file: !3, line: 2, type: !5, scopeLine: 9, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !19) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -987,7 +987,7 @@ fn array_in_parent_generated() { !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "grandparent", linkageName: "grandparent", scope: !3, file: !3, line: 2, type: !5, scopeLine: 7, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !19) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -1304,7 +1304,7 @@ fn complex_array_access_generated() { !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "grandparent", linkageName: "grandparent", scope: !3, file: !3, line: 2, type: !5, scopeLine: 7, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !19) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -1520,7 +1520,7 @@ fn function_block_method_debug_info() { !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !3, file: !3, line: 2, type: !5, scopeLine: 5, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !13) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) @@ -1927,7 +1927,7 @@ END_FUNCTION !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} - !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) + !2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: "", directory: "") !4 = distinct !DISubprogram(name: "parent", linkageName: "parent", scope: !3, file: !3, line: 2, type: !5, scopeLine: 6, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !15) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__dwarf_version_override.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__dwarf_version_override.snap index 0be6c582ac6..9024f8b1ad3 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__dwarf_version_override.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__dwarf_version_override.snap @@ -33,5 +33,5 @@ entry: !4 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic) !5 = !{i32 2, !"Dwarf Version", i32 4} !6 = !{i32 2, !"Debug Info Version", i32 3} -!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false) +!7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false, nameTableKind: None) !8 = !{!0} diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_alias_type.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_alias_type.snap index f594c0134e1..9d461ae312a 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_alias_type.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_alias_type.snap @@ -33,5 +33,5 @@ entry: !4 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic) !5 = !{i32 2, !"Dwarf Version", i32 5} !6 = !{i32 2, !"Debug Info Version", i32 3} -!7 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false) +!7 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !8, splitDebugInlining: false, nameTableKind: None) !8 = !{!0} diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_array_added_to_debug_info.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_array_added_to_debug_info.snap index bd144e1e9b9..bfefdc29141 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_array_added_to_debug_info.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_array_added_to_debug_info.snap @@ -70,5 +70,5 @@ entry: !16 = !{!11} !17 = !{i32 2, !"Dwarf Version", i32 5} !18 = !{i32 2, !"Debug Info Version", i32 3} -!19 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !20, splitDebugInlining: false) +!19 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !20, splitDebugInlining: false, nameTableKind: None) !20 = !{!0, !7, !12} diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_byteseq_added_to_debug_info.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_byteseq_added_to_debug_info.snap index 3966a5d615e..7272b0b1dd4 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_byteseq_added_to_debug_info.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_byteseq_added_to_debug_info.snap @@ -34,5 +34,5 @@ target triple = "[filtered]" !15 = !DIBasicType(name: "LWORD", size: 64, encoding: DW_ATE_unsigned, flags: DIFlagPublic) !16 = !{i32 2, !"Dwarf Version", i32 5} !17 = !{i32 2, !"Debug Info Version", i32 3} -!18 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !19, splitDebugInlining: false) +!18 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !19, splitDebugInlining: false, nameTableKind: None) !19 = !{!0, !4, !7, !10, !13} diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_float_added_to_debug_info.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_float_added_to_debug_info.snap index 5d0acb6e8ee..2db0b44b01c 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_float_added_to_debug_info.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_float_added_to_debug_info.snap @@ -22,5 +22,5 @@ target triple = "[filtered]" !6 = !DIBasicType(name: "LREAL", size: 64, encoding: DW_ATE_float, flags: DIFlagPublic) !7 = !{i32 2, !"Dwarf Version", i32 5} !8 = !{i32 2, !"Debug Info Version", i32 3} -!9 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !10, splitDebugInlining: false) +!9 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !10, splitDebugInlining: false, nameTableKind: None) !10 = !{!0, !4} diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_int_added_to_debug_info.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_int_added_to_debug_info.snap index 50eba4295ad..caf49c35c09 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_int_added_to_debug_info.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_int_added_to_debug_info.snap @@ -46,5 +46,5 @@ target triple = "[filtered]" !24 = !DIBasicType(name: "ULINT", size: 64, encoding: DW_ATE_unsigned, flags: DIFlagPublic) !25 = !{i32 2, !"Dwarf Version", i32 5} !26 = !{i32 2, !"Debug Info Version", i32 3} -!27 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !28, splitDebugInlining: false) +!27 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !28, splitDebugInlining: false, nameTableKind: None) !28 = !{!0, !4, !7, !10, !13, !16, !19, !22} diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_nested_struct_added_to_debug_info.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_nested_struct_added_to_debug_info.snap index 72da02559e4..09212977098 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_nested_struct_added_to_debug_info.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_nested_struct_added_to_debug_info.snap @@ -54,5 +54,5 @@ entry: !12 = !DIBasicType(name: "LREAL", size: 64, encoding: DW_ATE_float, flags: DIFlagPublic) !13 = !{i32 2, !"Dwarf Version", i32 5} !14 = !{i32 2, !"Debug Info Version", i32 3} -!15 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !16, splitDebugInlining: false) +!15 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !16, splitDebugInlining: false, nameTableKind: None) !16 = !{!0} diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_pointer_added_to_debug_info.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_pointer_added_to_debug_info.snap index bfc4880d1ba..2d224edce1e 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_pointer_added_to_debug_info.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_pointer_added_to_debug_info.snap @@ -57,5 +57,5 @@ entry: !12 = !DISubrange(count: 11, lowerBound: 0) !13 = !{i32 2, !"Dwarf Version", i32 5} !14 = !{i32 2, !"Debug Info Version", i32 3} -!15 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !16, splitDebugInlining: false) +!15 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !16, splitDebugInlining: false, nameTableKind: None) !16 = !{!0, !6} diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_string_added_to_debug_info.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_string_added_to_debug_info.snap index 58146cdd998..6da6309b12c 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_string_added_to_debug_info.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_string_added_to_debug_info.snap @@ -28,5 +28,5 @@ target triple = "[filtered]" !12 = !DIBasicType(name: "WCHAR", size: 16, encoding: DW_ATE_UTF, flags: DIFlagPublic) !13 = !{i32 2, !"Dwarf Version", i32 5} !14 = !{i32 2, !"Debug Info Version", i32 3} -!15 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !16, splitDebugInlining: false) +!15 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !16, splitDebugInlining: false, nameTableKind: None) !16 = !{!0, !8} diff --git a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_struct_added_to_debug_info.snap b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_struct_added_to_debug_info.snap index 6cb2693cce1..c33f76fe812 100644 --- a/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_struct_added_to_debug_info.snap +++ b/src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_struct_added_to_debug_info.snap @@ -65,5 +65,5 @@ entry: !15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !3, size: 5632, align [filtered], elements: !11) !16 = !{i32 2, !"Dwarf Version", i32 5} !17 = !{i32 2, !"Debug Info Version", i32 3} -!18 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !19, splitDebugInlining: false) +!18 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !19, splitDebugInlining: false, nameTableKind: None) !19 = !{!0, !13} diff --git a/src/index.rs b/src/index.rs index fabd80646f1..a1ef83f1ad0 100644 --- a/src/index.rs +++ b/src/index.rs @@ -235,6 +235,10 @@ impl VariableIndexEntry { self.get_variable_type() == VariableType::InOut } + pub fn is_output(&self) -> bool { + self.get_variable_type().is_output() + } + pub fn is_constant(&self) -> bool { self.is_constant } diff --git a/src/lowering/calls.rs b/src/lowering/calls.rs index 0268ea131a4..edc8822f272 100644 --- a/src/lowering/calls.rs +++ b/src/lowering/calls.rs @@ -64,6 +64,7 @@ use crate::{ index::Index, lowering::helper::create_member_reference_with_location, resolver::{AnnotationMap, StatementAnnotation}, + typesystem::{DataType, DataTypeInformation}, }; // Performs lowering for aggregate types defined in functions @@ -346,13 +347,17 @@ impl AstVisitorMut for AggregateTypeLowerer { std::mem::swap(node.get_stmt_mut(), reference.get_stmt_mut()); self.push_pre_statement(reference); } - // 1. Is this a function with any output assignments? - // 2. Do any of the output assignments have types that need casting? + // Is this a function with any output assignments? + // Do any of the output assignments have types that need casting? + // Do any of the output assignments have direct access? else if stmt .parameters .as_ref() .iter() - .any(|param| is_output_assignment_and_type_cast_needed(param, annotation.as_ref(), index)) + .enumerate() + .any(|(param_index, param)| + is_output_assignment_and_type_cast_needed(param, annotation.as_ref(), index, &qualified_name, param_index, function_entry.is_method()) + || is_output_assignment_and_has_direct_access(param, annotation.as_ref(), index, &qualified_name, param_index, function_entry.is_method())) // Stateful structs (such as function blocks) have their own output assignment mechanism in codegen, // and are not handled by this lowerer && (function_entry.is_function() || function_entry.is_method()) @@ -364,62 +369,17 @@ impl AstVisitorMut for AggregateTypeLowerer { let location = stmt.parameters.as_ref().map(|it| it.get_location()).unwrap_or_default(); let id = stmt.parameters.as_ref().map(|it| it.get_id()).unwrap_or(self.id_provider.next_id()); - stmt.parameters.as_ref().iter().for_each(|param| { - if let AstStatement::ExpressionList(list) = ¶m.stmt { - list.iter().for_each(|item| { - if !is_output_assignment_and_type_cast_needed(item, annotation.as_ref(), index) { - expressions.push(item.clone()); - } else if let AstStatement::OutputAssignment(output_assignment) = &item.stmt { - let left_type = annotation.get_type_or_void(&output_assignment.left, index); - - // 3. Generate a temporary variable of the type that the function is expecting and pass it by reference to the function - let name = format!( - "__{}_{}{}", - &qualified_name, - output_assignment.left.get_flat_reference_name().unwrap_or_default(), - self.counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed) - ); - - let alloca = AstNode { - stmt: AstStatement::AllocationStatement(Allocation { - name: name.clone(), - reference_type: left_type.get_name().to_string(), - }), - id: self.id_provider.next_id(), - location: item.location.clone(), - metadata: None, - }; - pre_statements.push(alloca); - - // 4. Replace variable in parameters with our new temporary variable that will be passed to the function - expressions.push(AstFactory::create_output_assignment( - *output_assignment.left.clone(), - create_member_reference_by_name( - &name, - item.location.clone(), - self.id_provider.next_id(), - self.id_provider.next_id(), - ), - self.id_provider.next_id(), - )); - - // 6. After the call is complete, assign the temporary variable that was passed to the function back to the original variable - post_statements.push(AstFactory::create_assignment( - *output_assignment.right.clone(), - create_member_reference_by_name( - &name, - item.location.clone(), - self.id_provider.next_id(), - self.id_provider.next_id(), - ), - self.id_provider.next_id(), - )); - } else { - expressions.push(item.clone()); - } - }); - } - }); + for (param_index, param) in stmt.parameters.as_ref().iter().enumerate() { + lower_output_assignments( + (&self.counter, self.id_provider.clone()), + param, + (&qualified_name, &return_name, function_entry.is_method()), + annotation.as_ref(), + index, + param_index, + (&mut pre_statements, &mut expressions, &mut post_statements), + ); + } stmt.parameters.replace(Box::new(AstFactory::create_expression_list(expressions, location, id))); @@ -474,41 +434,346 @@ fn is_output_assignment_and_type_cast_needed( node: &AstNode, annotations: &dyn AnnotationMap, index: &Index, + pou_name: &str, + param_index: usize, + is_method: bool, ) -> bool { match &node.stmt { - AstStatement::ExpressionList(nodes) => { - nodes.iter().any(|node| is_output_assignment_and_type_cast_needed(node, annotations, index)) - } + AstStatement::ExpressionList(nodes) => nodes.iter().enumerate().any(|(param_index, node)| { + is_output_assignment_and_type_cast_needed( + node, + annotations, + index, + pou_name, + param_index, + is_method, + ) + }), AstStatement::OutputAssignment(assignment) => { // For output assignment in a call these types need to be swapped // output => value_to_assign_to --> should be evaluated as value_to_assign_to := output let type_lhs = annotations.get_type_or_void(&assignment.right, index); let type_rhs = annotations.get_type_or_void(&assignment.left, index); - // If either type is void then this is an empty assignment and casting is not necessary - if type_lhs.is_void() || type_rhs.is_void() { + // Aggregate types are handled by codegen + if type_lhs.is_aggregate_type() || type_rhs.is_aggregate_type() { return false; } - let type_info_lhs = type_lhs.get_type_information(); - let type_info_rhs = type_rhs.get_type_information(); + type_cast_needed(type_lhs, type_rhs, index) + } + _ => { + // The first parameter of a method is always "this" + if is_method && param_index == 0 { + return false; + } + + let param_index = if is_method { (param_index as u32) - 1 } else { param_index as u32 }; + + // We don't want to accidentally assign a pointer back to a literal that is passed + if node.is_literal() { + return false; + } - let Ok(size_lhs) = type_info_lhs.get_size(index) else { + if !is_implicit_output_assignment(index, pou_name, param_index) { + return false; + } + + let Some(param_index_entry) = index.get_declared_parameter(pou_name, param_index) else { return false; }; - let Ok(size_rhs) = type_info_rhs.get_size(index) else { + + let Some(type_lhs_pointer) = index.find_effective_type_by_name(¶m_index_entry.data_type_name) + else { return false; }; - size_lhs != size_rhs - || (size_lhs == size_rhs - && ((type_info_lhs.is_signed_int() && type_info_rhs.is_unsigned_int()) - || (type_info_lhs.is_int() && type_info_rhs.is_float()))) + let type_lhs = match type_lhs_pointer.get_type_information() { + DataTypeInformation::Pointer { inner_type_name, .. } => { + let Some(type_lhs) = index.find_effective_type_by_name(inner_type_name) else { + return false; + }; + + type_lhs + } + _ => type_lhs_pointer, + }; + + let type_rhs = annotations.get_type_or_void(node, index); + + // Aggregate types are handled by codegen + if type_lhs.is_aggregate_type() || type_rhs.is_aggregate_type() { + return false; + } + + type_cast_needed(type_lhs, type_rhs, index) } - _ => false, } } +fn type_cast_needed(type_lhs: &DataType, type_rhs: &DataType, index: &Index) -> bool { + // If either type is void then this is an empty assignment and casting is not necessary + if type_lhs.is_void() || type_rhs.is_void() { + return false; + } + + let type_info_lhs = type_lhs.get_type_information(); + let type_info_rhs = type_rhs.get_type_information(); + + let Ok(size_lhs) = type_info_lhs.get_size(index) else { + return false; + }; + let Ok(size_rhs) = type_info_rhs.get_size(index) else { + return false; + }; + + size_lhs != size_rhs + || (size_lhs == size_rhs + && ((type_info_lhs.is_signed_int() && type_info_rhs.is_unsigned_int()) + || (type_info_lhs.is_int() && type_info_rhs.is_float()))) +} + +fn is_output_assignment_and_has_direct_access( + node: &AstNode, + annotations: &dyn AnnotationMap, + index: &Index, + pou_name: &str, + param_index: usize, + is_method: bool, +) -> bool { + match &node.stmt { + AstStatement::ExpressionList(nodes) => nodes.iter().enumerate().any(|(param_index, node)| { + is_output_assignment_and_has_direct_access( + node, + annotations, + index, + pou_name, + param_index, + is_method, + ) + }), + AstStatement::OutputAssignment(assignment) => { + let node_type = annotations.get_type_or_void(assignment.right.as_ref(), index); + + // Aggregate types are handled by codegen + if node_type.is_aggregate_type() { + return false; + } + + assignment.right.has_direct_access() + } + _ => { + // The first parameter of a method is always "this" + if is_method && param_index == 0 { + return false; + } + + let param_index = if is_method { (param_index as u32) - 1 } else { param_index as u32 }; + + // We don't want to accidentally assign a pointer back to a literal that is passed + if node.is_literal() { + return false; + } + + if !is_implicit_output_assignment(index, pou_name, param_index) { + return false; + } + + let node_type = annotations.get_type_or_void(node, index); + + // Aggregate types are handled by codegen + if node_type.is_aggregate_type() { + return false; + } + + node.has_direct_access() + } + } +} + +fn is_implicit_output_assignment(index: &Index, pou_name: &str, param_index: u32) -> bool { + let Some(param_index_entry) = index.get_declared_parameter(pou_name, param_index) else { + return false; + }; + + param_index_entry.is_output() +} + +fn lower_output_assignments( + (counter, id_provider): (&AtomicI32, IdProvider), + param: &AstNode, + (qualified_pou_name, pou_name, is_method): (&str, &str, bool), + annotations: &dyn AnnotationMap, + index: &Index, + param_index: usize, + (pre_statements, expressions, post_statements): (&mut Vec, &mut Vec, &mut Vec), +) { + let should_be_lowered = is_output_assignment_and_type_cast_needed( + param, + annotations, + index, + qualified_pou_name, + param_index, + is_method, + ) || is_output_assignment_and_has_direct_access( + param, + annotations, + index, + qualified_pou_name, + param_index, + is_method, + ); + + match ¶m.stmt { + AstStatement::ExpressionList(list) => { + list.iter().enumerate().for_each(|(item_index, item)| { + lower_output_assignments( + (counter, id_provider.clone()), + item, + (qualified_pou_name, pou_name, is_method), + annotations, + index, + item_index, + (pre_statements, expressions, post_statements), + ) + }); + } + AstStatement::OutputAssignment(output_assignment) => { + if !should_be_lowered { + expressions.push(param.clone()); + return; + } + + let Some(left_type) = annotations.get_type(&output_assignment.left, index) else { + // If this fails, simply return the expression + expressions.push(param.clone()); + return; + }; + + let Some(left_reference_name) = output_assignment.left.get_flat_reference_name() else { + // If this fails, simply return the expression + expressions.push(param.clone()); + return; + }; + + lower_output_assignment( + (counter, id_provider), + (left_type, left_reference_name, Some(&output_assignment.left)), + &output_assignment.right, + pou_name, + ¶m.location, + (pre_statements, expressions, post_statements), + ); + } + _ => { + if !should_be_lowered { + expressions.push(param.clone()); + return; + } + // The first parameter of a method is always "this", this is validated before hand + let param_index = if is_method { (param_index as u32) - 1 } else { param_index as u32 }; + + let Some(param_index_entry) = index.get_declared_parameter(qualified_pou_name, param_index) + else { + // If this fails, simply return the expression + expressions.push(param.clone()); + return; + }; + + let Some(left_pointer_type) = + index.find_effective_type_by_name(¶m_index_entry.data_type_name) + else { + // If this fails, simply return the expression + expressions.push(param.clone()); + return; + }; + + let left_type = match left_pointer_type.get_type_information() { + DataTypeInformation::Pointer { inner_type_name, .. } => { + let Some(left_type) = index.find_effective_type_by_name(inner_type_name) else { + // If this fails, simply return the expression + expressions.push(param.clone()); + return; + }; + + left_type + } + _ => left_pointer_type, + }; + + lower_output_assignment( + (counter, id_provider), + (left_type, param_index_entry.get_name(), None), + param, + pou_name, + ¶m.location, + (pre_statements, expressions, post_statements), + ); + } + } +} + +fn lower_output_assignment( + (counter, mut id_provider): (&AtomicI32, IdProvider), + (left_type, left_reference_name, left_assignment): (&DataType, &str, Option<&AstNode>), + right_assignment: &AstNode, + pou_name: &str, + location: &SourceLocation, + (pre_statements, expressions, post_statements): (&mut Vec, &mut Vec, &mut Vec), +) { + // Generate a temporary variable of the type that the function is expecting and pass it by reference to the function + let name = format!( + "__{}_{}{}", + pou_name, + left_reference_name, + counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed) + ); + + let alloca = AstNode { + stmt: AstStatement::AllocationStatement(Allocation { + name: name.clone(), + reference_type: left_type.get_name().to_string(), + }), + id: id_provider.next_id(), + location: location.clone(), + metadata: None, + }; + pre_statements.push(alloca); + + // Replace variable in parameters with our new temporary variable that will be passed to the function + if let Some(left_assignment) = left_assignment { + expressions.push(AstFactory::create_output_assignment( + left_assignment.clone(), + create_member_reference_by_name( + &name, + location.clone(), + id_provider.next_id(), + id_provider.next_id(), + ), + id_provider.next_id(), + )); + } else { + expressions.push(create_member_reference_by_name( + &name, + location.clone(), + id_provider.next_id(), + id_provider.next_id(), + )); + } + + // After the call is complete, assign the temporary variable that was passed to the function back to the original variable + post_statements.push(AstFactory::create_assignment( + right_assignment.clone(), + create_member_reference_by_name( + &name, + location.clone(), + id_provider.next_id(), + id_provider.next_id(), + ), + id_provider.next_id(), + )); +} + #[cfg(test)] mod tests { use insta::{assert_debug_snapshot, assert_snapshot}; diff --git a/src/test_utils.rs b/src/test_utils.rs index 82d889dbb54..64a8bb30145 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -260,6 +260,7 @@ pub mod tests { debug_level, online_change.clone(), &Target::System, + false, ); let llvm_index = code_generator .generate_llvm_index(&context, &annotations, &literals, &dependencies, &index, &got_layout) @@ -328,6 +329,7 @@ pub mod tests { debug_level, crate::OnlineChange::Disabled, &Target::System, + false, ); let got_layout = Mutex::new(HashMap::default()); diff --git a/tests/integration/snapshots/tests__integration__cfc__ir__actions_debug.snap b/tests/integration/snapshots/tests__integration__cfc__ir__actions_debug.snap index 32ccdb2490a..f47459e2d3b 100644 --- a/tests/integration/snapshots/tests__integration__cfc__ir__actions_debug.snap +++ b/tests/integration/snapshots/tests__integration__cfc__ir__actions_debug.snap @@ -66,7 +66,7 @@ entry: !7 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !2, file: !2, line: 1, baseType: !6, size: 32, align [filtered], offset: 32, flags: DIFlagPublic) !8 = !{i32 2, !"Dwarf Version", i32 5} !9 = !{i32 2, !"Debug Info Version", i32 3} -!10 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !11, splitDebugInlining: false) +!10 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !11, splitDebugInlining: false, nameTableKind: None) !11 = !{!0} !12 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !2, file: !2, line: 1, type: !13, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !10, retainedNodes: !15) !13 = !DISubroutineType(flags: DIFlagPublic, types: !14) diff --git a/tests/integration/snapshots/tests__integration__cfc__ir__conditional_return_debug.snap b/tests/integration/snapshots/tests__integration__cfc__ir__conditional_return_debug.snap index 86a0375922f..6d72e3181ef 100644 --- a/tests/integration/snapshots/tests__integration__cfc__ir__conditional_return_debug.snap +++ b/tests/integration/snapshots/tests__integration__cfc__ir__conditional_return_debug.snap @@ -31,7 +31,7 @@ else_block: ; preds = %entry !0 = !{i32 2, !"Dwarf Version", i32 5} !1 = !{i32 2, !"Debug Info Version", i32 3} -!2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false) +!2 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !3, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) !3 = !DIFile(filename: ".cfc", directory: "") !4 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !3, file: !3, line: 1, type: !5, scopeLine: 4, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8) !5 = !DISubroutineType(flags: DIFlagPublic, types: !6) diff --git a/tests/integration/snapshots/tests__integration__cfc__ir__jump_debug.snap b/tests/integration/snapshots/tests__integration__cfc__ir__jump_debug.snap index 9f17505ee0c..c0e7983b137 100644 --- a/tests/integration/snapshots/tests__integration__cfc__ir__jump_debug.snap +++ b/tests/integration/snapshots/tests__integration__cfc__ir__jump_debug.snap @@ -53,7 +53,7 @@ entry: !6 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic) !7 = !{i32 2, !"Dwarf Version", i32 5} !8 = !{i32 2, !"Debug Info Version", i32 3} -!9 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !10, splitDebugInlining: false) +!9 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !10, splitDebugInlining: false, nameTableKind: None) !10 = !{!0} !11 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !2, file: !2, line: 1, type: !12, scopeLine: 3, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !9, retainedNodes: !14) !12 = !DISubroutineType(flags: DIFlagPublic, types: !13) diff --git a/tests/integration/snapshots/tests__integration__cfc__ir__sink_source_debug.snap b/tests/integration/snapshots/tests__integration__cfc__ir__sink_source_debug.snap index 0ac8c23d0cf..11bfe9c83cc 100644 --- a/tests/integration/snapshots/tests__integration__cfc__ir__sink_source_debug.snap +++ b/tests/integration/snapshots/tests__integration__cfc__ir__sink_source_debug.snap @@ -42,7 +42,7 @@ entry: !6 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic) !7 = !{i32 2, !"Dwarf Version", i32 5} !8 = !{i32 2, !"Debug Info Version", i32 3} -!9 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !10, splitDebugInlining: false) +!9 = distinct !DICompileUnit(language: DW_LANG_Pascal83, file: !2, producer: "RuSTy Structured text Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !10, splitDebugInlining: false, nameTableKind: None) !10 = !{!0} !11 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !2, file: !2, line: 1, type: !12, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition, unit: !9, retainedNodes: !14) !12 = !DISubroutineType(flags: DIFlagPublic, types: !13) diff --git a/tests/lit/single/functions/function_parameter_with_bit_access.st b/tests/lit/single/functions/function_parameter_with_bit_access.st new file mode 100644 index 00000000000..7114e8794e3 --- /dev/null +++ b/tests/lit/single/functions/function_parameter_with_bit_access.st @@ -0,0 +1,22 @@ +// RUN: (%COMPILE %s && %RUN) | %CHECK %s +FUNCTION FLIP + VAR_INPUT + in: BYTE; + END_VAR + VAR_OUTPUT + out : BYTE; + END_VAR + out := NOT(in); +END_FUNCTION + +FUNCTION main + VAR + wordVar : WORD; + END_VAR + + wordVar := 0; + FLIP(2#01010101, wordVar.%b0); + + // CHECK: wordVar=170 + PRINTF('wordVar=%d$N', wordVar); +END_FUNCTION diff --git a/tests/lit/single/functions/function_parameter_with_bit_access_named_params.st b/tests/lit/single/functions/function_parameter_with_bit_access_named_params.st new file mode 100644 index 00000000000..c7c1a94e9fd --- /dev/null +++ b/tests/lit/single/functions/function_parameter_with_bit_access_named_params.st @@ -0,0 +1,22 @@ +// RUN: (%COMPILE %s && %RUN) | %CHECK %s +FUNCTION FLIP + VAR_INPUT + in: BYTE; + END_VAR + VAR_OUTPUT + out : BYTE; + END_VAR + out := NOT(in); +END_FUNCTION + +FUNCTION main + VAR + wordVar : WORD; + END_VAR + + wordVar := 0; + FLIP(in := 2#01010101, out => wordVar.%b0); + + // CHECK: wordVar=170 + PRINTF('wordVar=%d$N', wordVar); +END_FUNCTION