https://github.com/cpunion created 
https://github.com/llvm/llvm-project/pull/212598

## Summary

LLDB has `eLanguageTypeGo`, but no Go language plugin or type-system 
registration. As a result, `DW_LANG_Go` compile units warn that no language 
plugin exists and otherwise valid variables are not handled normally.

This change adds a basic, runtime-independent Go language layer:

- registers `DW_LANG_Go` and `.go` source files;
- uses Clang's type system for structural DWARF types, without enabling C 
expression semantics for Go;
- identifies the official Go user entry point as `main.main`;
- formats the official Go compiler's exact `string` layout (`{str, len}`).

Official Go and LLGo are deliberately kept distinct. LLGo currently uses a C 
ABI entry point and a `{data, len}` string layout; the generic formatter does 
not match it, so it remains structurally visible for a separate LLGo runtime 
adapter.

Expression evaluation, runtime containers, and goroutine-aware views are 
follow-up work.

On Darwin, default Go binaries also need #212597 because the Go linker emits 
GNU-style compressed Mach-O DWARF. This PR works independently with ELF and 
uncompressed Mach-O DWARF.

## Testing

- `GoLanguageTests`: 2/2 on macOS and Linux arm64
- `llvm-lit lldb/test/Shell/Process/GoLanguage.test`: passed on macOS and Linux 
arm64, covering both the official Go and LLGo layouts
- Real Go 1.26.5 binaries on macOS and Linux arm64: source breakpoint, 
parameters, locals, string, array, pointer, and `--stop-at-user-entry` at 
`main.main`
- Real LLGo macOS binary: source breakpoint and structural `{data, len}` 
string, array, pointer, and local-variable inspection without applying the 
official Go formatter


>From d3fc5b25e78a7e41d606a0ca67793006bc23ec16 Mon Sep 17 00:00:00 2001
From: Li Jie <[email protected]>
Date: Tue, 28 Jul 2026 23:14:02 +0800
Subject: [PATCH 1/4] [lldb] Add basic Go language support

---
 lldb/source/Plugins/Language/CMakeLists.txt   |  1 +
 .../source/Plugins/Language/Go/CMakeLists.txt |  9 ++
 .../Language/Go/GoFormatterFunctions.cpp      | 86 +++++++++++++++++++
 .../Language/Go/GoFormatterFunctions.h        | 25 ++++++
 .../source/Plugins/Language/Go/GoLanguage.cpp | 61 +++++++++++++
 lldb/source/Plugins/Language/Go/GoLanguage.h  | 42 +++++++++
 .../TypeSystem/Clang/TypeSystemClang.cpp      | 29 ++++++-
 lldb/test/Shell/Process/GoLanguage.test       | 44 ++++++++++
 lldb/test/Shell/Process/Inputs/go-language.c  | 29 +++++++
 lldb/unittests/Language/CMakeLists.txt        |  1 +
 lldb/unittests/Language/Go/CMakeLists.txt     |  6 ++
 lldb/unittests/Language/Go/GoLanguageTest.cpp | 37 ++++++++
 12 files changed, 367 insertions(+), 3 deletions(-)
 create mode 100644 lldb/source/Plugins/Language/Go/CMakeLists.txt
 create mode 100644 lldb/source/Plugins/Language/Go/GoFormatterFunctions.cpp
 create mode 100644 lldb/source/Plugins/Language/Go/GoFormatterFunctions.h
 create mode 100644 lldb/source/Plugins/Language/Go/GoLanguage.cpp
 create mode 100644 lldb/source/Plugins/Language/Go/GoLanguage.h
 create mode 100644 lldb/test/Shell/Process/GoLanguage.test
 create mode 100644 lldb/test/Shell/Process/Inputs/go-language.c
 create mode 100644 lldb/unittests/Language/Go/CMakeLists.txt
 create mode 100644 lldb/unittests/Language/Go/GoLanguageTest.cpp

