[Lldb-commits] [lldb] [lldb][Expression] Reject languages not supported by TypeSystems for expression evaluation (PR #156648)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 4 01:37:03 PDT 2025


Michael137 wrote:

> How do we explain that for my global variable `class`,
> 
> (lldb) expr class = 110
> 
> works when I happen to be stopped in a C frame, but if I can't find a C frame around there's no way I can replicate that behavior?

> How do we explain that for my global variable `class`,
> 
> 
> 
> (lldb) expr class = 110
> 
> 
> 
> works when I happen to be stopped in a C frame, but if I can't find a C frame around there's no way I can replicate that behavior?

Good question. The reason it works for your example when stopped in a C frame is that the Clang expression evaluator has a workaround in it to allow C++ keywords in pure C/ObjC expressions. If the frame (or before this patch the `--language` flag was C/ObjC), we explicitly "unmark" the reserved C++ keywords here:
https://github.com/llvm/llvm-project/blob/cc365331af423de99ae98655d035e4892842fe97/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp#L848-L861

But that in itself still has a workaround to make C-expressions work (because we rely on `using` to capture local variables)
```
static void RemoveCppKeyword(IdentifierTable &idents, llvm::StringRef token) {
  // FIXME: 'using' is used by LLDB for local variables, so we can't remove
  // this keyword without breaking this functionality.
  if (token == "using")
    return;
```

But we're still lying to the user about this being pure C expression evaluation. All-in-all, in my opinion, it would be best to keep this workaround contained to just expression evaluation from C/ObjC-frames. If we're stopped in a context where these identifiers were used as variable names, presumably that frame must be a language where this was allowed in. So we would still support the majority of use-cases.

The only scenario I can think of that this breaks is that if we're stopped in a C-frame, then declare a top-level variable in the expression context with a reserved identifier in the name, and then switch to a C++ frame and try to use it:

```
frame #3: 0x000000010000046c a.out`func at lib.c:2:14                                                     
   1     #include <stdlib.h>             
-> 2    int func() { abort(); }                                                                           
(lldb) expr --top-level -- int namespace = 10;                                                            
(lldb) expr namespace                                
(int) $0 = 10                                                                                             
(lldb) up                                                                                                 
frame #4: 0x0000000100000454 a.out`main at main.cpp:6:5
   1    extern "C" {                                 
   2    int func();       
   3    }                                                                                                 
   4                
   5    int main() {
-> 6        func();
   7    }
(lldb) expr namespace
            ˄      
            ╰─ error: expected identifier or '{'
(lldb) down          
```

Is that a scenario we want to support?


https://github.com/llvm/llvm-project/pull/156648


More information about the lldb-commits mailing list