[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-25 Thread via lldb-commits

https://github.com/jimingham closed 
https://github.com/llvm/llvm-project/pull/85492
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-19 Thread Adrian Prantl via lldb-commits

https://github.com/adrian-prantl approved this pull request.


https://github.com/llvm/llvm-project/pull/85492
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-18 Thread via lldb-commits

https://github.com/jimingham updated 
https://github.com/llvm/llvm-project/pull/85492

>From 59320299f5aa3f9e03695e762c9fec237362c460 Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 15 Mar 2024 17:56:20 -0700
Subject: [PATCH 1/2] Add register lookup as another fallback computation for
 address-expressions

The idea behind the address-expression is that it handles all the common
expressions that produce addresses.  It handles actual valid expressions
that return a scalar, and it handles useful cases that the various source 
languages
don't support.  At present, the fallback handles:

{+-}

which isn't valid C but is very handy.

This patch adds handling of:

$

and

${+-}

That's kind of pointless in C because the C expression parser handles
that expression already.  But some languages don't have a straightforward
way to represent register values like this (swift) so having this fallback
is quite a quality of life improvement.

I added a test which tests that I didn't mess up either of these fallbacks,
though it doesn't test the actually handling of registers that I added, since
the expression parser for C succeeds in that case and returns before this code
gets run.

I will add a test on the swift fork for that checks that this works the same
way for a swift frame after this check.
---
 lldb/source/Interpreter/OptionArgParser.cpp   | 49 ---
 .../commands/target/modules/lookup/Makefile   |  4 ++
 .../lookup/TestImageLookupPCExpression.py | 27 ++
 .../API/commands/target/modules/lookup/main.c | 15 ++
 4 files changed, 88 insertions(+), 7 deletions(-)
 create mode 100644 lldb/test/API/commands/target/modules/lookup/Makefile
 create mode 100644 
lldb/test/API/commands/target/modules/lookup/TestImageLookupPCExpression.py
 create mode 100644 lldb/test/API/commands/target/modules/lookup/main.c

diff --git a/lldb/source/Interpreter/OptionArgParser.cpp 
b/lldb/source/Interpreter/OptionArgParser.cpp
index 75ccad87467e95..dd914138fe0e6b 100644
--- a/lldb/source/Interpreter/OptionArgParser.cpp
+++ b/lldb/source/Interpreter/OptionArgParser.cpp
@@ -9,7 +9,9 @@
 #include "lldb/Interpreter/OptionArgParser.h"
 #include "lldb/DataFormatters/FormatManager.h"
 #include "lldb/Target/ABI.h"
+#include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Utility/RegisterValue.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/StreamString.h"
 
@@ -233,24 +235,57 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
   // Since the compiler can't handle things like "main + 12" we should try to
   // do this for now. The compiler doesn't like adding offsets to function
   // pointer types.
+  // Some languages also don't have a natural representation for register
+  // values (e.g. swift) so handle simple uses of them here as well.
   static RegularExpression g_symbol_plus_offset_regex(
-  "^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+  "^(\\$[^ +-]+)|(([^ 
+-]+)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*)$");
 
   llvm::SmallVector matches;
   if (g_symbol_plus_offset_regex.Execute(sref, )) {
 uint64_t offset = 0;
-llvm::StringRef name = matches[1];
-llvm::StringRef sign = matches[2];
-llvm::StringRef str_offset = matches[3];
-if (!str_offset.getAsInteger(0, offset)) {
+llvm::StringRef name;
+if (!matches[1].empty())
+  name = matches[1];
+else
+  name = matches[3];
+
+llvm::StringRef sign = matches[4];
+llvm::StringRef str_offset = matches[5];
+std::optional register_value;
+StackFrame *frame = exe_ctx->GetFramePtr();
+if (frame && !name.empty() && name[0] == '$') {
+  // Some languages don't have a natural type for register values, but it
+  // is still useful to look them up here:
+  RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
+  if (reg_ctx_sp) {
+llvm::StringRef base_name = name.substr(1);
+const RegisterInfo *reg_info = 
reg_ctx_sp->GetRegisterInfoByName(base_name);
+if (reg_info) {
+  RegisterValue reg_val;
+  bool success = reg_ctx_sp->ReadRegister(reg_info, reg_val);
+  if (success && reg_val.GetType() != RegisterValue::eTypeInvalid) {
+register_value = reg_val.GetAsUInt64(0, );
+if (!success)
+  register_value.reset();
+  }
+}
+  } 
+}
+if (!str_offset.empty() && !str_offset.getAsInteger(0, offset)) {
   Status error;
-  addr = ToAddress(exe_ctx, name, LLDB_INVALID_ADDRESS, );
+  if (register_value)
+addr = register_value.value();
+  else
+addr = ToAddress(exe_ctx, name, LLDB_INVALID_ADDRESS, );
   if (addr != LLDB_INVALID_ADDRESS) {
 if (sign[0] == '+')
   return addr + offset;
 return addr - offset;
   }
-}
+} else if (register_value)
+  // In the case of register values, someone might just want to 

[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-15 Thread Adrian Prantl via lldb-commits

adrian-prantl wrote:

This is going to be incredibly useful, thanks!

https://github.com/llvm/llvm-project/pull/85492
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-15 Thread Adrian Prantl via lldb-commits


@@ -233,24 +235,57 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
   // Since the compiler can't handle things like "main + 12" we should try to
   // do this for now. The compiler doesn't like adding offsets to function
   // pointer types.
+  // Some languages also don't have a natural representation for register
+  // values (e.g. swift) so handle simple uses of them here as well.
   static RegularExpression g_symbol_plus_offset_regex(
-  "^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+  "^(\\$[^ +-]+)|(([^ 
+-]+)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*)$");
 
   llvm::SmallVector matches;
   if (g_symbol_plus_offset_regex.Execute(sref, )) {
 uint64_t offset = 0;
-llvm::StringRef name = matches[1];
-llvm::StringRef sign = matches[2];
-llvm::StringRef str_offset = matches[3];
-if (!str_offset.getAsInteger(0, offset)) {
+llvm::StringRef name;
+if (!matches[1].empty())
+  name = matches[1];
+else
+  name = matches[3];

adrian-prantl wrote:

It might help to comment with an example what match[1,3] are: 
```
// $pc + 0  ... match[1] == "$pc"
```

https://github.com/llvm/llvm-project/pull/85492
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-15 Thread Adrian Prantl via lldb-commits


@@ -233,24 +235,57 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
   // Since the compiler can't handle things like "main + 12" we should try to
   // do this for now. The compiler doesn't like adding offsets to function
   // pointer types.
+  // Some languages also don't have a natural representation for register
+  // values (e.g. swift) so handle simple uses of them here as well.
   static RegularExpression g_symbol_plus_offset_regex(
-  "^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+  "^(\\$[^ +-]+)|(([^ 
+-]+)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*)$");
 
   llvm::SmallVector matches;
   if (g_symbol_plus_offset_regex.Execute(sref, )) {
 uint64_t offset = 0;
-llvm::StringRef name = matches[1];
-llvm::StringRef sign = matches[2];
-llvm::StringRef str_offset = matches[3];
-if (!str_offset.getAsInteger(0, offset)) {
+llvm::StringRef name;
+if (!matches[1].empty())
+  name = matches[1];
+else
+  name = matches[3];
+
+llvm::StringRef sign = matches[4];
+llvm::StringRef str_offset = matches[5];
+std::optional register_value;
+StackFrame *frame = exe_ctx->GetFramePtr();
+if (frame && !name.empty() && name[0] == '$') {

adrian-prantl wrote:

or even better:
StringRef regname = name.consume_front("$");
if (!regname.empty) ...

https://github.com/llvm/llvm-project/pull/85492
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-15 Thread Adrian Prantl via lldb-commits


@@ -233,24 +235,57 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
   // Since the compiler can't handle things like "main + 12" we should try to
   // do this for now. The compiler doesn't like adding offsets to function
   // pointer types.
+  // Some languages also don't have a natural representation for register
+  // values (e.g. swift) so handle simple uses of them here as well.
   static RegularExpression g_symbol_plus_offset_regex(
-  "^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+  "^(\\$[^ +-]+)|(([^ 
+-]+)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*)$");
 
   llvm::SmallVector matches;
   if (g_symbol_plus_offset_regex.Execute(sref, )) {
 uint64_t offset = 0;
-llvm::StringRef name = matches[1];
-llvm::StringRef sign = matches[2];
-llvm::StringRef str_offset = matches[3];
-if (!str_offset.getAsInteger(0, offset)) {
+llvm::StringRef name;
+if (!matches[1].empty())
+  name = matches[1];
+else
+  name = matches[3];
+
+llvm::StringRef sign = matches[4];
+llvm::StringRef str_offset = matches[5];
+std::optional register_value;
+StackFrame *frame = exe_ctx->GetFramePtr();
+if (frame && !name.empty() && name[0] == '$') {

adrian-prantl wrote:

```suggestion
if (frame && name.starts_with("$") {
```

https://github.com/llvm/llvm-project/pull/85492
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-15 Thread via lldb-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 9405d5af65853ac548cce2656497195010db1d86 
59320299f5aa3f9e03695e762c9fec237362c460 -- 
lldb/test/API/commands/target/modules/lookup/main.c 
lldb/source/Interpreter/OptionArgParser.cpp
``





View the diff from clang-format here.


``diff
diff --git a/lldb/source/Interpreter/OptionArgParser.cpp 
b/lldb/source/Interpreter/OptionArgParser.cpp
index dd914138fe..98e0971a8d 100644
--- a/lldb/source/Interpreter/OptionArgParser.cpp
+++ b/lldb/source/Interpreter/OptionArgParser.cpp
@@ -238,7 +238,8 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
   // Some languages also don't have a natural representation for register
   // values (e.g. swift) so handle simple uses of them here as well.
   static RegularExpression g_symbol_plus_offset_regex(
-  "^(\\$[^ +-]+)|(([^ 
+-]+)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*)$");
+  "^(\\$[^ +-]+)|(([^ "
+  "+-]+)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*)$");
 
   llvm::SmallVector matches;
   if (g_symbol_plus_offset_regex.Execute(sref, )) {
@@ -259,7 +260,8 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
   RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
   if (reg_ctx_sp) {
 llvm::StringRef base_name = name.substr(1);
-const RegisterInfo *reg_info = 
reg_ctx_sp->GetRegisterInfoByName(base_name);
+const RegisterInfo *reg_info =
+reg_ctx_sp->GetRegisterInfoByName(base_name);
 if (reg_info) {
   RegisterValue reg_val;
   bool success = reg_ctx_sp->ReadRegister(reg_info, reg_val);
@@ -269,7 +271,7 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
   register_value.reset();
   }
 }
-  } 
+  }
 }
 if (!str_offset.empty() && !str_offset.getAsInteger(0, offset)) {
   Status error;
@@ -283,7 +285,7 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
 return addr - offset;
   }
 } else if (register_value)
-  // In the case of register values, someone might just want to get the 
+  // In the case of register values, someone might just want to get the
   // value in a language whose expression parser doesn't support registers.
   return register_value.value();
   }
diff --git a/lldb/test/API/commands/target/modules/lookup/main.c 
b/lldb/test/API/commands/target/modules/lookup/main.c
index afe962f309..f2be761a72 100644
--- a/lldb/test/API/commands/target/modules/lookup/main.c
+++ b/lldb/test/API/commands/target/modules/lookup/main.c
@@ -1,15 +1,11 @@
 #include 
 
-void
-doSomething()
-{
-  printf ("Set a breakpoint here.\n");
-  printf ("Need a bit more code.\n");
+void doSomething() {
+  printf("Set a breakpoint here.\n");
+  printf("Need a bit more code.\n");
 }
 
-int
-main()
-{
+int main() {
   doSomething();
   return 0;
 }

``




https://github.com/llvm/llvm-project/pull/85492
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-15 Thread via lldb-commits

github-actions[bot] wrote:




:warning: Python code formatter, darker found issues in your code. :warning:



You can test this locally with the following command:


``bash
darker --check --diff -r 
9405d5af65853ac548cce2656497195010db1d86...59320299f5aa3f9e03695e762c9fec237362c460
 lldb/test/API/commands/target/modules/lookup/TestImageLookupPCExpression.py
``





View the diff from darker here.


``diff
--- TestImageLookupPCExpression.py  2024-03-16 00:56:20.00 +
+++ TestImageLookupPCExpression.py  2024-03-16 01:08:56.473285 +
@@ -22,6 +22,5 @@
 self, "Set a breakpoint here", self.main_source_file
 )
 
 self.expect("target modules lookup -va $pc", substrs=["doSomething"])
 self.expect("target modules lookup -va $pc+4", substrs=["doSomething"])
-

``




https://github.com/llvm/llvm-project/pull/85492
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-15 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: None (jimingham)


Changes

The idea behind the address-expression is that it handles all the common 
expressions that produce addresses.  It handles actual valid expressions that 
return a scalar, and it handles useful cases that the various source languages 
don't support.  At present, the fallback handles:

symbol_name{+-}offset

which isn't valid C but is very handy.

This patch adds handling of:

$reg_name

and

$reg_name{+-}offset

That's kind of pointless in C because the C expression parser handles that 
expression already.  But some languages don't have a straightforward way to 
represent register values like this (swift) so having this fallback is quite a 
quality of life improvement.

I added a test which tests that I didn't mess up either of these fallbacks, 
though it doesn't test the actually handling of registers that I added, since 
the expression parser for C succeeds in that case and returns before this code 
gets run.

I will add a test on the swift fork for that checks that this works the same 
way for a swift frame after this check.

---
Full diff: https://github.com/llvm/llvm-project/pull/85492.diff


4 Files Affected:

- (modified) lldb/source/Interpreter/OptionArgParser.cpp (+42-7) 
- (added) lldb/test/API/commands/target/modules/lookup/Makefile (+4) 
- (added) 
lldb/test/API/commands/target/modules/lookup/TestImageLookupPCExpression.py 
(+27) 
- (added) lldb/test/API/commands/target/modules/lookup/main.c (+15) 


``diff
diff --git a/lldb/source/Interpreter/OptionArgParser.cpp 
b/lldb/source/Interpreter/OptionArgParser.cpp
index 75ccad87467e95..dd914138fe0e6b 100644
--- a/lldb/source/Interpreter/OptionArgParser.cpp
+++ b/lldb/source/Interpreter/OptionArgParser.cpp
@@ -9,7 +9,9 @@
 #include "lldb/Interpreter/OptionArgParser.h"
 #include "lldb/DataFormatters/FormatManager.h"
 #include "lldb/Target/ABI.h"
+#include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Utility/RegisterValue.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/StreamString.h"
 
@@ -233,24 +235,57 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
   // Since the compiler can't handle things like "main + 12" we should try to
   // do this for now. The compiler doesn't like adding offsets to function
   // pointer types.
+  // Some languages also don't have a natural representation for register
+  // values (e.g. swift) so handle simple uses of them here as well.
   static RegularExpression g_symbol_plus_offset_regex(
-  "^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+  "^(\\$[^ +-]+)|(([^ 
+-]+)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*)$");
 
   llvm::SmallVector matches;
   if (g_symbol_plus_offset_regex.Execute(sref, )) {
 uint64_t offset = 0;
-llvm::StringRef name = matches[1];
-llvm::StringRef sign = matches[2];
-llvm::StringRef str_offset = matches[3];
-if (!str_offset.getAsInteger(0, offset)) {
+llvm::StringRef name;
+if (!matches[1].empty())
+  name = matches[1];
+else
+  name = matches[3];
+
+llvm::StringRef sign = matches[4];
+llvm::StringRef str_offset = matches[5];
+std::optional register_value;
+StackFrame *frame = exe_ctx->GetFramePtr();
+if (frame && !name.empty() && name[0] == '$') {
+  // Some languages don't have a natural type for register values, but it
+  // is still useful to look them up here:
+  RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
+  if (reg_ctx_sp) {
+llvm::StringRef base_name = name.substr(1);
+const RegisterInfo *reg_info = 
reg_ctx_sp->GetRegisterInfoByName(base_name);
+if (reg_info) {
+  RegisterValue reg_val;
+  bool success = reg_ctx_sp->ReadRegister(reg_info, reg_val);
+  if (success && reg_val.GetType() != RegisterValue::eTypeInvalid) {
+register_value = reg_val.GetAsUInt64(0, );
+if (!success)
+  register_value.reset();
+  }
+}
+  } 
+}
+if (!str_offset.empty() && !str_offset.getAsInteger(0, offset)) {
   Status error;
-  addr = ToAddress(exe_ctx, name, LLDB_INVALID_ADDRESS, );
+  if (register_value)
+addr = register_value.value();
+  else
+addr = ToAddress(exe_ctx, name, LLDB_INVALID_ADDRESS, );
   if (addr != LLDB_INVALID_ADDRESS) {
 if (sign[0] == '+')
   return addr + offset;
 return addr - offset;
   }
-}
+} else if (register_value)
+  // In the case of register values, someone might just want to get the 
+  // value in a language whose expression parser doesn't support registers.
+  return register_value.value();
   }
 
   if (error_ptr)
diff --git a/lldb/test/API/commands/target/modules/lookup/Makefile 
b/lldb/test/API/commands/target/modules/lookup/Makefile
new file mode 100644
index 

[Lldb-commits] [lldb] Add register lookup as another fallback computation for address-expressions (PR #85492)

2024-03-15 Thread via lldb-commits

https://github.com/jimingham created 
https://github.com/llvm/llvm-project/pull/85492

The idea behind the address-expression is that it handles all the common 
expressions that produce addresses.  It handles actual valid expressions that 
return a scalar, and it handles useful cases that the various source languages 
don't support.  At present, the fallback handles:

{+-}

which isn't valid C but is very handy.

This patch adds handling of:

$

and

${+-}

That's kind of pointless in C because the C expression parser handles that 
expression already.  But some languages don't have a straightforward way to 
represent register values like this (swift) so having this fallback is quite a 
quality of life improvement.

I added a test which tests that I didn't mess up either of these fallbacks, 
though it doesn't test the actually handling of registers that I added, since 
the expression parser for C succeeds in that case and returns before this code 
gets run.

I will add a test on the swift fork for that checks that this works the same 
way for a swift frame after this check.

>From 59320299f5aa3f9e03695e762c9fec237362c460 Mon Sep 17 00:00:00 2001
From: Jim Ingham 
Date: Fri, 15 Mar 2024 17:56:20 -0700
Subject: [PATCH] Add register lookup as another fallback computation for
 address-expressions

The idea behind the address-expression is that it handles all the common
expressions that produce addresses.  It handles actual valid expressions
that return a scalar, and it handles useful cases that the various source 
languages
don't support.  At present, the fallback handles:

{+-}

which isn't valid C but is very handy.

This patch adds handling of:

$

and

${+-}

That's kind of pointless in C because the C expression parser handles
that expression already.  But some languages don't have a straightforward
way to represent register values like this (swift) so having this fallback
is quite a quality of life improvement.

I added a test which tests that I didn't mess up either of these fallbacks,
though it doesn't test the actually handling of registers that I added, since
the expression parser for C succeeds in that case and returns before this code
gets run.

I will add a test on the swift fork for that checks that this works the same
way for a swift frame after this check.
---
 lldb/source/Interpreter/OptionArgParser.cpp   | 49 ---
 .../commands/target/modules/lookup/Makefile   |  4 ++
 .../lookup/TestImageLookupPCExpression.py | 27 ++
 .../API/commands/target/modules/lookup/main.c | 15 ++
 4 files changed, 88 insertions(+), 7 deletions(-)
 create mode 100644 lldb/test/API/commands/target/modules/lookup/Makefile
 create mode 100644 
lldb/test/API/commands/target/modules/lookup/TestImageLookupPCExpression.py
 create mode 100644 lldb/test/API/commands/target/modules/lookup/main.c

diff --git a/lldb/source/Interpreter/OptionArgParser.cpp 
b/lldb/source/Interpreter/OptionArgParser.cpp
index 75ccad87467e95..dd914138fe0e6b 100644
--- a/lldb/source/Interpreter/OptionArgParser.cpp
+++ b/lldb/source/Interpreter/OptionArgParser.cpp
@@ -9,7 +9,9 @@
 #include "lldb/Interpreter/OptionArgParser.h"
 #include "lldb/DataFormatters/FormatManager.h"
 #include "lldb/Target/ABI.h"
+#include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Utility/RegisterValue.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/StreamString.h"
 
@@ -233,24 +235,57 @@ OptionArgParser::DoToAddress(const ExecutionContext 
*exe_ctx, llvm::StringRef s,
   // Since the compiler can't handle things like "main + 12" we should try to
   // do this for now. The compiler doesn't like adding offsets to function
   // pointer types.
+  // Some languages also don't have a natural representation for register
+  // values (e.g. swift) so handle simple uses of them here as well.
   static RegularExpression g_symbol_plus_offset_regex(
-  "^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+  "^(\\$[^ +-]+)|(([^ 
+-]+)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*)$");
 
   llvm::SmallVector matches;
   if (g_symbol_plus_offset_regex.Execute(sref, )) {
 uint64_t offset = 0;
-llvm::StringRef name = matches[1];
-llvm::StringRef sign = matches[2];
-llvm::StringRef str_offset = matches[3];
-if (!str_offset.getAsInteger(0, offset)) {
+llvm::StringRef name;
+if (!matches[1].empty())
+  name = matches[1];
+else
+  name = matches[3];
+
+llvm::StringRef sign = matches[4];
+llvm::StringRef str_offset = matches[5];
+std::optional register_value;
+StackFrame *frame = exe_ctx->GetFramePtr();
+if (frame && !name.empty() && name[0] == '$') {
+  // Some languages don't have a natural type for register values, but it
+  // is still useful to look them up here:
+  RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
+  if (reg_ctx_sp) {
+llvm::StringRef base_name = name.substr(1);
+