|
22 | 22 | #include "swift/AST/Pattern.h"
|
23 | 23 | #include "swift/Basic/Defer.h"
|
24 | 24 | #include "swift/Basic/SourceManager.h"
|
| 25 | +#include "swift/Basic/Statistic.h" |
25 | 26 | #include "swift/Basic/StringExtras.h"
|
26 | 27 | #include "swift/Parse/Lexer.h"
|
27 | 28 | #include "swift/Parse/Parser.h"
|
28 | 29 | #include "swift/Sema/IDETypeChecking.h"
|
29 | 30 | #include "llvm/ADT/MapVector.h"
|
30 | 31 | #include "llvm/ADT/StringSwitch.h"
|
31 | 32 | #include "llvm/Support/SaveAndRestore.h"
|
| 33 | + |
| 34 | +#define DEBUG_TYPE "Sema" |
32 | 35 | using namespace swift;
|
33 | 36 |
|
34 | 37 | /// Return true if this expression is an implicit promotion from T to T?.
|
@@ -1992,6 +1995,10 @@ class VarDeclUsageChecker : public ASTWalker {
|
1992 | 1995 | /// This is a mapping from VarDecls to the if/while/guard statement that they
|
1993 | 1996 | /// occur in, when they are in a pattern in a StmtCondition.
|
1994 | 1997 | llvm::SmallDenseMap<VarDecl*, LabeledConditionalStmt*> StmtConditionForVD;
|
| 1998 | + |
| 1999 | +#ifndef NDEBUG |
| 2000 | + llvm::SmallPtrSet<Expr*, 32> AllExprsSeen; |
| 2001 | +#endif |
1995 | 2002 |
|
1996 | 2003 | bool sawError = false;
|
1997 | 2004 |
|
@@ -2732,13 +2739,19 @@ void VarDeclUsageChecker::markStoredOrInOutExpr(Expr *E, unsigned Flags) {
|
2732 | 2739 |
|
2733 | 2740 | /// The heavy lifting happens when visiting expressions.
|
2734 | 2741 | std::pair<bool, Expr *> VarDeclUsageChecker::walkToExprPre(Expr *E) {
|
| 2742 | + STATISTIC(VarDeclUsageCheckerExprVisits, |
| 2743 | + "# of times VarDeclUsageChecker::walkToExprPre is called"); |
| 2744 | + ++VarDeclUsageCheckerExprVisits; |
| 2745 | + |
2735 | 2746 | // Sema leaves some subexpressions null, which seems really unfortunate. It
|
2736 | 2747 | // should replace them with ErrorExpr.
|
2737 | 2748 | if (E == nullptr || !E->getType() || E->getType()->hasError()) {
|
2738 | 2749 | sawError = true;
|
2739 | 2750 | return { false, E };
|
2740 | 2751 | }
|
2741 | 2752 |
|
| 2753 | + assert(AllExprsSeen.insert(E).second && "duplicate traversal"); |
| 2754 | + |
2742 | 2755 | // If this is a DeclRefExpr found in a random place, it is a load of the
|
2743 | 2756 | // vardecl.
|
2744 | 2757 | if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
|
@@ -2783,9 +2796,13 @@ std::pair<bool, Expr *> VarDeclUsageChecker::walkToExprPre(Expr *E) {
|
2783 | 2796 | return { false, E };
|
2784 | 2797 | }
|
2785 | 2798 |
|
2786 |
| - // If we see an OpenExistentialExpr, remember the mapping for its OpaqueValue. |
2787 |
| - if (auto *oee = dyn_cast<OpenExistentialExpr>(E)) |
| 2799 | + // If we see an OpenExistentialExpr, remember the mapping for its OpaqueValue |
| 2800 | + // and only walk the subexpr. |
| 2801 | + if (auto *oee = dyn_cast<OpenExistentialExpr>(E)) { |
2788 | 2802 | OpaqueValueMap[oee->getOpaqueValue()] = oee->getExistentialValue();
|
| 2803 | + oee->getSubExpr()->walk(*this); |
| 2804 | + return { false, E }; |
| 2805 | + } |
2789 | 2806 |
|
2790 | 2807 | // Visit bindings.
|
2791 | 2808 | if (auto ove = dyn_cast<OpaqueValueExpr>(E)) {
|
|
0 commit comments