diff --git a/lldb/source/Plugins/Language/CMakeLists.txt 
b/lldb/source/Plugins/Language/CMakeLists.txt
index 6367ab916c8fb..df5627ac38e20 100644
--- a/lldb/source/Plugins/Language/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CMakeLists.txt
@@ -5,5 +5,6 @@ set_property(DIRECTORY PROPERTY 
LLDB_TOLERATED_PLUGIN_DEPENDENCIES
 )
 
 add_subdirectory(CPlusPlus)
+add_subdirectory(Go)
 add_subdirectory(ObjC)
 add_subdirectory(ObjCPlusPlus)
diff --git a/lldb/source/Plugins/Language/Go/CMakeLists.txt 
b/lldb/source/Plugins/Language/Go/CMakeLists.txt
new file mode 100644
index 0000000000000..2162fcda44cf4
--- /dev/null
+++ b/lldb/source/Plugins/Language/Go/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_lldb_library(lldbPluginGoLanguage PLUGIN
+  GoFormatterFunctions.cpp
+  GoLanguage.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbDataFormatters
+    lldbTarget
+)
diff --git a/lldb/source/Plugins/Language/Go/GoFormatterFunctions.cpp 
b/lldb/source/Plugins/Language/Go/GoFormatterFunctions.cpp
new file mode 100644
index 0000000000000..fb44e6ca4eab1
--- /dev/null
+++ b/lldb/source/Plugins/Language/Go/GoFormatterFunctions.cpp
@@ -0,0 +1,86 @@
+//===-- GoFormatterFunctions.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "GoFormatterFunctions.h"
+
+#include "lldb/Core/Address.h"
+#include "lldb/DataFormatters/StringPrinter.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/ValueObject/ValueObject.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+namespace {
+
+ValueObject *GetGoStringValue(ValueObject &valobj, ValueObjectSP &storage) {
+  if (!valobj.GetCompilerType().IsPointerType())
+    return &valobj;
+
+  Status error;
+  storage = valobj.Dereference(error);
+  if (error.Fail())
+    return nullptr;
+  return storage.get();
+}
+
+} // namespace
+
+bool lldb_private::formatters::IsGoString(ValueObject &valobj) {
+  ValueObjectSP storage;
+  ValueObject *value = GetGoStringValue(valobj, storage);
+  if (!value || value->GetCompilerType().GetTypeName() != "string")
+    return false;
+
+  return value->GetChildMemberWithName(ConstString("str"), true) &&
+         value->GetChildMemberWithName(ConstString("len"), true);
+}
+
+bool lldb_private::formatters::GoStringSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+  ValueObjectSP storage;
+  ValueObject *value = GetGoStringValue(valobj, storage);
+  if (!value)
+    return false;
+
+  ValueObjectSP data_sp =
+      value->GetChildMemberWithName(ConstString("str"), true);
+  ValueObjectSP len_sp =
+      value->GetChildMemberWithName(ConstString("len"), true);
+  if (!data_sp || !len_sp)
+    return false;
+
+  bool success = false;
+  const lldb::addr_t address = data_sp->GetValueAsUnsigned(0, &success);
+  if (!success)
+    return false;
+
+  const uint64_t length = len_sp->GetValueAsUnsigned(0, &success);
+  if (!success)
+    return false;
+  if (length == 0) {
+    stream.PutCString("\"\"");
+    return true;
+  }
+
+  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+  options.SetLocation(Address(address));
+  options.SetTargetSP(valobj.GetTargetSP());
+  options.SetStream(&stream);
+  options.SetSourceSize(length);
+  options.SetHasSourceSize(true);
+  options.SetZeroTermination(StringPrinter::ZeroTermination::Ignore);
+
+  if (!StringPrinter::ReadStringAndDumpToStream<
+          StringPrinter::StringElementType::UTF8>(options))
+    stream.PutCString("Summary Unavailable");
+  return true;
+}
diff --git a/lldb/source/Plugins/Language/Go/GoFormatterFunctions.h 
b/lldb/source/Plugins/Language/Go/GoFormatterFunctions.h
new file mode 100644
index 0000000000000..e3c73626928a7
--- /dev/null
+++ b/lldb/source/Plugins/Language/Go/GoFormatterFunctions.h
@@ -0,0 +1,25 @@
+//===-- GoFormatterFunctions.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_GO_GOFORMATTERFUNCTIONS_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_GO_GOFORMATTERFUNCTIONS_H
+
+#include "lldb/lldb-forward.h"
+
+namespace lldb_private {
+namespace formatters {
+
+bool IsGoString(ValueObject &valobj);
+
+bool GoStringSummaryProvider(ValueObject &valobj, Stream &stream,
+                             const TypeSummaryOptions &options);
+
+} // namespace formatters
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_GO_GOFORMATTERFUNCTIONS_H
diff --git a/lldb/source/Plugins/Language/Go/GoLanguage.cpp 
b/lldb/source/Plugins/Language/Go/GoLanguage.cpp
new file mode 100644
index 0000000000000..e3b78e16c7c18
--- /dev/null
+++ b/lldb/source/Plugins/Language/Go/GoLanguage.cpp
@@ -0,0 +1,61 @@
+//===-- GoLanguage.cpp 
----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "GoLanguage.h"
+
+#include "GoFormatterFunctions.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "llvm/Support/Threading.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(GoLanguage)
+
+void GoLanguage::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language",
+                                CreateInstance);
+}
+
+void GoLanguage::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+Language *GoLanguage::CreateInstance(lldb::LanguageType language) {
+  if (language == eLanguageTypeGo)
+    return new GoLanguage();
+  return nullptr;
+}
+
+HardcodedFormatters::HardcodedSummaryFinder
+GoLanguage::GetHardcodedSummaries() {
+  static llvm::once_flag g_initialize;
+  static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
+
+  llvm::call_once(g_initialize, [] {
+    g_formatters.push_back(
+        [](ValueObject &valobj, lldb::DynamicValueType,
+           FormatManager &) -> TypeSummaryImpl::SharedPointer {
+          static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
+              new CXXFunctionSummaryFormat(
+                  TypeSummaryImpl::Flags().SetDontShowChildren(true),
+                  formatters::GoStringSummaryProvider,
+                  "Go string summary provider"));
+          if (formatters::IsGoString(valobj))
+            return formatter_sp;
+          return nullptr;
+        });
+  });
+  return g_formatters;
+}
+
+bool GoLanguage::IsSourceFile(llvm::StringRef file_path) const {
+  return file_path.ends_with_insensitive(".go");
+}
diff --git a/lldb/source/Plugins/Language/Go/GoLanguage.h 
b/lldb/source/Plugins/Language/Go/GoLanguage.h
new file mode 100644
index 0000000000000..5676d6a25b432
--- /dev/null
+++ b/lldb/source/Plugins/Language/Go/GoLanguage.h
@@ -0,0 +1,42 @@
+//===-- GoLanguage.h --------------------------------------------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_GO_GOLANGUAGE_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_GO_GOLANGUAGE_H
+
+#include "lldb/Target/Language.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class GoLanguage : public Language {
+public:
+  GoLanguage() = default;
+  ~GoLanguage() override = default;
+
+  lldb::LanguageType GetLanguageType() const override {
+    return lldb::eLanguageTypeGo;
+  }
+
+  llvm::StringRef GetUserEntryPointName() const override { return "main"; }
+
+  HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override;
+
+  bool IsSourceFile(llvm::StringRef file_path) const override;
+
+  static void Initialize();
+  static void Terminate();
+  static Language *CreateInstance(lldb::LanguageType language);
+  static llvm::StringRef GetPluginNameStatic() { return "go"; }
+
+  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_GO_GOLANGUAGE_H
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp 
b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index b7646e783364e..3453d9091d879 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -115,6 +115,9 @@ TypeSystemClangSupportsLanguage(lldb::LanguageType 
language) {
          lldb_private::Language::LanguageIsCPlusPlus(language) ||
          lldb_private::Language::LanguageIsObjC(language) ||
          lldb_private::Language::LanguageIsPascal(language) ||
+         // Use Clang to represent Go DWARF types until there is a dedicated
+         // Go type system.
+         language == eLanguageTypeGo ||
          // Use Clang for Rust until there is a proper language plugin for it
          language == eLanguageTypeRust ||
          // Use Clang for D until there is a proper language plugin for it
@@ -123,6 +126,15 @@ TypeSystemClangSupportsLanguage(lldb::LanguageType 
language) {
          language == eLanguageTypeDylan;
 }
 
+class GoTypeSystemClang final : public TypeSystemClang {
+public:
+  using TypeSystemClang::TypeSystemClang;
+
+  lldb::LanguageType GetMinimumLanguage(lldb::opaque_compiler_type_t) override 
{
+    return lldb::eLanguageTypeGo;
+  }
+};
+
 // Checks whether m1 is an overload of m2 (as opposed to an override). This is
 // called by addOverridesForMethod to distinguish overrides (which share a
 // vtable entry) from overloads (which require distinct entries).
@@ -538,12 +550,22 @@ lldb::TypeSystemSP 
TypeSystemClang::CreateInstance(lldb::LanguageType language,
     }
   }
 
