aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/modules.cc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-08-15 19:00:43 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2022-08-15 21:35:10 +0200
commit8db5b71e212debcc4f6a17f80191ca187c307fcb (patch)
tree19dedca9ea02beaa0587e37b8b5f5301ca061361 /gcc/d/modules.cc
parente206fecaac29f559f4990312b875604eb1ce3ef3 (diff)
downloadgcc-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.cc20
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