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/decl.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/decl.cc')
-rw-r--r-- | gcc/d/decl.cc | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 0131b01..e91aee3 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -1046,18 +1046,10 @@ function_needs_inline_definition_p (FuncDeclaration *fd) if (!DECL_EXTERNAL (fd->csym)) return false; - /* Non-inlineable functions are always external. */ - if (DECL_UNINLINABLE (fd->csym)) - return false; - /* No function body available for inlining. */ if (!fd->fbody) return false; - /* Ignore functions that aren't decorated with `pragma(inline)'. */ - if (fd->inlining != PINLINE::always) - return false; - /* These functions are tied to the module they are defined in. */ if (fd->isFuncLiteralDeclaration () || fd->isUnitTestDeclaration () @@ -1070,6 +1062,14 @@ function_needs_inline_definition_p (FuncDeclaration *fd) if (function_defined_in_root_p (fd)) return false; + /* Non-inlineable functions are always external. */ + if (DECL_UNINLINABLE (fd->csym)) + return false; + + /* Ignore functions that aren't decorated with `pragma(inline)'. */ + if (!DECL_DECLARED_INLINE_P (fd->csym)) + return false; + /* Weak functions cannot be inlined. */ if (lookup_attribute ("weak", DECL_ATTRIBUTES (fd->csym))) return false; @@ -1081,8 +1081,8 @@ function_needs_inline_definition_p (FuncDeclaration *fd) return true; } -/* If the variable or function declaration in DECL needs to be defined, call - build_decl_tree on it now before returning its back-end symbol. */ +/* If the variable or function declaration in DECL needs to be defined, add it + to the list of deferred declarations to build later. */ static tree maybe_build_decl_tree (Declaration *decl) @@ -1103,7 +1103,7 @@ maybe_build_decl_tree (Declaration *decl) if (function_needs_inline_definition_p (fd)) { DECL_EXTERNAL (fd->csym) = 0; - build_decl_tree (fd); + d_defer_declaration (fd); } } |