15
15
-- of the license. --
16
16
-- ----------------------------------------------------------------------------
17
17
18
+ with Ada.Containers.Vectors ;
19
+
18
20
with Nlists ; use Nlists;
19
21
with Sinput ; use Sinput;
20
22
with Uintp.LLVM ; use Uintp.LLVM;
@@ -39,6 +41,15 @@ package body GNATLLVM.Records.Debug is
39
41
Equivalent_Keys => " =" );
40
42
-- A map from a discriminant's entity to the LLVM debuginfo.
41
43
44
+ package Member_Vectors is new
45
+ Ada.Containers.Vectors (Index_Type => Pos,
46
+ Element_Type => Metadata_T);
47
+ -- A vector of LLVM metadata, used when building the fields for a
48
+ -- type or a variant part.
49
+
50
+ subtype Member_Vector is Member_Vectors.Vector;
51
+ -- Type of vector of members.
52
+
42
53
function Convert_Choices (Choices : List_Id) return Word_Array;
43
54
-- Convert a list of choices (the discrete choices selecting a
44
55
-- variant part) to a word array. The resulting word array has an
@@ -47,15 +58,20 @@ package body GNATLLVM.Records.Debug is
47
58
-- or if the choice list is not recognized in some way.
48
59
49
60
function Convert_One_Field (M : in out Discriminant_Map.Map;
50
- F : Record_Field_Kind_Id) return Metadata_T;
61
+ F : Record_Field_Kind_Id;
62
+ Artificial : Boolean := False)
63
+ return Metadata_T;
51
64
-- Convert a single field to LLVM debug metadata. M is a map to
52
65
-- update; if the field is a discriminant, then it is recorded in
53
- -- the map for later lookup. Returns the LLVM debug metadata.
66
+ -- the map for later lookup. If Artificial is True, the created
67
+ -- field is marked artificial. Returns the LLVM debug metadata.
54
68
55
69
function Convert_Variant_Part (M : in out Discriminant_Map.Map;
56
70
RI : Record_Info;
57
71
Original_Type : Entity_Id;
58
- Is_Union : Boolean) return Metadata_Array
72
+ Is_Union : Boolean;
73
+ Toplevel_Members : in out Member_Vector)
74
+ return Metadata_Array
59
75
with pre => RI.Variants /= null ;
60
76
-- Convert a variant part to LLVM debug metadata, returning an
61
77
-- array holding the LLVM debug metadata for all the relevant
@@ -64,10 +80,24 @@ package body GNATLLVM.Records.Debug is
64
80
function Convert_RI_Chain (M : in out Discriminant_Map.Map;
65
81
Start : Record_Info_Id;
66
82
Original_Type : Entity_Id;
67
- Is_Union : Boolean) return Metadata_Array;
83
+ Is_Union : Boolean;
84
+ Toplevel_Members : in out Member_Vector;
85
+ Outermost_Call : Boolean)
86
+ return Metadata_Array;
68
87
-- Convert a chain of Record_Info_Ids to LLVM debug metadata,
69
88
-- returning an array holding the metadata for the relevant
70
- -- fields.
89
+ -- fields. Toplevel_Members points to the vector of members for
90
+ -- the outermost type being constructed; in some cases we may need
91
+ -- to add a field there when processing a variant part. This is
92
+ -- only null for the outermost call to Convert_RI_Chain.
93
+
94
+ function Convert_RI_Chain (M : in out Discriminant_Map.Map;
95
+ Start : Record_Info_Id;
96
+ Original_Type : Entity_Id;
97
+ Is_Union : Boolean)
98
+ return Metadata_Array;
99
+ -- A wrapper for Convert_RI_Chain that creates the outermost
100
+ -- member vector and passes it in.
71
101
72
102
-- -------------------
73
103
-- Convert_Choices --
@@ -112,7 +142,8 @@ package body GNATLLVM.Records.Debug is
112
142
-- ---------------------
113
143
114
144
function Convert_One_Field (M : in out Discriminant_Map.Map;
115
- F : Record_Field_Kind_Id) return Metadata_T
145
+ F : Record_Field_Kind_Id;
146
+ Artificial : Boolean := False) return Metadata_T
116
147
is
117
148
F_GT : constant GL_Type := Field_Type (F);
118
149
Mem_MD : constant Metadata_T :=
@@ -125,18 +156,20 @@ package body GNATLLVM.Records.Debug is
125
156
UI_To_ULL (Component_Bit_Offset (F));
126
157
Storage_Offset : constant ULL :=
127
158
(Offset / UBPU) * UBPU;
159
+ Flags : constant DI_Flags_T :=
160
+ (if Artificial then DI_Flag_Artificial else DI_Flag_Zero);
128
161
MD : constant Metadata_T :=
129
162
(if Is_Bitfield (F)
130
163
then DI_Create_Bit_Field_Member_Type
131
164
(No_Metadata_T, Name, File,
132
165
Get_Physical_Line_Number (F_S),
133
166
UI_To_ULL (Esize (F)), Offset,
134
- Storage_Offset, Mem_MD)
167
+ Storage_Offset, Mem_MD, Flags )
135
168
else DI_Create_Member_Type
136
169
(No_Metadata_T, Name, File,
137
170
Get_Physical_Line_Number (F_S),
138
171
UI_To_ULL (Esize (F)),
139
- Get_Type_Alignment (F_GT), Offset, Mem_MD));
172
+ Get_Type_Alignment (F_GT), Offset, Mem_MD, Flags ));
140
173
begin
141
174
-- Ensure the field is available so that a later lookup of a
142
175
-- discriminant will succeed.
@@ -152,10 +185,12 @@ package body GNATLLVM.Records.Debug is
152
185
-- Convert_Variant_Part --
153
186
-- ------------------------
154
187
155
- function Convert_Variant_Part (M : in out Discriminant_Map.Map;
156
- RI : Record_Info;
157
- Original_Type : Entity_Id;
158
- Is_Union : Boolean) return Metadata_Array
188
+ function Convert_Variant_Part
189
+ (M : in out Discriminant_Map.Map;
190
+ RI : Record_Info;
191
+ Original_Type : Entity_Id;
192
+ Is_Union : Boolean;
193
+ Toplevel_Members : in out Member_Vector) return Metadata_Array
159
194
is
160
195
package Member_Table is new Table.Table
161
196
(Table_Component_Type => Metadata_T,
@@ -173,7 +208,7 @@ package body GNATLLVM.Records.Debug is
173
208
Fields : constant Metadata_Array :=
174
209
(if Present (RI.Variants (J))
175
210
then Convert_RI_Chain (M, RI.Variants (J), Original_Type,
176
- Is_Union)
211
+ Is_Union, Toplevel_Members, False )
177
212
else Empty_Fields);
178
213
begin
179
214
if Is_Union then
@@ -213,16 +248,16 @@ package body GNATLLVM.Records.Debug is
213
248
function Convert_RI_Chain (M : in out Discriminant_Map.Map;
214
249
Start : Record_Info_Id;
215
250
Original_Type : Entity_Id;
216
- Is_Union : Boolean) return Metadata_Array
251
+ Is_Union : Boolean;
252
+ Toplevel_Members : in out Member_Vector;
253
+ Outermost_Call : Boolean)
254
+ return Metadata_Array
217
255
is
218
- package Member_Table is new Table.Table
219
- (Table_Component_Type => Metadata_T,
220
- Table_Index_Type => Int,
221
- Table_Low_Bound => 1 ,
222
- Table_Initial => 20 ,
223
- Table_Increment => 5 ,
224
- Table_Name => " Member_Table" );
225
-
256
+ Local_Members : aliased Member_Vector;
257
+ Members_To_Update : constant access Member_Vector :=
258
+ (if Outermost_Call
259
+ then Toplevel_Members'Access
260
+ else Local_Members'Access );
226
261
Ridx : Record_Info_Id := Start;
227
262
RI : Record_Info;
228
263
F : Record_Field_Kind_Id;
@@ -243,7 +278,7 @@ package body GNATLLVM.Records.Debug is
243
278
elsif Known_Static_Component_Bit_Offset (F) and then
244
279
Known_Static_Esize (F)
245
280
then
246
- Member_Table .Append (Convert_One_Field (M, F));
281
+ Members_To_Update .Append (Convert_One_Field (M, F));
247
282
end if ;
248
283
249
284
F_Idx := FI.Next;
@@ -259,41 +294,68 @@ package body GNATLLVM.Records.Debug is
259
294
RI.Variants /= null
260
295
then
261
296
declare
297
+ Variant_MD : Metadata_T;
262
298
MD : Metadata_T;
263
299
Parts : constant Metadata_Array :=
264
- Convert_Variant_Part (M, RI, Original_Type, Is_Union);
300
+ Convert_Variant_Part (M, RI, Original_Type, Is_Union,
301
+ Toplevel_Members);
265
302
Discrim : constant Entity_Id := Entity (RI.Variant_Expr);
266
303
begin
267
304
if Is_Union then
268
305
for I in Parts'Range loop
269
- Member_Table .Append (Parts (I));
306
+ Members_To_Update .Append (Parts (I));
270
307
end loop ;
271
308
else
272
309
if Ekind (Discrim) = E_Discriminant then
273
- pragma Assert
274
- (M.Contains (Original_Record_Component (Discrim)));
275
- MD := Create_Variant_Part
276
- (DI_Builder, M (Original_Record_Component (Discrim)),
277
- Parts);
278
- Member_Table.Append (MD);
310
+ -- If we already processed the discriminant, just
311
+ -- reuse its metadata here. However, if the
312
+ -- discriminant was inherited, there will not be
313
+ -- debuginfo for it. In this case, we emit an
314
+ -- artificial discriminant into this record, so
315
+ -- that the variant part can refer to it.
316
+ if M.Contains (Original_Record_Component (Discrim)) then
317
+ Variant_MD := M (Original_Record_Component (Discrim));
318
+ else
319
+ Variant_MD := Convert_One_Field
320
+ (M, Original_Record_Component (Discrim), True);
321
+ Toplevel_Members.Append (Variant_MD);
322
+ end if ;
323
+ MD := Create_Variant_Part (DI_Builder, Variant_MD, Parts);
324
+ Members_To_Update.Append (MD);
279
325
end if ;
280
326
end if ;
281
327
end ;
282
328
end if ;
283
329
284
330
declare
285
- Members : Metadata_Array (1 .. Member_Table.Last);
286
-
331
+ Members : Metadata_Array (Members_To_Update.First_Index
332
+ .. Members_To_Update.Last_Index);
287
333
begin
288
334
for J in Members'Range loop
289
- Members (J) := Member_Table.Table (J);
335
+ Members (J) := Members_To_Update (J);
290
336
end loop ;
291
337
292
338
return Members;
293
339
end ;
294
340
295
341
end Convert_RI_Chain ;
296
342
343
+ -- --------------------
344
+ -- Convert_RI_Chain --
345
+ -- --------------------
346
+
347
+ function Convert_RI_Chain (M : in out Discriminant_Map.Map;
348
+ Start : Record_Info_Id;
349
+ Original_Type : Entity_Id;
350
+ Is_Union : Boolean)
351
+ return Metadata_Array
352
+ is
353
+ Toplevel_Members : Member_Vector;
354
+ begin
355
+ return Convert_RI_Chain (M, Start, Original_Type, Is_Union,
356
+ Toplevel_Members, True);
357
+ end Convert_RI_Chain ;
358
+
297
359
-- ----------------------------
298
360
-- Create_Record_Debug_Info --
299
361
-- ----------------------------
0 commit comments