89 Commits

Author SHA1 Message Date
Chuanqi Xu
c2c840bd92 [Modules] Don't prevent @import from ObjectiveC
Previously we forbiden the users to import named modules from clang header
modules. However, due to an oversight, the @import form of Objective C
got involved. This is not want and we fix that in this patch.
2023-12-28 10:45:47 +08:00
Kazu Hirata
f3dcc2351c
[clang] Use StringRef::{starts,ends}_with (NFC) (#75149)
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.

I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
2023-12-13 08:54:13 -08:00
Chuanqi Xu
0f7aaeb324 [C++20] [Modules] Allow export from language linkage
Close https://github.com/llvm/llvm-project/issues/71347

Previously I misread the concept of module purview. I thought if a
declaration attached to a unnamed module, it can't be part of the module
purview. But after the issue report, I recognized that module purview is
more of a concept about locations instead of semantics.

Concretely, the things in the language linkage after module declarations
can be exported.

This patch refactors `Module::isModulePurview()` and introduces some
possible code cleanups.
2023-11-09 17:44:41 +08:00
Chuanqi Xu
427f13bd72 [NFC] [C++20] [Modules] Remove 'ModuleInterface' bit in Sema::ModuleScope
The 'ModuleInterface' in Sema::ModuleScope is confusing. It actually
means 'not implementation'. This patch removes that bit and extract the
information from the recorded clang::Module.
2023-11-09 15:20:32 +08:00
Vlad Serebrennikov
8775947633
[clang][NFC] Refactor clang::Linkage (#71049)
This patch introduces a new enumerator `Invalid = 0`, shifting other enumerators by +1. Contrary to how it might sound, this actually affirms status quo of how this enum is stored in `clang::Decl`:
```
  /// If 0, we have not computed the linkage of this declaration.
  /// Otherwise, it is the linkage + 1.
  mutable unsigned CacheValidAndLinkage : 3;
```
This patch makes debuggers to not be mistaken about enumerator stored in this bit-field. It also converts `clang::Linkage` to a scoped enum.
2023-11-02 20:57:29 +04:00
Vlad Serebrennikov
65761200ce [clang][NFC] Refactor LinkageSpecDecl::LanguageIDs
This patch converts `LinkageSpecDecl::LanguageIDs` into scoped enum, and moves it to namespace scope, so that it can be forward-declared where required.
2023-11-01 16:44:34 +03:00
Jan Svoboda
523c471250 Reapply "[clang] NFCI: Adopt SourceManager::getFileEntryRefForID()"
This reapplies ddbcc10b9e26b18f6a70e23d0611b9da75ffa52f, except for a tiny part that was reverted separately: 65331da0032ab4253a4bc0ddcb2da67664bd86a9. That will be reapplied later on, since it turned out to be more involved.

This commit is enabled by 5523fefb01c282c4cbcaf6314a9aaf658c6c145f and f0f548a65a215c450d956dbcedb03656449705b9, specifically the part that makes 'clang-tidy/checkers/misc/header-include-cycle.cpp' separator agnostic.
2023-09-08 19:04:01 -07:00
Jan Svoboda
0a9611fd8d Revert "[clang] NFCI: Adopt SourceManager::getFileEntryRefForID()"
This reverts commit ddbcc10b9e26b18f6a70e23d0611b9da75ffa52f.

The 'clang-tidy/checkers/misc/header-include-cycle.cpp' test started failing on Windows: https://lab.llvm.org/buildbot/#/builders/216/builds/26855.
2023-09-06 13:23:23 -07:00
Jan Svoboda
ddbcc10b9e [clang] NFCI: Adopt SourceManager::getFileEntryRefForID()
This commit replaces some calls to the deprecated `FileEntry::getName()` with `FileEntryRef::getName()` by swapping current usages of `SourceManager::getFileEntryForID()` with `SourceManager::getFileEntryRefForID()`. This lowers the number of usages of the deprecated `FileEntry::getName()` from 95 to 50.
2023-09-06 10:49:48 -07:00
Chuanqi Xu
574ee1c02e [C++20] [Modules] Prevent to accept clang modules
Close https://github.com/llvm/llvm-project/issues/64755

This wouldn't affect the form @import as the test shows. The two
affected test case `diag-flags.cpp` and `diag-pragma.cpp` are old test
cases in 2017 and 2018, when we're not so clear about the direction of
modules. And the things that these 2 tests tested can be covered by
clang modules naturally. So I change the them into clang modules to
not block this patch.
2023-08-17 11:45:50 +08:00
Elliot Goodrich
b0abd4893f [llvm] Add missing StringExtras.h includes
In preparation for removing the `#include "llvm/ADT/StringExtras.h"`
from the header to source file of `llvm/Support/Error.h`, first add in
all the missing includes that were previously included transitively
through this header.
2023-06-25 15:42:22 +01:00
Iain Sandoe
b37233a253 [C++20][Modules] Complete implementation of module.import p7.
The following test fails to compile TU b.cpp because we are not making the transitively imported modules visible (per [module.import]/p7)

```
a.cppm:
export module a;

export int foo() {
   return 42;
}

b.cppm:
export module b;
import a;

export int bar();

b.cpp:
module b;

int bar() {
   return foo();
}

clang++ -c -std=c++2b -fmodule-output a.cppm
clang++ -c -std=c++2b -fmodule-output -fprebuilt-module-path=. b.cppm
clang++ -c -std=c++2b -fprebuilt-module-path=. b.cpp
b.cpp:4:12: error: declaration of 'foo' must be imported from module 'a' before it is required
   return foo();
```

This is fixed by the following patch (which also addresses a FIXME in basic.def.odr/p6.cppm).

Differential Revision: https://reviews.llvm.org/D152746
2023-06-25 08:33:39 +01:00
Iain Sandoe
e5c7904fa0 [C++20][Modules] Implement P2615R1 revised export diagnostics.
It has been reported to that the current clang  errors for, specifically,
static_assert in export contexts are a serious blocker to adoption of
modules in some cases.

There is also implementation divergence with GCC and MSVC allowing the
constructs mentioned below where clang currently rejects them with an
error.

The category of errors [for declarations in an exported context] is:
(unnamed, static_assert, empty and asm decls). These are now permitted
after P2615R1 which was approved by WG21 as a DR (and thus should be
applied to C++20 as well).

This patch removes these diagnostics and amends the testsuite accordingly.

Differential Revision: https://reviews.llvm.org/D152946
2023-06-24 09:01:59 +01:00
Kadir Cetinkaya
4d0cfa6d09
[clang] Don't create import decls without -fmodules
When modules are disabled, there's no loaded module for these import
decls to point at. This results in crashes when there are modulemap
files but no -fmodules flag (this configuration is used for layering
check violations).

This patch makes sure import declarations are introduced only when
modules are enabled, which makes this case similar to textual headers
(no import decls are created for #include of textual headers from a
modulemap).

Differential Revision: https://reviews.llvm.org/D152274
2023-06-16 09:26:45 +02:00
Chuanqi Xu
52bc4b16cb [NFC] [C++20] [Modules] Refactor Sema::isModuleUnitOfCurrentTU into
Decl::isInAnotherModuleUnit

Refactor `Sema::isModuleUnitOfCurrentTU` to `Decl::isInAnotherModuleUnit`
to make code simpler a little bit. Note that although this patch
introduces a FIXME, this is an existing issue and this patch just tries
to describe it explicitly.
2023-05-23 10:52:22 +08:00
Chuanqi Xu
fc89e9044d [C++20] [Modules] Emit an warning for experimental header units
Currently, the header units are rarely used and it is not well tested.
To avoid further misunderstandings, let's mark it as experimental and
emit a warning when users wants to import it.

This is discussed in modules developers meeting.
2023-05-18 16:12:41 +08:00
Chuanqi Xu
88a720d194 [NFC] [C++20] [Modules] Rename ASTContext::getNamedModuleForCodeGen to ASTContext::getCurrentNamedModule
The original name "ASTContext::getNamedModuleForCodeGen" is not properly
reflecting the usage of the interface. This interface can be used to
judge the current module unit in both sema analysis and code generation.
So the original name was not so correct.
2023-05-16 11:24:35 +08:00
Chuanqi Xu
7f37066915 Revert "[NFC] [C++20] [Modules] Refactor Sema::isModuleUnitOfCurrentTU into"
This reverts commit f109b1016801e2b0dbee278f3c517057c0b1d441 as required
in
f109b10168 (commitcomment-113477829).
2023-05-16 10:47:53 +08:00
Chuanqi Xu
f109b10168 [NFC] [C++20] [Modules] Refactor Sema::isModuleUnitOfCurrentTU into
Decl::isInCurrentModuleUnit

Refactor `Sema::isModuleUnitOfCurrentTU` to `Decl::isInCurrentModuleUnit`
to make code simpler a little bit. Note that although this patch
introduces a FIXME, this is an existing issue and this patch just tries
to describe it explicitly.
2023-05-10 16:01:27 +08:00
Mark de Wever
ba15d186e5 [clang] Use -std=c++23 instead of -std=c++2b
During the ISO C++ Committee meeting plenary session the C++23 Standard
has been voted as technical complete.

This updates the reference to c++2b to c++23 and updates the __cplusplus
macro.

Drive-by fixes c++1z -> c++17 and c++2a -> c++20 when seen.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D149553
2023-05-04 19:19:52 +02:00
Chuanqi Xu
c1f76363e0 [C++20] [Modules] Continue parsing after we found reserved module names
Close https://github.com/llvm/llvm-project/issues/62112

In the previous change, we'll stop parsing directly after we found
reserved module names. But this may be too aggressive. This patch
changes this. Note that the parsing will still be stopped if the module
name is `module` or `import`.
2023-04-13 15:14:34 +08:00
Iain Sandoe
6e4f870a21 re-land [C++20][Modules] Introduce an implementation module.
We need to be able to distinguish individual TUs from the same module in cases
where TU-local entities either need to be hidden (or, for some cases of ADL in
template instantiation, need to be detected as exposures).

This creates a module type for the implementation which implicitly imports its
primary module interface per C++20:
[module.unit/8] 'A module-declaration that contains neither an export-keyword
nor a module-partition implicitly imports the primary module interface unit of
the module as if by a module-import-declaration.

Implementation modules are never serialized (-emit-module-interface for an
implementation unit is diagnosed and rejected).

Differential Revision: https://reviews.llvm.org/D126959
2023-03-29 08:52:28 +05:30
Aaron Ballman
e574833c2b Downgrade reserved module identifier error into a warning
Any project that wants to import std; potentially needs to be able to
build a module that does export std;. We silenced the error diagnostic
if the module identified itself as a system header, but this isn't
quite good enough, what we really need is a way to identify a system
module. It would be nice for that feature to be shared among the major
implementations, so this downgrades the diagnostic from an error to a
warning temporarily to give implementers time to determine what that
mechanism will look like. We may convert this warning back into an
error in a future release of Clang, but it's not guaranteed we will do
so.

Fixes https://github.com/llvm/llvm-project/issues/61446
Differential Revision: https://reviews.llvm.org/D146986
2023-03-28 08:53:44 -04:00
Mitch Phillips
074f6fd61d Revert "[C++20][Modules] Introduce an implementation module."
This reverts commit c6e9823724ef6bdfee262289ee34d162db436af0.

Reason: Broke the ASan buildbots, see https://reviews.llvm.org/D126959
(the original phabricator review) for more info.
2023-03-27 05:01:53 -07:00
Iain Sandoe
c6e9823724 [C++20][Modules] Introduce an implementation module.
We need to be able to distinguish individual TUs from the same module in cases
where TU-local entities either need to be hidden (or, for some cases of ADL in
template instantiation, need to be detected as exposures).

This creates a module type for the implementation which implicitly imports its
primary module interface per C++20:
[module.unit/8] 'A module-declaration that contains neither an export-keyword
nor a module-partition implicitly imports the primary module interface unit of
the module as if by a module-import-declaration.

Implementation modules are never serialized (-emit-module-interface for an
implementation unit is diagnosed and rejected).

Differential Revision: https://reviews.llvm.org/D126959
2023-03-23 12:47:44 +00:00
Chuanqi Xu
bf52ead24c [C++20] [Modules] Support to export declarations in language linkage
Close https://github.com/llvm/llvm-project/issues/60405

See the discussion in the above link for the background.

What the patch does:
- Rename `Module::ModuleKind::GlobalModuleFragment` to
  `Module::ModuleKind::ExplicitGlobalModuleFragment`.
- Add another module kind `ImplicitGlobalModuleFragment` to
  `ModuleKind`.
- Create an implicit global module fragment for the language linkage
  declarations inside a module purview.
    - If the language linkage lives inside the scope of an export decl,
      the created modules is marked as exported to outer modules.
- In fact, Sema will only create at most 2 implicit global module
  fragments to avoid creating a lot of unnecessary modules in the edging
case.

Reviewed By: iains

Differential Revision: https://reviews.llvm.org/D144367
2023-03-03 10:31:48 +08:00
Chuanqi Xu
2dfa957f12 [NFC] Remove the unused parameter in Sema::PushGlobalModuleFragment
The `IsImplicit` parameter should be removed since it is not used now.
2023-02-20 15:37:55 +08:00
Chuanqi Xu
70d78e0358 [NFC] Remove unused Sema::DirectModuleImports
Sema::DirectModuleImports is not used now. Remove it for clearness.
2023-02-20 15:07:49 +08:00
Chuanqi Xu
999ead9dc9 [Modules] Code cleanup after removing ModulesTS
Some codes become unused after we remove ModulesTS.
2023-02-16 15:22:38 +08:00
Chuanqi Xu
612f3ac26f [Modules] Remove -fmodules-ts
As the diagnostic message shows, we should remove -fmodules-ts flag in
clang/llvm17. Since clang/llvm16 is already branched. We can remove the
depreacared flag now.
2023-02-16 14:40:32 +08:00
Chuanqi Xu
24ecd99842 [NFC] Set C++20 Named Modules for CodeGen in ASTContext in the early place
Previously we'll set the named modules for ASTContext in ParseAST. But
this is not intuitive and we need comments to tell the intuition. This
patch moves the code the right the place, where the corrresponding
module is first created/loaded. Now it is more intuitive and we can use
the value in the earlier places.
2023-02-13 17:14:58 +08:00
Chuanqi Xu
1782e8f9e8 [C++20] [Modules] Allow -fmodule-file=<module-name>=<BMI-Path> for implementation unit and document the behavior
Close https://github.com/llvm/llvm-project/issues/57293.

Previsouly we can't use `-fmodule-file=<module-name>=<BMI-Path>` for
implementation units, it is a bug. Also the behavior of the above option
is not tested nor documented for C++20 Modules. This patch addresses the
2 problems.
2023-02-08 16:45:00 +08:00
Iain Sandoe
53a1314ed1 [C++20][Modules] Fix named module import diagnostics.
We have been incorrectly disallowing imports of named modules in the
global and private module fragments.

This addresses: https://github.com/llvm/llvm-project/issues/59688

Differential Revision: https://reviews.llvm.org/D140927
2023-01-22 10:22:36 +00:00
Jan Svoboda
c3efd52770 [clang][modules] Disallow importing private framework in the implementation
Whenever we are compiling implementation of a framework (with the `-fmodule-name=FW` option), we never translate `#import <FW/Header.h>` to an import, regardless of whether "Header.h" belongs to "FW" or "FW_Private". For the same reasons, we also disallow `@import FW`. However, we still allow `@import FW_Private`. This patch disallows that a well, to be consistent with the rest of the rules.

Reviewed By: benlangmuir

Differential Revision: https://reviews.llvm.org/D142167
2023-01-20 13:37:36 -08:00
Richard Howell
75fbb5d223 [clang][nfc] refactor Module::Header to use OptionalFileEntryRef
Refactor the `Module::Header` class to use an `OptionalFileEntryRef`
instead of a `FileEntry*`. This is preparation for refactoring the
`TopHeaderNames` to use `FileEntryRef` so that we preserve the
lookup path of the headers when serializing.

This is mostly based on https://reviews.llvm.org/D90497

Reviewed By: jansvoboda11

Differential Revision: https://reviews.llvm.org/D142113
2023-01-20 07:23:11 -08:00
Kazu Hirata
6ad0788c33 [clang] Use std::optional instead of llvm::Optional (NFC)
This patch replaces (llvm::|)Optional< with std::optional<.  I'll post
a separate patch to remove #include "llvm/ADT/Optional.h".

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-14 12:31:01 -08:00
Kazu Hirata
a1580d7b59 [clang] Add #include <optional> (NFC)
This patch adds #include <optional> to those files containing
llvm::Optional<...> or Optional<...>.

I'll post a separate patch to actually replace llvm::Optional with
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-14 11:07:21 -08:00
Benjamin Kramer
854c10f8d1 [Clang] Prepare for llvm::Optional becoming std::optional.
The needed tweaks are mostly trivial, the one nasty bit is Clang's usage
of OptionalStorage. To keep this working old Optional stays around as
clang::CustomizableOptional, with the default Storage removed.
Optional<File/DirectoryEntryRef> is replaced with a typedef.

I tested this with GCC 7.5, the oldest supported GCC I had around.

Differential Revision: https://reviews.llvm.org/D140332
2022-12-20 00:41:40 +01:00
Krzysztof Parzyszek
205c0589f9 Revert "[clang] Convert OptionalFileEntryRefDegradesToFileEntryPtr to std::optional"
This reverts commit 8f0df9f3bbc6d7f3d5cbfd955c5ee4404c53a75d.

The Optional*RefDegradesTo*EntryPtr types want to keep the same size as
the underlying type, which std::optional doesn't guarantee. For use with
llvm::Optional, they define their own storage class, and there is no way
to do that in std::optional.

On top of that, that commit broke builds with older GCCs, where
std::optional was not trivially copyable (static_assert in the clang
sources was failing).
2022-12-18 11:23:54 -08:00
Krzysztof Parzyszek
8f0df9f3bb [clang] Convert OptionalFileEntryRefDegradesToFileEntryPtr to std::optional 2022-12-17 15:24:14 -08:00
Kazu Hirata
8595f2e54d [Sema] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-03 11:13:39 -08:00
Chuanqi Xu
1614d63405 [NFC] Remove unused codes after 4a7be42d922af
There are still some unused codes remained after 4a7be42d922af. And this
patch tries to remove them.
2022-11-18 11:52:44 +08:00
Chuanqi Xu
9044226ba2 [NFC] [C++20] [Modules] Remove unused Global Module Fragment variables/arguments 2022-11-15 11:51:13 +08:00
Haojian Wu
964c4948cd Remove an unused local variable, NFC. 2022-11-03 13:57:46 +01:00
Aaron Ballman
b8ceb9f4e4 [C++20] Diagnose invalid and reserved module names
[module.unit]p1 specifies that module and import are invalid components
of a module name, that module names cannot contain reserved
identifiers, and that std followed by zero or more digits is reserved.

The first issue (module and import pseudo-keywords) requires a
diagnostic, the second issue (use of reserved identifiers) does not
require a diagnostic. We diagnose both the same -- the code is ill-
formed unless the module declaration is in a system "header". This
allows STL implementations to use the reserved module names while
preventing users from stealing them out from under us.

Differential Revision: https://reviews.llvm.org/D136953
2022-11-03 08:29:59 -04:00
Chuanqi Xu
9974ed8049 [C++20] [Modules] Remove assertion of current module when acting on import
Closes https://github.com/llvm/llvm-project/issues/58199

Previously, when we act on a import statement, we'll assume there is a
module declaration in the current TU if the command line tells us we're
compiling a module unit. This makes since on valid codes. However, for
invalid codes, it is possible. See
https://github.com/llvm/llvm-project/issues/58199 for example.

This patch removes the assertion. And the assertion is a noop and it
should be safe to remove it.
2022-10-08 16:44:51 +08:00
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 ac507102d258b6fc0cb57eb60c9dfabd57ff562f.

reverting while we figuere out why one of the green dragon lldb test fails.
2022-07-11 19:50:31 +01:00