Skip to content

[lldb][RPC] Upstream LLDB to RPC converstion Python script #138028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

chelcassanova
Copy link
Contributor

@chelcassanova chelcassanova commented Apr 30, 2025

As part of upstreaming LLDB RPC, this commit adds a python script that
is used by LLDB RPC to modify the public lldb header files for use with
RPC.

https://discourse.llvm.org/t/rfc-upstreaming-lldb-rpc/85804

@llvmbot
Copy link
Member

llvmbot commented Apr 30, 2025

@llvm/pr-subscribers-lldb

Author: Chelsea Cassanova (chelcassanova)

Changes

As part of upstreaming LLDB RPC, this commit adds python scripts that are used by LLDB RPC to modify the public lldb header files for use with RPC.

https://discourse.llvm.org/t/rfc-upstreaming-lldb-rpc/85804


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

3 Files Affected:

  • (added) lldb/scripts/convert-lldb-header-to-rpc-header.py (+65)
  • (added) lldb/scripts/framework-header-include-fix.py (+44)
  • (added) lldb/scripts/framework-header-version-fix.py (+65)
diff --git a/lldb/scripts/convert-lldb-header-to-rpc-header.py b/lldb/scripts/convert-lldb-header-to-rpc-header.py
new file mode 100755
index 0000000000000..4550837d8e08d
--- /dev/null
+++ b/lldb/scripts/convert-lldb-header-to-rpc-header.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+# Usage: convert-lldb-header-to-rpc-header.py <path/to/input-header.h> <path/to/output-header.h>
+# This scripts takes common LLDB headers (such as lldb-defines.h) and replaces references to LLDB
+# with those for RPC. This happens for:
+# - namespace definitions
+# - namespace usage
+# - version string macros
+# - ifdef/ifndef lines
+
+import argparse
+import os
+import re
+
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("input")
+    parser.add_argument("output")
+    args = parser.parse_args()
+    input_path = str(args.input)
+    output_path = str(args.output)
+    with open(input_path, "r") as input_file:
+        lines = input_file.readlines()
+
+    with open(output_path, "w") as output_file:
+        for line in lines:
+            # NOTE: We do not use lldb-forward.h or lldb-versioning.h in RPC, so remove
+            # all includes that are found for these files.
+            if re.match(
+                r'#include "lldb/lldb-forward|#include "lldb/lldb-versioning', line
+            ):
+                continue
+            # For lldb-rpc-defines.h, replace the ifndef LLDB_LLDB_ portion with LLDB_RPC_ as we're not
+            # using LLDB private definitions in RPC.
+            elif re.match(r".+LLDB_LLDB_", line):
+                output_file.write(re.sub(r"LLDB_LLDB_", r"LLDB_RPC_", line))
+            # Similarly to lldb-rpc-defines.h, replace the ifndef for LLDB_API in SBDefines.h to LLDB_RPC_API_ for the same reason.
+            elif re.match(r".+LLDB_API_", line):
+                output_file.write(re.sub(r"LLDB_API_", r"LLDB_RPC_API_", line))
+            # Replace the references for the macros that define the versioning strings in
+            # lldb-rpc-defines.h.
+            elif re.match(r".+LLDB_VERSION", line):
+                output_file.write(re.sub(r"LLDB_VERSION", r"LLDB_RPC_VERSION", line))
+            elif re.match(r".+LLDB_REVISION", line):
+                output_file.write(re.sub(r"LLDB_REVISION", r"LLDB_RPC_REVISION", line))
+            elif re.match(r".+LLDB_VERSION_STRING", line):
+                output_file.write(
+                    re.sub(r"LLDB_VERSION_STRING", r"LLDB_RPC_VERSION_STRING", line)
+                )
+            # For local #includes
+            elif re.match(r'#include "lldb/lldb-', line):
+                output_file.write(re.sub(r"lldb/lldb-", r"lldb-rpc-", line))
+            # Rename the lldb namespace definition to lldb-rpc.
+            elif re.match(r"namespace lldb", line):
+                output_file.write(re.sub(r"lldb", r"lldb_rpc", line))
+            # Rename namespace references
+            elif re.match(r".+lldb::", line):
+                output_file.write(re.sub(r"lldb::", r"lldb_rpc::", line))
+            else:
+                # Write any line that doesn't need to be converted
+                output_file.write(line)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/lldb/scripts/framework-header-include-fix.py b/lldb/scripts/framework-header-include-fix.py
new file mode 100755
index 0000000000000..e214ce005923f
--- /dev/null
+++ b/lldb/scripts/framework-header-include-fix.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+# Usage: framework-header-include-fix.py <path/to/input-header.h> <path/to/output-header.h>
+# This script modifies all #include lines in all lldb-rpc headers
+# from either filesystem or local includes to liblldbrpc includes.
+
+import argparse
+import os
+import re
+
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("input")
+    parser.add_argument("output")
+    args = parser.parse_args()
+    input_path = str(args.input)
+    output_path = str(args.output)
+    with open(input_path, "r+") as input_file:
+        lines = input_file.readlines()
+
+    with open(output_path, "w+") as output_file:
+        for line in lines:
+            # Replace includes from RPCCommon to liblldbrpc includes.
+            # e.g. #include <lldb-rpc/common/RPCArgument.h> -> #include <LLDBRPC/RPCArgument.h>
+            if re.match(r".+<lldb-rpc/common", line):
+                output_file.write(re.sub(r"<lldb-rpc/common", r"<LLDBRPC", line))
+                # Replace all local file includes to liblldbrpc includes.
+                # e.g. #include "SBFoo.h" -> #include <LLDBRPC/SBFoo.h>
+            elif re.match(r'#include "(.*)"', line):
+                include_filename = re.search(r'#include "(.*)"', line).groups()[0]
+                output_file.write(
+                    re.sub(
+                        r'#include "(.*)"',
+                        r"#include <LLDBRPC/" + include_filename + ">",
+                        line,
+                    )
+                )
+            else:
+                # Write any line that doesn't need to be converted
+                output_file.write(line)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/lldb/scripts/framework-header-version-fix.py b/lldb/scripts/framework-header-version-fix.py
new file mode 100755
index 0000000000000..72185f8e820ce
--- /dev/null
+++ b/lldb/scripts/framework-header-version-fix.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+# Usage: framework-header-version-fix.py <path/to/input-header.h> <path/to/output-header.h> MAJOR MINOR PATCH
+# This script modifies lldb-rpc-defines.h to uncomment the macro defines used for the LLDB
+# major, minor and patch values as well as populating their definitions.
+
+import argparse
+import os
+import re
+
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("input")
+    parser.add_argument("output")
+    parser.add_argument("lldb_version_major")
+    parser.add_argument("lldb_version_minor")
+    parser.add_argument("lldb_version_patch")
+    args = parser.parse_args()
+    input_path = str(args.input)
+    output_path = str(args.output)
+    lldb_version_major = args.lldb_version_major
+    lldb_version_minor = args.lldb_version_minor
+    lldb_version_patch = args.lldb_version_patch
+
+    with open(input_path, "r") as input_file:
+        lines = input_file.readlines()
+
+    with open(output_path, "w") as output_file:
+        for line in lines:
+            # Uncomment the line that defines the LLDB major version and populate its value.
+            if re.match(r"//#define LLDB_RPC_VERSION$", line):
+                output_file.write(
+                    re.sub(
+                        r"//#define LLDB_RPC_VERSION",
+                        r"#define LLDB_RPC_VERSION " + lldb_version_major,
+                        line,
+                    )
+                )
+            # Uncomment the line that defines the LLDB minor version and populate its value.
+            elif re.match(r"//#define LLDB_RPC_REVISION$", line):
+                output_file.write(
+                    re.sub(
+                        r"//#define LLDB_RPC_REVISION",
+                        r"#define LLDB_RPC_REVISION " + lldb_version_minor,
+                        line,
+                    )
+                )
+            # Uncomment the line that defines the complete LLDB version string and populate its value.
+            elif re.match(r"//#define LLDB_RPC_VERSION_STRING$", line):
+                output_file.write(
+                    re.sub(
+                        r"//#define LLDB_RPC_VERSION_STRING",
+                        r'#define LLDB_RPC_VERSION_STRING "{0}.{1}.{2}"'.format(
+                            lldb_version_major, lldb_version_minor, lldb_version_patch
+                        ),
+                        line,
+                    )
+                )
+            else:
+                # Write any line that doesn't need to be converted
+                output_file.write(line)
+
+
+if __name__ == "__main__":
+    main()

