[all-commits] [llvm/llvm-project] afda39: re-land [C++20][Modules] Build module static initi...

iains via All-commits all-commits at lists.llvm.org
Fri Jul 22 00:41:11 PDT 2022


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: afda39a566d9b076bbcbeac1a6a1d4f6aecb3274
      https://github.com/llvm/llvm-project/commit/afda39a566d9b076bbcbeac1a6a1d4f6aecb3274
  Author: Iain Sandoe <iain at sandoe.co.uk>
  Date:   2022-07-22 (Fri, 22 Jul 2022)

  Changed paths:
    M clang/include/clang/AST/ASTContext.h
    M clang/include/clang/Basic/Module.h
    M clang/include/clang/Sema/Sema.h
    M clang/lib/CodeGen/CGDeclCXX.cpp
    M clang/lib/CodeGen/CodeGenModule.cpp
    M clang/lib/CodeGen/CodeGenModule.h
    M clang/lib/Parse/ParseAST.cpp
    M clang/lib/Sema/SemaModule.cpp
    A clang/test/CodeGen/module-intializer-pmf.cpp
    A clang/test/CodeGen/module-intializer.cpp

  Log Message:
  -----------
  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




More information about the All-commits mailing list