mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Add -debug-constraints-on-line flag
This commit is contained in:
@@ -166,6 +166,10 @@ namespace swift {
|
||||
/// solver should be debugged.
|
||||
unsigned DebugConstraintSolverAttempt = 0;
|
||||
|
||||
/// Line numbers to activate the constraint solver debugger.
|
||||
/// Should be stored sorted.
|
||||
llvm::SmallVector<unsigned, 4> DebugConstraintSolverOnLines;
|
||||
|
||||
/// Enable named lazy member loading.
|
||||
bool NamedLazyMemberLoading = true;
|
||||
|
||||
|
||||
@@ -189,6 +189,12 @@ def debug_constraints : Flag<["-"], "debug-constraints">,
|
||||
def debug_constraints_attempt : Separate<["-"], "debug-constraints-attempt">,
|
||||
HelpText<"Debug the constraint solver at a given attempt">;
|
||||
|
||||
def debug_constraints_on_line : Separate<["-"], "debug-constraints-on-line">,
|
||||
HelpText<"Debug the constraint solver for expressions on <line>">,
|
||||
MetaVarName<"<line>">;
|
||||
def debug_constraints_on_line_EQ : Joined<["-"], "debug-constraints-on-line=">,
|
||||
Alias<debug_constraints_on_line>;
|
||||
|
||||
def disable_named_lazy_member_loading : Flag<["-"], "disable-named-lazy-member-loading">,
|
||||
HelpText<"Disable per-name lazy member loading">;
|
||||
|
||||
|
||||
@@ -339,6 +339,17 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
||||
|
||||
Opts.DebugConstraintSolverAttempt = attempt;
|
||||
}
|
||||
|
||||
for (const Arg *A : Args.filtered(OPT_debug_constraints_on_line)) {
|
||||
unsigned line;
|
||||
if (StringRef(A->getValue()).getAsInteger(10, line)) {
|
||||
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
|
||||
A->getAsString(Args), A->getValue());
|
||||
return true;
|
||||
}
|
||||
Opts.DebugConstraintSolverOnLines.push_back(line);
|
||||
}
|
||||
llvm::sort(Opts.DebugConstraintSolverOnLines);
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_debug_forbid_typecheck_prefix)) {
|
||||
Opts.DebugForbidTypecheckPrefix = A->getValue();
|
||||
|
||||
@@ -1020,11 +1020,48 @@ void ConstraintSystem::shrink(Expr *expr) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool debugConstraintSolverForExpr(ASTContext &C, Expr *expr) {
|
||||
if (C.LangOpts.DebugConstraintSolver)
|
||||
return true;
|
||||
|
||||
if (C.LangOpts.DebugConstraintSolverOnLines.empty())
|
||||
// No need to compute the line number to find out it's not present.
|
||||
return false;
|
||||
|
||||
// Get the lines on which the expression starts and ends.
|
||||
unsigned startLine = 0, endLine = 0;
|
||||
if (expr->getSourceRange().isValid()) {
|
||||
auto range =
|
||||
Lexer::getCharSourceRangeFromSourceRange(C.SourceMgr,
|
||||
expr->getSourceRange());
|
||||
startLine = C.SourceMgr.getLineNumber(range.getStart());
|
||||
endLine = C.SourceMgr.getLineNumber(range.getEnd());
|
||||
}
|
||||
|
||||
assert(startLine <= endLine && "expr ends before it starts?");
|
||||
|
||||
auto &lines = C.LangOpts.DebugConstraintSolverOnLines;
|
||||
assert(std::is_sorted(lines.begin(), lines.end()) &&
|
||||
"DebugConstraintSolverOnLines sorting invariant violated");
|
||||
|
||||
// Check if `lines` contains at least one line `L` where
|
||||
// `startLine <= L <= endLine`. If it does, `lower_bound(startLine)` and
|
||||
// `upper_bound(endLine)` will be different.
|
||||
auto startBound = llvm::lower_bound(lines, startLine);
|
||||
auto endBound = std::upper_bound(startBound, lines.end(), endLine);
|
||||
|
||||
return startBound != endBound;
|
||||
}
|
||||
|
||||
bool ConstraintSystem::solve(Expr *&expr,
|
||||
Type convertType,
|
||||
ExprTypeCheckListener *listener,
|
||||
SmallVectorImpl<Solution> &solutions,
|
||||
FreeTypeVariableBinding allowFreeTypeVariables) {
|
||||
llvm::SaveAndRestore<bool>
|
||||
debugForExpr(TC.getLangOpts().DebugConstraintSolver,
|
||||
debugConstraintSolverForExpr(TC.Context, expr));
|
||||
|
||||
// Attempt to solve the constraint system.
|
||||
auto solution = solveImpl(expr,
|
||||
convertType,
|
||||
|
||||
Reference in New Issue
Block a user