The ObjCMethodLookupTable for protocols was not being serialized and rebuilt on load, so NominalTypeDecl::lookupDirect() on selectors was not working correctly for deserialized types. Correct this oversight.
Previously when looking up a C++ operator (e.g. `==`), `ClangImporter::Implementation::lookupValue` returned a Swift function with a generated name (e.g. `func __operatorEqualEqual`), while the caller expected the result to be a Swift operator (e.g. `func ==`).
This change makes sure that we're returning a synthesized Swift operator when looking for a C++ operator.
This fixes an assertion failure in the typechecker:
```
swift-frontend: /home/build-user/swift/lib/Sema/ConstraintSystem.cpp:1454: std::pair<Type, Type> swift::constraints::ConstraintSystem::getTypeOfReference(swift::ValueDecl *, swift::FunctionRefKind, swift::constraints::ConstraintLocatorBuilder, swift::DeclContext *): Assertion `func->isOperator() && "Lookup should only find operators"' failed.
```
The Swift build scripts pass `-sdk /` to the Swift compiler when building the Swift stdlib and the overlays, and this affects the default include paths of Clang. We need to make sure that libstdc++ path detected by ClangImporter is the same path that will be used by Clang during compilation. To do that, let's pass `--sysroot` to the Clang driver when detecting the libstdc++ path.
To inject a modulemap into the libstdc++ directory, Swift needs to know the path of the libstdc++ installation. Previously it was assumed to be `/usr/include/c++/{version}`, however, this might not be the case. For example, on CentOS the stdlib is located at `/opt/rh/devtoolset-{version}/root/usr/include/c++/{version}`.
This change teaches Swift to extract the libstdc++ include paths from the Clang driver, and fixes C++ stdlib lookup on CentOS.
rdar://93341210
Previously the modulemap for the C++ stdlib on Linux was provided via `-fmodule-map-file=` Clang argument pointing to the modulemap file within the Swift toolchain. The modulemap file could not reference the stdlib headers directly, since the exact stdlib include directory varies across Linux versions (it generally looks like `/usr/include/c++/{gcc_version}`). So the modulemap file instead referenced a local header, which `#include <>`-ed the stdlib headers, relying on Clang include resolution.
Unfortunately this did not work properly in the presence of another C++ module which included the stdlib headers: sometimes decls from the stdlib were hijacked by the other module, and were not treated as a part of the stdlib by Clang. This caused compile errors in Swift.
This change uses LLVM VFS to inject the modulemap file into the libstdc++ directory. The modulemap file is now able to reference the stdlib headers directly, which fixes the issue.
Credits to Rintaro Ishizaki for proposing a similar idea for SwiftGlibc back in 2016.
LLVM has enabled opaque pointers by default. Disable while we migrate.
Note that individual tests can have opaque pointers enabled by using
`-Xcc -Xclang -Xcc -opaque-pointers`.
`InclusionDirective` was changed in llvm/llvm-project
d79ad2f1dbc2db63121620f55d6cfa915f2733ac to pass an
`Optional<FileEntryRef>` rather than a `FileEntry *`. Update overrides
in Swift to use the new API.
`ParseTopLevelDecl` was changed in llvm/llvm-project
ab28488efe6de6f8fa856a1dfd8c0320d41d7608 and now takes a
Sema::ModuleImportState output parameter rather than the previous
(defaulted) boolean.
If a namespace has redecls in different modules, Swift sometimes picked a redecl which is not visible from the requested module, and wrongly removed the namespace from lookup results.
This resulted in errors like this:
```
*** DESERIALIZATION FAILURE ***
Could not deserialize type for 'init(cxxString:)'
Caused by: top-level value not found (std)
Cross-reference to module '__ObjC'
... std
```
Temporarily disable the checks for mutable fields in a C++ struct. A better solution would be to use some heuristic to detect if a method mutates a mutable field, and allow the user to adjust mutability with the existing `nonmutating` annotation.
rdar://92621793
To fix a crash during deserialization, we need to store the mangled names of C++ class template instantiations in the lookup table.
For example, `std::string` will be serialized as `__CxxTemplateInstNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE`, and when another instance of the Swift compiler will later attempt to deserialize a decl referencing this instantiation, it will query the `SwiftLookupTable` for a decl with this name. If this instantiation is not referenced from the module that is currently being compiled, Swift will not instantiate `std::string` during typechecking, and the mangled name will be missing from `SwiftLookupTable`, leading to a deserialization failure. This happens when compiling with cross-module optimization enabled, and the current module does not reference `std::string`, but one of its dependencies does.