|
22 | 22 | #include "swift/AST/Module.h"
|
23 | 23 | #include "swift/AST/NameLookup.h"
|
24 | 24 | #include "swift/AST/Types.h"
|
| 25 | +#include "swift/ClangImporter/ClangImporter.h" |
25 | 26 |
|
26 | 27 | using namespace swift;
|
27 | 28 | using namespace swift::remote;
|
@@ -366,8 +367,8 @@ class RemoteASTTypeBuilder {
|
366 | 367 | return loc.getType();
|
367 | 368 | }
|
368 | 369 |
|
369 |
| - NominalTypeDecl *getAcceptableNominalTypeCandidate(ValueDecl *decl, |
370 |
| - Demangle::Node::Kind kind) { |
| 370 | + static NominalTypeDecl *getAcceptableNominalTypeCandidate(ValueDecl *decl, |
| 371 | + Demangle::Node::Kind kind) { |
371 | 372 | if (kind == Demangle::Node::Kind::Class) {
|
372 | 373 | return dyn_cast<ClassDecl>(decl);
|
373 | 374 | } else if (kind == Demangle::Node::Kind::Enum) {
|
@@ -557,44 +558,34 @@ RemoteASTTypeBuilder::findNominalTypeDecl(DeclContext *dc,
|
557 | 558 | NominalTypeDecl *
|
558 | 559 | RemoteASTTypeBuilder::findForeignNominalTypeDecl(Identifier name,
|
559 | 560 | Demangle::Node::Kind kind) {
|
560 |
| - SimpleIdentTypeRepr repr(SourceLoc(), name); |
561 |
| - auto type = checkTypeRepr(&repr); |
562 |
| - if (!type) return nullptr; |
563 |
| - |
564 |
| - if (auto nomTy = type->getAs<NominalType>()) { |
565 |
| - if (auto typeDecl = getAcceptableNominalTypeCandidate(nomTy->getDecl(), kind)) { |
566 |
| - if (typeDecl->hasClangNode()) |
567 |
| - return typeDecl; |
| 561 | + // Check to see if we have an importer loaded. |
| 562 | + auto importer = static_cast<ClangImporter *>(Ctx.getClangModuleLoader()); |
| 563 | + if (!importer) return nullptr; |
| 564 | + |
| 565 | + // Find the unique declaration that has the right kind. |
| 566 | + struct Consumer : VisibleDeclConsumer { |
| 567 | + Demangle::Node::Kind ExpectedKind; |
| 568 | + NominalTypeDecl *Result = nullptr; |
| 569 | + bool HadError = false; |
| 570 | + |
| 571 | + explicit Consumer(Demangle::Node::Kind kind) : ExpectedKind(kind) {} |
| 572 | + |
| 573 | + void foundDecl(ValueDecl *decl, DeclVisibilityKind reason) override { |
| 574 | + if (HadError) return; |
| 575 | + auto typeDecl = getAcceptableNominalTypeCandidate(decl, ExpectedKind); |
| 576 | + if (!typeDecl) return; |
| 577 | + if (!Result) { |
| 578 | + Result = typeDecl; |
| 579 | + } else { |
| 580 | + HadError = true; |
| 581 | + Result = nullptr; |
| 582 | + } |
568 | 583 | }
|
569 |
| - } |
570 |
| - return nullptr; |
571 |
| - |
572 |
| - UnqualifiedLookup lookup(name, getNotionalDC(), /*resolver*/ nullptr, |
573 |
| - /*known private*/ false, SourceLoc(), |
574 |
| - /*type lookup*/ true); |
575 |
| - |
576 |
| - NominalTypeDecl *result = nullptr; |
577 |
| - for (auto lookupResult : lookup.Results) { |
578 |
| - // We can ignore the base declaration here. |
579 |
| - auto decl = lookupResult.getValueDecl(); |
580 |
| - |
581 |
| - // Ignore results that are not the right kind of nominal type declaration. |
582 |
| - NominalTypeDecl *candidate = getAcceptableNominalTypeCandidate(decl, kind); |
583 |
| - if (!candidate) |
584 |
| - continue; |
585 |
| - |
586 |
| - // Ignore results that aren't foreign. |
587 |
| - if (!candidate->hasClangNode()) |
588 |
| - continue; |
589 |
| - |
590 |
| - // This is a viable result. |
| 584 | + } consumer(kind); |
591 | 585 |
|
592 |
| - // If we already have a viable result, it's ambiguous, so give up. |
593 |
| - if (result) return nullptr; |
594 |
| - result = candidate; |
595 |
| - } |
| 586 | + importer->lookupValue(name, consumer); |
596 | 587 |
|
597 |
| - return result; |
| 588 | + return consumer.Result; |
598 | 589 | }
|
599 | 590 |
|
600 | 591 | namespace {
|
|
0 commit comments