@@ -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,21 +295,23 @@ 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
+ let mut offset = 0 ; //self.target_data.offset_of_element(&struct_type, element_index as u32).unwrap_or (0);
307
+ for ( element_index , ( member_name, dt, location) ) in index_types. into_iter ( ) . enumerate ( ) {
308
+ let di_type = self . get_or_create_debug_type ( dt, index, types_index ) ?;
298
309
299
310
//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 ( ) ;
311
+ let size = types_index
312
+ . find_associated_type ( dt. get_name ( ) )
313
+ . map ( |llvm_type| self . target_data . get_bit_size ( & llvm_type) )
314
+ . unwrap_or ( 0 ) ;
303
315
304
316
types. push (
305
317
self . debug_info
@@ -308,24 +320,25 @@ impl<'ink> DebugBuilder<'ink> {
308
320
member_name,
309
321
file,
310
322
location. get_line_plus_one ( ) as u32 ,
311
- size. bits ( ) . into ( ) ,
323
+ size,
312
324
0 , // no alignment for now
313
- running_offset . bits ( ) . into ( ) ,
325
+ offset ,
314
326
DIFlags :: PUBLIC ,
315
327
di_type. into ( ) ,
316
328
)
317
329
. as_type ( ) ,
318
330
) ;
319
- running_offset += size;
331
+ offset += size;
320
332
}
321
333
334
+ let size = self . target_data . get_bit_size ( & struct_type) ;
322
335
//Create a struct type
323
336
let struct_type = self . debug_info . create_struct_type (
324
337
file. as_debug_info_scope ( ) ,
325
338
name,
326
339
file,
327
340
location. get_line_plus_one ( ) as u32 ,
328
- running_offset . bits ( ) . into ( ) ,
341
+ size ,
329
342
0 , // no alignment for now
330
343
DIFlags :: PUBLIC ,
331
344
None ,
@@ -344,9 +357,9 @@ impl<'ink> DebugBuilder<'ink> {
344
357
name : & str ,
345
358
inner_type : & str ,
346
359
dimensions : & [ Dimension ] ,
347
- size : Bytes ,
348
- alignment : Bytes ,
360
+ size : u64 ,
349
361
index : & Index ,
362
+ types_index : & LlvmTypedIndex ,
350
363
) -> Result < ( ) , Diagnostic > {
351
364
//find the inner type debug info
352
365
let inner_type = index. get_type ( inner_type) ?;
@@ -357,11 +370,11 @@ impl<'ink> DebugBuilder<'ink> {
357
370
//Convert to normal range
358
371
. collect :: < Result < Vec < Range < i64 > > , _ > > ( )
359
372
. map_err ( |err| Diagnostic :: codegen_error ( err, SourceLocation :: undefined ( ) ) ) ?;
360
- let inner_type = self . get_or_create_debug_type ( inner_type, index) ?;
373
+ let inner_type = self . get_or_create_debug_type ( inner_type, index, types_index ) ?;
361
374
let array_type = self . debug_info . create_array_type (
362
375
inner_type. into ( ) ,
363
- size. bits ( ) . into ( ) ,
364
- alignment . bits ( ) ,
376
+ size,
377
+ 0 , //No set alignment
365
378
subscript. as_slice ( ) ,
366
379
) ;
367
380
self . register_concrete_type ( name, DebugType :: Composite ( array_type) ) ;
@@ -372,17 +385,17 @@ impl<'ink> DebugBuilder<'ink> {
372
385
& mut self ,
373
386
name : & str ,
374
387
inner_type : & str ,
375
- size : Bytes ,
376
- alignment : Bytes ,
388
+ size : u64 ,
377
389
index : & Index ,
390
+ types_index : & LlvmTypedIndex ,
378
391
) -> Result < ( ) , Diagnostic > {
379
392
let inner_type = index. get_type ( inner_type) ?;
380
- let inner_type = self . get_or_create_debug_type ( inner_type, index) ?;
393
+ let inner_type = self . get_or_create_debug_type ( inner_type, index, types_index ) ?;
381
394
let pointer_type = self . debug_info . create_pointer_type (
382
395
name,
383
396
inner_type. into ( ) ,
384
- size. bits ( ) . into ( ) ,
385
- alignment . bits ( ) ,
397
+ size,
398
+ 0 , //No set alignment
386
399
inkwell:: AddressSpace :: from ( ADDRESS_SPACE_GLOBAL ) ,
387
400
) ;
388
401
self . register_concrete_type ( name, DebugType :: Derived ( pointer_type) ) ;
@@ -393,14 +406,15 @@ impl<'ink> DebugBuilder<'ink> {
393
406
& mut self ,
394
407
dt : & DataType ,
395
408
index : & Index ,
409
+ types_index : & LlvmTypedIndex ,
396
410
) -> Result < DebugType < ' ink > , Diagnostic > {
397
411
//Try to find a type in the types
398
- let dt_name = dt. get_name ( ) . to_lowercase ( ) ;
412
+ let dt_name = dt. get_name ( ) ;
399
413
//Attempt to re-register the type, this will do nothing if the type exists.
400
414
//TODO: This will crash on recursive datatypes
401
- self . register_debug_type ( & dt_name, dt, index) ?;
415
+ self . register_debug_type ( dt_name, dt, index, types_index ) ?;
402
416
self . types
403
- . get ( & dt_name)
417
+ . get ( & dt_name. to_lowercase ( ) )
404
418
. ok_or_else ( || {
405
419
Diagnostic :: new ( format ! ( "Cannot find debug information for type {dt_name}" ) )
406
420
. with_error_code ( "E076" )
@@ -413,21 +427,21 @@ impl<'ink> DebugBuilder<'ink> {
413
427
name : & str ,
414
428
length : i64 ,
415
429
encoding : StringEncoding ,
416
- size : Bytes ,
417
- alignment : Bytes ,
430
+ size : u64 ,
418
431
index : & Index ,
432
+ types_index : & LlvmTypedIndex ,
419
433
) -> Result < ( ) , Diagnostic > {
420
434
// Register a utf8 or 16 basic type
421
435
let inner_type = match encoding {
422
436
StringEncoding :: Utf8 => index. get_effective_type_or_void_by_name ( CHAR_TYPE ) ,
423
437
StringEncoding :: Utf16 => index. get_effective_type_or_void_by_name ( WCHAR_TYPE ) ,
424
438
} ;
425
- let inner_type = self . get_or_create_debug_type ( inner_type, index) ?;
439
+ let inner_type = self . get_or_create_debug_type ( inner_type, index, types_index ) ?;
426
440
//Register an array
427
441
let array_type = self . debug_info . create_array_type (
428
442
inner_type. into ( ) ,
429
- size. bits ( ) . into ( ) ,
430
- alignment . bits ( ) ,
443
+ size,
444
+ 0 , //No set alignment
431
445
#[ allow( clippy:: single_range_in_vec_init) ]
432
446
& [ ( 0 ..length) ] ,
433
447
) ;
@@ -439,11 +453,12 @@ impl<'ink> DebugBuilder<'ink> {
439
453
& mut self ,
440
454
name : & str ,
441
455
referenced_type : & str ,
442
- index : & Index ,
443
456
location : & SourceLocation ,
457
+ index : & Index ,
458
+ types_index : & LlvmTypedIndex ,
444
459
) -> Result < ( ) , Diagnostic > {
445
460
let inner_dt = index. get_effective_type_by_name ( referenced_type) ?;
446
- let inner_type = self . get_or_create_debug_type ( inner_dt, index) ?;
461
+ let inner_type = self . get_or_create_debug_type ( inner_dt, index, types_index ) ?;
447
462
let file = location
448
463
. get_file_name ( )
449
464
. map ( |it| self . get_or_create_debug_file ( it) )
@@ -627,21 +642,26 @@ impl<'ink> Debug<'ink> for DebugBuilder<'ink> {
627
642
name : & str ,
628
643
datatype : & ' idx DataType ,
629
644
index : & ' idx Index ,
645
+ types_index : & LlvmTypedIndex ,
630
646
) -> Result < ( ) , Diagnostic > {
631
647
//check if the type is currently registered
632
648
if !self . types . contains_key ( & name. to_lowercase ( ) ) {
633
649
let type_info = datatype. get_type_information ( ) ;
634
- let size = type_info. get_size ( index) . unwrap ( ) ;
650
+ let size = types_index
651
+ . find_associated_type ( name)
652
+ . map ( |llvm_type| self . target_data . get_bit_size ( & llvm_type) )
653
+ . unwrap_or ( 0 ) ;
635
654
let location = & datatype. location ;
636
655
match type_info {
637
656
DataTypeInformation :: Struct { members, .. } => {
638
- self . create_struct_type ( name, members. as_slice ( ) , index, location)
657
+ //TODO: we can only register this after expansion
658
+ self . create_struct_type ( name, members. as_slice ( ) , location, index, types_index)
639
659
}
640
660
DataTypeInformation :: Array { name, inner_type_name, dimensions, .. } => {
641
- self . create_array_type ( name, inner_type_name, dimensions, size, Bytes :: new ( 0 ) , index )
661
+ self . create_array_type ( name, inner_type_name, dimensions, size, index , types_index )
642
662
}
643
663
DataTypeInformation :: Pointer { name, inner_type_name, .. } => {
644
- self . create_pointer_type ( name, inner_type_name, size, Bytes :: new ( 0 ) , index )
664
+ self . create_pointer_type ( name, inner_type_name, size, index , types_index )
645
665
}
646
666
DataTypeInformation :: Integer { signed, size, .. } => {
647
667
let encoding = if type_info. is_bool ( ) {
@@ -663,11 +683,11 @@ impl<'ink> Debug<'ink> for DebugBuilder<'ink> {
663
683
let length = string_size
664
684
. as_int_value ( index)
665
685
. map_err ( |err| Diagnostic :: codegen_error ( err, SourceLocation :: undefined ( ) ) ) ?;
666
- self . create_string_type ( name, length, * encoding, size, Bytes :: new ( 0 ) , index )
686
+ self . create_string_type ( name, length, * encoding, size, index , types_index )
667
687
}
668
688
DataTypeInformation :: Alias { name, referenced_type }
669
689
| DataTypeInformation :: Enum { name, referenced_type, .. } => {
670
- self . create_typedef_type ( name, referenced_type, index, location )
690
+ self . create_typedef_type ( name, referenced_type, location , index, types_index )
671
691
}
672
692
// Other types are just derived basic types
673
693
_ => Ok ( ( ) ) ,
@@ -897,10 +917,13 @@ impl<'ink> Debug<'ink> for DebugBuilderEnum<'ink> {
897
917
name : & str ,
898
918
datatype : & ' idx DataType ,
899
919
index : & ' idx Index ,
920
+ types_index : & ' idx LlvmTypedIndex ,
900
921
) -> Result < ( ) , Diagnostic > {
901
922
match self {
902
923
Self :: None => Ok ( ( ) ) ,
903
- 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
+ }
904
927
}
905
928
}
906
929
0 commit comments