@@ -9,6 +9,7 @@ use inkwell::{
9
9
DWARFEmissionKind , DebugInfoBuilder ,
10
10
} ,
11
11
module:: Module ,
12
+ targets:: TargetData ,
12
13
values:: { BasicMetadataValueEnum , FunctionValue , GlobalValue , PointerValue } ,
13
14
} ;
14
15
use rustc_hash:: FxHashMap ;
@@ -18,13 +19,15 @@ use plc_diagnostics::diagnostics::Diagnostic;
18
19
use plc_source:: source_location:: SourceLocation ;
19
20
20
21
use crate :: {
21
- datalayout:: { Bytes , MemoryLocation } ,
22
22
index:: { Index , PouIndexEntry , VariableIndexEntry } ,
23
23
typesystem:: { DataType , DataTypeInformation , Dimension , StringEncoding , CHAR_TYPE , WCHAR_TYPE } ,
24
24
DebugLevel , OptimizationLevel ,
25
25
} ;
26
26
27
- use super :: generators:: { llvm:: Llvm , statement_generator:: FunctionContext , ADDRESS_SPACE_GLOBAL } ;
27
+ use super :: {
28
+ generators:: { llvm:: Llvm , statement_generator:: FunctionContext , ADDRESS_SPACE_GLOBAL } ,
29
+ llvm_index:: LlvmTypedIndex ,
30
+ } ;
28
31
29
32
#[ derive( PartialEq , Eq ) ]
30
33
#[ allow( non_camel_case_types) ]
@@ -83,6 +86,7 @@ pub trait Debug<'ink> {
83
86
name : & str ,
84
87
datatype : & ' idx DataType ,
85
88
index : & ' idx Index ,
89
+ types_index : & ' idx LlvmTypedIndex ,
86
90
) -> Result < ( ) , Diagnostic > ;
87
91
88
92
/// Creates a globally accessible variable with the given datatype.
@@ -167,6 +171,7 @@ pub struct DebugBuilder<'ink> {
167
171
variables : FxHashMap < VariableKey , DILocalVariable < ' ink > > ,
168
172
optimization : OptimizationLevel ,
169
173
files : FxHashMap < & ' static str , DIFile < ' ink > > ,
174
+ target_data : TargetData ,
170
175
}
171
176
172
177
/// A wrapper that redirects to correct debug builder implementation based on the debug context.
@@ -230,6 +235,9 @@ impl<'ink> DebugBuilderEnum<'ink> {
230
235
"" ,
231
236
) ;
232
237
238
+ let data_layout = module. get_data_layout ( ) ;
239
+ let data_layout = data_layout. as_str ( ) . to_str ( ) . expect ( "Data layout is valid" ) ;
240
+ let target_data = TargetData :: create ( data_layout) ;
233
241
let dbg_obj = DebugBuilder {
234
242
context,
235
243
debug_info,
@@ -238,6 +246,7 @@ impl<'ink> DebugBuilderEnum<'ink> {
238
246
variables : Default :: default ( ) ,
239
247
optimization,
240
248
files : Default :: default ( ) ,
249
+ target_data,
241
250
} ;
242
251
match debug_level {
243
252
DebugLevel :: VariablesOnly ( _) => DebugBuilderEnum :: VariablesOnly ( dbg_obj) ,
@@ -273,8 +282,9 @@ impl<'ink> DebugBuilder<'ink> {
273
282
& mut self ,
274
283
name : & str ,
275
284
members : & [ VariableIndexEntry ] ,
276
- index : & Index ,
277
285
location : & SourceLocation ,
286
+ index : & Index ,
287
+ types_index : & LlvmTypedIndex ,
278
288
) -> Result < ( ) , Diagnostic > {
279
289
//Create each type
280
290
let index_types = members
@@ -285,22 +295,25 @@ impl<'ink> DebugBuilder<'ink> {
285
295
index. get_type ( type_name. as_ref ( ) ) . map ( |dt| ( name, dt, location) )
286
296
} )
287
297
. collect :: < Result < Vec < _ > , Diagnostic > > ( ) ?;
298
+ let struct_type = types_index. get_associated_type ( name) . map ( |it| it. into_struct_type ( ) ) ?;
288
299
289
300
let file = location
290
301
. get_file_name ( )
291
302
. map ( |it| self . get_or_create_debug_file ( it) )
292
303
. unwrap_or_else ( || self . compile_unit . get_file ( ) ) ;
293
304
294
305
let mut types = vec ! [ ] ;
295
- let mut running_offset = MemoryLocation :: new ( 0 ) ;
296
- for ( member_name, dt, location) in index_types. into_iter ( ) {
297
- let di_type = self . get_or_create_debug_type ( dt, index) ?;
306
+ for ( element_index, ( member_name, dt, location) ) in index_types. into_iter ( ) . enumerate ( ) {
307
+ let di_type = self . get_or_create_debug_type ( dt, index, types_index) ?;
298
308
299
309
//Adjust the offset based on the field alignment
300
- let type_info = dt. get_type_information ( ) ;
301
- let alignment = type_info. get_alignment ( index) ;
302
- let size = type_info. get_size ( index) . unwrap ( ) ;
303
- running_offset = running_offset. align_to ( alignment) ;
310
+ let size = types_index
311
+ . find_associated_type ( dt. get_name ( ) )
312
+ . map ( |llvm_type| self . target_data . get_bit_size ( & llvm_type) )
313
+ . unwrap_or ( 0 ) ;
314
+ //Offset in bits
315
+ let offset =
316
+ self . target_data . offset_of_element ( & struct_type, element_index as u32 ) . unwrap_or ( 0 ) * 8 ;
304
317
305
318
types. push (
306
319
self . debug_info
@@ -309,27 +322,25 @@ impl<'ink> DebugBuilder<'ink> {
309
322
member_name,
310
323
file,
311
324
location. get_line_plus_one ( ) as u32 ,
312
- size. bits ( ) . into ( ) ,
313
- alignment . bits ( ) ,
314
- running_offset . bits ( ) . into ( ) ,
325
+ size,
326
+ 0 , // No set alignment
327
+ offset ,
315
328
DIFlags :: PUBLIC ,
316
329
di_type. into ( ) ,
317
330
)
318
331
. as_type ( ) ,
319
332
) ;
320
- running_offset += size;
321
333
}
322
334
323
- let struct_dt = index. get_type_information_or_void ( name) ;
324
-
335
+ let size = self . target_data . get_bit_size ( & struct_type) ;
325
336
//Create a struct type
326
337
let struct_type = self . debug_info . create_struct_type (
327
338
file. as_debug_info_scope ( ) ,
328
339
name,
329
340
file,
330
341
location. get_line_plus_one ( ) as u32 ,
331
- running_offset . bits ( ) . into ( ) ,
332
- struct_dt . get_alignment ( index ) . bits ( ) ,
342
+ size ,
343
+ 0 , // No set alignment
333
344
DIFlags :: PUBLIC ,
334
345
None ,
335
346
types. as_slice ( ) ,
@@ -347,9 +358,9 @@ impl<'ink> DebugBuilder<'ink> {
347
358
name : & str ,
348
359
inner_type : & str ,
349
360
dimensions : & [ Dimension ] ,
350
- size : Bytes ,
351
- alignment : Bytes ,
361
+ size : u64 ,
352
362
index : & Index ,
363
+ types_index : & LlvmTypedIndex ,
353
364
) -> Result < ( ) , Diagnostic > {
354
365
//find the inner type debug info
355
366
let inner_type = index. get_type ( inner_type) ?;
@@ -360,11 +371,11 @@ impl<'ink> DebugBuilder<'ink> {
360
371
//Convert to normal range
361
372
. collect :: < Result < Vec < Range < i64 > > , _ > > ( )
362
373
. map_err ( |err| Diagnostic :: codegen_error ( err, SourceLocation :: undefined ( ) ) ) ?;
363
- let inner_type = self . get_or_create_debug_type ( inner_type, index) ?;
374
+ let inner_type = self . get_or_create_debug_type ( inner_type, index, types_index ) ?;
364
375
let array_type = self . debug_info . create_array_type (
365
376
inner_type. into ( ) ,
366
- size. bits ( ) . into ( ) ,
367
- alignment . bits ( ) ,
377
+ size,
378
+ 0 , //No set alignment
368
379
subscript. as_slice ( ) ,
369
380
) ;
370
381
self . register_concrete_type ( name, DebugType :: Composite ( array_type) ) ;
@@ -375,17 +386,17 @@ impl<'ink> DebugBuilder<'ink> {
375
386
& mut self ,
376
387
name : & str ,
377
388
inner_type : & str ,
378
- size : Bytes ,
379
- alignment : Bytes ,
389
+ size : u64 ,
380
390
index : & Index ,
391
+ types_index : & LlvmTypedIndex ,
381
392
) -> Result < ( ) , Diagnostic > {
382
393
let inner_type = index. get_type ( inner_type) ?;
383
- let inner_type = self . get_or_create_debug_type ( inner_type, index) ?;
394
+ let inner_type = self . get_or_create_debug_type ( inner_type, index, types_index ) ?;
384
395
let pointer_type = self . debug_info . create_pointer_type (
385
396
name,
386
397
inner_type. into ( ) ,
387
- size. bits ( ) . into ( ) ,
388
- alignment . bits ( ) ,
398
+ size,
399
+ 0 , //No set alignment
389
400
inkwell:: AddressSpace :: from ( ADDRESS_SPACE_GLOBAL ) ,
390
401
) ;
391
402
self . register_concrete_type ( name, DebugType :: Derived ( pointer_type) ) ;
@@ -396,14 +407,15 @@ impl<'ink> DebugBuilder<'ink> {
396
407
& mut self ,
397
408
dt : & DataType ,
398
409
index : & Index ,
410
+ types_index : & LlvmTypedIndex ,
399
411
) -> Result < DebugType < ' ink > , Diagnostic > {
400
412
//Try to find a type in the types
401
- let dt_name = dt. get_name ( ) . to_lowercase ( ) ;
413
+ let dt_name = dt. get_name ( ) ;
402
414
//Attempt to re-register the type, this will do nothing if the type exists.
403
415
//TODO: This will crash on recursive datatypes
404
- self . register_debug_type ( & dt_name, dt, index) ?;
416
+ self . register_debug_type ( dt_name, dt, index, types_index ) ?;
405
417
self . types
406
- . get ( & dt_name)
418
+ . get ( & dt_name. to_lowercase ( ) )
407
419
. ok_or_else ( || {
408
420
Diagnostic :: new ( format ! ( "Cannot find debug information for type {dt_name}" ) )
409
421
. with_error_code ( "E076" )
@@ -416,21 +428,21 @@ impl<'ink> DebugBuilder<'ink> {
416
428
name : & str ,
417
429
length : i64 ,
418
430
encoding : StringEncoding ,
419
- size : Bytes ,
420
- alignment : Bytes ,
431
+ size : u64 ,
421
432
index : & Index ,
433
+ types_index : & LlvmTypedIndex ,
422
434
) -> Result < ( ) , Diagnostic > {
423
435
// Register a utf8 or 16 basic type
424
436
let inner_type = match encoding {
425
437
StringEncoding :: Utf8 => index. get_effective_type_or_void_by_name ( CHAR_TYPE ) ,
426
438
StringEncoding :: Utf16 => index. get_effective_type_or_void_by_name ( WCHAR_TYPE ) ,
427
439
} ;
428
- let inner_type = self . get_or_create_debug_type ( inner_type, index) ?;
440
+ let inner_type = self . get_or_create_debug_type ( inner_type, index, types_index ) ?;
429
441
//Register an array
430
442
let array_type = self . debug_info . create_array_type (
431
443
inner_type. into ( ) ,
432
- size. bits ( ) . into ( ) ,
433
- alignment . bits ( ) ,
444
+ size,
445
+ 0 , //No set alignment
434
446
#[ allow( clippy:: single_range_in_vec_init) ]
435
447
& [ ( 0 ..length) ] ,
436
448
) ;
@@ -442,11 +454,12 @@ impl<'ink> DebugBuilder<'ink> {
442
454
& mut self ,
443
455
name : & str ,
444
456
referenced_type : & str ,
445
- index : & Index ,
446
457
location : & SourceLocation ,
458
+ index : & Index ,
459
+ types_index : & LlvmTypedIndex ,
447
460
) -> Result < ( ) , Diagnostic > {
448
461
let inner_dt = index. get_effective_type_by_name ( referenced_type) ?;
449
- let inner_type = self . get_or_create_debug_type ( inner_dt, index) ?;
462
+ let inner_type = self . get_or_create_debug_type ( inner_dt, index, types_index ) ?;
450
463
let file = location
451
464
. get_file_name ( )
452
465
. map ( |it| self . get_or_create_debug_file ( it) )
@@ -458,7 +471,7 @@ impl<'ink> DebugBuilder<'ink> {
458
471
file,
459
472
location. get_line_plus_one ( ) as u32 ,
460
473
file. as_debug_info_scope ( ) ,
461
- inner_dt . get_type_information ( ) . get_alignment ( index ) . bits ( ) ,
474
+ 0 , //No set alignment
462
475
) ;
463
476
self . register_concrete_type ( name, DebugType :: Derived ( typedef) ) ;
464
477
@@ -542,11 +555,7 @@ impl<'ink> DebugBuilder<'ink> {
542
555
. iter ( )
543
556
. filter ( |it| it. is_local ( ) || it. is_temp ( ) || it. is_return ( ) )
544
557
{
545
- let var_type = index
546
- . find_effective_type_by_name ( variable. get_type_name ( ) )
547
- . expect ( "Type should exist at this stage" ) ;
548
- let alignment = var_type. get_type_information ( ) . get_alignment ( index) . bits ( ) ;
549
- self . register_local_variable ( variable, alignment, func) ;
558
+ self . register_local_variable ( variable, 0 , func) ;
550
559
}
551
560
552
561
let implementation = pou. find_implementation ( index) . expect ( "A POU will have an impl at this stage" ) ;
@@ -634,22 +643,25 @@ impl<'ink> Debug<'ink> for DebugBuilder<'ink> {
634
643
name : & str ,
635
644
datatype : & ' idx DataType ,
636
645
index : & ' idx Index ,
646
+ types_index : & LlvmTypedIndex ,
637
647
) -> Result < ( ) , Diagnostic > {
638
648
//check if the type is currently registered
639
649
if !self . types . contains_key ( & name. to_lowercase ( ) ) {
640
650
let type_info = datatype. get_type_information ( ) ;
641
- let size = type_info. get_size ( index) . unwrap ( ) ;
642
- let alignment = type_info. get_alignment ( index) ;
651
+ let size = types_index
652
+ . find_associated_type ( name)
653
+ . map ( |llvm_type| self . target_data . get_bit_size ( & llvm_type) )
654
+ . unwrap_or ( 0 ) ;
643
655
let location = & datatype. location ;
644
656
match type_info {
645
657
DataTypeInformation :: Struct { members, .. } => {
646
- self . create_struct_type ( name, members. as_slice ( ) , index, location )
658
+ self . create_struct_type ( name, members. as_slice ( ) , location , index, types_index )
647
659
}
648
660
DataTypeInformation :: Array { name, inner_type_name, dimensions, .. } => {
649
- self . create_array_type ( name, inner_type_name, dimensions, size, alignment , index )
661
+ self . create_array_type ( name, inner_type_name, dimensions, size, index , types_index )
650
662
}
651
663
DataTypeInformation :: Pointer { name, inner_type_name, .. } => {
652
- self . create_pointer_type ( name, inner_type_name, size, alignment , index )
664
+ self . create_pointer_type ( name, inner_type_name, size, index , types_index )
653
665
}
654
666
DataTypeInformation :: Integer { signed, size, .. } => {
655
667
let encoding = if type_info. is_bool ( ) {
@@ -671,11 +683,11 @@ impl<'ink> Debug<'ink> for DebugBuilder<'ink> {
671
683
let length = string_size
672
684
. as_int_value ( index)
673
685
. map_err ( |err| Diagnostic :: codegen_error ( err, SourceLocation :: undefined ( ) ) ) ?;
674
- self . create_string_type ( name, length, * encoding, size, alignment , index )
686
+ self . create_string_type ( name, length, * encoding, size, index , types_index )
675
687
}
676
688
DataTypeInformation :: Alias { name, referenced_type }
677
689
| DataTypeInformation :: Enum { name, referenced_type, .. } => {
678
- self . create_typedef_type ( name, referenced_type, index, location )
690
+ self . create_typedef_type ( name, referenced_type, location , index, types_index )
679
691
}
680
692
// Other types are just derived basic types
681
693
_ => Ok ( ( ) ) ,
@@ -905,10 +917,13 @@ impl<'ink> Debug<'ink> for DebugBuilderEnum<'ink> {
905
917
name : & str ,
906
918
datatype : & ' idx DataType ,
907
919
index : & ' idx Index ,
920
+ types_index : & ' idx LlvmTypedIndex ,
908
921
) -> Result < ( ) , Diagnostic > {
909
922
match self {
910
923
Self :: None => Ok ( ( ) ) ,
911
- Self :: VariablesOnly ( obj) | Self :: Full ( obj) => obj. register_debug_type ( name, datatype, index) ,
924
+ Self :: VariablesOnly ( obj) | Self :: Full ( obj) => {
925
+ obj. register_debug_type ( name, datatype, index, types_index)
926
+ }
912
927
}
913
928
}
914
929
0 commit comments