xref: /llvm-project/mlir/lib/Debug/BreakpointManagers/FileLineColLocBreakpointManager.cpp (revision 7f069f5ef4fee00520ed0c350dca42c3c4b72b61)
1*7f069f5eSMehdi Amini //===- FileLineColLocBreakpointManager.cpp - MLIR Optimizer Driver --------===//
2*7f069f5eSMehdi Amini //
3*7f069f5eSMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*7f069f5eSMehdi Amini // See https://llvm.org/LICENSE.txt for license information.
5*7f069f5eSMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*7f069f5eSMehdi Amini //
7*7f069f5eSMehdi Amini //===----------------------------------------------------------------------===//
8*7f069f5eSMehdi Amini 
9*7f069f5eSMehdi Amini #include "mlir/Debug/BreakpointManagers/FileLineColLocBreakpointManager.h"
10*7f069f5eSMehdi Amini #include "mlir/IR/Diagnostics.h"
11*7f069f5eSMehdi Amini #include "llvm/Support/raw_ostream.h"
12*7f069f5eSMehdi Amini 
13*7f069f5eSMehdi Amini using namespace mlir;
14*7f069f5eSMehdi Amini using namespace mlir::tracing;
15*7f069f5eSMehdi Amini 
16*7f069f5eSMehdi Amini FailureOr<std::tuple<StringRef, int64_t, int64_t>>
parseFromString(StringRef str,function_ref<void (Twine)> diag)17*7f069f5eSMehdi Amini FileLineColLocBreakpoint::parseFromString(StringRef str,
18*7f069f5eSMehdi Amini                                           function_ref<void(Twine)> diag) {
19*7f069f5eSMehdi Amini   // Watch at debug locations arguments are expected to be in the form:
20*7f069f5eSMehdi Amini   // `fileName:line:col`, `fileName:line`, or `fileName`.
21*7f069f5eSMehdi Amini 
22*7f069f5eSMehdi Amini   if (str.empty()) {
23*7f069f5eSMehdi Amini     if (diag)
24*7f069f5eSMehdi Amini       diag("error: initializing FileLineColLocBreakpoint with empty file name");
25*7f069f5eSMehdi Amini     return failure();
26*7f069f5eSMehdi Amini   }
27*7f069f5eSMehdi Amini 
28*7f069f5eSMehdi Amini   // This logic is complex because on Windows `:` is a comment valid path
29*7f069f5eSMehdi Amini   // character: `C:\...`.
30*7f069f5eSMehdi Amini   auto [fileLine, colStr] = str.rsplit(':');
31*7f069f5eSMehdi Amini   auto [file, lineStr] = fileLine.rsplit(':');
32*7f069f5eSMehdi Amini   // Extract the line and column value
33*7f069f5eSMehdi Amini   int64_t line = -1, col = -1;
34*7f069f5eSMehdi Amini   if (lineStr.empty()) {
35*7f069f5eSMehdi Amini     // No candidate for line number, try to use the column string as line
36*7f069f5eSMehdi Amini     // instead.
37*7f069f5eSMehdi Amini     file = fileLine;
38*7f069f5eSMehdi Amini     if (!colStr.empty() && colStr.getAsInteger(0, line))
39*7f069f5eSMehdi Amini       file = str;
40*7f069f5eSMehdi Amini   } else {
41*7f069f5eSMehdi Amini     if (lineStr.getAsInteger(0, line)) {
42*7f069f5eSMehdi Amini       // Failed to parse a line number, try to use the column string as line
43*7f069f5eSMehdi Amini       // instead. If this failed as well, the entire string is the file name.
44*7f069f5eSMehdi Amini       file = fileLine;
45*7f069f5eSMehdi Amini       if (colStr.getAsInteger(0, line))
46*7f069f5eSMehdi Amini         file = str;
47*7f069f5eSMehdi Amini     } else {
48*7f069f5eSMehdi Amini       // We successfully parsed a line number, try to parse the column number.
49*7f069f5eSMehdi Amini       // This shouldn't fail, or the entire string is the file name.
50*7f069f5eSMehdi Amini       if (colStr.getAsInteger(0, col)) {
51*7f069f5eSMehdi Amini         file = str;
52*7f069f5eSMehdi Amini         line = -1;
53*7f069f5eSMehdi Amini       }
54*7f069f5eSMehdi Amini     }
55*7f069f5eSMehdi Amini   }
56*7f069f5eSMehdi Amini   return std::tuple<StringRef, int64_t, int64_t>{file, line, col};
57*7f069f5eSMehdi Amini }
58