Skip to content

Commit d235fdc

Browse files
authored
Merge pull request swiftlang#21116 from akyrtzi/break-dependency-cycles
[AST] Break dependency cycles of swiftAST against swiftSema and swiftClangImporter
2 parents 290e902 + 7653cce commit d235fdc

File tree

10 files changed

+286
-277
lines changed

10 files changed

+286
-277
lines changed

include/swift/AST/Module.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,9 @@ class LoadedFile : public FileUnit {
13151315
return nullptr;
13161316
}
13171317

1318+
/// Returns the Swift module that overlays a Clang module.
1319+
virtual ModuleDecl *getAdapterModule() const { return nullptr; }
1320+
13181321
virtual bool isSystemModule() const { return false; }
13191322

13201323
/// Retrieve the set of generic signatures stored within this module.

include/swift/AST/NameLookup.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "llvm/ADT/SmallPtrSet.h"
2121
#include "llvm/ADT/SmallVector.h"
22+
#include "swift/AST/ASTVisitor.h"
2223
#include "swift/AST/Identifier.h"
2324
#include "swift/AST/Module.h"
2425
#include "swift/Basic/SourceLoc.h"
@@ -381,6 +382,85 @@ getDirectlyInheritedNominalTypeDecls(
381382
SelfBounds getSelfBoundsFromWhereClause(
382383
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl);
383384

385+
namespace namelookup {
386+
387+
/// Performs a qualified lookup into the given module and, if necessary, its
388+
/// reexports, observing proper shadowing rules.
389+
void
390+
lookupVisibleDeclsInModule(ModuleDecl *M, ModuleDecl::AccessPathTy accessPath,
391+
SmallVectorImpl<ValueDecl *> &decls,
392+
NLKind lookupKind,
393+
ResolutionKind resolutionKind,
394+
LazyResolver *typeResolver,
395+
const DeclContext *moduleScopeContext,
396+
ArrayRef<ModuleDecl::ImportedModule> extraImports = {});
397+
398+
/// Searches through statements and patterns for local variable declarations.
399+
class FindLocalVal : public StmtVisitor<FindLocalVal> {
400+
friend class ASTVisitor<FindLocalVal>;
401+
402+
const SourceManager &SM;
403+
SourceLoc Loc;
404+
VisibleDeclConsumer &Consumer;
405+
406+
public:
407+
FindLocalVal(const SourceManager &SM, SourceLoc Loc,
408+
VisibleDeclConsumer &Consumer)
409+
: SM(SM), Loc(Loc), Consumer(Consumer) {}
410+
411+
void checkValueDecl(ValueDecl *D, DeclVisibilityKind Reason) {
412+
Consumer.foundDecl(D, Reason);
413+
}
414+
415+
void checkPattern(const Pattern *Pat, DeclVisibilityKind Reason);
416+
417+
void checkParameterList(const ParameterList *params);
418+
419+
void checkGenericParams(GenericParamList *Params);
420+
421+
void checkSourceFile(const SourceFile &SF);
422+
423+
private:
424+
bool isReferencePointInRange(SourceRange R) {
425+
return SM.rangeContainsTokenLoc(R, Loc);
426+
}
427+
428+
void visitBreakStmt(BreakStmt *) {}
429+
void visitContinueStmt(ContinueStmt *) {}
430+
void visitFallthroughStmt(FallthroughStmt *) {}
431+
void visitFailStmt(FailStmt *) {}
432+
void visitReturnStmt(ReturnStmt *) {}
433+
void visitYieldStmt(YieldStmt *) {}
434+
void visitThrowStmt(ThrowStmt *) {}
435+
void visitPoundAssertStmt(PoundAssertStmt *) {}
436+
void visitDeferStmt(DeferStmt *DS) {
437+
// Nothing in the defer is visible.
438+
}
439+
440+
void checkStmtCondition(const StmtCondition &Cond);
441+
442+
void visitIfStmt(IfStmt *S);
443+
void visitGuardStmt(GuardStmt *S);
444+
445+
void visitWhileStmt(WhileStmt *S);
446+
void visitRepeatWhileStmt(RepeatWhileStmt *S);
447+
void visitDoStmt(DoStmt *S);
448+
449+
void visitForEachStmt(ForEachStmt *S);
450+
451+
void visitBraceStmt(BraceStmt *S, bool isTopLevelCode = false);
452+
453+
void visitSwitchStmt(SwitchStmt *S);
454+
455+
void visitCaseStmt(CaseStmt *S);
456+
457+
void visitDoCatchStmt(DoCatchStmt *S);
458+
void visitCatchClauses(ArrayRef<CatchStmt*> clauses);
459+
void visitCatchStmt(CatchStmt *S);
460+
461+
};
462+
463+
} // end namespace namelookup
384464
} // end namespace swift
385465

386466
#endif