+  auto create_type_system = [&](llvm::StringRef name) -> lldb::TypeSystemSP {
+    if (language == lldb::eLanguageTypeGo)
+      return std::make_shared<GoTypeSystemClang>(name, triple);
+    return std::make_shared<TypeSystemClang>(name, triple);
+  };
+
   if (module) {
     std::string ast_name =
         "ASTContext for '" + module->GetFileSpec().GetPath() + "'";
-    return std::make_shared<TypeSystemClang>(ast_name, triple);
-  } else if (target && target->IsValid())
-    return std::make_shared<ScratchTypeSystemClang>(*target, triple);
+    return create_type_system(ast_name);
+  } else if (target && target->IsValid()) {
+    if (language == lldb::eLanguageTypeGo)
+      return create_type_system("Scratch ASTContext for Go");
+    else
+      return std::make_shared<ScratchTypeSystemClang>(*target, triple);
+  }
   return lldb::TypeSystemSP();
 }
 
@@ -562,6 +584,7 @@ LanguageSet 
TypeSystemClang::GetSupportedLanguagesForTypes() {
   languages.Insert(lldb::eLanguageTypeC_plus_plus_14);
   languages.Insert(lldb::eLanguageTypeC_plus_plus_17);
   languages.Insert(lldb::eLanguageTypeC_plus_plus_20);
+  languages.Insert(lldb::eLanguageTypeGo);
   return languages;
 }
 
