diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2022-05-15 14:47:54 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2022-07-22 08:38:07 +0100 |
commit | afda39a566d9b076bbcbeac1a6a1d4f6aecb3274 (patch) | |
tree | 11f30af6ac67f3c656d37c1d0ebeb0ad98fbbfd3 /clang/lib/Sema/SemaModule.cpp | |
parent | 2a88fb2ecb72300bfbbc74c586fb415cc18c9f9d (diff) | |
download | llvm-afda39a566d9b076bbcbeac1a6a1d4f6aecb3274.zip llvm-afda39a566d9b076bbcbeac1a6a1d4f6aecb3274.tar.gz llvm-afda39a566d9b076bbcbeac1a6a1d4f6aecb3274.tar.bz2 |
re-land [C++20][Modules] Build module static initializers per P1874R1.
The re-land fixes module map module dependencies seen on Greendragon, but
not in the clang test suite.
---
Currently we only implement this for the Itanium ABI since the correct
mangling for the initializers in other ABIs is not yet known.
Intended result:
For a module interface [which includes partition interface and implementation
units] (instead of the generic CXX initializer) we emit a module init that:
- wraps the contained initializations in a control variable to ensure that
the inits only happen once, even if a module is imported many times by
imports of the main unit.
- calls module initializers for imported modules first. Note that the
order of module import is not significant, and therefore neither is the
order of imported module initializers.
- We then call initializers for the Global Module Fragment (if present)
- We then call initializers for the current module.
- We then call initializers for the Private Module Fragment (if present)
For a module implementation unit, or a non-module TU that imports at least one
module we emit a regular CXX init that:
- Calls the initializers for any imported modules first.
- Then proceeds as normal with remaining inits.
For all module unit kinds we include a global constructor entry, this allows
for the (in most cases unusual) possibility that a module object could be
included in a final binary without a specific call to its initializer.
Implementation:
- We provide the module pointer in the AST Context so that CodeGen can act
on it and its sub-modules.
- We need to account for module build lines like this:
` clang -cc1 -std=c++20 Foo.pcm -emit-obj -o Foo.o` or
` clang -cc1 -std=c++20 -xc++-module Foo.cpp -emit-obj -o Foo.o`
- in order to do this, we add to ParseAST to set the module pointer in
the ASTContext, once we establish that this is a module build and we
know the module pointer. To be able to do this, we make the query for
current module public in Sema.
- In CodeGen, we determine if the current build requires a CXX20-style module
init and, if so, we defer any module initializers during the "Eagerly
Emitted" phase.
- We then walk the module initializers at the end of the TU but before
emitting deferred inits (which adds any hidden and static ones, fixing
https://github.com/llvm/llvm-project/issues/51873 ).
- We then proceed to emit the deferred inits and continue to emit the CXX
init function.
Differential Revision: https://reviews.llvm.org/D126189
Diffstat (limited to 'clang/lib/Sema/SemaModule.cpp')
-rw-r--r-- | clang/lib/Sema/SemaModule.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index e9a1ac17..f5c24bd 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -344,6 +344,16 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, // statements, so imports are allowed. ImportState = ModuleImportState::ImportAllowed; + // For an implementation, We already made an implicit import (its interface). + // Make and return the import decl to be added to the current TU. + if (MDK == ModuleDeclKind::Implementation) { + // Make the import decl for the interface. + ImportDecl *Import = + ImportDecl::Create(Context, CurContext, ModuleLoc, Mod, Path[0].second); + // and return it to be added. + return ConvertDeclToDeclGroup(Import); + } + // FIXME: Create a ModuleDecl. return nullptr; } |