Commit Graph

43 Commits

Author SHA1 Message Date
Iain Sandoe fee3cccc6c [C++20][Modules] Improve handing of Private Module Fragment diagnostics.
This adds a check for exported inline functions, that there is a definition in
the definition domain (which, in practice, can only be the module purview but
before any PMF starts) since the PMF definition domain cannot contain exports.

This is:
[dcl.inline]/7
If an inline function or variable that is attached to a named module is declared in
a definition domain, it shall be defined in that domain.

The patch also amends diagnostic output by excluding the PMF sub-module from the
set considered as sources of missing decls.  There is no point in telling the user
that the import of a PMF object is missing - since such objects are never reachable
to an importer.  We still show the definition (as unreachable), to help point out
this.

Differential Revision: https://reviews.llvm.org/D128328
2022-08-21 10:19:46 +01:00
Chuanqi Xu e8e46cdce3 [NFC] [C++20] [Modules] Use Sema::isCurrentModulePurview() to simplify the codes 2022-07-27 14:15:32 +08:00
Iain Sandoe afda39a566 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
2022-07-22 08:38:07 +01:00
Iain Sandoe b19d3ee712 Revert "[C++20][Modules] Build module static initializers per P1874R1."
This reverts commit ac507102d2.

reverting while we figuere out why one of the green dragon lldb test fails.
2022-07-11 19:50:31 +01:00
Iain Sandoe ac507102d2 [C++20][Modules] Build module static initializers per P1874R1.
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
2022-07-09 09:09:09 +01:00
Chuanqi Xu 354a597b9f [C++20] [Modules] Don't complain about duplicated default template argument across modules
See https://github.com/cplusplus/draft/pull/5204 for a detailed
 background.

 Simply, the test redundant-template-default-arg.cpp attached to this
 patch should be accepted instead of being complained about the
 redefinition.

 Reviewed By: urnathan, rsmith, ChuanqiXu

 Differential Revision: https://reviews.llvm.org/D118034
2022-07-08 11:10:51 +08:00
Chuanqi Xu 9c04851cf5 [C++20] [Module] Support reachable definition initially/partially
This patch introduces a new kind of ModuleOwnershipKind as
ReachableWhenImported. This intended the status for reachable described
at: https://eel.is/c++draft/module.reach#3.