@JDevlieghere
Copy link
Member

We should add shell tests for these scripts.

@chelcassanova
Copy link
Contributor Author

I can add shell tests 👍🏾

@chelcassanova chelcassanova force-pushed the upstream-lldb-rpc/add-python-scripts-for-headers branch from c915f7c to c51a312 Compare May 2, 2025 18:46
Copy link
Member

@bulbazord bulbazord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding tests. Please let others take a look before merging.

@chelcassanova
Copy link
Contributor Author

For what it's worth, while these scripts do work for intended purpose for now, an approach I'd love is to have all this header modification be a subtool of the lldb-rpc-gen tool itself. Subtooling a ClangTool is something I'm not too sure on how to do so maybe a better Clang expert can help guide the way on this? :)

@chelcassanova chelcassanova force-pushed the upstream-lldb-rpc/add-python-scripts-for-headers branch from c51a312 to a00c76d Compare May 13, 2025 22:39
@chelcassanova
Copy link
Contributor Author

@DavidSpickett I pushed here to address most of the outstanding changes I needed to make from your comments, and this change should also fix the CI issue on BuildKite. Could you give this patch another pass over?

Comment on lines 1 to 4
// Copy lldb-defines.h from source.
# RUN: mkdir -p %t/input
# RUN: mkdir -p %t/output
# RUN: cp %p/../../../../../include/lldb/lldb-defines.h %t/input
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're mixing two comment styles here, and lit doesn't actually treat these any differently (it just look for RUN lines). So let's settle on one and drop them everywhere else.

