|
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 "llvm/ADT/MapVector.h"
|
29 | 30 | #include "llvm/ADT/StringSwitch.h"
|
30 | 31 | #include "llvm/Support/SaveAndRestore.h"
|
| 32 | + |
| 33 | +#define DEBUG_TYPE "Sema" |
31 | 34 | using namespace swift;
|
32 | 35 |
|
33 | 36 | /// Return true if this expression is an implicit promotion from T to T?.
|
@@ -2045,6 +2048,10 @@ class VarDeclUsageChecker : public ASTWalker {
|
2045 | 2048 | /// This is a mapping from VarDecls to the if/while/guard statement that they
|
2046 | 2049 | /// occur in, when they are in a pattern in a StmtCondition.
|
2047 | 2050 | llvm::SmallDenseMap<VarDecl*, LabeledConditionalStmt*> StmtConditionForVD;
|
| 2051 | + |
| 2052 | +#ifndef NDEBUG |
| 2053 | + llvm::SmallPtrSet<Expr*, 32> AllExprsSeen; |
| 2054 | +#endif |
2048 | 2055 |
|
2049 | 2056 | bool sawError = false;
|
2050 | 2057 |
|
@@ -2788,13 +2795,19 @@ void VarDeclUsageChecker::markStoredOrInOutExpr(Expr *E, unsigned Flags) {
|
2788 | 2795 |
|
2789 | 2796 | /// The heavy lifting happens when visiting expressions.
|
2790 | 2797 | std::pair<bool, Expr *> VarDeclUsageChecker::walkToExprPre(Expr *E) {
|
| 2798 | + STATISTIC(VarDeclUsageCheckerExprVisits, |
| 2799 | + "# of times VarDeclUsageChecker::walkToExprPre is called"); |
| 2800 | + ++VarDeclUsageCheckerExprVisits; |
| 2801 | + |
2791 | 2802 | // Sema leaves some subexpressions null, which seems really unfortunate. It
|
2792 | 2803 | // should replace them with ErrorExpr.
|
2793 | 2804 | if (E == nullptr || !E->getType() || E->getType()->hasError()) {
|
2794 | 2805 | sawError = true;
|
2795 | 2806 | return { false, E };
|
2796 | 2807 | }
|
2797 | 2808 |
|
| 2809 | + assert(AllExprsSeen.insert(E).second && "duplicate traversal"); |
| 2810 | + |
2798 | 2811 | // If this is a DeclRefExpr found in a random place, it is a load of the
|
2799 | 2812 | // vardecl.
|
2800 | 2813 | if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
|
@@ -2839,9 +2852,13 @@ std::pair<bool, Expr *> VarDeclUsageChecker::walkToExprPre(Expr *E) {
|
2839 | 2852 | return { false, E };
|
2840 | 2853 | }
|
2841 | 2854 |
|
2842 |
| - // If we see an OpenExistentialExpr, remember the mapping for its OpaqueValue. |
2843 |
| - if (auto *oee = dyn_cast<OpenExistentialExpr>(E)) |
| 2855 | + // If we see an OpenExistentialExpr, remember the mapping for its OpaqueValue |
| 2856 | + // and only walk the subexpr. |
| 2857 | + if (auto *oee = dyn_cast<OpenExistentialExpr>(E)) { |
2844 | 2858 | OpaqueValueMap[oee->getOpaqueValue()] = oee->getExistentialValue();
|
| 2859 | + oee->getSubExpr()->walk(*this); |
| 2860 | + return { false, E }; |
| 2861 | + } |
2845 | 2862 |
|
2846 | 2863 | // Visit bindings.
|
2847 | 2864 | if (auto ove = dyn_cast<OpaqueValueExpr>(E)) {
|
|
0 commit comments