Previously, the clang importer marked all const methods as mutating whenever a C++ record had mutable fields. This change allows overriding this behavior by using the "nonmutating" swift_attr attribute.
Fixes SR-15907.
The `SWIFT_COMPILER_VERSION` define is used to stamp a vendor’s version number into a Swift compiler binary. It can be queried from Swift code using `#if _compiler_version` and from Clang by using a preprocessor definition called `__SWIFT_COMPILER_VERSION`. These are unsupported compiler-internal features used primarily by Apple Swift.
In Swift 1.0 through 5.5, Apple Swift used a scheme for `SWIFT_COMPILER_VERSION` where the major version matched the embedded clang (e.g. 1300 for Apple Clang 13.0.0) and the minor version was ignored. Starting in Swift 5.6, Apple Swift started using major and minor version numbers that matched the Swift.org version number. This makes them easier to understand, but it means that version 1300.0.x was followed by version 5.6.x. Not only did version numbers go backwards, but also the old logic to ignore minor versions was now a liability, because it meant you would not be able to target a change to 5.7.x compilers but not 5.6.x compilers.
This commit addresses the problem by:
* Modifying the existing `#if _compiler_version(string-literal)` feature so it transforms the major version into a major and minor that will compare correctly to new version numbers. For instance, “1300.*” is transformed into “1.300”, which will compare correctly to a “5.6” or “5.7” version even if it doesn’t really capture the fact that “1300” was a Swift 5.5 compiler. As a bonus, this allows you to use the feature to backwards-compatibly test new compilers using the existing feature: “5007.*” will be seen by compilers before 5.7 as an unknown future version, but will be seen by 5.7 compilers as targeting them.
* Modifying the `__SWIFT_COMPILER_VERSION` clang define similarly so that, to preprocessor conditions written for the old scheme, a 5.7 compiler will appear to have major version 5007.
* Adding a new variant of `#if _compiler_version` with the same syntax as `#if swift` and `#if compiler`—that is, taking a comparison operator and a bare set of dotted version numbers, rather than a string literal. Going forward, this will be how version checks are written once compatibility with compilers before this change is no longer a concern.
These changes are only lightly tested because tests have to work without any compiler version defined (the default in most configurations), but I’ve tested what I can.
Fixes rdar://89841295.
Do not attempt to serialize C++ builtin decls. This caused an assertion failure in `clang::ASTWriter::getDeclID` when building SwiftCompilerSources:
```
Assertion failed: (DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!"), function getDeclID, file ASTWriter.cpp, line 5272.
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project and the crash backtrace.
Stack dump:
0. <eof> parser at end of file
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 swift-frontend 0x00000001123e21c7 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 39
1 swift-frontend 0x00000001123e10e8 llvm::sys::RunSignalHandlers() + 248
2 swift-frontend 0x00000001123e2810 SignalHandler(int) + 288
3 libsystem_platform.dylib 0x00007fff204a0d7d _sigtramp + 29
4 libsystem_platform.dylib 0x0000000000000008 _sigtramp + 18446603339974439592
5 libsystem_c.dylib 0x00007fff203b0406 abort + 125
6 libsystem_c.dylib 0x00007fff203af7d8 err + 0
7 swift-frontend 0x000000011345b983 clang::ASTWriter::getDeclID(clang::Decl const*) (.cold.1) + 35
8 swift-frontend 0x0000000110a584b2 clang::ASTWriter::getDeclID(clang::Decl const*) + 322
9 swift-frontend 0x000000010e36649c llvm::OnDiskChainedHashTableGenerator<(anonymous namespace)::BaseNameToEntitiesTableWriterInfo>::Emit(llvm::raw_ostream&, (anonymous namespace)::BaseNameToEntitiesTableWriterInfo&) + 1244
10 swift-frontend 0x000000010e364927 swift::SwiftLookupTableWriter::writeExtensionContents(clang::Sema&, llvm::BitstreamWriter&) + 1351
11 swift-frontend 0x0000000110a59b62 clang::ASTWriter::WriteModuleFileExtension(clang::Sema&, clang::ModuleFileExtensionWriter&) + 946
```
This change adds a module map for libstdc++, which allows it to be properly imported into Swift as a module. The module map is installed into `usr/lib/swift/linux/{arch}` similarly to `glibc.modulemap`, and is passed to Clang as `-fmodule-map-file`.
That means it is now possible to import std directly from Swift on Linux, when C++ interop is enabled.
The module map currently declares a single `std` module without splitting the headers into submodules. This is going to change in the near future.
rdar://87654514
As per SR-14137 this caches entries in ImportedDecls even when the
import failed.
Also have to mention I did this based on Thomas's PR #36747.
This should help us better handle complex templates and dependant types.
`OverlayFileSystem` is very simple - it just passes along each request
to each VFS it contains until one is successful (or none are). Use it
when wrapping the VFS to pass down into the Clang invocation creation,
instead of the much more complicated `RedirectingFileSystem`.
This has the side effect of also fixing a case where due to a bug in
`RedirectingFileSystem`, the originally passed in path will be returned
regardless of `use-external-name`. While that should also be fixed,
there is no reason to use this VFS here anyway.
Added a small cursor info test case that should catch issues like this
in the future.
This commit adds very basic support for importing and calling base class methods, getting and setting base class fields, and using types inside of base classes.
Previously, ImportDiagnosticTarget was a PointerUnion of five types. This required more spare bits than were available on 32-bit platforms, so the compiler (and more importantly, lldb) could not be built for those.
Fortunately, it turns out that there’s no good reason for `clang::ModuleMacro` to be part of the pointer union—we always convert it to `clang::MacroInfo` before looking up diagnostics anyway. Removing it gets us back into territory which ought to be 32-bit-safe.
Fixes rdar://88922618.
Clang AST requires to have only a single definition in a redeclaration
chain, that's why it demotes duplicate definitions from other modules to
declarations. But on the Swift side it is important to know a module
contains a full definition and not just a forward declaration, even if
it was demoted to a declaration.
Replace the existing `-enable-experimental-clang-importer-diagnostics`
flag with an opt-out version entitled `-disable-experimentalc-clang-importer-diagnostics`.
Enable the beviour previously hidden behind the old flag by default.
Clang importer diagnostics that are produced as a result of a reference
in Swift code are attached to as notes to the Sema produced diagnostic
that indicates the declaration is unavailable.
Ex: Notes about why a C function import failed are attached to
the error explaining that the symbol could not be found in scope.
This patch introduces new diagnostics to the ClangImporter to help
explain why certain C, Objective-C or C++ declarations fail to import
into Swift. This patch includes new diagnostics for the following entities:
- C functions
- C struct fields
- Macros
- Objective-C properties
- Objective-C methods
In particular, notes are attached to indicate when any of the above
entities fail to import as a result of refering an incomplete (only
forward declared) type.
The new diangostics are hidden behind two new flags, -enable-experimental-clang-importer-diagnostics
and -enable-experimental-eager-clang-module-diagnostics. The first flag emits diagnostics lazily,
while the second eagerly imports all declarations visible from loaded Clang modules. The first
flag is intended for day to day swiftc use, the second for module linting or debugging the importer.
This fixes a race condition in parallel builds. DebugExtRefs is part of the
Clang module hash. ObjectFilePCHContainerOperations has its own CodenOpts object
which always sets DebugExtRefs=true, so the module has could differ depending on
whether a module was built as a top-level module or as a dependency of another
module.
This fixes the SwiftREPL tests.
rdar://86279876
When looking for a Swift module on disk, we were scanning all module search paths if they contain the module we are searching for. In a setup where each module is contained in its own framework search path, this scaled quadratically with the number of modules being imported. E.g. a setup with 100 modules being imported form 100 module search paths could cause on the order of 10,000 checks of `FileSystem::exists`. While these checks are fairly fast (~10µs), they add up to ~100ms.
To improve this, perform a first scan of all module search paths and list the files they contain. From this, create a lookup map that maps filenames to the search paths they can be found in. E.g. for
```
searchPath1/
Module1.framework
searchPath2/
Module1.framework
Module2.swiftmodule
```
we create the following lookup table
```
Module1.framework -> [searchPath1, searchPath2]
Module2.swiftmodule -> [searchPath2]
```
This change teaches ClangImporter to import C++ methods marked with `__attribute__((__swift_attr__("mutating")))` as mutating in Swift. This is useful, for example, when a method mutates `this` despite being `const` in C++ (e.g. via `const_cast`).
...by using `__attribute__((swift_attr("@Sendable")))`. `@_nonSendable` will "beat" `@Sendable`, while `@_nonSendable(_assumed)` will not.
This commit also checks if `SwiftAttr` supports `#pragma clang attribute` and, if it does, defines `__SWIFT_ATTR_SUPPORTS_SENDABLE_DECLS` in imported headers so they know they can apply these attributes in an auditing style.