Suggested change
// Copy lldb-defines.h from source.
# RUN: mkdir -p %t/input
# RUN: mkdir -p %t/output
# RUN: cp %p/../../../../../include/lldb/lldb-defines.h %t/input
// Copy lldb-defines.h from source.
RUN: mkdir -p %t/input
RUN: mkdir -p %t/output
RUN: cp %p/../../../../../include/lldb/lldb-defines.h %t/input

or

Suggested change
// Copy lldb-defines.h from source.
# RUN: mkdir -p %t/input
# RUN: mkdir -p %t/output
# RUN: cp %p/../../../../../include/lldb/lldb-defines.h %t/input
# Copy lldb-defines.h from source.
RUN: mkdir -p %t/input
RUN: mkdir -p %t/output
RUN: cp %p/../../../../../include/lldb/lldb-defines.h %t/input

I think the latter is slightly more common.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I didn't know that about llvm-lit. I'll change everything to use Python-style comments and remove the hashes from the lit commands

Comment on lines 2 to 8
# Usage: convert-lldb-header-to-rpc-header.py <path/to/input-header.h> <path/to/output-header.h>
# This scripts takes common LLDB headers (such as lldb-defines.h) and replaces references to LLDB
# with those for RPC. This happens for:
# - namespace definitions
# - namespace usage
# - version string macros
# - ifdef/ifndef lines
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python has a PEP that describes how to document files/modules. We should use that here too.

Suggested change
# Usage: convert-lldb-header-to-rpc-header.py <path/to/input-header.h> <path/to/output-header.h>
# This scripts takes common LLDB headers (such as lldb-defines.h) and replaces references to LLDB
# with those for RPC. This happens for:
# - namespace definitions
# - namespace usage
# - version string macros
# - ifdef/ifndef lines
"""
Usage: convert-lldb-header-to-rpc-header.py <path/to/input-header.h> <path/to/output-header.h>
This scripts takes common LLDB headers (such as lldb-defines.h) and replaces references to LLDB
with those for RPC. This happens for:
- namespace definitions
- namespace usage
- version string macros
- ifdef/ifndef lines
"""

