@@ -4935,11 +4935,12 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
4935
4935
4936
4936
// Find the results that are actually a member of "recordDecl".
4937
4937
TinyPtrVector<ValueDecl *> result;
4938
+ ClangModuleLoader *clangModuleLoader = ctx.getClangModuleLoader ();
4938
4939
for (auto found : allResults) {
4939
4940
auto named = found.get <clang::NamedDecl *>();
4940
4941
if (dyn_cast<clang::Decl>(named->getDeclContext ()) ==
4941
4942
recordDecl->getClangDecl ()) {
4942
- if (auto import = ctx. getClangModuleLoader () ->importDeclDirectly (named))
4943
+ if (auto import = clangModuleLoader ->importDeclDirectly (named))
4943
4944
result.push_back (cast<ValueDecl>(import ));
4944
4945
}
4945
4946
}
@@ -4955,16 +4956,32 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
4955
4956
continue ;
4956
4957
4957
4958
auto *baseRecord = baseType->getAs <clang::RecordType>()->getDecl ();
4958
- if (auto import =
4959
- ctx.getClangModuleLoader ()->importDeclDirectly (baseRecord)) {
4959
+ if (auto import = clangModuleLoader->importDeclDirectly (baseRecord)) {
4960
4960
// If we are looking up the base class, go no further. We will have
4961
4961
// already found it during the other lookup.
4962
4962
if (cast<ValueDecl>(import )->getName () == name)
4963
4963
continue ;
4964
4964
4965
- auto baseResults = cast<NominalTypeDecl>(import )->lookupDirect (name);
4965
+ // Add Clang members that are imported lazily.
4966
+ auto baseResults = evaluateOrDefault (
4967
+ ctx.evaluator ,
4968
+ ClangRecordMemberLookup ({cast<NominalTypeDecl>(import ), name}), {});
4969
+ // Add members that are synthesized eagerly, such as subscripts.
4970
+ for (auto member :
4971
+ cast<NominalTypeDecl>(import )->getCurrentMembersWithoutLoading ()) {
4972
+ if (auto namedMember = dyn_cast<ValueDecl>(member)) {
4973
+ if (namedMember->hasName () &&
4974
+ namedMember->getName ().getBaseName () == name &&
4975
+ // Make sure we don't add duplicate entries, as that would
4976
+ // wrongly imply that lookup is ambiguous.
4977
+ !llvm::is_contained (baseResults, namedMember)) {
4978
+ baseResults.push_back (namedMember);
4979
+ }
4980
+ }
4981
+ }
4966
4982
for (auto foundInBase : baseResults) {
4967
- if (auto newDecl = cloneBaseMemberDecl (foundInBase, recordDecl)) {
4983
+ if (auto newDecl = clangModuleLoader->importBaseMemberDecl (
4984
+ foundInBase, recordDecl)) {
4968
4985
result.push_back (newDecl);
4969
4986
}
4970
4987
}
@@ -5761,6 +5778,18 @@ Decl *ClangImporter::importDeclDirectly(const clang::NamedDecl *decl) {
5761
5778
return Impl.importDecl (decl, Impl.CurrentVersion );
5762
5779
}
5763
5780
5781
+ ValueDecl *ClangImporter::importBaseMemberDecl (ValueDecl *decl,
5782
+ DeclContext *newContext) {
5783
+ // Make sure we don't clone the decl again for this class, as that would
5784
+ // result in multiple definitions of the same symbol.
5785
+ std::pair<ValueDecl *, DeclContext *> key = {decl, newContext};
5786
+ if (!Impl.clonedBaseMembers .count (key)) {
5787
+ ValueDecl *cloned = cloneBaseMemberDecl (decl, newContext);
5788
+ Impl.clonedBaseMembers [key] = cloned;
5789
+ }
5790
+ return Impl.clonedBaseMembers [key];
5791
+ }
5792
+
5764
5793
void ClangImporter::diagnoseTopLevelValue (const DeclName &name) {
5765
5794
Impl.diagnoseTopLevelValue (name);
5766
5795
}
0 commit comments