# LLDB - Python Providers

> NOTE: LLDB's C++<->Python FFI expects a version of Python designated at the time LLDB was
>compiled. LLDB is careful to correspond this version to the minimum in typical Linux and macOS
>distributions, but on Windows there is no easy solution. If you receive an import error regarding
>`_lldb` not existing, a mismatched Python version is likely the cause.
>
> LLDB is considering solutions this issue. For updates, see
>[this discussion][minimal_python_install] and [this github issue][issue_167001]

[minimal_python_install]: https://discourse.llvm.org/t/a-minimal-python-install-for-lldb/88658
[issue_167001]: https://github.com/llvm/llvm-project/issues/167001

> NOTE: As of <!-- date-check --> Nov 2025,
> LLDB's minimum supported Python version is 3.8, with plans to update it to
> 3.9 or 3.10, depending on several outside factors. Scripts should ideally be written with only the
> features available in the minimum supported Python version. Please see [this discussion][mrpv] for
> more info.

[mrpv]: https://discourse.llvm.org/t/rfc-upgrading-llvm-s-minimum-required-python-version/88605/

> NOTE: The path to LLDB's Python package can be located via the CLI command `lldb -P`

LLDB provides 3 mechanisms for customizing output:

* Formats
* Synthetic providers
* Summary providers

## Formats

