@@ -4946,11 +4946,12 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
4946
4946
4947
4947
// Find the results that are actually a member of "recordDecl".
4948
4948
TinyPtrVector<ValueDecl *> result;
4949
+ ClangModuleLoader *clangModuleLoader = ctx.getClangModuleLoader ();
4949
4950
for (auto found : allResults) {
4950
4951
auto named = found.get <clang::NamedDecl *>();
4951
4952
if (dyn_cast<clang::Decl>(named->getDeclContext ()) ==
4952
4953
recordDecl->getClangDecl ()) {
4953
- if (auto import = ctx. getClangModuleLoader () ->importDeclDirectly (named))
4954
+ if (auto import = clangModuleLoader ->importDeclDirectly (named))
4954
4955
result.push_back (cast<ValueDecl>(import ));
4955
4956
}
4956
4957
}
@@ -4966,16 +4967,32 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
4966
4967
continue ;
4967
4968
4968
4969
auto *baseRecord = baseType->getAs <clang::RecordType>()->getDecl ();
4969
- if (auto import =
4970
- ctx.getClangModuleLoader ()->importDeclDirectly (baseRecord)) {
4970
+ if (auto import = clangModuleLoader->importDeclDirectly (baseRecord)) {
4971
4971
// If we are looking up the base class, go no further. We will have
4972
4972
// already found it during the other lookup.
4973
4973
if (cast<ValueDecl>(import )->getName () == name)
4974
4974
continue ;
4975
4975
4976
- auto baseResults = cast<NominalTypeDecl>(import )->lookupDirect (name);
4976
+ // Add Clang members that are imported lazily.
4977
+ auto baseResults = evaluateOrDefault (
4978
+ ctx.evaluator ,
4979
+ ClangRecordMemberLookup ({cast<NominalTypeDecl>(import ), name}), {});
4980
+ // Add members that are synthesized eagerly, such as subscripts.
4981
+ for (auto member :
4982
+ cast<NominalTypeDecl>(import )->getCurrentMembersWithoutLoading ()) {
4983
+ if (auto namedMember = dyn_cast<ValueDecl>(member)) {
4984
+ if (namedMember->hasName () &&
4985
+ namedMember->getName ().getBaseName () == name &&
4986
+ // Make sure we don't add duplicate entries, as that would
4987
+ // wrongly imply that lookup is ambiguous.
4988
+ !llvm::is_contained (baseResults, namedMember)) {
4989
+ baseResults.push_back (namedMember);
4990
+ }
4991
+ }
4992
+ }
4977
4993
for (auto foundInBase : baseResults) {
4978
- if (auto newDecl = cloneBaseMemberDecl (foundInBase, recordDecl)) {
4994
+ if (auto newDecl = clangModuleLoader->importBaseMemberDecl (
4995
+ foundInBase, recordDecl)) {
4979
4996
result.push_back (newDecl);
4980
4997
}
4981
4998
}
@@ -5772,6 +5789,18 @@ Decl *ClangImporter::importDeclDirectly(const clang::NamedDecl *decl) {
5772
5789
return Impl.importDecl (decl, Impl.CurrentVersion );
5773
5790
}
5774
5791
5792
+ ValueDecl *ClangImporter::importBaseMemberDecl (ValueDecl *decl,
5793
+ DeclContext *newContext) {
5794
+ // Make sure we don't clone the decl again for this class, as that would
5795
+ // result in multiple definitions of the same symbol.
5796
+ std::pair<ValueDecl *, DeclContext *> key = {decl, newContext};
5797
+ if (!Impl.clonedBaseMembers .count (key)) {
5798
+ ValueDecl *cloned = cloneBaseMemberDecl (decl, newContext);
5799
+ Impl.clonedBaseMembers [key] = cloned;
5800
+ }
5801
+ return Impl.clonedBaseMembers [key];
5802
+ }
5803
+
5775
5804
void ClangImporter::diagnoseTopLevelValue (const DeclName &name) {
5776
5805
Impl.diagnoseTopLevelValue (name);
5777
5806
}
0 commit comments