diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-08-15 19:00:43 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-08-15 21:35:10 +0200 |
commit | 8db5b71e212debcc4f6a17f80191ca187c307fcb (patch) | |
tree | 19dedca9ea02beaa0587e37b8b5f5301ca061361 /gcc/d/modules.cc | |
parent | e206fecaac29f559f4990312b875604eb1ce3ef3 (diff) | |
download | gcc-8db5b71e212debcc4f6a17f80191ca187c307fcb.zip gcc-8db5b71e212debcc4f6a17f80191ca187c307fcb.tar.gz gcc-8db5b71e212debcc4f6a17f80191ca187c307fcb.tar.bz2 |
d: Defer compiling inline definitions until after the module has finished.
This is to prevent the case of when generating the methods of a struct
type, we don't accidentally emit an inline function that references it,
as the outer struct itself would still be incomplete.
gcc/d/ChangeLog:
* d-tree.h (d_defer_declaration): Declare.
* decl.cc (function_needs_inline_definition_p): Defer checking
DECL_UNINLINABLE and DECL_DECLARED_INLINE_P.
(maybe_build_decl_tree): Call d_defer_declaration instead of
build_decl_tree.
* modules.cc (deferred_inline_declarations): New variable.
(build_module_tree): Set deferred_inline_declarations and a handle
declarations pushed to it.
(d_defer_declaration): New function.
Diffstat (limited to 'gcc/d/modules.cc')
-rw-r--r-- | gcc/d/modules.cc | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc index edc7912..0aac8fe 100644 --- a/gcc/d/modules.cc +++ b/gcc/d/modules.cc @@ -121,6 +121,9 @@ static module_info *current_testing_module; static Module *current_module_decl; +/* Any inline symbols that were deferred during codegen. */ +vec<Declaration *> *deferred_inline_declarations; + /* Returns an internal function identified by IDENT. This is used by both module initialization and dso handlers. */ @@ -724,6 +727,9 @@ build_module_tree (Module *decl) current_testing_module = &mitest; current_module_decl = decl; + vec<Declaration *> deferred_decls = vNULL; + deferred_inline_declarations = &deferred_decls; + /* Layout module members. */ if (decl->members) { @@ -811,9 +817,14 @@ build_module_tree (Module *decl) layout_moduleinfo (decl); } + /* Process all deferred functions after finishing module. */ + for (size_t i = 0; i < deferred_decls.length (); ++i) + build_decl_tree (deferred_decls[i]); + current_moduleinfo = NULL; current_testing_module = NULL; current_module_decl = NULL; + deferred_inline_declarations = NULL; } /* Returns the current function or module context for the purpose @@ -888,6 +899,15 @@ register_module_decl (Declaration *d) } } +/* Add DECL as a declaration to emit at the end of the current module. */ + +void +d_defer_declaration (Declaration *decl) +{ + gcc_assert (deferred_inline_declarations != NULL); + deferred_inline_declarations->safe_push (decl); +} + /* Wrapup all global declarations and start the final compilation. */ void |