d: Delay completing aggregate and enum types until after attributes have been applied.
commitf4c3ce32fa54c1aefac0b3a825d8a3f73de95939
authorIain Buclaw <ibuclaw@gdcproject.org>
Tue, 14 Jun 2022 13:56:59 +0000 (14 15:56 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Wed, 15 Jun 2022 10:33:42 +0000 (15 12:33 +0200)
treed7b38ef3868c7d1619c1d23c513fa43d2800507e
parent2636660b6f35423e0cfbf53bfad5c5fed6ae6471
d: Delay completing aggregate and enum types until after attributes have been applied.

Because of forward/recursive references, the TYPE_SIZE, TYPE_ALIGN, and
TYPE_MODE of structs and enums were set before laying out its members.

This adds a new macro TYPE_FORWARD_REFERENCES for storing those forward
references against the incomplete type, laying them out after the type
has been completed.  Construction of the TYPE_DECL has also been moved
on earlier in the type generation pass, which will allow the possibility
of adding gdc-specific type attributes to the D front-end in the future.

gcc/d/ChangeLog:

* d-attribs.cc (apply_user_attributes): Set ATTR_FLAG_TYPE_IN_PLACE
only on incomplete types.
* d-codegen.cc (copy_aggregate_type): Set TYPE_STUB_DECL after copy.
* d-compiler.cc (Compiler::onParseModule): Adjust.
* d-tree.h (AGGREGATE_OR_ENUM_TYPE_CHECK): Define.
(TYPE_FORWARD_REFERENCES): Define.
* decl.cc (gcc_attribute_p): Update documentation.
(DeclVisitor::visit (StructDeclaration *)): Exit before building type
node if gcc.attributes symbol.
(DeclVisitor::visit (ClassDeclaration *)): Build type node and add
TYPE_NAME to current binding level before emitting anything else.
(DeclVisitor::visit (InterfaceDeclaration *)): Likewise.
(DeclVisitor::visit (EnumDeclaration *)): Likewise.
(build_type_decl): Move rest_of_decl_compilation() call to
finish_aggregate_type().
* types.cc (insert_aggregate_field): Move layout_decl() call to
finish_aggregate_type().
(insert_aggregate_bitfield): Likewise.
(layout_aggregate_members): Adjust.
(finish_incomplete_fields): New function.
(finish_aggregate_type): Handle forward referenced field types.  Call
rest_of_type_compilation() after completing the aggregate.
(TypeVisitor::visit (TypeEnum *)): Don't set size and alignment until
after apply_user_attributes().  Call rest_of_type_compilation() after
completing the enumeral.
(TypeVisitor::visit (TypeStruct *)): Call build_type_decl() before
apply_user_attributes().  Don't set size, alignment, and mode until
after apply_user_attributes().
(TypeVisitor::visit (TypeClass *)): Call build_type_decl() before
applly_user_attributes().
gcc/d/d-attribs.cc
gcc/d/d-codegen.cc
gcc/d/d-compiler.cc
gcc/d/d-tree.h
gcc/d/decl.cc
gcc/d/types.cc