Protocol conformance checking requests a qualified name lookup of
"successor()", not "successor", which is a compound name with zero
arguments rather than a simple name.
Teach ClangRecordMemberLookup to be aware of this. Without accounting
for this, protocol conformances will fail.
rdar://169217941
.pointee is a computed variable whose getter and setter are synthesized
from operator*() (dereference).
.successor() is a method that is synthesized from operator++()
(prefix increment).
They are currently created at the end of importing each StructDecl.
That relies on importing operators eagerly, which can lead to template
over-instantiation issues, and is also extra work that we should try to
avoid.
Also, .pointee picks getters and setters based on the last-seen
operator*() overload, which is an unintuitive programming model and also
especially error-prone when matters of inheritance are involved.
We should teach ClangImporter to look up and synthesize these members
on-demand, rather than relying on synthesizing these eagerly.
rdar://167360692
ClangImporter.cpp is so large that it is getting difficult to navigate.
Migrate lookup-related code to a separate file, ClangLookup.cpp.
This patch moves the ClangRecordMemberLookup request to ClangLookup.cpp.
This request looks for members of a given (Swift) name in a (imported)
Clang record, as well as in any of its base classes. The results are
imported to convert them to swift::ValueDecls.
Members found in base classes are not directly added to the inherting class,
because Swift does not model inheritance for imported structs. Instead,
they are "cloned" from base members via a synthesized accessor that is
constructed lazily. This indirection delegates the low-level details of
the base member access to Clang.
At this time of refactoring, lookup for automatically synthesized members
like .pointee and .successor relies on the RecordDecl import logic being
eager. Inherited lookup also has known limitations around inherited
C-style enums and static member functions.
The lookup logic for non-public members is gated under ImportNonPublicCxxMembers
feature, to mitigate issues that may arise from exposing ClangImporter to
private decls that it cannot yet robustly handle. For instance, it does not
deduplicate non-public members that seem to appear twice during lookup due to
UsingShadowDecl.
Also, the inherited lookup logic does not leverage the existing facilities from
Clang, because it needs to handle Swift-specific details like including members
injected by SWIFT_NAME and dropping constructors looked up from foreign
reference types. For member functions, it performs some member deduplication
according to parameter count, to avoid creating spurious ambiguity.
For the inevitable future Git archaeologist, what follows are the commits whose
blame is destroyed by this refactoring:
b8e52a7ad2 [cxx-interop] Lazily import members of Clang namespaces and records via requests.
bb00e8dcfe [cxx-interop] Rudimentary support for importing base classes.
0ca8dd364f [nfc][cxx-interop] Add three requests `ClangDirectLookupRequest`, `CXXNamespaceMemberLookup`, and `ClangRecordMemberLookup`.
fc3b3a1d71 [cxx-interop] Implement foreign reference types.
51a1176d90 [cxx-interop] Clang member lookup should not look into Swift extensions
8df9fca041 [cxx-interop] Don't import constructors of foreign reference types.
a10332548c [cxx-interop] Do not add base class members that cause lookup ambiguities with a derived class member of the same name
796075ab88 [cxx-interop] Fix spurious ambiguous member lookup (#78132)
1341516dba [cxx-interop] Fix spurious ambiguous member lookup for eagerly imported members (#78673)
be73254cdc [cxx-interop] Import private members (#78942)
66c2e2c52b [cxx-interop] Import non-public inherited members (#79348)
edc742013d [cxx-interop] Make experimental flag ImportNonPublicCxxMembers (#79728)
e3618dd797 [Clang importer] Report auxiliary decls from C++ member lookup
84a4a8bedb [Importer] Ensure that we can see macro-expanded declarations in C++ namespaces
bbf92fd6e1 [cxx-interop] Import non-public members of SWIFT_PRIVATE_FILEID-annotated classes (#80320)
e8bcc52356 [cxx-interop] Fix access check for nested private C++ enums (#80366)
1f2107f357 [cxx-interop] Avoid unchecked recursion when importing C++ classes with circular inheritance
79227e7a09 [cxx-interop] Fix ambiguous methods in long chains of inheritance
4de92656dd [cxx-interop] Fix unqualified name lookup failure
585ca5e2da [cxx-interop] Adding swift_name attributes to virtual methods overrides
72be0e0851 [Clang importer] Import incomplete SWIFT_SHARED_REFERENCE types
35bcc99f99 [cxx-interop] Fix miscompilation for inferred shared references
ClangImporter.cpp is so large that it is getting difficult to navigate.
Migrate lookup-related code to a separate file, ClangLookup.cpp.
This patch moves CXXNamespaceMemberLookup and its related helper. This request
looks for decls in a namespace, by performing a ClangDirectLookupRequest in each
redeclaration of that namespace. The results are imported to convert them to
swift::ValueDecls.
For the inevitable future Git archaeologist, what follows are the commits whose
blame is destroyed by this refactoring:
b8e52a7a [cxx-interop] Lazily import members of Clang namespaces and records via requests.
0ca8dd36 [nfc][cxx-interop] Add three requests `ClangDirectLookupRequest`, `CXXNamespaceMemberLookup`, and `ClangRecordMemberLookup`.
0c7b1cee [cxx-interop] serialize x-refs for class template specializations
84a4a8be [Importer] Ensure that we can see macro-expanded declarations in C++ namespaces
ClangImporter.cpp is so large that it is getting difficult to navigate.
Start to migrate lookup-related code to a separate file, ClangLookup.cpp.
This first patch moves ClangDirectLookupRequest and related helpers to a new
file, ClangLookup.cpp. This request looks for decls imported from Clang
according to their Swift name, from mappings stored in the SwiftLookupTable
that ClangImporter writes into (its copy of ) the Clang modules it imports.
This request also includes separate handling of lookup in class template
specializations, which are not in the SwiftLookupTable.
At this time of refactoring, lookup works like this. If we are looking in some
struct Foo for a member Bar, we look for _everything_ named "Bar" in the module
that owns Foo, and then filter out everything that isn't a member of Foo
(according to DeclContext). This is inefficient, but correctly accounts for
members that have been "injected" into structs via the SIWFT_NAME, and also
accounts for other name mappings done by the NameImporter.
For the inevitable future Git archaeologist, what follows are the commits whose
blame is destroyed by this refactoring:
b8e52a7a [cxx-interop] Lazily import members of Clang namespaces and records via requests.
0ca8dd36 [nfc][cxx-interop] Add three requests `ClangDirectLookupRequest`, `CXXNamespaceMemberLookup`, and `ClangRecordMemberLookup`.
1089959b [interop] clang name lookup should find declarations in inline namespaces
c952fc17 [cxx-interop] Fix lookup of class template instantiations
0eed1a94 [cxx-interop] correctly add and lookup enumerators added to enums that correspond to namespaces