68
68
#include " llvm/Support/FileSystem.h"
69
69
#include " llvm/Support/Memory.h"
70
70
#include " llvm/Support/Path.h"
71
- #include " llvm/Support/YAMLTraits.h"
72
71
#include " llvm/Support/YAMLParser.h"
72
+ #include " llvm/Support/YAMLTraits.h"
73
73
#include < algorithm>
74
74
#include < memory>
75
75
@@ -3863,11 +3863,6 @@ void ClangImporter::Implementation::lookupValue(
3863
3863
importDeclReal (clangDecl->getMostRecentDecl (), CurrentVersion,
3864
3864
/* useCanonicalDecl*/ !isNamespace);
3865
3865
3866
- if (isNamespace) {
3867
- if (auto extension = cast_or_null<ExtensionDecl>(realDecl))
3868
- realDecl = extension->getExtendedNominal ();
3869
- }
3870
-
3871
3866
if (!realDecl)
3872
3867
continue ;
3873
3868
decl = cast<ValueDecl>(realDecl);
@@ -4049,7 +4044,7 @@ SmallVector<SwiftLookupTable::SingleEntry, 4>
4049
4044
ClangDirectLookupRequest::evaluate (Evaluator &evaluator,
4050
4045
ClangDirectLookupDescriptor desc) const {
4051
4046
auto &ctx = desc.decl ->getASTContext ();
4052
- auto *clangDecl = desc.decl -> getClangDecl () ;
4047
+ auto *clangDecl = desc.clangDecl ;
4053
4048
// Class templates aren't in the lookup table.
4054
4049
if (auto spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(clangDecl))
4055
4050
return lookupInClassTemplateSpecialization (ctx, spec, desc.name );
@@ -4065,49 +4060,20 @@ ClangDirectLookupRequest::evaluate(Evaluator &evaluator,
4065
4060
4066
4061
auto foundDecls = lookupTable->lookup (
4067
4062
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.
4104
4064
SmallVector<SwiftLookupTable::SingleEntry, 4 > filteredDecls;
4105
4065
llvm::copy_if (
4106
4066
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;
4111
4077
});
4112
4078
return filteredDecls;
4113
4079
}
@@ -4116,17 +4082,22 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
4116
4082
Evaluator &evaluator, CXXNamespaceMemberLookupDescriptor desc) const {
4117
4083
EnumDecl *namespaceDecl = desc.namespaceDecl ;
4118
4084
DeclName name = desc.name ;
4119
-
4085
+ auto *clangNamespaceDecl =
4086
+ cast<clang::NamespaceDecl>(namespaceDecl->getClangDecl ());
4120
4087
auto &ctx = namespaceDecl->getASTContext ();
4121
- auto allResults = evaluateOrDefault (
4122
- ctx.evaluator , ClangDirectLookupRequest ({namespaceDecl, name}), {});
4123
4088
4124
4089
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
+ }
4130
4101
}
4131
4102
4132
4103
return result;
@@ -4139,7 +4110,9 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
4139
4110
4140
4111
auto &ctx = recordDecl->getASTContext ();
4141
4112
auto allResults = evaluateOrDefault (
4142
- ctx.evaluator , ClangDirectLookupRequest ({recordDecl, name}), {});
4113
+ ctx.evaluator ,
4114
+ ClangDirectLookupRequest ({recordDecl, recordDecl->getClangDecl (), name}),
4115
+ {});
4143
4116
4144
4117
// Find the results that are actually a member of "recordDecl".
4145
4118
TinyPtrVector<ValueDecl *> result;
@@ -4188,8 +4161,9 @@ ClangImporter::Implementation::loadNamedMembers(
4188
4161
auto table = findLookupTable (*CMO);
4189
4162
assert (table && " clang module without lookup table" );
4190
4163
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));
4193
4167
4194
4168
// Force the members of the entire inheritance hierarchy to be loaded and
4195
4169
// deserialized before loading the named member of a class. This warms up
@@ -4202,6 +4176,7 @@ ClangImporter::Implementation::loadNamedMembers(
4202
4176
if (auto *superclassDecl = classDecl->getSuperclassDecl ())
4203
4177
(void ) const_cast <ClassDecl *>(superclassDecl)->lookupDirect (N);
4204
4178
4179
+ // TODO: update this to use the requestified lookup.
4205
4180
TinyPtrVector<ValueDecl *> Members;
4206
4181
for (auto entry : table->lookup (SerializedSwiftName (N),
4207
4182
effectiveClangContext)) {
0 commit comments