From 6459685874fe386db8c5ca30c388bd15e0f5a468 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 10 Apr 2026 18:16:37 -0400
Subject: [PATCH 48/48] FIXME: WIP on goto definition

---
 gcc/lsp/gcc-impl/server.cc | 11 ++++-
 gcc/lsp/gcc-impl/worker.cc | 82 ++++++++++++++++++++++++++++++++++++++
 gcc/lsp/gcc-impl/worker.h  |  4 ++
 gcc/lsp/lsp-spec.cc        | 20 ++++++++++
 gcc/lsp/lsp-spec.h         | 11 ++---
 5 files changed, 122 insertions(+), 6 deletions(-)

diff --git a/gcc/lsp/gcc-impl/server.cc b/gcc/lsp/gcc-impl/server.cc
index efdaaed377e..b32dfb4c37e 100644
--- a/gcc/lsp/gcc-impl/server.cc
+++ b/gcc/lsp/gcc-impl/server.cc
@@ -474,6 +474,12 @@ consume_client_request (json_rpc::request &&req)
 	(std::move (req));
       return;
     }
+  else if (0 == strcmp (method, "textDocument/definition"))
+    {
+      delegate_textDocument_request_to_worker<spec::DefinitionParams>
+	(std::move (req));
+      return;
+    }
   else if (0 == strcmp (method, "textDocument/documentSymbol"))
     {
       delegate_textDocument_request_to_worker<spec::DocumentSymbolParams>
@@ -753,7 +759,10 @@ lsp::gcc_impl::server::mediator::get_ServerCapabilities ()
 
   result.declarationProvider.set_optional_value
     (lsp::spec::boolean (true));
-  
+
+  result.definitionProvider.set_optional_value
+    (lsp::spec::boolean (true));
+
   result.documentHighlightProvider.set_optional_value
     (lsp::spec::boolean (true));
 
diff --git a/gcc/lsp/gcc-impl/worker.cc b/gcc/lsp/gcc-impl/worker.cc
index 97de2976966..06f2cd37865 100644
--- a/gcc/lsp/gcc-impl/worker.cc
+++ b/gcc/lsp/gcc-impl/worker.cc
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "context.h"
 #include "channels.h"
 #include "uris.h"
+#include "function.h"
 #if 0
 #include "diagnostic.h"
 #include "diagnostics/color.h"
@@ -248,6 +249,27 @@ consume_json_rpc_request (json_rpc::request &&req)
 	 unmarshal_result.take_value ());
       return;
     }
+  else if (0 == strcmp (method, "textDocument/definition"))
+    {
+      auto unmarshal_result
+	= spec::DefinitionParams::from_json (req.get_id (),
+					      *req.get_params ());
+      if (unmarshal_result.get_error ())
+	{
+	  gcc_unreachable (); // FIXME
+#if 0
+	  send_response_to_client
+	    (json_rpc::response::invalid_params (req,
+						 std::move (unmarshal_result)));
+#endif
+	  return;
+	}
+
+      on_request_textDocument_definition
+	(req.take_id (),
+	 unmarshal_result.take_value ());
+      return;
+    }
   else if (0 == strcmp (method, "textDocument/documentSymbol"))
     {
       auto unmarshal_result
@@ -443,6 +465,66 @@ on_request_textDocument_declaration (std::unique_ptr<json::value> req_id,
 				  json::make_null ()));
 }
 