Note that this patch is not intended to support all semantics about
reachable semantics. For example, this patch didn't implement discarded
declarations in GMF. (https://eel.is/c++draft/module.global.frag#3).

This fixes: https://bugs.llvm.org/show_bug.cgi?id=52281 and
https://godbolt.org/z/81f3ocjfW.

Reviewed By: rsmith, iains

Differential Revision: https://reviews.llvm.org/D113545
2022-06-29 12:48:48 +08:00
Chuanqi Xu 7a541406b5 Revert "[C++20] [Modules] Implement Reachable initiallly"
This reverts commit a223ba0a69.

The previous commit don't contain additional information, which is bad.
2022-06-29 12:43:26 +08:00
Chuanqi Xu a223ba0a69 [C++20] [Modules] Implement Reachable initiallly 2022-06-29 12:32:31 +08:00
Iain Sandoe 92fed06f80 [C++20][Modules] Remove an empty statement [NFC].
This addresses a post commit review comment by removing an unused and empty
'else' (replaced with a comment).
2022-04-11 10:06:23 +01:00
Iain Sandoe f60dc3caa6 [C++20][Modules] Adjust handling of exports of namespaces and using-decls.
This adjusts the handling for:

export module  M;

export namespace {};

export namespace N {};
export using namespace N;

In the first case, we were allowing empty anonymous namespaces
as part of an extension allowing empty top-level entities, but that seems
inappropriate in this case, since the linkage would be internal for the
anonymous namespace.  We now report an error for this.

The second case was producing a warning diagnostic that this was
accepted as an extension - however the C++20 standard does allow this
as well-formed.

In the third case we keep the current practice that this is accepted with a
warning (as an extension). The C++20 standard says it's an error.

We also ensure that using decls are only applied to items with external linkage.

This adjusts error messages for exports involving redeclarations in modules to
be more specific about the reason that the decl has been rejected.

Differential Revision: https://reviews.llvm.org/D122119
2022-04-08 08:57:37 +01:00
Iain Sandoe d9cea8d3a8 [C++20][Modules][HU 4/5] Handle pre-processed header units.
We wish to support emitting a pre-processed output for an importable
header unit, that can be consumed to produce the same header units as
the original source.

This means that ee need to find the original filename used to produce
the re-preprocessed output, so that it can be assigned as the module
name.  This is peeked from the first line of the pre-processed source
when the action sets up the files.

Differential Revision: https://reviews.llvm.org/D121098
2022-03-27 09:38:06 +01:00
Iain Sandoe cf396c56e7 [C++20][Modules] Correct an assert for modules-ts.
When adding the support for modules partitions we added an assert that the
actual status of Global Module Fragments matches the state machine that is
driven by the module; keyword.

That does not apply to the modules-ts case, where there is an implicit GMF.

Differential Revision: https://reviews.llvm.org/D122394
2022-03-25 14:55:13 +00:00
Iain Sandoe 6c0e60e884 [C++20][Modules][HU 1/5] Introduce header units as a module type.
This is the first in a series of patches that introduce C++20 importable
header units.

These differ from clang header modules in that:
 (a) they are identifiable by an internal name
 (b) they represent the top level source for a single header - although
     that might include or import other headers.

We name importable header units with the path by which they are specified
(although that need not be the absolute path for the file).

So "foo/bar.h" would have a name "foo/bar.h".  Header units are made a
separate module type so that we can deal with diagnosing places where they
are permitted but a named module is not.

Differential Revision: https://reviews.llvm.org/D121095
2022-03-25 09:17:14 +00:00
Simon Pilgrim 8d0931114f [clang] Sema::ActOnModuleImport - remove superfluous nullptr test
Mod has already been dereferenced
2022-03-09 11:40:36 +00:00
Chuanqi Xu 3eb2da76d7 [NFC] [C++20] [Modules] Simplify ActOnModuleImport by merging Path and Parition
Reviewed By: iains

Differential Revision: https://reviews.llvm.org/D120793
2022-03-02 23:06:36 +08:00
Iain Sandoe b3fcfcb946 [C++20][Modules][7/8] Find the primary interface name for a module.
When we are building modules, there are cases where the only way to determine
validity of access is by comparing primary interface names.  This is because we need
to be able to associate a primary interface name with an imported partition, but
before the primary interface module is complete - so that textual comparison is
necessary.

If this turns out to be needed many times, we could cache the result, but it seems
unlikely to be significant (at this time); cases with very many imported partitions
would seem unusual.

Differential Revision: https://reviews.llvm.org/D118598
2022-02-28 08:50:25 +00:00
Iain Sandoe 853ca54723 [C++20][Modules][6/8] Record direct module imports.
This is a small cache to avoid having to check both Exports and
Imports.

Differential Revision: https://reviews.llvm.org/D118589
2022-02-27 10:07:11 +00:00
Iain Sandoe 1a76d25639 [C++20][Modules][5/8] Diagnose wrong import/export for partition CMIs.
We cannot export partition implementation CMIs, but we can export the content
of partition interface CMIs.

Differential Revision: https://reviews.llvm.org/D118588
2022-02-26 11:27:08 +00:00
Iain Sandoe 6114491441 [C++20][Modules][4/8] Handle generation of partition implementation CMIs.
Partition implementations are special, they generate a CMI, but it
does not have an 'export' line, and we cannot export anything from the
it [that is it can only make decls available to other members of the
owning module, not to importers of that].

Add initial testcases for partition handling, derived from the examples in
Section 10 of the C++20 standard, which identifies what should be accepted
and/or rejected.

Differential Revision: https://reviews.llvm.org/D118587
2022-02-25 09:33:14 +00:00
Benjamin Kramer fb3a2d45cd [Sema] Silence unused variable warning in Release builds. NFC. 2022-02-24 11:00:52 +01:00
Iain Sandoe 69350e569d [C++20][Modules][3/8] Initial handling for module partitions.
This implements the parsing and recognition of module partition CMIs
and removes the FIXMEs in the parser.

Module partitions are recognised in the base computation of visibility,
however additional amendments to visibility follow in subsequent patches.

Differential Revision: https://reviews.llvm.org/D118586
2022-02-24 09:01:09 +00:00
Iain Sandoe c9cc8035eb [C++20][Modules][2/8] Add enumerations for partition modules and stream them.
This is an initial enabling patch for module partition support.
We add enumerations for partition interfaces/implementations.

This means that the module kind enumeration now occupies three
bits, so the AST streamer is adjusted for this.  Adding one bit there
seems preferable to trying to overload the meanings of existing
kinds (and we will also want to add a C++20 header unit case later).

Differential Revision: https://reviews.llvm.org/D114714
2022-02-22 10:08:15 +00:00
Iain Sandoe ab28488efe [C++20][Modules][1/8] Track valid import state.
In C++20 modules imports must be together and at the start of the module.
Rather than growing more ad-hoc flags to test state, this keeps track of the
phase of of a valid module TU (first decl, global module frag, module,
private module frag).  If the phasing is broken (with some diagnostic) the
pattern does not conform to a valid C++20 module, and we set the state
accordingly.

We can thus issue diagnostics when imports appear in the wrong places and
decouple the C++20 modules state from other module variants (modules-ts and
clang modules).  Additionally, we attempt to diagnose wrong imports before
trying to find the module where possible (the latter will generally emit an
unhelpful diagnostic about the module not being available).

Although this generally simplifies the handling of C++20 module import
diagnostics, the motivation was that, in particular, it allows detecting
invalid imports like:

import module A;

int some_decl();

import module B;

where being in a module purview is insufficient to identify them.

Differential Revision: https://reviews.llvm.org/D118893
2022-02-21 09:09:37 +00:00
Iain Sandoe 673879249d Revert "[C++20][Modules][1/8] Track valid import state."
This reverts commit 8a3f9a584a.

need to investigate build failures that do not show on CI or local
testing.
2022-02-20 10:22:07 +00:00
Iain Sandoe 8a3f9a584a [C++20][Modules][1/8] Track valid import state.
In C++20 modules imports must be together and at the start of the module.
Rather than growing more ad-hoc flags to test state, this keeps track of the
phase of of a valid module TU (first decl, global module frag, module,
private module frag).  If the phasing is broken (with some diagnostic) the
pattern does not conform to a valid C++20 module, and we set the state
accordingly.

We can thus issue diagnostics when imports appear in the wrong places and
decouple the C++20 modules state from other module variants (modules-ts and
clang modules).  Additionally, we attempt to diagnose wrong imports before
trying to find the module where possible (the latter will generally emit an
unhelpful diagnostic about the module not being available).

Although this generally simplifies the handling of C++20 module import
diagnostics, the motivation was that, in particular, it allows detecting
invalid imports like:

import module A;

int some_decl();

import module B;

where being in a module purview is insufficient to identify them.

Differential Revision: https://reviews.llvm.org/D118893
2022-02-20 10:13:57 +00:00
Chuanqi Xu 3504937dfb [C++20] [Modules] Don't create multiple global module fragment
Since the serialization code would recognize modules by names and the
name of all global module fragment is <global>, so that the
serialization code would complain for the same module.

This patch fixes this by using a unique global module fragment in Sema.
Before this patch, the compiler would fail on an assertion complaining
the duplicated modules.

Reviewed By: urnathan, rsmith

Differential Revision: https://reviews.llvm.org/D115610
2022-02-08 11:52:09 +08:00
Timm Bäder ba845787b3 [clang][sema] Add missing diagnostic parameter
The test case otherwise fails an assertion in Diagnostic::getArgKind().

Differential Revision: https://reviews.llvm.org/D116595
2022-01-24 09:59:20 +01:00
Chuanqi Xu 4f8916cfdd [C++20] [Modules] Exit early if export decl is not valid
This patch fixes a crash due to following simple program:
> export struct Unit {
>    bool operator<(const Unit&);
> };

It would crash since the compiler would set the module ownership for
Unit. And the declaration with a module ownership is assumed to own a
module. But here isn't one. So here is the crash.

This patch fixes this by exiting early if it finds the export decl is
already invalid.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D117093
2022-01-14 10:21:42 +08:00
Chuanqi Xu 86b001a941 [C++20] [Modules] Mark imported module as imported if not exported
In C++20 Modules, imported module which doesn't get exported wouldn't be
recorded. This patch would record such modules to avoid possible
incorrect visibility problems.

Reviewed By: urnathan

Differential Revision: https://reviews.llvm.org/D116098
2021-12-23 21:14:13 +08:00
Chuanqi Xu 1e2c31c66b Revert "[C++20] [Coroutines] Mark imported module as imported if not exported"
This reverts commit 368318bcce.

The title is not right. It should be a patch about modules instead of
coroutines.
2021-12-23 21:10:07 +08:00
Chuanqi Xu 368318bcce [C++20] [Coroutines] Mark imported module as imported if not exported
In C++20 Modules, imported module which doesn't get exported wouldn't be
recorded. This patch would record such modules to avoid possible
incorrect visibility problems.

Reviewed By: urnathan

Differential Revision: https://reviews.llvm.org/D116098
2021-12-23 20:51:05 +08:00
Chuanqi Xu 4168efe1b2 [NFC] Fix C++20 module test in PPC and warning 2021-12-08 14:25:51 +08:00
Chuanqi Xu e587372f85 [C++20] [Module] Support extern C/C++ semantics
According to [module.unit]p7.2.3, a declaration within a linkage-specification
should be attached to the global module.
This let user to forward declare types across modules.

Reviewed by: rsmith, aaron.ballman

Differential Revision: https://reviews.llvm.org/D110215
2021-12-08 13:29:16 +08:00
Duncan P. N. Exon Smith 9f151df178 Change Module::ASTFile and ModuleFile::File => Optional<FileEntryRef>, NFC
Change `Module::ASTFile` and `ModuleFile::File` to use
`Optional<FileEntryRef>` instead of `const FileEntry *`. One of many
steps toward removing `FileEntry::getName`.

Differential Revision: https://reviews.llvm.org/D89836
2020-11-02 15:11:51 -05:00
Ehud Katz c63f1b160e [DeclCXX] Remove unknown external linkage specifications
Partial revert of r372681 "Support for DWARF-5 C++ language tags".

The change introduced new external linkage languages ("C++11" and
"C++14") which not supported in C++.

It also changed the definition of the existing enum to use the DWARF
constants. The problem is that "LinkageSpecDeclBits.Language" (the field
that reserves this enum) is actually defined as 3 bits length
(bitfield), which cannot contain the new DWARF constants. Defining the
enum as integer literals is more appropriate for maintaining valid
values.

Differential Revision: https://reviews.llvm.org/D69935
2019-11-21 15:23:05 +02:00
Adrian Prantl 350de4f05d Support for DWARF-5 C++ language tags.
This patch provides support for DW_LANG_C_plus_plus_11,
DW_LANG_C_plus_plus_14 tags in the Clang C++ frontend.

Patch by Sourabh Singh Tomar!
Differential Revision: https://reviews.llvm.org/D67613

Reapplies r372663 after adapting a failing test in the LLDB testsuite.

llvm-svn: 372681
2019-09-24 00:38:49 +00:00
Jonas Devlieghere 5c49c26714 Revert "Support for DWARF-5 C++ language tags."
This reverts commit bf9c8ffb54.

llvm-svn: 372672
2019-09-23 23:49:36 +00:00
Adrian Prantl bf9c8ffb54 Support for DWARF-5 C++ language tags.
This patch provides support for DW_LANG_C_plus_plus_11,
DW_LANG_C_plus_plus_14 tags in the Clang C++ frontend.

Patch by Sourabh Singh Tomar!
Differential Revision: https://reviews.llvm.org/D67613

llvm-svn: 372663
2019-09-23 22:01:49 +00:00
Rui Ueyama 49a3ad21d6 Fix parameter name comments using clang-tidy. NFC.
This patch applies clang-tidy's bugprone-argument-comment tool
to LLVM, clang and lld source trees. Here is how I created this
patch:

$ git clone https://github.com/llvm/llvm-project.git
$ cd llvm-project
$ mkdir build
$ cd build
$ cmake -GNinja -DCMAKE_BUILD_TYPE=Debug \
    -DLLVM_ENABLE_PROJECTS='clang;lld;clang-tools-extra' \
    -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DLLVM_ENABLE_LLD=On \
    -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ../llvm
$ ninja
$ parallel clang-tidy -checks='-*,bugprone-argument-comment' \
    -config='{CheckOptions: [{key: StrictMode, value: 1}]}' -fix \
    ::: ../llvm/lib/**/*.{cpp,h} ../clang/lib/**/*.{cpp,h} ../lld/**/*.{cpp,h}

llvm-svn: 366177
2019-07-16 04:46:31 +00:00
Richard Smith e181de7f4f [c++2a] Implement semantic restrictions for 'export' declarations.
llvm-svn: 358932
2019-04-22 22:50:11 +00:00
Richard Smith a5bbbfef15 [c++2a] Add semantic support for private module fragments.
llvm-svn: 358713
2019-04-18 21:12:54 +00:00
Richard Smith b7bdb8cf33 Split out modules-specific declaration handling from SemaDecl.cpp into a
new SemaModule.cpp.

llvm-svn: 358633
2019-04-18 00:57:02 +00:00