The official documentation is [here](https://lldb.llvm.org/use/variable.html#type-format).
In short,
formats allow one to set the default print format for primitive types (e.g. print `25u8` as decimal
`25`, hex `0x19`, or binary `00011001`).

Rust will almost always need to override `unsigned char`, `signed char`, `char`, `u8`, and `i8`, to
(unsigned) decimal format.

## Synthetic Providers

The official documentation is [here](https://lldb.llvm.org/use/variable.html#synthetic-children),
but some information is vague, outdated, or entirely missing.

Nearly all interaction the user has with variables will be through LLDB's
[`SBValue` objects][sbvalue] which are used both in the Python API, and internally via LLDB's
plugins and CLI.

[sbvalue]: https://lldb.llvm.org/python_api/lldb.SBValue.html

A Synthetic Provider is a Python class, written with a specific interface, that is associated with
one or more Rust types.
The Synthetic Provider wraps `SBValue` objects and LLDB will call our
class's functions when inspecting the variable.

The wrapped value is still an `SBValue`, but when calling e.g. `SBValue.GetChildAtIndex`, it will
internally call `SyntheticProvider.get_child_at_index`.
You can check if a value has a synthetic
provider via `SBValue.IsSynthetic()`, and which synthetic it is via `SBValue.GetTypeSynthetic()`.
If you want to interact with the underlying non-synthetic value, you can call
`SBValue.GetNonSyntheticValue()`.


The expected interface is as follows:

```python
class SyntheticProvider:
    def __init__(self, valobj: SBValue, _lldb_internal): ...

    # optional
    def update(self) -> bool: ...

    # optional
    def has_children(self) -> bool: ...

    # optional
    def num_children(self, max_children: int) -> int: ...

    def get_child_index(self, name: str) -> int: ...

    def get_child_at_index(self, index: int) -> SBValue: ...

    # optional
    def get_type_name(self) -> str: ...

    # optional
    def get_value(self) -> SBValue: ...
```

Below are explanations of the methods, their quirks, and how they should generally be used.
If a method overrides an `SBValue` method, that method will be listed.

### `__init__`

This function is called once per object, and must store the `valobj` in the Python class so that it
is accessible elsewhere.
Very little else should be done here.

### (optional) `update`

This function is called prior to LLDB interacting with a variable, but after `__init__`.
LLDB tracks whether `update` has already been called.
If it has been, and if it is not possible for the variable
to have changed (e.g. inspecting the same variable a second time without stepping), it will omit the
call to `update`.

This function has 2 purposes:

* Store/update any information that may have changed since the last time `update` was run
* Inform LLDB if there were changes to the children such that it should flush the child cache.

Typical operations include storing the heap pointer, length, capacity, and element type of a `Vec`,
determining an enum variable's variant, or checking which slots of a `HashMap` are occupied.

The bool returned from this function is somewhat complicated, see:
[`update` caching](#update-caching) below for more info.
When in doubt, return `False`/`None`.
As of <!-- date-check --> Nov 2025,
none of the visualizers return `True`, but that may change as the debug info test suite is improved.

#### `update` caching

LLDB attempts to cache values when possible, including child values.
This cache is effectively the
number of child objects, and the addresses of the underlying debugee memory that the child object
represents.
By returning `True`, you indicate to LLDB that the number of children and the addresses
of those children have not changed since the last time `update` was run, meaning it can reuse the
cached children.

**Returning `True` in the wrong circumstances will result in the debugger outputting incorrect
information**.

Returning `False` indicates that there have been changes, the cache will be flushed, and the
children will be fetched from scratch.
It is the safer option if you are unsure.

The only relationship that matters is parent-to-child.
Grandchildren depend on the `update` function of their direct parent, not that of the grandparent.

It is important to view the child cache as pointers-to-memory.
For example, if a slice's `data_ptr`
value and `length` have not changed, returning `True` is appropriate.
Even if the slice is mutable
and elements of it are overwritten (e.g. `slice[0] = 15`), because the child cache consists of
*pointers*, they will reflect the new data at that memory location.

Conversely, if `data_ptr` has changed, that means it is pointing to a new location in memory, the
child pointers are invalid, and the cache must be flushed.
If the `length` has changed, we need to flush the cache to reflect the new number of children.
If `length` has changed but `data_ptr` has
not, it is possible to store the old children in the `SyntheticProvider` itself (e.g.
`list[SBValue]`) and dole those out rather than generating them from scratch, only creating new
children if they do not already exist in the `SyntheticProvider`'s list.

For further clarification, see [this discussion](https://discourse.llvm.org/t/when-is-it-safe-to-cache-syntheticprovider-update/88608)

> NOTE: when testing the caching behavior, do not rely on LLDB's heuristic to persist variables when
> stepping. Instead, store the variable in a Python object (e.g. `v = lldb.frame.var("var_name")`),
> step forward, and then inspect the stored variable.

### (optional) `has_children`

> Overrides `SBValue.MightHaveChildren`

This is a shortcut used by LLDB to check if the value has children *at all*, without doing
potentially expensive computations to determine how many children there are (e.g. linked list).
Often, this will be a one-liner of `return True`/`return False` or
`return self.valobj.MightHaveChildren()`.

### (optional) `num_children`

> Overrides `SBValue.GetNumChildren`

Returns the total number of children that LLDB should try to access when printing the type.
This number **does not** need to match to total number of synthetic children.

The `max_children` argument can be returned if calculating the number of children can be expensive
(e.g. linked list). If this is not a consideration, `max_children` can be omitted from the function
signature.

Additionally, fields can be intentionally "hidden" from LLDB while still being accessible to the
user.
For example, one might want a `vec![1, 2, 3]` to display only its elements, but still have the
`len` and `capacity` values accessible on request.
By returning `3` from `num_children`, one can
restrict LLDB to only displaying `[1, 2, 3]`, while users can still directly access `v.len` and
`v.capacity`.
See: [Example Provider: Vec\<T\>](#example-provider-vect) to see an implementation of this.

### `get_child_index`

> Overrides `SBValue.GetIndexOfChildWithName`
>
> Affects `SBValue.GetChildMemberWithName`

Given a name, returns the index that the child should be accessed at.
It is expected that the return value of this function is passed directly to `get_child_at_index`.
As with `num_children`, the
values returned here *can* be arbitrary, so long as they are properly coordinated with
`get_child_at_index`.

One special value is `$$dereference$$`.
Accounting for this pseudo-field will allow LLDB to use the
`SBValue` returned from `get_child_at_index` as the result of a dereference via LLDB's expression
parser (e.g. `*val` and `val->field`)

### `get_child_at_index`

> Overrides `SBValue.GetChildAtIndex`

Given an index, returns a child `SBValue`.
Often these are generated via
`SBValue.CreateValueFromAddress`, but less commonly `SBValue.CreateChildAtOffset`,
`SBValue.CreateValueFromExpression`, and `SBValue.CreateValueFromData`.
These functions can be a
little finicky, so you may need to fiddle with them to get the output you want.

In some cases, `SBValue.Clone` is appropriate.
It creates a new child that is an exact copy of an existing child, but with a new name.
This is useful for cases like tuples, which have field names of
the style `__0`, `__1`, ... when we would prefer they were named `0`, `1`, ...

Small alterations can be made to the resulting child before it is returned.
This is useful for `&str`/`String`, where we would prefer if the children were displayed as
`lldb.eFormatBytesWithASCII` rather than just as a decimal value.

### (optional) `get_type_name`

> Overrides `SBValue.GetDisplayTypeName`

Overrides the displayed name of a type.
For a synthetic `SBValue` whose type name is overridden, the
original type name can still be retrieved via `SBValue.GetTypeName()` and
`SBValue.GetType().GetName()`

This can be helpful in shortening the name of common standard library types (e.g.
`std::collections::hash::map::HashMap<K, V, std::hash::random::RandomState>` -> `HashMap<K, V>`), or
in normalizing MSVC type names (e.g. `ref$<str$>` -> `&str`).

The string manipulation can be a little tricky, especially on MSVC where we cannot conveniently
access the generic parameters of the type.

### (optional) `get_value`

> Overrides `SBValue.GetValue()`, `SBValue.GetValueAsUnsigned()`, `SBValue.GetValueAsSigned()`,
>`SBValue.GetValueAsAddress()`,

The `SBValue` returned is expected to be a primitive type or pointer, and is treated as the value of
the variable in expressions.

> IMPORTANT: The `SBValue` returned **must be stored in the `SyntheticProvider`**.
> As of <!-- date-check --> Nov 2025,
> there is a bug where if the `SBValue` is acquired within `get_value` and not stored
> anywhere, Python will segfault when LLDB attempts to access the value.

## Summary Providers

Summary providers are Python functions of the following form:

```python
def SummaryProvider(valobj: SBValue, _lldb_internal) -> str: ...
```

Where the returned string is passed verbatim to the user.
If the returned value isn't a string, it
is naively convered to a string (e.g. `return None` prints `"None"`, not an empty string).

If the `SBValue` passed in is of a type that has a Synthetic Provider, `valobj.IsSynthetic()` will
return `True`, and the synthetic's corresponding functions will be used.
If this is undesirable, the original value can be retrieved via `valobj.GetNonSyntheticValue()`.
This can be helpful in cases
like `String`, where individually calling `GetChildAtIndex` in a loop is much slower than accessing
the heap pointer, reading the whole byte array directly from the debugee's memory, and using
Python's `bytes.decode()`.

### Instance Summaries

Regular `SummaryProvider` functions take an opaque `SBValue`.
That `SBValue` will reflect the type's
`SyntheticProvider` if one exists, but we cannot access the `SyntheticProvider` instance itself, or
any of its internal implementation details.
This is deterimental in cases where we need some of
those internal details to help complete the summary.
As of <!-- date-check --> Nov 2025, in the synthetic we just
run the non-synthetic value through the synthetic provider
(`synth = SyntheticProvider(valobj.GetNonSyntheticValue(), _dict)`), but this is obviously
suboptimal and there are plans to use the method outlined below.

Instead, we can leverage the Python module's state to allow for instance summaries.
Prior art for
this technique exists in the [old CodeLLDB Rust visualizer scripts](https://github.com/vadimcn/codelldb/blob/cf9574977b80e29c6de2c44d12f1071a53a54caf/formatters/rust.py#L110).

In short: every Synthetic Provider's `__init__` function stores a unique ID and a weak reference to
`self` in a global dictionary.
The Synthetic Provider class also implements a `get_summary` function.
The type's `SummaryProvider` is a function that looks up the unique ID in this dictionary,
then calls a `get_summary` on the instance it retrieves.

```python
import weakref

SYNTH_BY_ID = weakref.WeakValueDictionary()

class SyntheticProvider:
    valobj: SBValue

    # slots requires opting-in to __weakref__
    __slots__ = ("valobj", "__weakref__")

    def __init__(valobj: SBValue, _dict):
        SYNTH_BY_ID[valobj.GetID()] = self
        self.valobj = valobj

    def get_summary(self) -> str:
        ...

def InstanceSummaryProvider(valobj: SBValue, _dict) -> str:
    # GetNonSyntheticValue should never fail as InstanceSummaryProvider implies an instance of a
    # `SyntheticProvider`. No non-synthetic types should ever have this summary assigned to them
    # We use GetNonSyntheticValue because the synthetic vaobj has its own unique ID
    return SYNTH_BY_ID[valobj.GetNonSyntheticValue().GetID()].get_summary()
```

For example, one might use this for the Enum synthetic provider.
The summary would like to access
the variant name, but there isn't a convenient way to reflect this via the type name or child-values
of the synthetic.
By implementing an instance summary, we can retrieve the variant name via
`self.variant.GetTypeName()` and some string manipulation.

# Writing visualizer scripts

> IMPORTANT: Unlike GDB and CDB, LLDB can debug executables with either DWARF or PDB debug info.
>Visualizers must be written to account for both formats whenever possible. See:
>[rust-codegen](./rust-codegen.md#dwarf-vs-pdb) for an overview of the differences

Scripts are injected into LLDB via the CLI command `command script import <path-to-script>.py`.
Once
injected, classes and functions can be added to the synthetic/summary pool with `type synthetic add`
and `type summary add` respectively.
The summaries and synthetics can be associated with a
"category", which is typically named after the language the providers are intended for.
The category we use will be called `Rust`.

> TIP: all LLDB commands can be prefixed with `help` (e.g. `help type synthetic add`) for a brief
description, list of arguments, and examples.

In the past, we used `command source ...`, which executes a series of CLI commands from the
file `lldb_commands` to add providers.
This file was somewhat unwieldy,
and has been supplanted by the Python API equivalent outlined below.

## `__lldb_init_module`

This is an optional function of the form:

```python
def __lldb_init_module(debugger: SBDebugger, _lldb_internal) -> None: ...
```

This function is called at the end of `command script import ...`, but before control returns back
to the CLI.
It allows the script to initialize its own state.

Crucially, it is passed a reference to the debugger itself.
This allows us to create the `Rust` category and add providers to it.
It can also allow us to conditionally change which providers we
use depending on what version of LLDB the script detects.
This is vital for backwards compatibility
once we begin using recognizer functions, as recognizers were added in lldb 19.0.

## Visualizer resolution

The order that visualizers resolve in is listed [here][formatters_101].
In short:

[formatters_101]: https://lldb.llvm.org/use/variable.html#finding-formatters-101

* If there is an exact match (non-regex name, recognizer function, or type already matched to
provider), use that
* If the object is a pointer/reference, try to use the dereferenced type's formatter
* If the object is a typedef, check the underlying type for a formatter
* If none of the above work, iterate through the regex type matchers

Within each of those steps, **iteration is done backwards** to allow new commands to "override" old
commands.
This is important for cases like `Box<str>` vs `Box<T>`, were we want a specialized
synthetic for the former, but a more generalized synthetic for the latter.

## Minutiae

LLDB's API is very powerful, but there are some "gotchas" and unintuitive behavior, some of which
will be outlined below.
The Python implementation can be viewed at the path returned by the CLI
command `lldb -P` in `lldb\__init__.py`.
In addition to the
[examples in the lldb repo][synth_examples], there are also [C++ visualizers][plugin_cpp] that can
be used as a reference (e.g. [LibCxxVector, the equivalent to `Vec<T>`][cxx_vector]). While C++'s
visualizers are written in C++ and have access to LLDB's internals, the API and general practices
are very similar.

[synth_examples]:https://github.com/llvm/llvm-project/tree/main/lldb/examples/synthetic
[plugin_cpp]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/Language/CPlusPlus
[cxx_vector]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp

### `SBValue`

* Pointer/reference `SBValue`s will effectively "auto-deref" in some cases, acting as if the
children of the pointed-to-object are its own children.
* The non-function fields are typically [`property()`][property] fields that point directly to the
function anyway (e.g. `SBValue.type = property(GetType, None)`). Accessing through these shorthands
is a bit slower to access than just calling the function directly, so they should be avoided.
Some
of the properties return special objects with special properties (e.g. `SBValue.member` returns an
object that acts like `dict[str, SBValue]` to access children).
Internally, many of these special
objects just allocate a new class instance and call the function on the `SBValue` anyway, resulting
in additional performance loss (e.g. `SBValue.member` internally just implements `__getitem__` which
is the one-liner `return self.valobj.GetChildMemberWithName(name)`)
* `SBValue.GetID` returns a unique `int` for each value for the duration of the debug session.
Synthetic `SBValue`'s have a different ID than their underlying `SBValue`.
The underlying ID can be retrieved via `SBValue.GetNonSyntheticValue().GetID()`.
* When manually calculating an address, `SBValue.GetValueAsAddress` should be preferred over
`SBValue.GetValueAsUnsigned` due to [target-specific behavior][get_address]
* Getting a string representation of an `SBValue` can be tricky because `GetSummary` requires a
summary provider and `GetValue` requires the type be representable by a primitive.
In almost all
cases where neither of those conditions are met, the type is a user defined struct that can be
passed through `StructSummaryProvider`.

[property]: https://docs.python.org/3/library/functions.html#property
[get_address]: https://lldb.llvm.org/python_api/lldb.SBValue.html#lldb.SBValue.GetValueAsAddress

### `SBType`

* "Aggregate type" means a non-primitive struct/class/union
* "Template" is equivalent to "Generic"
* Types can be looked up by their name via `SBTarget.FindFirstType(type_name)`.
  `SBTarget` can be acquired via `SBValue.GetTarget`
* `SBType.template_args` returns `None` instead of an empty list if the type has no generics
* It is sometimes necessary to transform a type into the type you want via functions like
`SBType.GetArrayType` and `SBType.GetPointerType`.
These functions cannot fail.
They ask the underlying LLDB `TypeSystem` plugin for the type, bypassing the debug info completely.
Even if the
type does not exist in the debug info at all, these functions can create the appropriate type.
* `SBType.GetCanonicalType` is effectively `SBType.GetTypedefedType` + `SBType.GetUnqualifiedType`.
Unlike `SBType.GetTypedefedType`, it will always return a valid `SBType` regardless of whether or
not the original `SBType` is a typedef.
* `SBType.GetStaticFieldWithName` was added in LLDB 18. Unfortunately, backwards compatibility isn't
always possible since the static fields are otherwise completely inaccessible.


# Example Provider: `Vec<T>`

## SyntheticProvider

We start with the typical prelude, using `__slots__` since we have known fields.
In addition to the
object itself, we also need to store the type of the elements because `Vec`'s heap pointer is a
`*mut u8`, not a `*mut T`.
Rust is a statically typed language, so the type of `T` will never change.
That means we can store it during initialization.
The heap pointer, length, and capacity *can* change though, and thus are default initialized here.

```python
import lldb

class VecSyntheticProvider:
    valobj: SBValue
    data_ptr: SBValue
    len: int
    cap: int
    element_type: SBType

    __slots__ = (
        "valobj",
        "data_ptr",
        "len",
        "cap",
        "element_type",
        "__weakref__",
    )

    def __init__(valobj: SBValue, _dict) -> None:
        self.valobj = valobj
        # invalid type is a better default than `None`
        self.element_type = SBType()

        # special handling to account for DWARF/PDB differences
        if (arg := valobj.GetType().GetTemplateArgumentType(0)):
            self.element_type = arg
        else:
            arg_name = next(get_template_args(valobj.GetTypeName()))
            self.element_type = resolve_msvc_template_arg(arg_name, valobj.GetTarget())
```

For the implementation of `get_template_args` and `resolve_msvc_template_arg`, please see:
[`lldb_providers.py`](https://github.com/rust-lang/rust/blob/main/src/etc/lldb_providers.py#L136).

Next, the update function.
We check if the pointer or length have changed.
We can ommit checking the
capacity, as the number of children will remain the same unless `len` changes.
If changing the capacity resulted in a reallocation, `data_ptr`'s address would be different.

If `data_ptr` and `length` haven't changed, we can take advantage of LLDB's caching and return
early.
If they have changed, we store the new values and tell LLDB to flush the cache.

```python
def update(self):
    ptr = self.valobj.GetChildMemberWithName("data_ptr")
    len = self.valobj.GetChildMemberWithName("length").GetValueAsUnsigned()

    if (
        self.data_ptr.GetValueAsAddress() == ptr.GetValueAsAddress()
        and self.len == len
    ):
        # Our child address offsets and child count are still valid
        # so we can reuse cached children
        return True

    self.data_ptr = ptr
    self.len = len

    return False
```

`has_children` and `num_children` are both straightforward:

```python
def has_children(self) -> bool:
    return True

def num_children(self) -> int:
    return self.len
```

When accessing elements, we expect values of the format `[0]`, `[1]`, etc. to mimic indexing.
Additionally, we still want the user to be able to quickly access the length and capacity, as they
can be very useful when debugging.
We assign these values `u32::MAX - 1` and `u32::MAX - 2`
respectively, as we can almost surely guarantee that they will not overlap with element values.
Note that we can account for both the full and shorthand `capacity` name.

```python
    def get_child_index(self, name: str) -> int:
        index = name.lstrip("[").rstrip("]")
        if index.isdigit():
            return int(index)
        if name == "len":
            return lldb.UINT32_MAX - 1
        if name == "cap" or name == "capacity":
            return lldb.UINT32_MAX - 2

        return -1
```

We now have to properly coordinate `get_child_at_index` so that the elements, length, and capacity
are all accessible.

```python
def get_child_at_index(self, index: int) -> SBValue:
    if index == UINT32_MAX - 1:
        return self.valobj.GetChildMemberWithName("len")
    if index == UINT32_MAX - 2:
        return (
            self.valobj.GetChildMemberWithName("buf")
            .GetChildMemberWithName("inner")
            .GetChildMemberWithName("cap")
            .GetChildAtIndex(0)
            .Clone("capacity")
        )
    addr = self.data_ptr.GetValueAsAddress()
    addr += index * self.element_type.GetByteSize()
    return self.valobj.CreateValueFromAddress(f"[{index}]", addr, self.element_type)
```

For the type's display name, we can strip the path qualifier.
User defined types named `Vec` will end up fully qualified, so there shouldn't be any ambiguity.
We can also remove the allocator generic, as it's very very rarely useful.
We use `get_template_args` instead of `self.element_type.GetName()` for 3 reasons:

1. If we fail to resolve the element type for any reason, `self.valobj`'s type name can still let
the user know what the real type of the element is
2. Type names are not subject to the limitations of DWARF and PDB nodes, so the template type in
the name will reflect things like `*const`/`*mut` and `&`/`&mut`.
3. As of <!-- date-check --> Nov 2025,
we don't normalize MSVC type names, but once we do, we will need to work with the
string-names of types anyway.
It's also much easier to cache a string-to-string conversion compared
to an `SBType`-to-string conversion.

```python
def get_type_name(self) -> str:
    return f"Vec<{next(get_template_args(self.valobj))}>"
```

There isn't an appropriate primitive value with which to represent a `Vec`, so we simply ommit
the `get_value` function.

## SummaryProvider

The summary provider is very simple thanks to our synthetic provider.
The only real hiccup is that
`GetSummary` only returns a value if the object's type has a `SummaryProvider`.
If it doesn't, it will return an empty string which is not ideal.
In a full set of visualizer scripts, we can ensure
that every type that doesn't have a `GetSummary()` or a `GetValue()` is a struct, and then delegate
to a generic `StructSummaryProvider`.
For this demonstration, I will gloss over that detail.

```python
def VecSummaryProvider(valobj: SBValue, _lldb_internal) -> str:
    children = []
    for i in range(valobj.GetNumChildren()):
        child = valobj.GetChildAtIndex(i)
        summary = child.GetSummary()
        if summary is None:
            summary = child.GetValue()
            if summary is None:
                summary = "{...}"

        children.append(summary)

    return f"vec![{", ".join(children)}]"
```

## Enabling the providers

Assume this synthetic is imported into `lldb_lookup.py`

With CLI commands:

```txt
type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust
type summary add -F lldb_lookup.summary_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust
```

With `__lldb_init_module`:

```python
def __lldb_init_module(debugger: SBDebugger, _dict: LLDBOpaque):
    # Ensure the category exists and is enabled
    rust_cat = debugger.GetCategory("Rust")

    if not rust_cat.IsValid():
        rust_cat = debugger.CreateCategory("Rust")

    rust_cat.SetEnabled(True)

    # Register Vec providers
    vec_regex = r"^(alloc::([a-z_]+::)+)Vec<.+>$"
    sb_name = lldb.SBTypeNameSpecifier(vec_regex, is_regex=True)

    sb_synth = lldb.SBTypeSynthetic.CreateWithClassName("lldb_lookup.VecSyntheticProvider")
    sb_synth.SetOptions(lldb.eTypeOptionCascade)

    sb_summary = lldb.SBTypeSummary.CreateWithFunctionName("lldb_lookup.VecSummaryProvider")
    sb_summary.SetOptions(lldb.eTypeOptionCascade)

    rust_cat.AddTypeSynthetic(sb_name, sb_synth)
    rust_cat.AddSummary(sb_name, sb_summary)
```

## Output

Without providers:

```text
(lldb) v vec_v
(alloc::vec::Vec<int, alloc::alloc::Global>) vec_v = {
  buf = {
    inner = {
      ptr = {
        pointer = (pointer = "\n")
        _marker = {}
      }
      cap = (__0 = 5)
      alloc = {}
    }
    _marker = {}
  }
  len = 5
}
(lldb) v vec_v[0]
error: <user expression 0>:1:6: subscripted value is not an array or pointer
   1 | vec_v[0]
     | ^
```

With providers (`v <var_name>` prints the summary and then a list of all children):

```text
(lldb) v vec_v
(Vec<int>) vec_v = vec![10, 20, 30, 40, 50] {
  [0] = 10
  [1] = 20
  [2] = 30
  [3] = 40
  [4] = 50
}
(lldb) v vec_v[0]
(int) vec_v[0] = 10
```

We can also confirm that the "hidden" length and capacity are still accessible:

```text
(lldb) v vec_v.len
(unsigned long long) vec_v.len = 5
(lldb) v vec_v.capacity
(unsigned long long) vec_v.capacity = 5
(lldb) v vec_v.cap
(unsigned long long) vec_v.cap = 5
```
