aboutsummaryrefslogtreecommitdiffstats
path: root/src/ortho
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2021-05-18 20:54:51 +0200
committerTristan Gingold <tgingold@free.fr>2021-05-18 20:54:51 +0200
commit17e24689d3fd3a9e5d58c5c9cb9901e456f3e869 (patch)
treed683500a09f8dd25b653d241611978cec7c3c054 /src/ortho
parentf07792aec9c4e943978f8212e2a0f6e870294dbf (diff)
downloadghdl-17e24689d3fd3a9e5d58c5c9cb9901e456f3e869.tar.gz
ghdl-17e24689d3fd3a9e5d58c5c9cb9901e456f3e869.tar.bz2
ghdl-17e24689d3fd3a9e5d58c5c9cb9901e456f3e869.zip
ortho/gcc, ortho/llvm: do not allocate space for unbounded fields. Fix #1764
Diffstat (limited to 'src/ortho')
-rw-r--r--src/ortho/gcc/ortho-lang-49.c11
-rw-r--r--src/ortho/gcc/ortho-lang-5.c11
-rw-r--r--src/ortho/gcc/ortho-lang-6.c11
-rw-r--r--src/ortho/gcc/ortho-lang-7.c11
-rw-r--r--src/ortho/gcc/ortho-lang-8.c11
-rw-r--r--src/ortho/gcc/ortho-lang-9.c11
-rw-r--r--src/ortho/llvm6/llvm-cbindings.cpp41
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;