6868#include " llvm/Support/FileSystem.h"
6969#include " llvm/Support/Memory.h"
7070#include " llvm/Support/Path.h"
71- #include " llvm/Support/YAMLTraits.h"
7271#include " llvm/Support/YAMLParser.h"
72+ #include " llvm/Support/YAMLTraits.h"
7373#include < algorithm>
7474#include < memory>
7575
@@ -3863,11 +3863,6 @@ void ClangImporter::Implementation::lookupValue(
38633863 importDeclReal (clangDecl->getMostRecentDecl (), CurrentVersion,
38643864 /* useCanonicalDecl*/ !isNamespace);
38653865
3866- if (isNamespace) {
3867- if (auto extension = cast_or_null<ExtensionDecl>(realDecl))
3868- realDecl = extension->getExtendedNominal ();
3869- }
3870-
38713866 if (!realDecl)
38723867 continue ;
38733868 decl = cast<ValueDecl>(realDecl);
@@ -4049,7 +4044,7 @@ SmallVector<SwiftLookupTable::SingleEntry, 4>
40494044ClangDirectLookupRequest::evaluate (Evaluator &evaluator,
40504045 ClangDirectLookupDescriptor desc) const {
40514046 auto &ctx = desc.decl ->getASTContext ();
4052- auto *clangDecl = desc.decl -> getClangDecl () ;
4047+ auto *clangDecl = desc.clangDecl ;
40534048 // Class templates aren't in the lookup table.
40544049 if (auto spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(clangDecl))
40554050 return lookupInClassTemplateSpecialization (ctx, spec, desc.name );
@@ -4065,49 +4060,20 @@ ClangDirectLookupRequest::evaluate(Evaluator &evaluator,
40654060
40664061 auto foundDecls = lookupTable->lookup (
40674062 SerializedSwiftName (desc.name .getBaseName ()), effectiveClangContext);
4068- // TODO: in `SwiftLookupTable::lookup` the `searchContext` is only a string.
4069- // This is problematic because we might have two nested search contexts with
4070- // the same name. The search context needs to be updated to be a decl (or
4071- // decl context), but that will be a larger, seperate refactor. When that
4072- // happens we can remove the below logic.
4073- //
4074- // We filter here by ensuring that each decl and all of its parents have the
4075- // same name as `clangDecl` and its parents. This is prefered to checking the
4076- // decl context pointer is equal to `clangDecl` because we may have a forward
4077- // declared struct, multiple redecls of a namespace, or transparent contexts.
4078- auto deepCompareDeclContexts = [](auto first, auto second) {
4079- while (first->getParent () && second->getParent ()) {
4080- first = first->getParent ();
4081- second = second->getParent ();
4082-
4083- // Look through transparent contexts. If we have one (or more) extern C++
4084- // contexts, that is the same as none.
4085- while (first->isTransparentContext ())
4086- first = first->getParent ();
4087- while (second->isTransparentContext ())
4088- second = second->getParent ();
4089-
4090- auto firstName = dyn_cast<clang::NamedDecl>(first);
4091- auto secondName = dyn_cast<clang::NamedDecl>(second);
4092-
4093- if (!firstName || !secondName) {
4094- if (firstName != secondName)
4095- return false ;
4096- continue ;
4097- }
4098-
4099- if (firstName->getName () != secondName->getName ())
4100- return false ;
4101- }
4102- return !first->getParent () && !second->getParent ();
4103- };
4063+ // Make sure that `clangDecl` is the parent of all the members we found.
41044064 SmallVector<SwiftLookupTable::SingleEntry, 4 > filteredDecls;
41054065 llvm::copy_if (
41064066 foundDecls, std::back_inserter (filteredDecls),
4107- [&deepCompareDeclContexts, dc = cast<clang::DeclContext>(clangDecl)](
4108- SwiftLookupTable::SingleEntry decl) {
4109- return deepCompareDeclContexts (
4110- decl.get <clang::NamedDecl *>()->getDeclContext (), dc);
4067+ [clangDecl](SwiftLookupTable::SingleEntry decl) {
4068+ auto first = decl.get <clang::NamedDecl *>()->getDeclContext ();
4069+ auto second = cast<clang::DeclContext>(clangDecl);
4070+ if (auto firstDecl = dyn_cast<clang::Decl>(first)) {
4071+ if (auto secondDecl = dyn_cast<clang::Decl>(second))
4072+ return firstDecl->getCanonicalDecl () == secondDecl->getCanonicalDecl ();
4073+ else
4074+ return false ;
4075+ }
4076+ return first == second;
41114077 });
41124078 return filteredDecls;
41134079}
@@ -4116,17 +4082,22 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
41164082 Evaluator &evaluator, CXXNamespaceMemberLookupDescriptor desc) const {
41174083 EnumDecl *namespaceDecl = desc.namespaceDecl ;
41184084 DeclName name = desc.name ;
4119-
4085+ auto *clangNamespaceDecl =
4086+ cast<clang::NamespaceDecl>(namespaceDecl->getClangDecl ());
41204087 auto &ctx = namespaceDecl->getASTContext ();
4121- auto allResults = evaluateOrDefault (
4122- ctx.evaluator , ClangDirectLookupRequest ({namespaceDecl, name}), {});
41234088
41244089 TinyPtrVector<ValueDecl *> result;
4125- for (auto found : allResults) {
4126- auto clangMember = found.get <clang::NamedDecl *>();
4127- if (auto import =
4128- ctx.getClangModuleLoader ()->importDeclDirectly (clangMember))
4129- result.push_back (cast<ValueDecl>(import ));
4090+ for (auto redecl : clangNamespaceDecl->redecls ()) {
4091+ auto allResults = evaluateOrDefault (
4092+ ctx.evaluator , ClangDirectLookupRequest ({namespaceDecl, redecl, name}),
4093+ {});
4094+
4095+ for (auto found : allResults) {
4096+ auto clangMember = found.get <clang::NamedDecl *>();
4097+ if (auto import =
4098+ ctx.getClangModuleLoader ()->importDeclDirectly (clangMember))
4099+ result.push_back (cast<ValueDecl>(import ));
4100+ }
41304101 }
41314102
41324103 return result;
@@ -4139,7 +4110,9 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
41394110
41404111 auto &ctx = recordDecl->getASTContext ();
41414112 auto allResults = evaluateOrDefault (
4142- ctx.evaluator , ClangDirectLookupRequest ({recordDecl, name}), {});
4113+ ctx.evaluator ,
4114+ ClangDirectLookupRequest ({recordDecl, recordDecl->getClangDecl (), name}),
4115+ {});
41434116
41444117 // Find the results that are actually a member of "recordDecl".
41454118 TinyPtrVector<ValueDecl *> result;
@@ -4188,8 +4161,9 @@ ClangImporter::Implementation::loadNamedMembers(
41884161 auto table = findLookupTable (*CMO);
41894162 assert (table && " clang module without lookup table" );
41904163
4191- assert (isa<clang::ObjCContainerDecl>(CD) || isa<clang::NamespaceDecl>(CD) ||
4192- isa<clang::RecordDecl>(CD));
4164+ assert (!isa<clang::NamespaceDecl>(CD) && " Namespace members should be loaded"
4165+ " via a request." );
4166+ assert (isa<clang::ObjCContainerDecl>(CD));
41934167
41944168 // Force the members of the entire inheritance hierarchy to be loaded and
41954169 // deserialized before loading the named member of a class. This warms up
@@ -4202,6 +4176,7 @@ ClangImporter::Implementation::loadNamedMembers(
42024176 if (auto *superclassDecl = classDecl->getSuperclassDecl ())
42034177 (void ) const_cast <ClassDecl *>(superclassDecl)->lookupDirect (N);
42044178
4179+ // TODO: update this to use the requestified lookup.
42054180 TinyPtrVector<ValueDecl *> Members;
42064181 for (auto entry : table->lookup (SerializedSwiftName (N),
42074182 effectiveClangContext)) {
0 commit comments