Skip to content

Commit f19ed86

Browse files
committed
Merge branch 'topic/recursive-types' into 'master'
Handle self-referential types See merge request eng/toolchain/gnat-llvm!364
2 parents 5761f41 + 4a857a3 commit f19ed86

File tree

6 files changed

+74
-13
lines changed

6 files changed

+74
-13
lines changed

llvm-interface/gnatllvm-debuginfo.adb

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,30 @@ package body GNATLLVM.DebugInfo is
11321132
then Implementation_Base_Type (TE)
11331133
else Get_Fullest_View (TE));
11341134

1135+
Empty_Fields : Metadata_Array (1 .. 0);
1136+
11351137
begin
1138+
-- A type might be self-referential. For example, a
1139+
-- record may have a member whose type refers back to the
1140+
-- same record type. To handle this case, we construct a
1141+
-- empty composite type and record it; then later we
1142+
-- update the members of the type.
1143+
if Is_Unchecked_Union (TE) then
1144+
Result := DI_Create_Union_Type
1145+
(Get_Scope_For (TE), Get_Possibly_Local_Name (TE),
1146+
Get_Debug_File_Node (Get_Source_File_Index (S)),
1147+
Get_Physical_Line_Number (S), Size, Align, DI_Flag_Zero,
1148+
Empty_Fields, 0, "");
1149+
else
1150+
Result := DI_Create_Struct_Type
1151+
(Get_Scope_For (TE), Get_Possibly_Local_Name (TE),
1152+
Get_Debug_File_Node (Get_Source_File_Index (S)),
1153+
Get_Physical_Line_Number (S), Size, Align, DI_Flag_Zero,
1154+
No_Metadata_T, Empty_Fields, 0, No_Metadata_T, "");
1155+
end if;
1156+
1157+
Set_Debug_Metadata (TE, Result);
1158+
11361159
F := First_Component_Or_Discriminant (TE);
11371160
while Present (F) loop
11381161
if Get_Fullest_View (Scope (Ancestor_Field (F)))
@@ -1186,20 +1209,14 @@ package body GNATLLVM.DebugInfo is
11861209
Members (J) := Member_Table.Table (J);
11871210
end loop;
11881211

1189-
if Is_Unchecked_Union (TE) then
1190-
Result := DI_Create_Union_Type
1191-
(Get_Scope_For (TE), Get_Possibly_Local_Name (TE),
1192-
Get_Debug_File_Node (Get_Source_File_Index (S)),
1193-
Get_Physical_Line_Number (S), Size, Align, DI_Flag_Zero,
1194-
Members, 0, "");
1195-
else
1196-
Result := DI_Create_Struct_Type
1197-
(Get_Scope_For (TE), Get_Possibly_Local_Name (TE),
1198-
Get_Debug_File_Node (Get_Source_File_Index (S)),
1199-
Get_Physical_Line_Number (S), Size, Align, DI_Flag_Zero,
1200-
No_Metadata_T, Members, 0, No_Metadata_T, "");
1201-
end if;
1212+
-- At least in theory it seems that LLVM may replace
1213+
-- the object entirely, so don't assume Result will be
1214+
-- the same, and be sure to clear it from the cache.
1215+
Result := Replace_Composite_Elements (DI_Builder, Result,
1216+
Members);
1217+
Clear_Debug_Metadata (TE);
12021218
end;
1219+
12031220
end Record_Type;
12041221

12051222
-- For an enumeration type, make an enumerator metadata for each

llvm-interface/gnatllvm-environment.adb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,11 @@ package body GNATLLVM.Environment is
546546
procedure Set_Debug_Metadata (TE : Entity_Id; DT : Metadata_T)
547547
renames Env_Debug.Set;
548548

549+
procedure Clear_Debug_Metadata (TE : Entity_Id) is
550+
begin
551+
Env_Debug.Set (TE, No_Metadata_T);
552+
end Clear_Debug_Metadata;
553+
549554
function Get_Array_Info (TE : Entity_Id) return Array_Info_Id
550555
renames Env_Array.Get;
551556
function Get_Array_Info_N (TE : Entity_Id) return Array_Info_Id

llvm-interface/gnatllvm-environment.ads

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ package GNATLLVM.Environment is
199199
or else Get_Debug_Metadata_N (TE) = DT),
200200
Post => Get_Debug_Metadata_N (TE) = DT, Inline;
201201

202+
procedure Clear_Debug_Metadata (TE : Entity_Id)
203+
with Post => No (Get_Debug_Metadata_N (TE)), Inline;
204+
202205
procedure Set_Array_Info (TE : Entity_Id; AI : Array_Info_Id)
203206
with Pre => Is_Array_Type (TE)
204207
and then (No (Get_Array_Info_N (TE))

llvm-interface/gnatllvm-wrapper.adb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,4 +966,22 @@ package body GNATLLVM.Wrapper is
966966
uint32_t (Align_In_Bits));
967967
end Create_Global_Variable_Declaration;
968968

969+
function Replace_Composite_Elements
970+
(Builder : DI_Builder_T;
971+
Composite : Metadata_T;
972+
Elements : Metadata_Array) return Metadata_T
973+
is
974+
function Replace_Composite_Elements_C
975+
(Builder : DI_Builder_T;
976+
Composite : Metadata_T;
977+
Elements : System.Address;
978+
Num_Elements : unsigned) return Metadata_T
979+
with Import => True, Convention => C,
980+
External_Name => "Replace_Composite_Elements";
981+
begin
982+
return Replace_Composite_Elements_C (Builder, Composite,
983+
Elements'Address,
984+
unsigned (Elements'Length));
985+
end Replace_Composite_Elements;
986+
969987
end GNATLLVM.Wrapper;

llvm-interface/gnatllvm-wrapper.ads

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,4 +578,11 @@ package GNATLLVM.Wrapper is
578578
Decl : Metadata_T;
579579
Align_In_Bits : Nat) return Metadata_T;
580580

581+
function Replace_Composite_Elements
582+
(Builder : DI_Builder_T;
583+
Composite : Metadata_T;
584+
Elements : Metadata_Array) return Metadata_T;
585+
-- Wrapper for DIBuilder::replaceArrays that only allows updating
586+
-- the elements of a composite type.
587+
581588
end GNATLLVM.Wrapper;

llvm-interface/llvm_wrapper.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,3 +1565,14 @@ LLVMMetadataRef Create_Global_Variable_Declaration(
15651565
false, unwrap<DIExpression>(Expr), MD,
15661566
nullptr, AlignInBits));
15671567
}
1568+
1569+
extern "C"
1570+
LLVMMetadataRef Replace_Composite_Elements(
1571+
LLVMDIBuilderRef Builder, LLVMMetadataRef Composite,
1572+
LLVMMetadataRef *Elements, unsigned NumElements) {
1573+
auto Elems = unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements});
1574+
DICompositeType *T = unwrap<DICompositeType>(Composite);
1575+
unwrap(Builder)->replaceArrays(T, Elems);
1576+
// T might have been modified by replaceArrays.
1577+
return wrap(T);
1578+
}

0 commit comments

Comments
 (0)