[Mlir-commits] [mlir] 0573ec9 - [mlir][lsp] Handle unrepresentable file locations (#220913)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Sep 10 01:22:35 PDT 2026
Author: Mehdi Amini
Date: 2026-09-10T10:22:30+02:00
New Revision: 0573ec95004aad9970129dce97d3d3ef34aba978
URL: https://github.com/llvm/llvm-project/commit/0573ec95004aad9970129dce97d3d3ef34aba978
DIFF: https://github.com/llvm/llvm-project/commit/0573ec95004aad9970129dce97d3d3ef34aba978.diff
LOG: [mlir][lsp] Handle unrepresentable file locations (#220913)
Added:
Modified:
mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
mlir/test/mlir-lsp-server/definition.test
mlir/test/mlir-lsp-server/diagnostics.test
Removed:
################################################################################
diff --git a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
index fd0d1fc1df039..f5ab91ce6f9a8 100644
--- a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
+++ b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/LSP/Logging.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
+#include <limits>
#include <optional>
using namespace mlir;
@@ -34,6 +35,17 @@ static SMRange convertTokenLocToRange(SMLoc loc) {
return lsp::convertTokenLocToRange(loc, "$-.");
}
+/// Convert an MLIR one-based file position to a zero-based LSP position. A
+/// zero position represents an unknown coordinate and maps to zero.
+static std::optional<int> convertFileLocPosition(unsigned value) {
+ if (value == 0)
+ return 0;
+ --value;
+ if (value > static_cast<unsigned>(std::numeric_limits<int>::max()))
+ return std::nullopt;
+ return static_cast<int>(value);
+}
+
/// Returns a language server location from the given MLIR file location.
/// `uriScheme` is the scheme to use when building new uris.
static std::optional<lsp::Location>
@@ -61,9 +73,14 @@ getLocationFromLoc(StringRef uriScheme, FileLineColLoc loc,
return std::nullopt;
}
+ std::optional<int> line = convertFileLocPosition(loc.getLine());
+ std::optional<int> character = convertFileLocPosition(loc.getColumn());
+ if (!line || !character)
+ return std::nullopt;
+
lsp::Position position;
- position.line = loc.getLine() - 1;
- position.character = loc.getColumn() ? loc.getColumn() - 1 : 0;
+ position.line = *line;
+ position.character = *character;
return lsp::Location{*sourceURI, lsp::Range(position)};
}
@@ -90,11 +107,15 @@ getLocationFromLoc(llvm::SourceMgr &sourceMgr, Location loc,
// Use range of potential identifier starting at location, else length 1
// range.
- location->range.end.character += 1;
- if (std::optional<SMRange> range = convertTokenLocToRange(loc)) {
- auto lineCol = sourceMgr.getLineAndColumn(range->End);
- location->range.end.character =
- std::max(fileLoc.getColumn() + 1, lineCol.second - 1);
+ if (location->range.end.character < std::numeric_limits<int>::max())
+ ++location->range.end.character;
+ if (loc.isValid()) {
+ SMRange range = convertTokenLocToRange(loc);
+ auto lineCol = sourceMgr.getLineAndColumn(range.End);
+ uint64_t endCharacter = std::max<uint64_t>(
+ static_cast<uint64_t>(fileLoc.getColumn()) + 1, lineCol.second - 1);
+ location->range.end.character = static_cast<int>(
+ std::min<uint64_t>(endCharacter, std::numeric_limits<int>::max()));
}
return WalkResult::interrupt();
}
diff --git a/mlir/test/mlir-lsp-server/definition.test b/mlir/test/mlir-lsp-server/definition.test
index 99f7c2b2c3953..d5e23299a511f 100644
--- a/mlir/test/mlir-lsp-server/definition.test
+++ b/mlir/test/mlir-lsp-server/definition.test
@@ -113,6 +113,95 @@
// CHECK-NEXT: "uri": "{{.*}}/foo.mlir"
// CHECK-NEXT: }
// -----
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{
+ "uri":"test:///locations.mlir",
+ "languageId":"mlir",
+ "version":1,
+ "text":"func.func @locations() {\n%valid = arith.constant true loc(\"bar.mlir\":2:3)\n%zero = arith.constant true loc(\"bar.mlir\":0:0)\n%max = arith.constant true loc(\"bar.mlir\":2147483648:2147483648)\n%bad_column = arith.constant true loc(\"bar.mlir\":1:4294967295)\n%bad_line = arith.constant true loc(\"bar.mlir\":4294967295:1)\nreturn\n}"
+}}}
+// -----
+{"jsonrpc":"2.0","id":4,"method":"textDocument/definition","params":{
+ "textDocument":{"uri":"test:///locations.mlir"},
+ "position":{"line":1,"character":10}
+}}
+// CHECK: "id": 4
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 2,
+// CHECK-NEXT: "line": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 2,
+// CHECK-NEXT: "line": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/bar.mlir"
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// -----
+{"jsonrpc":"2.0","id":5,"method":"textDocument/definition","params":{
+ "textDocument":{"uri":"test:///locations.mlir"},
+ "position":{"line":2,"character":10}
+}}
+// CHECK: "id": 5
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 0,
+// CHECK-NEXT: "line": 0
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 0,
+// CHECK-NEXT: "line": 0
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/bar.mlir"
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// -----
+{"jsonrpc":"2.0","id":6,"method":"textDocument/definition","params":{
+ "textDocument":{"uri":"test:///locations.mlir"},
+ "position":{"line":3,"character":10}
+}}
+// CHECK: "id": 6
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 2147483647,
+// CHECK-NEXT: "line": 2147483647
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 2147483647,
+// CHECK-NEXT: "line": 2147483647
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "uri": "{{.*}}/bar.mlir"
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// -----
+{"jsonrpc":"2.0","id":7,"method":"textDocument/definition","params":{
+ "textDocument":{"uri":"test:///locations.mlir"},
+ "position":{"line":4,"character":20}
+}}
+// CHECK: "id": 7
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": []
+// -----
+{"jsonrpc":"2.0","id":8,"method":"textDocument/definition","params":{
+ "textDocument":{"uri":"test:///locations.mlir"},
+ "position":{"line":5,"character":20}
+}}
+// CHECK: "id": 8
+// CHECK-NEXT: "jsonrpc": "2.0",
+// CHECK-NEXT: "result": []
+// -----
{"jsonrpc":"2.0","id":3,"method":"shutdown"}
// -----
{"jsonrpc":"2.0","method":"exit"}
diff --git a/mlir/test/mlir-lsp-server/diagnostics.test b/mlir/test/mlir-lsp-server/diagnostics.test
index 25c57ba531f3b..45f0b9eb19c1b 100644
--- a/mlir/test/mlir-lsp-server/diagnostics.test
+++ b/mlir/test/mlir-lsp-server/diagnostics.test
@@ -61,6 +61,26 @@
// CHECK-NEXT: "version": 1
// CHECK-NEXT: }
// -----
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{
+ "uri":"test:///foo.mlir",
+ "languageId":"mlir",
+ "version":2,
+ "text":"func.func @foo() -> i32 { return loc(\"foo.mlir\":1:2147483648) }"
+}}}
+// CHECK: "message": "'func.return' op has 0 operands, but enclosing function (@foo) returns 1",
+// CHECK: "relatedInformation": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "location": {
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "character": 2147483647,
+// CHECK-NEXT: "line": 0
+// CHECK-NEXT: },
+// CHECK-NEXT: "start": {
+// CHECK-NEXT: "character": 2147483647,
+// CHECK-NEXT: "line": 0
+// CHECK: "version": 2
+// -----
{"jsonrpc":"2.0","id":3,"method":"shutdown"}
// -----
{"jsonrpc":"2.0","method":"exit"}
More information about the Mlir-commits
mailing list