+static location_t
+get_location_of_definition (tree decl)
+{
+  switch (TREE_CODE (decl))
+    {
+    default:
+      // FIXME: this is getting at the decl, not the defn
+      return DECL_SOURCE_LOCATION (decl);
+    case FUNCTION_DECL:
+      {
+	function *fn = DECL_STRUCT_FUNCTION (decl);
+	return fn->function_start_locus; // FIXME
+      }
+    }
+}
+
+void
+lsp::gcc_impl::worker::mediator::
+on_request_textDocument_definition (std::unique_ptr<json::value> req_id,
+				     spec::DefinitionParams &&p)
+{
+  auto logger = get_logger ();
+  LSP_LOG_SCOPE (logger);
+
+  gcc_assert (m_frontend);
+
+  if (auto ast_node = get_ast_node_at_position (p))
+    {
+      // FIXME:
+      if (0)
+	{
+	  fprintf (stderr, "\nnode at position: \n");
+	  visit_node (*ast_node);
+	}
+      if (ast_node->m_expr)
+	{
+	  if (DECL_P (ast_node->m_expr))
+	    {
+	      location_t loc = get_location_of_definition (ast_node->m_expr);
+	      // FIXME: this is getting at the decl, not the defn
+	      auto result (lsp::spec::Location::from_location_t (loc));
+	      send_response_to_server
+		(json_rpc::response::success (std::move (req_id),
+					      result.to_json ()));
+	      return;
+	    }
+	}
+      else
+	{
+	  if (logger)
+	    logger->log ("ast node %s has no tree node", ast_node->m_kind);
+	}
+    }
+
+  if (logger)
+    logger->log ("ast node not found");
+  send_response_to_server
+    (json_rpc::response::success (std::move (req_id),
+				  json::make_null ()));
+}
 struct decl_usage_visitor
 {
   decl_usage_visitor (tree decl)
diff --git a/gcc/lsp/gcc-impl/worker.h b/gcc/lsp/gcc-impl/worker.h
index 7c7678c57af..08ce5c02641 100644
--- a/gcc/lsp/gcc-impl/worker.h
+++ b/gcc/lsp/gcc-impl/worker.h
@@ -109,6 +109,10 @@ public:
   on_request_textDocument_declaration (std::unique_ptr<json::value> req_id,
 				       spec::DeclarationParams &&p);
 
+  void
+  on_request_textDocument_definition (std::unique_ptr<json::value> req_id,
+				      spec::DefinitionParams &&p);
+
   void
   on_request_textDocument_documentHighlight (std::unique_ptr<json::value> req_id,
 					     spec::DocumentHighlightParams &&p);
diff --git a/gcc/lsp/lsp-spec.cc b/gcc/lsp/lsp-spec.cc
index 842b947ef95..3d12394e572 100644
--- a/gcc/lsp/lsp-spec.cc
+++ b/gcc/lsp/lsp-spec.cc
@@ -580,6 +580,7 @@ BEGIN_DEFINE_FROM_JSON(ServerCapabilities)
   UNMARSHAL_OPTIONAL_PROPERTY (HoverOptions, hoverProvider);
   UNMARSHAL_OPTIONAL_PROPERTY (SignatureHelpOptions, signatureHelpProvider);
   UNMARSHAL_OPTIONAL_PROPERTY (boolean, declarationProvider);
+  UNMARSHAL_OPTIONAL_PROPERTY (boolean, definitionProvider);
   UNMARSHAL_OPTIONAL_PROPERTY (boolean, documentHighlightProvider);
   UNMARSHAL_OPTIONAL_PROPERTY (boolean, documentSymbolProvider);
   UNMARSHAL_OPTIONAL_PROPERTY (boolean, codeActionProvider);
@@ -594,6 +595,7 @@ BEGIN_DEFINE_TO_JSON(ServerCapabilities)
   MARSHAL_OPTIONAL_PROPERTY (HoverOptions, hoverProvider);
   MARSHAL_OPTIONAL_PROPERTY (SignatureHelpOptions, signatureHelpProvider);
   MARSHAL_OPTIONAL_PROPERTY (boolean, declarationProvider);
+  MARSHAL_OPTIONAL_PROPERTY (boolean, definitionProvider);
   MARSHAL_OPTIONAL_PROPERTY (boolean, documentHighlightProvider);
   MARSHAL_OPTIONAL_PROPERTY (boolean, documentSymbolProvider);
   MARSHAL_OPTIONAL_PROPERTY (boolean, codeActionProvider);
@@ -1088,6 +1090,24 @@ BEGIN_DEFINE_TO_JSON(DeclarationParams)
 }
 END_DEFINE_TO_JSON
 
+// struct DefinitionParams : public TextDocumentPositionParams
+
+BEGIN_DEFINE_FROM_JSON(DefinitionParams)
+{
+  // FIXME: chain up to parent
+  UNMARSHAL_REQUIRED_PROPERTY (TextDocumentIdentifier, textDocument);
+  UNMARSHAL_REQUIRED_PROPERTY (Position, position);
+}
+END_DEFINE_FROM_JSON
+
+BEGIN_DEFINE_TO_JSON(DefinitionParams)
+{
+  // FIXME: chain up to parent
+  MARSHAL_REQUIRED_PROPERTY (TextDocumentIdentifier, textDocument);
+  MARSHAL_REQUIRED_PROPERTY (Position, position);
+}
+END_DEFINE_TO_JSON
+
 // struct DocumentSymbolParams
 
 BEGIN_DEFINE_FROM_JSON(DocumentSymbolParams)
diff --git a/gcc/lsp/lsp-spec.h b/gcc/lsp/lsp-spec.h
index 55cfdcb03c7..02fbaa86ee4 100644
--- a/gcc/lsp/lsp-spec.h
+++ b/gcc/lsp/lsp-spec.h
@@ -482,13 +482,9 @@ struct ServerCapabilities
   optional<HoverOptions> hoverProvider;
   optional<SignatureHelpOptions> signatureHelpProvider;
   optional<boolean> declarationProvider;
+  optional<boolean> definitionProvider;
 
 #if 0
-	/**
-	 * The server provides goto definition support.
-	 */
-	definitionProvider?: boolean | DefinitionOptions;
-
 	/**
 	 * The server provides goto type definition support.
 	 *
@@ -901,6 +897,11 @@ struct DeclarationParams : public TextDocumentPositionParams
   DECLARE_JSON_METHODS(DeclarationParams)
 };
 
+struct DefinitionParams : public TextDocumentPositionParams
+{
+  DECLARE_JSON_METHODS(DefinitionParams)
+};
+
 struct DocumentSymbolParams // FIXME
 {
   DECLARE_JSON_METHODS(DocumentSymbolParams)
-- 
2.49.0

