https://github.com/Michael137 updated 
https://github.com/llvm/llvm-project/pull/161688

>From 70209138f76ddcc59e6ee3f9a0cfac734d6db00d Mon Sep 17 00:00:00 2001
From: Michael Buch <[email protected]>
Date: Fri, 3 Oct 2025 09:24:49 +0100
Subject: [PATCH 1/4] [lldb][Lanugage] Add
 Language::GetDisplayNameForLanguageType API

The intention for this API is to be used when presenting language names to the 
user, e.g., in expression evaluation diagnostics or LLDB errors.

Most uses of `GetNameForLanguageType` can be probably replaced with 
`GetDisplayNameForLanguageType`, but that's out of scope of this PR.

This uses `llvm::dwarf::LanguageDescription` under the hood, so we would lose 
the version numbers in the names. If we deem those to be important, we could 
switch to an implementation that hardcodes a list of user-friendly names with 
version numbers included.
---
 lldb/include/lldb/Target/Language.h | 7 +++++++
 lldb/source/Target/Language.cpp     | 4 ++++
 2 files changed, 11 insertions(+)

diff --git a/lldb/include/lldb/Target/Language.h 
b/lldb/include/lldb/Target/Language.h
index 3d0aa326d5a6d..48a7ac2cea42f 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -404,8 +404,15 @@ class Language : public PluginInterface {
   GetLanguageTypeFromString(const char *string) = delete;
   static lldb::LanguageType GetLanguageTypeFromString(llvm::StringRef string);
 
+  /// Returns the internal LLDB name for the specified language. When 
presenting
+  /// the language name to users, use \ref GetDisplayNameForLanguageType
+  /// instead.
   static const char *GetNameForLanguageType(lldb::LanguageType language);
 
+  /// Returns a user-friendly name for the specified language.
+  static llvm::StringRef
+  GetDisplayNameForLanguageType(lldb::LanguageType language);
+
   static void PrintAllLanguages(Stream &s, const char *prefix,
                                 const char *suffix);
 
diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp
index 484d9badde397..f0fc48e18793b 100644
--- a/lldb/source/Target/Language.cpp
+++ b/lldb/source/Target/Language.cpp
@@ -270,6 +270,10 @@ const char *Language::GetNameForLanguageType(LanguageType 
language) {
     return language_names[eLanguageTypeUnknown].name;
 }
 
+llvm::StringRef Language::GetDisplayNameForLanguageType(LanguageType language) 
{
+  return SourceLanguage(language).GetDescription();
+}
+
 void Language::PrintSupportedLanguagesForExpressions(Stream &s,
                                                      llvm::StringRef prefix,
                                                      llvm::StringRef suffix) {

>From fb4be5f7dac30810af9b0fd8c107344d955bc282 Mon Sep 17 00:00:00 2001
From: Michael Buch <[email protected]>
Date: Thu, 2 Oct 2025 16:24:12 +0100
Subject: [PATCH 2/4] [lldb][Expression] Emit a 'Note' diagnistc that indicates
 the language used for expression evaluation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since it's a 'Note' diagnostic it would only show up when expression
evaluation actually failed. This helps with expression evaluation
failure reports in mixed language environments where it's not quite clear
what language the expression ran as. It may also reduce confusion around
why the expression evaluator ran an expression in a language it wasn't
asked to run (a softer alternative to what I attempted in 
https://github.com/llvm/llvm-project/pull/156648).

Here are some example outputs:
```
(lldb) expr -l c -- blah
                    ˄
                    ╰─ error: use of undeclared identifier 'blah'
note: Requested expression evaluation as 'c' but fell back to 'c++'.
(lldb) expr -l c++ -- blah
                      ˄
                      ╰─ error: use of undeclared identifier 'blah'
note: Requested expression evaluation as c++
(lldb) expr -l objc -- blah
                       ˄
                       ╰─ error: use of undeclared identifier 'blah'
note: Requested expression evaluation as 'objective-c' but fell back to 
'objective-c++'.
(lldb) expr -l rust -- blah
                       ˄
                       ╰─ error: use of undeclared identifier 'blah'
note: Requested expression evaluation as rust
```

I didn't put the diagnostic on the same line as the inline diagnostic
for now because of implementation convenience, but if reviewers deem
that a blocker I can take a stab at that again.

Also, other language plugins (namely Swift), won't immediately benefit
from this and will have to emit their own diagnistc. I played around
with having a virtual API on `UserExpression` or `ExpressionParser` that
will be called consistently, but by the time we're about to parse the
expression we are already several frames deep into the plugin. Before
(and at the beginning of) the generic `UserExpression::Parse` call we
don't have enough information to notify which language we're going to
parse in (at least for the C++ plugin).

rdar://160297649
---
 .../Clang/ClangExpressionParser.cpp           | 29 ++++++++++++++++---
 .../Clang/ClangExpressionParser.h             |  1 +
 .../Clang/ClangFunctionCaller.cpp             |  4 +--
 .../Clang/ClangUserExpression.cpp             |  4 +--
 .../Clang/ClangUtilityFunction.cpp            |  2 +-
 5 files changed, 31 insertions(+), 9 deletions(-)

diff --git 
a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 924953cc43fa2..77a8afa511a6a 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -74,6 +74,7 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Expression/DiagnosticManager.h"
 #include "lldb/Expression/IRExecutionUnit.h"
 #include "lldb/Expression/IRInterpreter.h"
 #include "lldb/Host/File.h"
@@ -527,7 +528,8 @@ static void SetupTargetOpts(CompilerInstance &compiler,
 
 static void SetupLangOpts(CompilerInstance &compiler,
                           ExecutionContextScope &exe_scope,
-                          const Expression &expr) {
+                          const Expression &expr,
+                          DiagnosticManager &diagnostic_manager) {
   Log *log = GetLog(LLDBLog::Expressions);
 
   // If the expression is being evaluated in the context of an existing stack
@@ -547,6 +549,8 @@ static void SetupLangOpts(CompilerInstance &compiler,
                      : lldb::eLanguageTypeUnknown),
         lldb_private::Language::GetNameForLanguageType(language));
 
+  lldb::LanguageType language_for_note = language;
+
   LangOptions &lang_opts = compiler.getLangOpts();
 
   switch (language) {
@@ -560,12 +564,14 @@ static void SetupLangOpts(CompilerInstance &compiler,
     // family language, because the expression parser uses features of C++ to
     // capture values.
     lang_opts.CPlusPlus = true;
+    language_for_note = lldb::eLanguageTypeC_plus_plus;
     break;
   case lldb::eLanguageTypeObjC:
     lang_opts.ObjC = true;
     // FIXME: the following language option is a temporary workaround,
     // to "ask for ObjC, get ObjC++" (see comment above).
     lang_opts.CPlusPlus = true;
+    language_for_note = lldb::eLanguageTypeObjC_plus_plus;
 
     // Clang now sets as default C++14 as the default standard (with
     // GNU extensions), so we do the same here to avoid mismatches that
@@ -610,6 +616,21 @@ static void SetupLangOpts(CompilerInstance &compiler,
     break;
   }
 
+  if (language_for_note != language)
+    diagnostic_manager.AddDiagnostic(
+        llvm::formatv(
+            "Requested expression evaluation as '{0}' but fell back to '{1}'.",
+            lldb_private::Language::GetNameForLanguageType(language),
+            lldb_private::Language::GetNameForLanguageType(language_for_note))
+            .str(),
+        lldb::Severity::eSeverityInfo, 
DiagnosticOrigin::eDiagnosticOriginLLDB);
+  else
+    diagnostic_manager.AddDiagnostic(
+        llvm::formatv("Requested expression evaluation as '{0}'",
+                      lldb_private::Language::GetNameForLanguageType(language))
+            .str(),
+        lldb::Severity::eSeverityInfo, 
DiagnosticOrigin::eDiagnosticOriginLLDB);
+
   lang_opts.Bool = true;
   lang_opts.WChar = true;
   lang_opts.Blocks = true;
@@ -687,8 +708,8 @@ static void SetupImportStdModuleLangOpts(CompilerInstance 
&compiler,
 
 ClangExpressionParser::ClangExpressionParser(
     ExecutionContextScope *exe_scope, Expression &expr,
-    bool generate_debug_info, std::vector<std::string> include_directories,
-    std::string filename)
+    bool generate_debug_info, DiagnosticManager &diagnostic_manager,
+    std::vector<std::string> include_directories, std::string filename)
     : ExpressionParser(exe_scope, expr, generate_debug_info), m_compiler(),
       m_pp_callbacks(nullptr),
       m_include_directories(std::move(include_directories)),
@@ -754,7 +775,7 @@ ClangExpressionParser::ClangExpressionParser(
   }
 
   // 4. Set language options.
-  SetupLangOpts(*m_compiler, *exe_scope, expr);
+  SetupLangOpts(*m_compiler, *exe_scope, expr, diagnostic_manager);
   auto *clang_expr = dyn_cast<ClangUserExpression>(&m_expr);
   if (clang_expr && clang_expr->DidImportCxxModules()) {
     LLDB_LOG(log, "Adding lang options for importing C++ modules");
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 93e0b007dbcc8..734ad51c9646e 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -65,6 +65,7 @@ class ClangExpressionParser : public ExpressionParser {
   ///     diagnostics (i.e. errors, warnings or notes from Clang).
   ClangExpressionParser(ExecutionContextScope *exe_scope, Expression &expr,
                         bool generate_debug_info,
+                        DiagnosticManager &diagnostic_manager,
                         std::vector<std::string> include_directories = {},
                         std::string filename = "<clang expression>");
 
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index e4a094f3aa512..d2db319afb7a0 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -189,8 +189,8 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP 
thread_to_use_sp,
   lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
   if (jit_process_sp) {
     const bool generate_debug_info = true;
-    auto *clang_parser = new ClangExpressionParser(jit_process_sp.get(), *this,
-                                                   generate_debug_info);
+    auto *clang_parser = new ClangExpressionParser(
+        jit_process_sp.get(), *this, generate_debug_info, diagnostic_manager);
     num_errors = clang_parser->Parse(diagnostic_manager);
     m_parser.reset(clang_parser);
   } else {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 6b743e29e21f6..e8d5ec3c7fd96 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -574,7 +574,7 @@ bool ClangUserExpression::TryParse(
 
   m_parser = std::make_unique<ClangExpressionParser>(
       exe_ctx.GetBestExecutionContextScope(), *this, generate_debug_info,
-      m_include_directories, m_filename);
+      diagnostic_manager, m_include_directories, m_filename);
 
   unsigned num_errors = m_parser->Parse(diagnostic_manager);
 
@@ -818,7 +818,7 @@ bool ClangUserExpression::Complete(ExecutionContext 
&exe_ctx,
   }
 
   ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
-                               false);
+                               false, diagnostic_manager);
 
   // We have to find the source code location where the user text is inside
   // the transformed expression code. When creating the transformed text, we
diff --git 
a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 1f44200c4cff8..e6983066a12fa 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -120,7 +120,7 @@ bool ClangUtilityFunction::Install(DiagnosticManager 
&diagnostic_manager,
 
   const bool generate_debug_info = true;
   ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
-                               generate_debug_info);
+                               generate_debug_info, diagnostic_manager);
 
   unsigned num_errors = parser.Parse(diagnostic_manager);
 

>From 817898fa919c3fe9530acf0adf6a0415367ccf07 Mon Sep 17 00:00:00 2001
From: Michael Buch <[email protected]>
Date: Fri, 3 Oct 2025 09:29:17 +0100
Subject: [PATCH 3/4] fixup! reword diagnostic; use
 GetDisplayNameForLanguageType

---
 .../ExpressionParser/Clang/ClangExpressionParser.cpp   | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git 
a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 77a8afa511a6a..faef42d34adee 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -619,15 +619,15 @@ static void SetupLangOpts(CompilerInstance &compiler,
   if (language_for_note != language)
     diagnostic_manager.AddDiagnostic(
         llvm::formatv(
-            "Requested expression evaluation as '{0}' but fell back to '{1}'.",
-            lldb_private::Language::GetNameForLanguageType(language),
-            lldb_private::Language::GetNameForLanguageType(language_for_note))
+            "Requested expression evaluation in '{0}' is not supported. Used 
'{1}' instead.",
+            lldb_private::Language::GetDisplayNameForLanguageType(language),
+            
lldb_private::Language::GetDisplayNameForLanguageType(language_for_note))
             .str(),
         lldb::Severity::eSeverityInfo, 
DiagnosticOrigin::eDiagnosticOriginLLDB);
   else
     diagnostic_manager.AddDiagnostic(
-        llvm::formatv("Requested expression evaluation as '{0}'",
-                      lldb_private::Language::GetNameForLanguageType(language))
+        llvm::formatv("Requested expression evaluation as '{0}'.",
+                      
lldb_private::Language::GetDisplayNameForLanguageType(language))
             .str(),
         lldb::Severity::eSeverityInfo, 
DiagnosticOrigin::eDiagnosticOriginLLDB);
 

>From 224af5ea52df2415992a04e9424bfadb186114a7 Mon Sep 17 00:00:00 2001
From: Michael Buch <[email protected]>
Date: Fri, 3 Oct 2025 09:30:05 +0100
Subject: [PATCH 4/4] fixup! clang-format

---
 .../ExpressionParser/Clang/ClangExpressionParser.cpp  | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git 
a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index faef42d34adee..d297d32e61b9a 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -619,15 +619,18 @@ static void SetupLangOpts(CompilerInstance &compiler,
   if (language_for_note != language)
     diagnostic_manager.AddDiagnostic(
         llvm::formatv(
-            "Requested expression evaluation in '{0}' is not supported. Used 
'{1}' instead.",
+            "Requested expression evaluation in '{0}' is not supported. Used "
+            "'{1}' instead.",
             lldb_private::Language::GetDisplayNameForLanguageType(language),
-            
lldb_private::Language::GetDisplayNameForLanguageType(language_for_note))
+            lldb_private::Language::GetDisplayNameForLanguageType(
+                language_for_note))
             .str(),
         lldb::Severity::eSeverityInfo, 
DiagnosticOrigin::eDiagnosticOriginLLDB);
   else
     diagnostic_manager.AddDiagnostic(
-        llvm::formatv("Requested expression evaluation as '{0}'.",
-                      
lldb_private::Language::GetDisplayNameForLanguageType(language))
+        llvm::formatv(
+            "Requested expression evaluation as '{0}'.",
+            lldb_private::Language::GetDisplayNameForLanguageType(language))
             .str(),
         lldb::Severity::eSeverityInfo, 
DiagnosticOrigin::eDiagnosticOriginLLDB);
 

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

Reply via email to