diff --git a/lldb/test/Shell/Process/GoLanguage.test 
b/lldb/test/Shell/Process/GoLanguage.test
new file mode 100644
index 0000000000000..22748db8f4eec
--- /dev/null
+++ b/lldb/test/Shell/Process/GoLanguage.test
@@ -0,0 +1,44 @@
+Test DW_LANG_Go compile units with layouts used by the Go compiler and LLGo.
+The generic language layer handles the Go compiler's string layout. LLGo's
+distinct runtime layout remains visible for its marker-selected adapter.
+
+UNSUPPORTED: system-windows
+
+RUN: %clang_host %S/Inputs/go-language.c -std=c99 -g -S -emit-llvm -o - \
+RUN:   | sed -e 's/DW_LANG_C99/DW_LANG_Go/g' \
+RUN:         -e 's/producer: "[^"]*"/producer: "Go cmd\/compile"/' >%t.go.ll
+RUN: %clang_host %t.go.ll -g -o %t.go.exe
+RUN: %lldb -o "breakpoint set -n inspect" -o run \
+RUN:   -o "frame variable value text text_ptr array" -o continue \
+RUN:   -o "frame variable text text_ptr" -o quit -b %t.go.exe 2>&1 \
+RUN:   | FileCheck %s --check-prefix=GO
+
+RUN: %clang_host %S/Inputs/go-language.c -DLLGO_LAYOUT -std=c99 -g -S \
+RUN:   -emit-llvm -o - | sed -e 's/DW_LANG_C99/DW_LANG_Go/g' \
+RUN:   -e 's/producer: "[^"]*"/producer: "LLGo"/' >%t.llgo.ll
+RUN: %clang_host %t.llgo.ll -g -o %t.llgo.exe
+RUN: %lldb -o "breakpoint set -n inspect" -o run \
+RUN:   -o "frame variable value text text_ptr array" -o continue \
+RUN:   -o "frame variable text text_ptr" -o quit -b %t.llgo.exe 2>&1 \
+RUN:   | FileCheck %s --check-prefix=LLGO
+
+GO-NOT: this version of LLDB has no plugin for the language "go"
+GO: (long) value = 7
+GO: (string) text = "go"
+GO: (string *) text_ptr = {{.*}}"go"
+GO: (array2) array =
+GO: values = ([0] = 11, [1] = 13)
+GO: (string) text = ""
+GO: (string *) text_ptr = {{.*}}""
+
+LLGO-NOT: this version of LLDB has no plugin for the language "go"
+LLGO: (long) value = 7
+LLGO: (string) text = {
+LLGO: data =
+LLGO: len = 4
+LLGO: (string *) text_ptr =
+LLGO: (array2) array =
+LLGO: values = ([0] = 11, [1] = 13)
+LLGO: (string) text = {
+LLGO: len = 0
+LLGO: (string *) text_ptr =
diff --git a/lldb/test/Shell/Process/Inputs/go-language.c 
b/lldb/test/Shell/Process/Inputs/go-language.c
new file mode 100644
index 0000000000000..4ccde38e67f3b
--- /dev/null
+++ b/lldb/test/Shell/Process/Inputs/go-language.c
@@ -0,0 +1,29 @@
+#ifdef LLGO_LAYOUT
+#define GO_TEXT "llgo"
+#define GO_TEXT_LENGTH 4
+#define GO_STRING_DATA data
+#else
+#define GO_TEXT "go"
+#define GO_TEXT_LENGTH 2
+#define GO_STRING_DATA str
+#endif
+
+typedef struct {
+  const unsigned char *GO_STRING_DATA;
+  long len;
+} string;
+
+typedef struct {
+  long values[2];
+} array2;
+
+__attribute__((noinline)) long inspect(long value, string text, string 
*text_ptr, array2 array) { return value + array.values[0] + text.len + 
text_ptr->len; }
+
+int main(void) {
+  string text = {(const unsigned char *)GO_TEXT, GO_TEXT_LENGTH};
+  string empty = {(const unsigned char *)"", 0};
+  array2 array = {{11, 13}};
+  long first = inspect(7, text, &text, array);
+  long second = inspect(7, empty, &empty, array);
+  return first + second == 0;
+}
diff --git a/lldb/unittests/Language/CMakeLists.txt 
b/lldb/unittests/Language/CMakeLists.txt
index a0bdc62af98c6..7a26b505108ca 100644
--- a/lldb/unittests/Language/CMakeLists.txt
+++ b/lldb/unittests/Language/CMakeLists.txt
@@ -1,3 +1,4 @@
 add_subdirectory(CPlusPlus)
 add_subdirectory(CLanguages)
+add_subdirectory(Go)
 add_subdirectory(ObjC)
diff --git a/lldb/unittests/Language/Go/CMakeLists.txt 
b/lldb/unittests/Language/Go/CMakeLists.txt
new file mode 100644
index 0000000000000..abb8340b09b6d
--- /dev/null
+++ b/lldb/unittests/Language/Go/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_lldb_unittest(GoLanguageTests
+  GoLanguageTest.cpp
+
+  LINK_LIBS
+    lldbPluginGoLanguage
+)
diff --git a/lldb/unittests/Language/Go/GoLanguageTest.cpp 
b/lldb/unittests/Language/Go/GoLanguageTest.cpp
new file mode 100644
index 0000000000000..f12aa03d27d2a
--- /dev/null
+++ b/lldb/unittests/Language/Go/GoLanguageTest.cpp
@@ -0,0 +1,37 @@
+//===-- GoLanguageTest.cpp 
------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Language/Go/GoLanguage.h"
+#include "TestingSupport/SubsystemRAII.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+TEST(GoLanguage, LookupByLanguageType) {
+  SubsystemRAII<GoLanguage> language;
+
+  Language *plugin = Language::FindPlugin(lldb::eLanguageTypeGo);
+  ASSERT_NE(plugin, nullptr);
+  EXPECT_EQ(plugin->GetPluginName(), "go");
+  EXPECT_EQ(plugin->GetLanguageType(), lldb::eLanguageTypeGo);
+  EXPECT_EQ(plugin->GetUserEntryPointName(), "main");
+  EXPECT_EQ(plugin->GetHardcodedSummaries().size(), 1u);
+
+  EXPECT_EQ(GoLanguage::CreateInstance(lldb::eLanguageTypeC), nullptr);
+}
+
+TEST(GoLanguage, RecognizesGoSourceFiles) {
+  GoLanguage language;
+
+  EXPECT_TRUE(language.IsSourceFile("main.go"));
+  EXPECT_TRUE(language.IsSourceFile("/tmp/UPPER.GO"));
+  EXPECT_FALSE(language.IsSourceFile("main.c"));
+  EXPECT_FALSE(language.IsSourceFile("go.mod"));
+}

>From 7a0d70e7fc8224cc9fb07fa95f47a74e25e655c3 Mon Sep 17 00:00:00 2001
From: Li Jie <[email protected]>
Date: Tue, 28 Jul 2026 23:28:04 +0800
Subject: [PATCH 2/4] [lldb][Go] Use the Go user entry point name

---
 lldb/source/Plugins/Language/Go/GoLanguage.h  | 2 +-
 lldb/unittests/Language/Go/GoLanguageTest.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/Language/Go/GoLanguage.h 
b/lldb/source/Plugins/Language/Go/GoLanguage.h
index 5676d6a25b432..ee05d8009ffc1 100644
--- a/lldb/source/Plugins/Language/Go/GoLanguage.h
+++ b/lldb/source/Plugins/Language/Go/GoLanguage.h
@@ -23,7 +23,7 @@ class GoLanguage : public Language {
     return lldb::eLanguageTypeGo;
   }
 
-  llvm::StringRef GetUserEntryPointName() const override { return "main"; }
+  llvm::StringRef GetUserEntryPointName() const override { return "main.main"; 
}
 
   HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override;
 
diff --git a/lldb/unittests/Language/Go/GoLanguageTest.cpp 
b/lldb/unittests/Language/Go/GoLanguageTest.cpp
index f12aa03d27d2a..e947f19a25754 100644
--- a/lldb/unittests/Language/Go/GoLanguageTest.cpp
+++ b/lldb/unittests/Language/Go/GoLanguageTest.cpp
@@ -21,7 +21,7 @@ TEST(GoLanguage, LookupByLanguageType) {
   ASSERT_NE(plugin, nullptr);
   EXPECT_EQ(plugin->GetPluginName(), "go");
   EXPECT_EQ(plugin->GetLanguageType(), lldb::eLanguageTypeGo);
-  EXPECT_EQ(plugin->GetUserEntryPointName(), "main");
+  EXPECT_EQ(plugin->GetUserEntryPointName(), "main.main");
   EXPECT_EQ(plugin->GetHardcodedSummaries().size(), 1u);
 
   EXPECT_EQ(GoLanguage::CreateInstance(lldb::eLanguageTypeC), nullptr);

>From 0fa979c28e874e580cbaf13163259a495f5b7142 Mon Sep 17 00:00:00 2001
From: Li Jie <[email protected]>
Date: Tue, 28 Jul 2026 23:31:19 +0800
Subject: [PATCH 3/4] [lldb][test] Verify Go source plugin lookup

---
 lldb/unittests/Language/Go/GoLanguageTest.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lldb/unittests/Language/Go/GoLanguageTest.cpp 
b/lldb/unittests/Language/Go/GoLanguageTest.cpp
index e947f19a25754..4a8006c47c683 100644
--- a/lldb/unittests/Language/Go/GoLanguageTest.cpp
+++ b/lldb/unittests/Language/Go/GoLanguageTest.cpp
@@ -23,6 +23,7 @@ TEST(GoLanguage, LookupByLanguageType) {
   EXPECT_EQ(plugin->GetLanguageType(), lldb::eLanguageTypeGo);
   EXPECT_EQ(plugin->GetUserEntryPointName(), "main.main");
   EXPECT_EQ(plugin->GetHardcodedSummaries().size(), 1u);
+  EXPECT_EQ(Language::FindPlugin("main.go"), plugin);
 
   EXPECT_EQ(GoLanguage::CreateInstance(lldb::eLanguageTypeC), nullptr);
 }

>From 55bba0afb8ba6f463b98823b179582fabb73b0aa Mon Sep 17 00:00:00 2001
From: Li Jie <[email protected]>
Date: Tue, 28 Jul 2026 23:45:19 +0800
Subject: [PATCH 4/4] [lldb][Go] Preserve Clang scratch type-system behavior

---
 .../TypeSystem/Clang/TypeSystemClang.cpp      | 24 +++++++++++--------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp 
b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 3453d9091d879..36519c2e67c0c 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -135,6 +135,15 @@ class GoTypeSystemClang final : public TypeSystemClang {
   }
 };
 
+class GoScratchTypeSystemClang final : public ScratchTypeSystemClang {
+public:
+  using ScratchTypeSystemClang::ScratchTypeSystemClang;
+
+  lldb::LanguageType GetMinimumLanguage(lldb::opaque_compiler_type_t) override 
{
+    return lldb::eLanguageTypeGo;
+  }
+};
+
 // Checks whether m1 is an overload of m2 (as opposed to an override). This is
 // called by addOverridesForMethod to distinguish overrides (which share a
 // vtable entry) from overloads (which require distinct entries).
@@ -550,21 +559,16 @@ lldb::TypeSystemSP 
TypeSystemClang::CreateInstance(lldb::LanguageType language,
     }
   }
 
-  auto create_type_system = [&](llvm::StringRef name) -> lldb::TypeSystemSP {
-    if (language == lldb::eLanguageTypeGo)
-      return std::make_shared<GoTypeSystemClang>(name, triple);
-    return std::make_shared<TypeSystemClang>(name, triple);
-  };
-
   if (module) {
     std::string ast_name =
         "ASTContext for '" + module->GetFileSpec().GetPath() + "'";
-    return create_type_system(ast_name);
+    if (language == lldb::eLanguageTypeGo)
+      return std::make_shared<GoTypeSystemClang>(ast_name, triple);
+    return std::make_shared<TypeSystemClang>(ast_name, triple);
   } else if (target && target->IsValid()) {
     if (language == lldb::eLanguageTypeGo)
-      return create_type_system("Scratch ASTContext for Go");
-    else
-      return std::make_shared<ScratchTypeSystemClang>(*target, triple);
+      return std::make_shared<GoScratchTypeSystemClang>(*target, triple);
+    return std::make_shared<ScratchTypeSystemClang>(*target, triple);
   }
   return lldb::TypeSystemSP();
 }

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to