<feed xmlns='http://www.w3.org/2005/Atom'>
<title>llvm-project.git/lldb/test/API/python_api, branch main</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/'/>
<entry>
<title>[lldb] Add a test for capturing stdout/stderr from Python commands (#168138)</title>
<updated>2025-11-14T22:43:01+00:00</updated>
<author>
<name>Jonas Devlieghere</name>
<email>jonas@devlieghere.com</email>
</author>
<published>2025-11-14T22:43:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=6dad2c2cfb9255bb8b4fec3565f99ffda32dfb1a'/>
<id>6dad2c2cfb9255bb8b4fec3565f99ffda32dfb1a</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>[LLDB] Fix debuginfo ELF files overwriting Unified Section List (#166635)</title>
<updated>2025-11-06T23:56:11+00:00</updated>
<author>
<name>Jacob Lalonde</name>
<email>jalalonde@fb.com</email>
</author>
<published>2025-11-06T23:56:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=32ebf635c2be171b01a288b00b3e64b8de72e61a'/>
<id>32ebf635c2be171b01a288b00b3e64b8de72e61a</id>
<content type='text'>
Recently I've been deep diving ELF cores in LLDB, aspiring to move LLDB
closer to GDB in capability. One issue I encountered was a system lib
losing it's unwind plan when loading the debuginfo. The reason for this
was the debuginfo has the eh_frame section stripped and the main
executable did not.

The root cause of this was this line in
[ObjectFileElf](https://github.com/llvm/llvm-project/blob/163933e9e7099f352ff8df1973f9a9c3d7def6c5/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp#L1972)
```
  // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
  // unified section list.
  if (GetType() != eTypeDebugInfo)
    unified_section_list = *m_sections_up;
```

This would always be executed because CalculateType can never return an
eTypeDebugInfo
```
ObjectFile::Type ObjectFileELF::CalculateType() {
  switch (m_header.e_type) {
  case llvm::ELF::ET_NONE:
    // 0 - No file type
    return eTypeUnknown;

  case llvm::ELF::ET_REL:
    // 1 - Relocatable file
    return eTypeObjectFile;

  case llvm::ELF::ET_EXEC:
    // 2 - Executable file
    return eTypeExecutable;

  case llvm::ELF::ET_DYN:
    // 3 - Shared object file
    return eTypeSharedLibrary;

  case ET_CORE:
    // 4 - Core file
    return eTypeCoreFile;

  default:
    break;
  }
  return eTypeUnknown;
}
```

This makes sense as there isn't a explicit sh_type to denote that this
file is a debuginfo. After some discussion with @clayborg and
@GeorgeHuyubo we settled on joining the exciting unified section list
with whatever new sections were being added. Adding each new unique
section, or taking the section with the maximum file size. We picked
this strategy to pick the section with the most information. In most
scenarios, LHS should be SHT_NOBITS and RHS would be SHT_PROGBITS.

Here is a diagram documenting the existing vs proposed new way.
&lt;img width="1666" height="1093" alt="image"
src="https://github.com/user-attachments/assets/73ba9620-c737-439e-9934-ac350d88a3b5"
/&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Recently I've been deep diving ELF cores in LLDB, aspiring to move LLDB
closer to GDB in capability. One issue I encountered was a system lib
losing it's unwind plan when loading the debuginfo. The reason for this
was the debuginfo has the eh_frame section stripped and the main
executable did not.

The root cause of this was this line in
[ObjectFileElf](https://github.com/llvm/llvm-project/blob/163933e9e7099f352ff8df1973f9a9c3d7def6c5/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp#L1972)
```
  // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
  // unified section list.
  if (GetType() != eTypeDebugInfo)
    unified_section_list = *m_sections_up;
```

This would always be executed because CalculateType can never return an
eTypeDebugInfo
```
ObjectFile::Type ObjectFileELF::CalculateType() {
  switch (m_header.e_type) {
  case llvm::ELF::ET_NONE:
    // 0 - No file type
    return eTypeUnknown;

  case llvm::ELF::ET_REL:
    // 1 - Relocatable file
    return eTypeObjectFile;

  case llvm::ELF::ET_EXEC:
    // 2 - Executable file
    return eTypeExecutable;

  case llvm::ELF::ET_DYN:
    // 3 - Shared object file
    return eTypeSharedLibrary;

  case ET_CORE:
    // 4 - Core file
    return eTypeCoreFile;

  default:
    break;
  }
  return eTypeUnknown;
}
```

This makes sense as there isn't a explicit sh_type to denote that this
file is a debuginfo. After some discussion with @clayborg and
@GeorgeHuyubo we settled on joining the exciting unified section list
with whatever new sections were being added. Adding each new unique
section, or taking the section with the maximum file size. We picked
this strategy to pick the section with the most information. In most
scenarios, LHS should be SHT_NOBITS and RHS would be SHT_PROGBITS.

Here is a diagram documenting the existing vs proposed new way.
&lt;img width="1666" height="1093" alt="image"
src="https://github.com/user-attachments/assets/73ba9620-c737-439e-9934-ac350d88a3b5"
/&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Introduce SBFrameList for lazy frame iteration (#166651)</title>
<updated>2025-11-06T00:02:02+00:00</updated>
<author>
<name>Med Ismail Bennani</name>
<email>ismail@bennani.ma</email>
</author>
<published>2025-11-06T00:02:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=d584d00ed250e547c9910e0a93b7f9d07f2e71c3'/>
<id>d584d00ed250e547c9910e0a93b7f9d07f2e71c3</id>
<content type='text'>
This patch introduces `SBFrameList`, a new SBAPI class that allows
iterating over stack frames lazily without calling
`SBThread::GetFrameAtIndex` in a loop.

The new `SBThread::GetFrames()` method returns an `SBFrameList` that
supports Python iteration (`for frame in frame_list:`), indexing
(`frame_list[0]`, `frame_list[-1]`), and length queries (`len()`).

The implementation uses `StackFrameListSP` as the opaque pointer,
sharing the thread's underlying frame list to ensure frames are
materialized on-demand.

This is particularly useful for ScriptedFrameProviders, where user
scripts will be to iterate, filter, and replace frames lazily without
materializing the entire stack upfront.

Signed-off-by: Med Ismail Bennani &lt;ismail@bennani.ma&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch introduces `SBFrameList`, a new SBAPI class that allows
iterating over stack frames lazily without calling
`SBThread::GetFrameAtIndex` in a loop.

The new `SBThread::GetFrames()` method returns an `SBFrameList` that
supports Python iteration (`for frame in frame_list:`), indexing
(`frame_list[0]`, `frame_list[-1]`), and length queries (`len()`).

The implementation uses `StackFrameListSP` as the opaque pointer,
sharing the thread's underlying frame list to ensure frames are
materialized on-demand.

This is particularly useful for ScriptedFrameProviders, where user
scripts will be to iterate, filter, and replace frames lazily without
materializing the entire stack upfront.

Signed-off-by: Med Ismail Bennani &lt;ismail@bennani.ma&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Add alternative SBThread::GetStopDescription (#165379)</title>
<updated>2025-10-30T21:43:53+00:00</updated>
<author>
<name>Ebuka Ezike</name>
<email>yerimyah1@gmail.com</email>
</author>
<published>2025-10-30T21:43:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=c46bfed1a484d30cd251a9a225649d74e3bf0af5'/>
<id>c46bfed1a484d30cd251a9a225649d74e3bf0af5</id>
<content type='text'>
the function signature for `GetStopDescription` is
`lldb::SBThread::GetStopDescription(char *dst_or_null, size_t len)`.
To get a description you need to call the function first time to get the
buffer size. a second time to get the description.

This is little worse from the python size as the signature is
`lldb.SBThread.GetStopDescription(int: len) -&gt; list[str]` the user has
to pass the max size as possible with no way of checking if it is
enough.

This patch adds a new api
`lldb.SBThread.GetStopDescription(desc: lldb.SBStream()) -&gt; bool` `bool
lldb::SBThread::GetStopDescription(lldb::SBStream &amp;description)` which
handles this case.

Adds new Test case for lua.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the function signature for `GetStopDescription` is
`lldb::SBThread::GetStopDescription(char *dst_or_null, size_t len)`.
To get a description you need to call the function first time to get the
buffer size. a second time to get the description.

This is little worse from the python size as the signature is
`lldb.SBThread.GetStopDescription(int: len) -&gt; list[str]` the user has
to pass the max size as possible with no way of checking if it is
enough.

This patch adds a new api
`lldb.SBThread.GetStopDescription(desc: lldb.SBStream()) -&gt; bool` `bool
lldb::SBThread::GetStopDescription(lldb::SBStream &amp;description)` which
handles this case.

Adds new Test case for lua.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][swig] Support SBFileSpec::GetPath (#162964)</title>
<updated>2025-10-13T18:24:12+00:00</updated>
<author>
<name>Wanyi</name>
<email>wanyi@meta.com</email>
</author>
<published>2025-10-13T18:24:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=068e1796bac5229210f57862862e8995d4b6f009'/>
<id>068e1796bac5229210f57862862e8995d4b6f009</id>
<content type='text'>
# Summary
`SBFileSpec::GetPath(char *dst_path, size_t dst_len)` contains `char*`
type argument. Need to handle this for python. Fortunately there're
already similar definitions we can reuse.

# Test Plan
Start the freshly built lldb and run the following code
```
$ lldb
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
&gt;&gt;&gt; debugger = lldb.SBDebugger.Create()
&gt;&gt;&gt; debugger.SetAsync (False)
&gt;&gt;&gt; target = debugger.CreateTarget("~/tmp/hello")
&gt;&gt;&gt; target.IsValid()
True
&gt;&gt;&gt; breakpoint = target.BreakpointCreateByName('main', 'hello')
&gt;&gt;&gt; breakpoint.GetNumLocations()
1
&gt;&gt;&gt; process = target.LaunchSimple (None, None, os.getcwd())
&gt;&gt;&gt; process.IsValid()
True
&gt;&gt;&gt; thread = process.GetThreadAtIndex(0)
&gt;&gt;&gt; frame = thread.GetFrameAtIndex(0)
&gt;&gt;&gt; line = frame.GetLineEntry()

# Important line below
&gt;&gt;&gt; file = line.GetFileSpec().GetPath(1024)
# Important line above

&gt;&gt;&gt; print(file)
/home/wanyi/tmp/main.cpp
```

## Before this change
```
$ lldb
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
&gt;&gt;&gt; debugger = lldb.SBDebugger.Create()
&gt;&gt;&gt; debugger.SetAsync (False)
&gt;&gt;&gt; target = debugger.CreateTarget("~/tmp/hello")
&gt;&gt;&gt; target.IsValid()
True
&gt;&gt;&gt; breakpoint = target.BreakpointCreateByName('main', 'hello')
&gt;&gt;&gt; breakpoint.GetNumLocations()
1
&gt;&gt;&gt; process = target.LaunchSimple (None, None, os.getcwd())
&gt;&gt;&gt; process.IsValid()
True
&gt;&gt;&gt; thread = process.GetThreadAtIndex(0)
&gt;&gt;&gt; frame = thread.GetFrameAtIndex(0)
&gt;&gt;&gt; line = frame.GetLineEntry()
&gt;&gt;&gt; file = line.GetFileSpec().GetPath(1024)
Traceback (most recent call last):
  File "&lt;console&gt;", line 1, in &lt;module&gt;
TypeError: SBFileSpec.GetPath() missing 1 required positional argument: 'dst_len'
&gt;&gt;&gt; print(file)
Traceback (most recent call last):
  File "&lt;console&gt;", line 1, in &lt;module&gt;
NameError: name 'file' is not defined
```</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
# Summary
`SBFileSpec::GetPath(char *dst_path, size_t dst_len)` contains `char*`
type argument. Need to handle this for python. Fortunately there're
already similar definitions we can reuse.

# Test Plan
Start the freshly built lldb and run the following code
```
$ lldb
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
&gt;&gt;&gt; debugger = lldb.SBDebugger.Create()
&gt;&gt;&gt; debugger.SetAsync (False)
&gt;&gt;&gt; target = debugger.CreateTarget("~/tmp/hello")
&gt;&gt;&gt; target.IsValid()
True
&gt;&gt;&gt; breakpoint = target.BreakpointCreateByName('main', 'hello')
&gt;&gt;&gt; breakpoint.GetNumLocations()
1
&gt;&gt;&gt; process = target.LaunchSimple (None, None, os.getcwd())
&gt;&gt;&gt; process.IsValid()
True
&gt;&gt;&gt; thread = process.GetThreadAtIndex(0)
&gt;&gt;&gt; frame = thread.GetFrameAtIndex(0)
&gt;&gt;&gt; line = frame.GetLineEntry()

# Important line below
&gt;&gt;&gt; file = line.GetFileSpec().GetPath(1024)
# Important line above

&gt;&gt;&gt; print(file)
/home/wanyi/tmp/main.cpp
```

## Before this change
```
$ lldb
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
&gt;&gt;&gt; debugger = lldb.SBDebugger.Create()
&gt;&gt;&gt; debugger.SetAsync (False)
&gt;&gt;&gt; target = debugger.CreateTarget("~/tmp/hello")
&gt;&gt;&gt; target.IsValid()
True
&gt;&gt;&gt; breakpoint = target.BreakpointCreateByName('main', 'hello')
&gt;&gt;&gt; breakpoint.GetNumLocations()
1
&gt;&gt;&gt; process = target.LaunchSimple (None, None, os.getcwd())
&gt;&gt;&gt; process.IsValid()
True
&gt;&gt;&gt; thread = process.GetThreadAtIndex(0)
&gt;&gt;&gt; frame = thread.GetFrameAtIndex(0)
&gt;&gt;&gt; line = frame.GetLineEntry()
&gt;&gt;&gt; file = line.GetFileSpec().GetPath(1024)
Traceback (most recent call last):
  File "&lt;console&gt;", line 1, in &lt;module&gt;
TypeError: SBFileSpec.GetPath() missing 1 required positional argument: 'dst_len'
&gt;&gt;&gt; print(file)
Traceback (most recent call last):
  File "&lt;console&gt;", line 1, in &lt;module&gt;
NameError: name 'file' is not defined
```</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Fix TypeSystemClang::GetBasicTypeEnumeration for 128-bit int types (#162278)</title>
<updated>2025-10-13T13:52:30+00:00</updated>
<author>
<name>Matej Košík</name>
<email>99839051+sedymrak@users.noreply.github.com</email>
</author>
<published>2025-10-13T13:52:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=14a1d3e0aeb7b8fe2cfdb2e8e029ddee8a334d14'/>
<id>14a1d3e0aeb7b8fe2cfdb2e8e029ddee8a334d14</id>
<content type='text'>
When we take the following C program:
```
int main() {
  return 0;
}
```
and create a statically-linked executable from it:
```
clang -static -g -o main main.c
```
Then we can observe the following `lldb` behavior:
```
$ lldb
(lldb) target create main
Current executable set to '.../main' (x86_64).
(lldb) breakpoint set --name main
Breakpoint 1: where = main`main + 11 at main.c:2:3, address = 0x000000000022aa7b
(lldb) process launch
Process 3773637 launched: '/home/me/tmp/built-in/main' (x86_64)
Process 3773637 stopped
* thread #1, name = 'main', stop reason = breakpoint 1.1
    frame #0: 0x000000000022aa7b main`main at main.c:2:3
   1   	int main() {
-&gt; 2   	  return 0;
   3   	}
(lldb) script lldb.debugger.GetSelectedTarget().FindFirstType("__int128").size
0
(lldb) script lldb.debugger.GetSelectedTarget().FindFirstType("unsigned __int128").size
0
(lldb) quit
```
The value return by the `SBTarget::FindFirstType` method is wrong for
the `__int128` and `unsigned __int128` basic types.

The proposed changes make the `TypeSystemClang::GetBasicTypeEnumeration`
method consistent with `gcc` and `clang` C [language
extension](https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html)
related to 128-bit integer types as well as with the
`BuiltinType::getName` method in the LLVM codebase itself.

When the above change is applied, the behavior of the `lldb` changes in
the following (desired) way:
```
$ lldb
(lldb) target create main
Current executable set to '.../main' (x86_64).
(lldb) breakpoint set --name main
Breakpoint 1: where = main`main + 11 at main.c:2:3, address = 0x000000000022aa7b
(lldb) process launch
Process 3773637 launched: '/home/me/tmp/built-in/main' (x86_64)
Process 3773637 stopped
* thread #1, name = 'main', stop reason = breakpoint 1.1
    frame #0: 0x000000000022aa7b main`main at main.c:2:3
   1   	int main() {
-&gt; 2   	  return 0;
   3   	}
(lldb) script lldb.debugger.GetSelectedTarget().FindFirstType("__int128").size
16
(lldb) script lldb.debugger.GetSelectedTarget().FindFirstType("unsigned __int128").size
16
(lldb) quit
```

---------

Co-authored-by: Matej Košík &lt;matej.kosik@codasip.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When we take the following C program:
```
int main() {
  return 0;
}
```
and create a statically-linked executable from it:
```
clang -static -g -o main main.c
```
Then we can observe the following `lldb` behavior:
```
$ lldb
(lldb) target create main
Current executable set to '.../main' (x86_64).
(lldb) breakpoint set --name main
Breakpoint 1: where = main`main + 11 at main.c:2:3, address = 0x000000000022aa7b
(lldb) process launch
Process 3773637 launched: '/home/me/tmp/built-in/main' (x86_64)
Process 3773637 stopped
* thread #1, name = 'main', stop reason = breakpoint 1.1
    frame #0: 0x000000000022aa7b main`main at main.c:2:3
   1   	int main() {
-&gt; 2   	  return 0;
   3   	}
(lldb) script lldb.debugger.GetSelectedTarget().FindFirstType("__int128").size
0
(lldb) script lldb.debugger.GetSelectedTarget().FindFirstType("unsigned __int128").size
0
(lldb) quit
```
The value return by the `SBTarget::FindFirstType` method is wrong for
the `__int128` and `unsigned __int128` basic types.

The proposed changes make the `TypeSystemClang::GetBasicTypeEnumeration`
method consistent with `gcc` and `clang` C [language
extension](https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html)
related to 128-bit integer types as well as with the
`BuiltinType::getName` method in the LLVM codebase itself.

When the above change is applied, the behavior of the `lldb` changes in
the following (desired) way:
```
$ lldb
(lldb) target create main
Current executable set to '.../main' (x86_64).
(lldb) breakpoint set --name main
Breakpoint 1: where = main`main + 11 at main.c:2:3, address = 0x000000000022aa7b
(lldb) process launch
Process 3773637 launched: '/home/me/tmp/built-in/main' (x86_64)
Process 3773637 stopped
* thread #1, name = 'main', stop reason = breakpoint 1.1
    frame #0: 0x000000000022aa7b main`main at main.c:2:3
   1   	int main() {
-&gt; 2   	  return 0;
   3   	}
(lldb) script lldb.debugger.GetSelectedTarget().FindFirstType("__int128").size
16
(lldb) script lldb.debugger.GetSelectedTarget().FindFirstType("unsigned __int128").size
16
(lldb) quit
```

---------

Co-authored-by: Matej Košík &lt;matej.kosik@codasip.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][Expression] Emit a 'Note' diagnostic that indicates the language used for expression evaluation (#161688)</title>
<updated>2025-10-10T18:23:02+00:00</updated>
<author>
<name>Michael Buch</name>
<email>michaelbuch12@gmail.com</email>
</author>
<published>2025-10-10T18:23:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=e3620fe0685c656915977d55f822a82090041965'/>
<id>e3620fe0685c656915977d55f822a82090041965</id>
<content type='text'>
Depends on:
* https://github.com/llvm/llvm-project/pull/162050

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:
```
# Without target
(lldb) expr blah
note: Falling back to default language. Ran expression as 'Objective C++'.

# Stopped in target
(lldb) expr blah
note: Ran expression as 'C++14'.

(lldb) expr -l objc -- blah
note: Expression evaluation in pure Objective-C not supported. Ran expression as 'Objective C++'.

(lldb) expr -l c -- blah
note: Expression evaluation in pure C not supported. Ran expression as 'ISO C++'.

(lldb) expr -l c++14 -- blah
note: Ran expression as 'C++14'

(lldb) expr -l c++20 -- blah
note: Ran expression as 'C++20'

(lldb) expr -l objective-c++ -- blah
note: Ran expression as 'Objective C++'

(lldb) expr -l D -- blah
note: Expression evaluation in D not supported. Falling back to default language. Ran expression as 'Objective C++'.
```

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
rdar://159669244</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Depends on:
* https://github.com/llvm/llvm-project/pull/162050

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:
```
# Without target
(lldb) expr blah
note: Falling back to default language. Ran expression as 'Objective C++'.

# Stopped in target
(lldb) expr blah
note: Ran expression as 'C++14'.

(lldb) expr -l objc -- blah
note: Expression evaluation in pure Objective-C not supported. Ran expression as 'Objective C++'.

(lldb) expr -l c -- blah
note: Expression evaluation in pure C not supported. Ran expression as 'ISO C++'.

(lldb) expr -l c++14 -- blah
note: Ran expression as 'C++14'

(lldb) expr -l c++20 -- blah
note: Ran expression as 'C++20'

(lldb) expr -l objective-c++ -- blah
note: Ran expression as 'Objective C++'

(lldb) expr -l D -- blah
note: Expression evaluation in D not supported. Falling back to default language. Ran expression as 'Objective C++'.
```

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
rdar://159669244</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Add support for unique target ids (#160736)</title>
<updated>2025-10-07T19:36:47+00:00</updated>
<author>
<name>Janet Yang</name>
<email>qxy11@meta.com</email>
</author>
<published>2025-10-07T19:36:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=7546bd38041612e8b768f4b315e491cd549d608c'/>
<id>7546bd38041612e8b768f4b315e491cd549d608c</id>
<content type='text'>
### Summary
Add support for unique target ids per Target instance. This is needed
for upcoming changes to allow debugger instances to be shared across
separate DAP instances for child process debugging. We want the IDE to
be able to attach to existing targets in an already runny lldb-dap
session, and having a unique ID per target would make that easier.

Each Target instance will have its own unique id, and uses a
function-local counter in `TargetList::CreateTargetInternal` to assign
incremental unique ids.

### Tests
Added several unit tests to test basic functionality, uniqueness of
targets, and target deletion doesn't affect the uniqueness.
```
bin/lldb-dotest -p TestDebuggerAPI
```</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
### Summary
Add support for unique target ids per Target instance. This is needed
for upcoming changes to allow debugger instances to be shared across
separate DAP instances for child process debugging. We want the IDE to
be able to attach to existing targets in an already runny lldb-dap
session, and having a unique ID per target would make that easier.

Each Target instance will have its own unique id, and uses a
function-local counter in `TargetList::CreateTargetInternal` to assign
incremental unique ids.

### Tests
Added several unit tests to test basic functionality, uniqueness of
targets, and target deletion doesn't affect the uniqueness.
```
bin/lldb-dotest -p TestDebuggerAPI
```</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Correct style of error messages (#156774)</title>
<updated>2025-09-04T23:37:41+00:00</updated>
<author>
<name>Jonas Devlieghere</name>
<email>jonas@devlieghere.com</email>
</author>
<published>2025-09-04T23:37:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=820f4402745dda82fca482f2b83925e2953e6ad9'/>
<id>820f4402745dda82fca482f2b83925e2953e6ad9</id>
<content type='text'>
The LLVM Style Guide says the following about error and warning messages
[1]:

&gt; [T]o match error message styles commonly produced by other tools,
&gt; start the first sentence with a lowercase letter, and finish the last
&gt; sentence without a period, if it would end in one otherwise.

I often provide this feedback during code review, but we still have a
bunch of places where we have inconsistent error message, which bothers
me as a user. This PR identifies a handful of those places and updates
the messages to be consistent.

[1] https://llvm.org/docs/CodingStandards.html#error-and-warning-messages</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The LLVM Style Guide says the following about error and warning messages
[1]:

&gt; [T]o match error message styles commonly produced by other tools,
&gt; start the first sentence with a lowercase letter, and finish the last
&gt; sentence without a period, if it would end in one otherwise.

I often provide this feedback during code review, but we still have a
bunch of places where we have inconsistent error message, which bothers
me as a user. This PR identifies a handful of those places and updates
the messages to be consistent.

[1] https://llvm.org/docs/CodingStandards.html#error-and-warning-messages</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Reland: Add Pythonic API to SBStructuredData extension (#156771)</title>
<updated>2025-09-04T15:34:34+00:00</updated>
<author>
<name>Dave Lee</name>
<email>davelee.com@gmail.com</email>
</author>
<published>2025-09-04T15:34:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=d289ff761b2daab625f057efdee25c6616117640'/>
<id>d289ff761b2daab625f057efdee25c6616117640</id>
<content type='text'>
* Adds `dynamic` property to automatically convert `SBStructuredData`
instances to the associated Python type (`str`, `int`, `float`, `bool`,
`NoneType`, etc)
* Implements `__getitem__` for Pythonic array and dictionary
subscripting
  * Subscripting return the result of the `dynamic` property
* Updates `__iter__` to support dictionary instances (supporting `for`
loops)
* Adds `__str__`, `__int__`, and `__float__`

With these changes, these two expressions are equal:

```py
data["name"] == data.GetValueForKey("name").GetStringValue(1024)
```

**Note**: Unlike the original commit (#155061), this re-commit removes
the `__bool__` implementation, which broke crashlog. Somewhere in the
crashlog execution, it depends on `__bool__` meaning only `IsValid()`.

Additionally did some cleanup in TestStructuredDataAPI.py.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Adds `dynamic` property to automatically convert `SBStructuredData`
instances to the associated Python type (`str`, `int`, `float`, `bool`,
`NoneType`, etc)
* Implements `__getitem__` for Pythonic array and dictionary
subscripting
  * Subscripting return the result of the `dynamic` property
* Updates `__iter__` to support dictionary instances (supporting `for`
loops)
* Adds `__str__`, `__int__`, and `__float__`

With these changes, these two expressions are equal:

```py
data["name"] == data.GetValueForKey("name").GetStringValue(1024)
```

**Note**: Unlike the original commit (#155061), this re-commit removes
the `__bool__` implementation, which broke crashlog. Somewhere in the
crashlog execution, it depends on `__bool__` meaning only `IsValid()`.

Additionally did some cleanup in TestStructuredDataAPI.py.</pre>
</div>
</content>
</entry>
</feed>
