|
27 | 27 | #include "swift/AST/DiagnosticEngine.h"
|
28 | 28 | #include "swift/AST/DiagnosticsClangImporter.h"
|
29 | 29 | #include "swift/AST/DiagnosticsSema.h"
|
| 30 | +#include "swift/AST/Evaluator.h" |
30 | 31 | #include "swift/AST/IRGenOptions.h"
|
31 | 32 | #include "swift/AST/ImportCache.h"
|
32 | 33 | #include "swift/AST/LinkLibrary.h"
|
|
41 | 42 | #include "swift/AST/Types.h"
|
42 | 43 | #include "swift/Basic/Assertions.h"
|
43 | 44 | #include "swift/Basic/Defer.h"
|
| 45 | +#include "swift/Basic/LLVM.h" |
44 | 46 | #include "swift/Basic/Platform.h"
|
45 | 47 | #include "swift/Basic/Range.h"
|
46 | 48 | #include "swift/Basic/SourceLoc.h"
|
@@ -6161,14 +6163,43 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
|
6161 | 6163 | ClangModuleLoader *clangModuleLoader = ctx.getClangModuleLoader();
|
6162 | 6164 | for (auto found : directResults) {
|
6163 | 6165 | auto named = found.get<clang::NamedDecl *>();
|
6164 |
| - if (dyn_cast<clang::Decl>(named->getDeclContext()) == |
6165 |
| - recordDecl->getClangDecl()) { |
6166 |
| - // Don't import constructors on foreign reference types. |
6167 |
| - if (isa<clang::CXXConstructorDecl>(named) && isa<ClassDecl>(recordDecl)) |
| 6166 | + if (dyn_cast<clang::Decl>(named->getDeclContext()) != |
| 6167 | + recordDecl->getClangDecl()) |
| 6168 | + continue; |
| 6169 | + |
| 6170 | + // Don't import constructors on foreign reference types. |
| 6171 | + if (isa<clang::CXXConstructorDecl>(named) && isa<ClassDecl>(recordDecl)) |
| 6172 | + continue; |
| 6173 | + |
| 6174 | + auto imported = clangModuleLoader->importDeclDirectly(named); |
| 6175 | + if (!imported) |
| 6176 | + continue; |
| 6177 | + |
| 6178 | + // If this member is found due to inheritance, clone it from the base class |
| 6179 | + // by synthesizing getters and setters. |
| 6180 | + if (inheritingDecl != recordDecl) { |
| 6181 | + imported = clangModuleLoader->importBaseMemberDecl( |
| 6182 | + cast<ValueDecl>(imported), inheritingDecl); |
| 6183 | + if (!imported) |
6168 | 6184 | continue;
|
| 6185 | + } |
| 6186 | + result.push_back(cast<ValueDecl>(imported)); |
| 6187 | + } |
6169 | 6188 |
|
6170 |
| - if (auto import = clangModuleLoader->importDeclDirectly(named)) |
6171 |
| - result.push_back(cast<ValueDecl>(import)); |
| 6189 | + if (inheritingDecl != recordDecl) { |
| 6190 | + // For inheritied members, add members that are synthesized eagerly, such as |
| 6191 | + // subscripts. This is not necessary for non-inherited members because those |
| 6192 | + // should already be in the lookup table. |
| 6193 | + for (auto member : |
| 6194 | + cast<NominalTypeDecl>(recordDecl)->getCurrentMembersWithoutLoading()) { |
| 6195 | + auto namedMember = dyn_cast<ValueDecl>(member); |
| 6196 | + if (!namedMember || !namedMember->hasName() || |
| 6197 | + namedMember->getName().getBaseName() != name) |
| 6198 | + continue; |
| 6199 | + |
| 6200 | + if (auto imported = clangModuleLoader->importBaseMemberDecl( |
| 6201 | + namedMember, inheritingDecl)) |
| 6202 | + result.push_back(cast<ValueDecl>(imported)); |
6172 | 6203 | }
|
6173 | 6204 | }
|
6174 | 6205 |
|
@@ -6207,43 +6238,14 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
|
6207 | 6238 | ClangRecordMemberLookup(
|
6208 | 6239 | {cast<NominalTypeDecl>(import), name, inheritingDecl}),
|
6209 | 6240 | {});
|
6210 |
| - // Add members that are synthesized eagerly, such as subscripts. |
6211 |
| - for (auto member : |
6212 |
| - cast<NominalTypeDecl>(import)->getCurrentMembersWithoutLoading()) { |
6213 |
| - if (auto namedMember = dyn_cast<ValueDecl>(member)) { |
6214 |
| - if (namedMember->hasName() && |
6215 |
| - namedMember->getName().getBaseName() == name && |
6216 |
| - // Make sure we don't add duplicate entries, as that would |
6217 |
| - // wrongly imply that lookup is ambiguous. |
6218 |
| - !llvm::is_contained(baseResults, namedMember)) { |
6219 |
| - baseResults.push_back(namedMember); |
6220 |
| - } |
6221 |
| - } |
6222 |
| - } |
| 6241 | + |
6223 | 6242 | for (auto foundInBase : baseResults) {
|
6224 | 6243 | // Do not add duplicate entry with the same arity,
|
6225 | 6244 | // as that would cause an ambiguous lookup.
|
6226 | 6245 | if (foundNameArities.count(getArity(foundInBase)))
|
6227 | 6246 | continue;
|
6228 | 6247 |
|
6229 |
| - // Do not importBaseMemberDecl() if this is a recursive lookup into |
6230 |
| - // some class's superclass. importBaseMemberDecl() caches synthesized |
6231 |
| - // members, which does not work if we call it on its result, e.g.: |
6232 |
| - // |
6233 |
| - // importBaseMemberDecl(importBaseMemberDecl(foundInBase, |
6234 |
| - // recorDecl), recordDecl) |
6235 |
| - // |
6236 |
| - // Instead, we simply pass on the imported decl (foundInBase) as is, |
6237 |
| - // so that only the top-most request calls importBaseMemberDecl(). |
6238 |
| - if (inheritingDecl != recordDecl) { |
6239 |
| - result.push_back(foundInBase); |
6240 |
| - continue; |
6241 |
| - } |
6242 |
| - |
6243 |
| - if (auto newDecl = clangModuleLoader->importBaseMemberDecl( |
6244 |
| - foundInBase, recordDecl)) { |
6245 |
| - result.push_back(newDecl); |
6246 |
| - } |
| 6248 | + result.push_back(foundInBase); |
6247 | 6249 | }
|
6248 | 6250 | }
|
6249 | 6251 | }
|
|
0 commit comments