aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaModule.cpp
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2022-05-15 14:47:54 +0100
committerIain Sandoe <iain@sandoe.co.uk>2022-07-22 08:38:07 +0100
commitafda39a566d9b076bbcbeac1a6a1d4f6aecb3274 (patch)
tree11f30af6ac67f3c656d37c1d0ebeb0ad98fbbfd3 /clang/lib/Sema/SemaModule.cpp
parent2a88fb2ecb72300bfbbc74c586fb415cc18c9f9d (diff)
downloadllvm-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.cpp10
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;
}