include/swift/ClangImporter/ClangModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class ClangModuleUnit final : public LoadedFile {
5454
bool isTopLevel() const;
5555

5656
/// Returns the Swift module that overlays this Clang module.
57-
ModuleDecl *getAdapterModule() const;
57+
ModuleDecl *getAdapterModule() const override;
5858

5959
/// Retrieve the "exported" name of the module, which is usually the module
6060
/// name, but might be the name of the public module through which this

lib/AST/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ add_swift_host_library(swiftAST STATIC
3737
Identifier.cpp
3838
InlinableText.cpp
3939
LayoutConstraint.cpp
40-
LookupVisibleDecls.cpp
4140
Module.cpp
4241
ModuleLoader.cpp
4342
ModuleNameLookup.cpp

lib/AST/ModuleNameLookup.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#include "NameLookupImpl.h"
1413
#include "swift/AST/NameLookup.h"
1514
#include "swift/AST/ASTContext.h"
1615
#include "swift/AST/LazyResolver.h"

lib/AST/NameLookup.cpp

Lines changed: 194 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
#include "NameLookupImpl.h"
1817
#include "swift/AST/NameLookup.h"
1918
#include "swift/AST/ASTContext.h"
2019
#include "swift/AST/ASTScope.h"
@@ -25,6 +24,7 @@
2524
#include "swift/AST/LazyResolver.h"
2625
#include "swift/AST/Initializer.h"
2726
#include "swift/AST/NameLookupRequests.h"
27+
#include "swift/AST/ParameterList.h"
2828
#include "swift/AST/ReferencedNameTracker.h"
2929
#include "swift/Basic/SourceManager.h"
3030
#include "swift/Basic/Statistic.h"
@@ -37,6 +37,11 @@
3737
#define DEBUG_TYPE "namelookup"
3838

3939
using namespace swift;
40+
using namespace swift::namelookup;
41+
42+
void VisibleDeclConsumer::anchor() {}
43+
void VectorDeclConsumer::anchor() {}
44+
void NamedDeclConsumer::anchor() {}
4045

4146
ValueDecl *LookupResultEntry::getBaseDecl() const {
4247
if (BaseDC == nullptr)
@@ -2690,3 +2695,191 @@ swift::getDirectlyInheritedNominalTypeDecls(
26902695

26912696
return result;
26922697
}
2698+
2699+
void FindLocalVal::checkPattern(const Pattern *Pat, DeclVisibilityKind Reason) {
2700+
switch (Pat->getKind()) {
2701+
case PatternKind::Tuple:
2702+
for (auto &field : cast<TuplePattern>(Pat)->getElements())
2703+
checkPattern(field.getPattern(), Reason);
2704+
return;
2705+
case PatternKind::Paren:
2706+
case PatternKind::Typed:
2707+
case PatternKind::Var:
2708+
return checkPattern(Pat->getSemanticsProvidingPattern(), Reason);
2709+
case PatternKind::Named:
2710+
return checkValueDecl(cast<NamedPattern>(Pat)->getDecl(), Reason);
2711+
case PatternKind::EnumElement: {
2712+
auto *OP = cast<EnumElementPattern>(Pat);
2713+
if (OP->hasSubPattern())
2714+
checkPattern(OP->getSubPattern(), Reason);
2715+
return;
2716+
}
2717+
case PatternKind::OptionalSome:
2718+
checkPattern(cast<OptionalSomePattern>(Pat)->getSubPattern(), Reason);
2719+
return;
2720+
2721+
case PatternKind::Is: {
2722+
auto *isPat = cast<IsPattern>(Pat);
2723+
if (isPat->hasSubPattern())
2724+
checkPattern(isPat->getSubPattern(), Reason);
2725+
return;
2726+
}
2727+
2728+
// Handle non-vars.
2729+
case PatternKind::Bool:
2730+
case PatternKind::Expr:
2731+
case PatternKind::Any:
2732+
return;
2733+
}
2734+
}
2735+
2736+
void FindLocalVal::checkParameterList(const ParameterList *params) {
2737+
for (auto param : *params) {
2738+
checkValueDecl(param, DeclVisibilityKind::FunctionParameter);
2739+
}
2740+
}
2741+
2742+
void FindLocalVal::checkGenericParams(GenericParamList *Params) {
2743+
if (!Params)
2744+
return;
2745+
2746+
for (auto P : *Params)
2747+
checkValueDecl(P, DeclVisibilityKind::GenericParameter);
2748+
}
2749+
2750+
void FindLocalVal::checkSourceFile(const SourceFile &SF) {
2751+
for (Decl *D : SF.Decls)
2752+
if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
2753+
visitBraceStmt(TLCD->getBody(), /*isTopLevel=*/true);
2754+
}
2755+
2756+
void FindLocalVal::checkStmtCondition(const StmtCondition &Cond) {
2757+
SourceLoc start = SourceLoc();
2758+
for (auto entry : Cond) {
2759+
if (start.isInvalid())
2760+
start = entry.getStartLoc();
2761+
if (auto *P = entry.getPatternOrNull()) {
2762+
SourceRange previousConditionsToHere = SourceRange(start, entry.getEndLoc());
2763+
if (!isReferencePointInRange(previousConditionsToHere))
2764+
checkPattern(P, DeclVisibilityKind::LocalVariable);
2765+
}
2766+
}
2767+
}
2768+
2769+
void FindLocalVal::visitIfStmt(IfStmt *S) {
2770+
if (!isReferencePointInRange(S->getSourceRange()))
2771+
return;
2772+
2773+
if (!S->getElseStmt() ||
2774+
!isReferencePointInRange(S->getElseStmt()->getSourceRange())) {
2775+
checkStmtCondition(S->getCond());
2776+
}
2777+
2778+
visit(S->getThenStmt());
2779+
if (S->getElseStmt())
2780+
visit(S->getElseStmt());
2781+
}
2782+
2783+
void FindLocalVal::visitGuardStmt(GuardStmt *S) {
2784+
if (SM.isBeforeInBuffer(Loc, S->getStartLoc()))
2785+
return;
2786+
2787+
// Names in the guard aren't visible until after the body.
2788+
if (!isReferencePointInRange(S->getBody()->getSourceRange()))
2789+
checkStmtCondition(S->getCond());
2790+
2791+
visit(S->getBody());
2792+
}
2793+
2794+
void FindLocalVal::visitWhileStmt(WhileStmt *S) {
2795+
if (!isReferencePointInRange(S->getSourceRange()))
2796+
return;
2797+
2798+
checkStmtCondition(S->getCond());
2799+
visit(S->getBody());
2800+
}
2801+
void FindLocalVal::visitRepeatWhileStmt(RepeatWhileStmt *S) {
2802+
visit(S->getBody());
2803+
}
2804+
void FindLocalVal::visitDoStmt(DoStmt *S) {
2805+
visit(S->getBody());
2806+
}
2807+
2808+
void FindLocalVal::visitForEachStmt(ForEachStmt *S) {
2809+
if (!isReferencePointInRange(S->getSourceRange()))
2810+
return;
2811+
visit(S->getBody());
2812+
if (!isReferencePointInRange(S->getSequence()->getSourceRange()))
2813+
checkPattern(S->getPattern(), DeclVisibilityKind::LocalVariable);
2814+
}
2815+
2816+
void FindLocalVal::visitBraceStmt(BraceStmt *S, bool isTopLevelCode) {
2817+
if (isTopLevelCode) {
2818+
if (SM.isBeforeInBuffer(Loc, S->getStartLoc()))
2819+
return;
2820+
} else {
2821+
if (!isReferencePointInRange(S->getSourceRange()))
2822+
return;
2823+
}
2824+
2825+
for (auto elem : S->getElements()) {
2826+
if (auto *S = elem.dyn_cast<Stmt*>())
2827+
visit(S);
2828+
}
2829+
for (auto elem : S->getElements()) {
2830+
if (auto *D = elem.dyn_cast<Decl*>()) {
2831+
if (auto *VD = dyn_cast<ValueDecl>(D))
2832+
checkValueDecl(VD, DeclVisibilityKind::LocalVariable);
2833+
}
2834+
}
2835+
}
2836+
2837+
void FindLocalVal::visitSwitchStmt(SwitchStmt *S) {
2838+
if (!isReferencePointInRange(S->getSourceRange()))
2839+
return;
2840+
for (CaseStmt *C : S->getCases()) {
2841+
visit(C);
2842+
}
2843+
}
2844+
2845+
void FindLocalVal::visitCaseStmt(CaseStmt *S) {
2846+
if (!isReferencePointInRange(S->getSourceRange()))
2847+
return;
2848+
// Pattern names aren't visible in the patterns themselves,
2849+
// just in the body or in where guards.
2850+
bool inPatterns = isReferencePointInRange(S->getLabelItemsRange());
2851+
auto items = S->getCaseLabelItems();
2852+
if (inPatterns) {
2853+
for (const auto &CLI : items) {
2854+
auto guard = CLI.getGuardExpr();
2855+
if (guard && isReferencePointInRange(guard->getSourceRange())) {
2856+
checkPattern(CLI.getPattern(), DeclVisibilityKind::LocalVariable);
2857+
break;
2858+
}
2859+
}
2860+
}
2861+
if (!inPatterns && !items.empty())
2862+
checkPattern(items[0].getPattern(), DeclVisibilityKind::LocalVariable);
2863+
visit(S->getBody());
2864+
}
2865+
2866+
void FindLocalVal::visitDoCatchStmt(DoCatchStmt *S) {
2867+
if (!isReferencePointInRange(S->getSourceRange()))
2868+
return;
2869+
visit(S->getBody());
2870+
visitCatchClauses(S->getCatches());
2871+
}
2872+
void FindLocalVal::visitCatchClauses(ArrayRef<CatchStmt*> clauses) {
2873+
// TODO: some sort of binary search?
2874+
for (auto clause : clauses) {
2875+
visitCatchStmt(clause);
2876+
}
2877+
}
2878+
void FindLocalVal::visitCatchStmt(CatchStmt *S) {
2879+
if (!isReferencePointInRange(S->getSourceRange()))
2880+
return;
2881+
// Names in the pattern aren't visible until after the pattern.
2882+
if (!isReferencePointInRange(S->getErrorPattern()->getSourceRange()))
2883+
checkPattern(S->getErrorPattern(), DeclVisibilityKind::LocalVariable);
2884+
visit(S->getBody());
2885+
}

0 commit comments

Comments
 (0)