diff options
author | Tristan Gingold <tgingold@free.fr> | 2021-05-18 20:54:51 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2021-05-18 20:54:51 +0200 |
commit | 17e24689d3fd3a9e5d58c5c9cb9901e456f3e869 (patch) | |
tree | d683500a09f8dd25b653d241611978cec7c3c054 | |
parent | f07792aec9c4e943978f8212e2a0f6e870294dbf (diff) | |
download | ghdl-17e24689d3fd3a9e5d58c5c9cb9901e456f3e869.tar.gz ghdl-17e24689d3fd3a9e5d58c5c9cb9901e456f3e869.tar.bz2 ghdl-17e24689d3fd3a9e5d58c5c9cb9901e456f3e869.zip |
ortho/gcc, ortho/llvm: do not allocate space for unbounded fields. Fix #1764
-rw-r--r-- | src/ortho/gcc/ortho-lang-49.c | 11 | ||||
-rw-r--r-- | src/ortho/gcc/ortho-lang-5.c | 11 | ||||
-rw-r--r-- | src/ortho/gcc/ortho-lang-6.c | 11 | ||||
-rw-r--r-- | src/ortho/gcc/ortho-lang-7.c | 11 | ||||
-rw-r--r-- | src/ortho/gcc/ortho-lang-8.c | 11 | ||||
-rw-r--r-- | src/ortho/gcc/ortho-lang-9.c | 11 | ||||
-rw-r--r-- | src/ortho/llvm6/llvm-cbindings.cpp | 41 |
7 files changed, 92 insertions, 15 deletions
diff --git a/src/ortho/gcc/ortho-lang-49.c b/src/ortho/gcc/ortho-lang-49.c index d2c3dfc52..e8b4f5643 100644 --- a/src/ortho/gcc/ortho-lang-49.c +++ b/src/ortho/gcc/ortho-lang-49.c @@ -50,6 +50,8 @@ #include "stor-layout.h" #include "varasm.h" +#define TYPE_UNBOUNDED(t) TYPE_LANG_FLAG_0(t) + /* Returns the number of FIELD_DECLs in TYPE. Copied here from expr.c in gcc4.9 as it is no longer exported by tree.h. */ @@ -1139,6 +1141,13 @@ new_record_union_field (struct o_element_list *list, { tree res; + if (TYPE_UNBOUNDED(etype)) { + /* If the field type is unbounded, it mustn't use any space in the + record. Use VOID instead. */ + TYPE_UNBOUNDED(list->res) = 1; + etype = void_type_node; + } + res = build_decl (input_location, FIELD_DECL, ident, etype); DECL_CONTEXT (res) = list->res; chain_append (&list->chain, res); @@ -1303,6 +1312,7 @@ new_array_type (tree el_type, tree index_type) /* Build an incomplete array. */ range_type = build_range_type (index_type, size_zero_node, NULL_TREE); res = build_array_type (el_type, range_type); + TYPE_UNBOUNDED(res) = 1; return res; } @@ -1313,6 +1323,7 @@ new_array_subtype (tree atype, tree eltype, tree length) tree index_type; tree res; + gcc_assert(!TYPE_UNBOUNDED(eltype)); index_type = TYPE_DOMAIN (atype); range_type = ortho_build_array_range(index_type, length); diff --git a/src/ortho/gcc/ortho-lang-5.c b/src/ortho/gcc/ortho-lang-5.c index 8daa5dd92..6a3d5cdb8 100644 --- a/src/ortho/gcc/ortho-lang-5.c +++ b/src/ortho/gcc/ortho-lang-5.c @@ -66,6 +66,8 @@ #include "stor-layout.h" #include "varasm.h" +#define TYPE_UNBOUNDED(t) TYPE_LANG_FLAG_0(t) + /* Returns the number of FIELD_DECLs in TYPE. Copied here from expr.c in gcc4.9 as it is no longer exported by tree.h. */ @@ -1125,6 +1127,13 @@ new_record_union_field (struct o_element_list *list, { tree res; + if (TYPE_UNBOUNDED(etype)) { + /* If the field type is unbounded, it mustn't use any space in the + record. Use VOID instead. */ + TYPE_UNBOUNDED(list->res) = 1; + etype = void_type_node; + } + res = build_decl (input_location, FIELD_DECL, ident, etype); DECL_CONTEXT (res) = list->res; chain_append (&list->chain, res); @@ -1289,6 +1298,7 @@ new_array_type (tree el_type, tree index_type) /* Build an incomplete array. */ range_type = build_range_type (index_type, size_zero_node, NULL_TREE); res = build_array_type (el_type, range_type); + TYPE_UNBOUNDED(res) = 1; return res; } @@ -1299,6 +1309,7 @@ new_array_subtype (tree atype, tree eltype, tree length) tree index_type; tree res; + gcc_assert(!TYPE_UNBOUNDED(eltype)); index_type = TYPE_DOMAIN (atype); range_type = ortho_build_array_range(index_type, length); diff --git a/src/ortho/gcc/ortho-lang-6.c b/src/ortho/gcc/ortho-lang-6.c index 244b26c6c..d2f15cc51 100644 --- a/src/ortho/gcc/ortho-lang-6.c +++ b/src/ortho/gcc/ortho-lang-6.c @@ -66,6 +66,8 @@ #include "stor-layout.h" #include "varasm.h" +#define TYPE_UNBOUNDED(t) TYPE_LANG_FLAG_0(t) + /* Returns the number of FIELD_DECLs in TYPE. Copied here from expr.c in gcc4.9 as it is no longer exported by tree.h. */ @@ -1125,6 +1127,13 @@ new_record_union_field (struct o_element_list *list, { tree res; + if (TYPE_UNBOUNDED(etype)) { + /* If the field type is unbounded, it mustn't use any space in the + record. Use VOID instead. */ + TYPE_UNBOUNDED(list->res) = 1; + etype = void_type_node; + } + res = build_decl (input_location, FIELD_DECL, ident, etype); DECL_CONTEXT (res) = list->res; chain_append (&list->chain, res); @@ -1289,6 +1298,7 @@ new_array_type (tree el_type, tree index_type) /* Build an incomplete array. */ range_type = build_range_type (index_type, size_zero_node, NULL_TREE); res = build_array_type (el_type, range_type); + TYPE_UNBOUNDED(res) = 1; return res; } @@ -1299,6 +1309,7 @@ new_array_subtype (tree atype, tree eltype, tree length) tree index_type; tree res; + gcc_assert(!TYPE_UNBOUNDED(eltype)); index_type = TYPE_DOMAIN (atype); range_type = ortho_build_array_range(index_type, length); diff --git a/src/ortho/gcc/ortho-lang-7.c b/src/ortho/gcc/ortho-lang-7.c index a5b97d8c6..4600fc602 100644 --- a/src/ortho/gcc/ortho-lang-7.c +++ b/src/ortho/gcc/ortho-lang-7.c @@ -66,6 +66,8 @@ #include "stor-layout.h" #include "varasm.h" +#define TYPE_UNBOUNDED(t) TYPE_LANG_FLAG_0(t) + /* Returns the number of FIELD_DECLs in TYPE. Copied here from expr.c in gcc4.9 as it is no longer exported by tree.h. */ @@ -1137,6 +1139,13 @@ new_record_union_field (struct o_element_list *list, { tree res; + if (TYPE_UNBOUNDED(etype)) { + /* If the field type is unbounded, it mustn't use any space in the + record. Use VOID instead. */ + TYPE_UNBOUNDED(list->res) = 1; + etype = void_type_node; + } + res = build_decl (input_location, FIELD_DECL, ident, etype); DECL_CONTEXT (res) = list->res; chain_append (&list->chain, res); @@ -1301,6 +1310,7 @@ new_array_type (tree el_type, tree index_type) /* Build an incomplete array. */ range_type = build_range_type (index_type, size_zero_node, NULL_TREE); res = build_array_type (el_type, range_type); + TYPE_UNBOUNDED(res) = 1; return res; } @@ -1311,6 +1321,7 @@ new_array_subtype (tree atype, tree eltype, tree length) tree index_type; tree res; + gcc_assert(!TYPE_UNBOUNDED(eltype)); index_type = TYPE_DOMAIN (atype); range_type = ortho_build_array_range(index_type, length); diff --git a/src/ortho/gcc/ortho-lang-8.c b/src/ortho/gcc/ortho-lang-8.c index 2c37bdbf5..f88cea0c1 100644 --- a/src/ortho/gcc/ortho-lang-8.c +++ b/src/ortho/gcc/ortho-lang-8.c @@ -66,6 +66,8 @@ #include "stor-layout.h" #include "varasm.h" +#define TYPE_UNBOUNDED(t) TYPE_LANG_FLAG_0(t) + /* Returns the number of FIELD_DECLs in TYPE. Copied here from expr.c in gcc4.9 as it is no longer exported by tree.h. */ @@ -1138,6 +1140,13 @@ new_record_union_field (struct o_element_list *list, { tree res; + if (TYPE_UNBOUNDED(etype)) { + /* If the field type is unbounded, it mustn't use any space in the + record. Use VOID instead. */ + TYPE_UNBOUNDED(list->res) = 1; + etype = void_type_node; + } + res = build_decl (input_location, FIELD_DECL, ident, etype); DECL_CONTEXT (res) = list->res; chain_append (&list->chain, res); @@ -1302,6 +1311,7 @@ new_array_type (tree el_type, tree index_type) /* Build an incomplete array. */ range_type = build_range_type (index_type, size_zero_node, NULL_TREE); res = build_array_type (el_type, range_type); + TYPE_UNBOUNDED(res) = 1; return res; } @@ -1312,6 +1322,7 @@ new_array_subtype (tree atype, tree eltype, tree length) tree index_type; tree res; + gcc_assert(!TYPE_UNBOUNDED(eltype)); index_type = TYPE_DOMAIN (atype); range_type = ortho_build_array_range(index_type, length); diff --git a/src/ortho/gcc/ortho-lang-9.c b/src/ortho/gcc/ortho-lang-9.c index 66e7d7ab0..b7dfab4f3 100644 --- a/src/ortho/gcc/ortho-lang-9.c +++ b/src/ortho/gcc/ortho-lang-9.c @@ -66,6 +66,8 @@ #include "stor-layout.h" #include "varasm.h" +#define TYPE_UNBOUNDED(t) TYPE_LANG_FLAG_0(t) + /* Returns the number of FIELD_DECLs in TYPE. Copied here from expr.c in gcc4.9 as it is no longer exported by tree.h. */ @@ -1138,6 +1140,13 @@ new_record_union_field (struct o_element_list *list, { tree res; + if (TYPE_UNBOUNDED(etype)) { + /* If the field type is unbounded, it mustn't use any space in the + record. Use VOID instead. */ + TYPE_UNBOUNDED(list->res) = 1; + etype = void_type_node; + } + res = build_decl (input_location, FIELD_DECL, ident, etype); DECL_CONTEXT (res) = list->res; chain_append (&list->chain, res); @@ -1302,6 +1311,7 @@ new_array_type (tree el_type, tree index_type) /* Build an incomplete array. */ range_type = build_range_type (index_type, size_zero_node, NULL_TREE); res = build_array_type (el_type, range_type); + TYPE_UNBOUNDED(res) = 1; return res; } @@ -1312,6 +1322,7 @@ new_array_subtype (tree atype, tree eltype, tree length) tree index_type; tree res; + gcc_assert(!TYPE_UNBOUNDED(eltype)); index_type = TYPE_DOMAIN (atype); range_type = ortho_build_array_range(index_type, length); diff --git a/src/ortho/llvm6/llvm-cbindings.cpp b/src/ortho/llvm6/llvm-cbindings.cpp index 98470d8fa..2f5cebe83 100644 --- a/src/ortho/llvm6/llvm-cbindings.cpp +++ b/src/ortho/llvm6/llvm-cbindings.cpp @@ -376,8 +376,12 @@ struct OTnodeBase { DIType *Dbg; #endif + // Kind of type. OTKind Kind; + + // If true, the type is bounded: all the elements have a defined size. bool Bounded; + OTnodeBase (LLVMTypeRef R, OTKind K, bool Bounded) : Ref(R), #ifdef USE_DEBUG @@ -643,7 +647,7 @@ struct OElementList { OFKind Kind; // Number of fields. - unsigned Count; + unsigned BndCount; // For record: the access to the incomplete (but named) type. OTnode RecType; @@ -685,9 +689,10 @@ extern "C" void new_record_field(OElementList *Elements, OFnodeRec **El, OIdent Ident, OTnode Etype) { - *El = new OFnodeRec(Etype, Ident, Elements->Count); + *El = new OFnodeRec(Etype, Ident, Etype->Bounded ? Elements->BndCount : ~0U); Elements->Els->push_back(*El); - Elements->Count++; + if (Etype->Bounded) + Elements->BndCount++; } struct OTnodeRecBase : OTnodeBase { @@ -710,16 +715,19 @@ struct OTnodeIncompleteRec : OTnodeRecBase { static DINodeArray buildDebugRecordElements(OTnodeRecBase *Atype) { - unsigned Count = Atype->Els.size(); - std::vector<Metadata *> els(Count); + std::vector<Metadata *> els; + + els.reserve(Atype->Els.size()); unsigned i = 0; for (OFnodeBase *e : Atype->Els) { - unsigned bitoff = 8 * LLVMOffsetOfElement(TheTargetData, Atype->Ref, i); - els[i++] = DBuilder->createMemberType - (DebugCurrentSubprg, StringRef(e->Ident.cstr), NULL, 0, - e->FType->getBitSize(), /* align */ 0, - bitoff, DINode::DIFlags::FlagZero, e->FType->Dbg); + if (!e->FType->Bounded) + break; + unsigned bitoff = 8 * LLVMOffsetOfElement(TheTargetData, Atype->Ref, i++); + els.push_back(DBuilder->createMemberType + (DebugCurrentSubprg, StringRef(e->Ident.cstr), NULL, 0, + e->FType->getBitSize(), /* align */ 0, + bitoff, DINode::DIFlags::FlagZero, e->FType->Dbg)); } return DBuilder->getOrCreateArray(els); @@ -729,21 +737,24 @@ buildDebugRecordElements(OTnodeRecBase *Atype) extern "C" void finish_record_type(OElementList *Els, OTnode *Res) { - LLVMTypeRef *Types = new LLVMTypeRef[Els->Count]; + LLVMTypeRef *Types = new LLVMTypeRef[Els->BndCount]; // Create types array for elements. int i = 0; bool Bounded = true; for (OFnodeBase *Field : *Els->Els) { - Bounded &= Field->FType->Bounded; - Types[i++] = Field->FType->Ref; + if (Field->FType->Bounded) + Types[i++] = Field->FType->Ref; + else + Bounded = false; } + assert(i == Els->BndCount); OTnodeRecBase *T; if (Els->RecType != nullptr) { // Completion - LLVMStructSetBody (Els->RecType->Ref, Types, Els->Count, 0); + LLVMStructSetBody (Els->RecType->Ref, Types, Els->BndCount, 0); Els->RecType->Bounded = Bounded; T = static_cast<OTnodeRecBase *>(Els->RecType); T->Els = std::move(*Els->Els); @@ -762,7 +773,7 @@ finish_record_type(OElementList *Els, OTnode *Res) } else { // Non-completion. // Debug info are created when the type is declared. - T = new OTnodeRec(LLVMStructType(Types, Els->Count, 0), Bounded); + T = new OTnodeRec(LLVMStructType(Types, Els->BndCount, 0), Bounded); T->Els = std::move(*Els->Els); } *Res = T; |