Comment on lines 1 to 4
// Copy lldb-rpc-defines.h from source.
# RUN: mkdir -p %t/input
# RUN: mkdir -p %t/output
# RUN: cp %p/../../../../../include/lldb/lldb-defines.h %t/input
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the goal to run this on the sources to catch regressions, or are we just using the source file as a meaningful input? If it's the latter, I would recommend copying the file into the Inputs directory and reducing it to the bare minimum needed for the test.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the script failed to work at all, that would be caught by the build step, right?

In which case yes the input for this should be small. It'll save us cutting down the real file to find the place that's failing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed all the tests so that the files are no longer copied from source. Each test should now be using truncated versions of whatever files will be operated on and these files are in the tests' Inputs directory.

Copy link
Collaborator

@DavidSpickett DavidSpickett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With Jonas' comments addressed I'm probably fine with this. Need to read the design doc again to be sure.

@chelcassanova chelcassanova force-pushed the upstream-lldb-rpc/add-python-scripts-for-headers branch 4 times, most recently from 01e35b2 to 2b6f460 Compare May 27, 2025 19:34
@chelcassanova
Copy link
Contributor Author

I think this could be ready to land now @DavidSpickett and @JDevlieghere, could you give this another once over?

@chelcassanova chelcassanova force-pushed the upstream-lldb-rpc/add-python-scripts-for-headers branch from 2b6f460 to 4520d08 Compare May 28, 2025 21:13
@chelcassanova chelcassanova changed the title [lldb][RPC] Upstream Python scripts [lldb][RPC] Upstream LLDB to RPC converstion Python script May 28, 2025
Copy link
Collaborator

@DavidSpickett DavidSpickett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with the license comment addressed.

@DavidSpickett
Copy link
Collaborator

CI failure but looks unrelated.

@chelcassanova chelcassanova force-pushed the upstream-lldb-rpc/add-python-scripts-for-headers branch from 4520d08 to 208288f Compare May 30, 2025 22:46
Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Might be worth making this match the other scripts and doing this once instead of line-by-line.

@chelcassanova chelcassanova force-pushed the upstream-lldb-rpc/add-python-scripts-for-headers branch from 208288f to 4f818cc Compare June 4, 2025 16:24
Copy link

github-actions bot commented Jun 4, 2025

✅ With the latest revision this PR passed the Python code formatter.

As part of upstreaming LLDB RPC, this commit adds a python script that
is used by LLDB RPC to modify the public lldb header files for use with
RPC.

https://discourse.llvm.org/t/rfc-upstreaming-lldb-rpc/85804
@chelcassanova chelcassanova force-pushed the upstream-lldb-rpc/add-python-scripts-for-headers branch from 4f818cc to ba96f13 Compare June 4, 2025 16:30
@chelcassanova
Copy link
Contributor Author

Might be worth making this match the other scripts and doing this once instead of line-by-line.

Updated the patch to do this 👍🏾

@chelcassanova chelcassanova merged commit a2d2941 into llvm:main Jun 11, 2025
10 checks passed
tomtor pushed a commit to tomtor/llvm-project that referenced this pull request Jun 14, 2025
As part of upstreaming LLDB RPC, this commit adds a python script that
is used by LLDB RPC to modify the public lldb header files for use with
RPC.

https://discourse.llvm.org/t/rfc-upstreaming-lldb-rpc/85804
chelcassanova added a commit to chelcassanova/llvm-project that referenced this pull request Jun 17, 2025
As part of upstreaming LLDB RPC, this commit adds a python script that
is used by LLDB RPC to modify the public lldb header files for use with
RPC.

https://discourse.llvm.org/t/rfc-upstreaming-lldb-rpc/85804
(cherry picked from commit a2d2941)
akuhlens pushed a commit to akuhlens/llvm-project that referenced this pull request Jun 24, 2025
As part of upstreaming LLDB RPC, this commit adds a python script that
is used by LLDB RPC to modify the public lldb header files for use with
RPC.

https://discourse.llvm.org/t/rfc-upstreaming-lldb-rpc/85804
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants