From 5d4ea841ccbc919deaf2aaf53fec20f5af4c8b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E9=BE=99=E6=88=90?= Date: Wed, 26 Nov 2025 09:55:06 +0800 Subject: [PATCH] add lldb Type summary --- .gitignore | 3 ++- .vscode/launch.json | 10 ++++++++-- include/lightir/BasicBlock.hpp | 17 ++++++++++++++--- include/lightir/Constant.hpp | 3 ++- lldb_formatters.py | 23 +++++++++++++++++++++++ src/lightir/Constant.cpp | 16 +++++++++++----- src/lightir/Function.cpp | 15 --------------- src/lightir/Type.cpp | 11 +++++++---- tests/1-parser/.gitignore | 3 ++- 9 files changed, 69 insertions(+), 32 deletions(-) create mode 100644 lldb_formatters.py diff --git a/.gitignore b/.gitignore index 7a4fac0..ea22ee2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ build/ .vs out CMakePresets.json -Folder.DotSettings.user \ No newline at end of file +Folder.DotSettings.user +.env \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 08d2cf4..07303e2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,7 +16,10 @@ // 程序运行的目录 "cwd": "${workspaceFolder}", // 程序运行前运行的命令(例如 build) - "preLaunchTask": "make cminusfc" + "preLaunchTask": "make cminusfc", + "initCommands": [ + "command script import ${workspaceFolder}/lldb_formatters.py" + ] }, { "type": "lldb", @@ -32,7 +35,10 @@ "./build/1.cminus" ], // 程序运行的目录 - "cwd": "${workspaceFolder}" + "cwd": "${workspaceFolder}", + "initCommands": [ + "command script import ${workspaceFolder}/lldb_formatters.py" + ] } ] } \ No newline at end of file diff --git a/include/lightir/BasicBlock.hpp b/include/lightir/BasicBlock.hpp index 3bbc935..bbefd6e 100755 --- a/include/lightir/BasicBlock.hpp +++ b/include/lightir/BasicBlock.hpp @@ -27,11 +27,22 @@ class BasicBlock : public Value { std::list &get_pre_basic_blocks() { return pre_bbs_; } std::list &get_succ_basic_blocks() { return succ_bbs_; } - void add_pre_basic_block(BasicBlock *bb) { pre_bbs_.push_back(bb); } - void add_succ_basic_block(BasicBlock *bb) { succ_bbs_.push_back(bb); } + // 自动去重 + void add_pre_basic_block(BasicBlock *bb) + { + for (auto i : pre_bbs_) if (i == bb) return; + pre_bbs_.push_back(bb); + } + // 自动去重 + void add_succ_basic_block(BasicBlock *bb) + { + for (auto i : succ_bbs_) if (i == bb) return; + succ_bbs_.push_back(bb); + } void remove_pre_basic_block(BasicBlock *bb) { pre_bbs_.remove(bb); } + // 若你将 br label0, label0 的其中一个 label0 改为 label1,并且调用 remove_suc label0,那 suc 集合中也将不再包含 label0 void remove_succ_basic_block(BasicBlock *bb) { succ_bbs_.remove(bb); } - BasicBlock* get_entry_block_of_same_function() const; + BasicBlock* get_entry_block_of_same_function() const; // If the Block is terminated by ret/br bool is_terminated() const; diff --git a/include/lightir/Constant.hpp b/include/lightir/Constant.hpp index 14f504a..cacacd1 100755 --- a/include/lightir/Constant.hpp +++ b/include/lightir/Constant.hpp @@ -15,12 +15,13 @@ public: Constant(Type *ty, const std::string &name = "") : User(ty, name) {} ~Constant() override; +protected: }; class ConstantInt : public Constant { private: int value_; - ConstantInt(Type *ty, int val) : Constant(ty, ""), value_(val) {} + ConstantInt(Type* ty, int val) : Constant(ty, ""), value_(val) {} public: int get_value() const { return value_; } diff --git a/lldb_formatters.py b/lldb_formatters.py new file mode 100644 index 0000000..71b9506 --- /dev/null +++ b/lldb_formatters.py @@ -0,0 +1,23 @@ +import lldb + +def parseString(val : lldb.SBValue): + summary = val.GetSummary() or val.GetValue() + if summary: + # 去掉两端引号,只留裸文本(可选) + if summary.startswith('"') and summary.endswith('"'): + summary = summary[1:-1] + return summary + return "" + +def TypePrinterSummary(valobj: lldb.SBValue, internal_dict): + # 调用 print 函数进行显示 + name: lldb.SBValue = valobj.EvaluateExpression("print()"); + return parseString(name) + +def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict): + types = ["Type", "IntegerType", "FunctionType", "ArrayType", "PointerType", "FloatType"] + for i in types: + debugger.HandleCommand( + f"type summary add -F lldb_formatters.TypePrinterSummary {i} -w my" + ) + debugger.HandleCommand("type category enable my") \ No newline at end of file diff --git a/src/lightir/Constant.cpp b/src/lightir/Constant.cpp index d80a371..4e4edbb 100755 --- a/src/lightir/Constant.cpp +++ b/src/lightir/Constant.cpp @@ -34,16 +34,18 @@ Constant::~Constant() = default; ConstantInt *ConstantInt::get(int val, Module *m) { if (cached_int.find(std::make_pair(val, m)) != cached_int.end()) return cached_int[std::make_pair(val, m)].get(); - return (cached_int[std::make_pair(val, m)] = std::unique_ptr( + ConstantInt* ret = (cached_int[std::make_pair(val, m)] = std::unique_ptr( new ConstantInt(m->get_int32_type(), val))) .get(); + return ret; } ConstantInt *ConstantInt::get(bool val, Module *m) { if (cached_bool.find(std::make_pair(val, m)) != cached_bool.end()) return cached_bool[std::make_pair(val, m)].get(); - return (cached_bool[std::make_pair(val, m)] = std::unique_ptr( + auto ret = (cached_bool[std::make_pair(val, m)] = std::unique_ptr( new ConstantInt(m->get_int1_type(), val ? 1 : 0))) .get(); + return ret; } std::string ConstantInt::print() { std::string const_ir; @@ -73,7 +75,8 @@ Constant *ConstantArray::get_element_value(int index) const ConstantArray *ConstantArray::get(ArrayType *ty, const std::vector &val) { - return new ConstantArray(ty, val); + auto ret = new ConstantArray(ty, val); + return ret; } std::string ConstantArray::print() { @@ -98,9 +101,10 @@ std::string ConstantArray::print() { ConstantFP *ConstantFP::get(float val, Module *m) { if (cached_float.find(std::make_pair(val, m)) != cached_float.end()) return cached_float[std::make_pair(val, m)].get(); - return (cached_float[std::make_pair(val, m)] = std::unique_ptr( + auto ret = (cached_float[std::make_pair(val, m)] = std::unique_ptr( new ConstantFP(m->get_float_type(), val))) .get(); + return ret; } std::string ConstantFP::print() { @@ -116,7 +120,9 @@ std::string ConstantFP::print() { ConstantZero *ConstantZero::get(Type *ty, Module *m) { if (not cached_zero[ty]) - cached_zero[ty] = std::unique_ptr(new ConstantZero(ty)); + { + cached_zero[ty] = std::unique_ptr(new ConstantZero(ty)); + } return cached_zero[ty].get(); } diff --git a/src/lightir/Function.cpp b/src/lightir/Function.cpp index e3cddc9..c1649dd 100755 --- a/src/lightir/Function.cpp +++ b/src/lightir/Function.cpp @@ -159,21 +159,6 @@ void Function::check_for_block_relation_error() const assert((bbs.count(i)) && "函数 F 的基本块表中包含基本块 a, a 的前驱块表中的某基本块 b 不在 F 的基本块表中"); } } - // 检查基本块的前驱和后继表不包含重复的基本块 - /* - for (auto& bb : basic_blocks_) - { - bbs.clear(); - for(auto suc: bb.get_succ_basic_blocks()){ - assert((!bbs.count(suc)) && "基本块的后继表中包含重复项目"); - bbs.emplace(suc); - } - for(auto suc: bb.get_pre_basic_blocks()){ - assert((!bbs.count(suc)) && "基本块的前驱表中包含重复项目"); - bbs.emplace(suc); - } - } - */ // 检查基本块基本信息 for (auto bb : basic_blocks_) { diff --git a/src/lightir/Type.cpp b/src/lightir/Type.cpp index ad41a4f..d5106cb 100755 --- a/src/lightir/Type.cpp +++ b/src/lightir/Type.cpp @@ -112,14 +112,16 @@ std::string Type::print() const { } IntegerType::IntegerType(unsigned num_bits, Module *m) - : Type(Type::IntegerTyID, m), num_bits_(num_bits) {} + : Type(Type::IntegerTyID, m), num_bits_(num_bits) +{ +} IntegerType::~IntegerType() = default; unsigned IntegerType::get_num_bits() const { return num_bits_; } FunctionType::FunctionType(Type *result, const std::vector& params) - : Type(Type::FunctionTyID, nullptr) { + : Type(Type::FunctionTyID, result->get_module()) { assert(is_valid_return_type(result) && "Invalid return type for function!"); result_ = result; @@ -171,7 +173,7 @@ ArrayType *ArrayType::get(Type *contained, unsigned num_elements) { PointerType::PointerType(Type *contained) : Type(Type::PointerTyID, contained->get_module()), contained_(contained) { - static constexpr std::array allowed_elem_type = { + static constexpr std::array allowed_elem_type = { Type::IntegerTyID, Type::FloatTyID, Type::ArrayTyID, Type::PointerTyID}; auto elem_type_id = contained->get_type_id(); assert(std::find(allowed_elem_type.begin(), allowed_elem_type.end(), @@ -185,7 +187,8 @@ PointerType *PointerType::get(Type *contained) { return contained->get_module()->get_pointer_type(contained); } -FloatType::FloatType(Module *m) : Type(Type::FloatTyID, m) {} +FloatType::FloatType(Module *m) : Type(Type::FloatTyID, m) { +} FloatType::~FloatType() = default; diff --git a/tests/1-parser/.gitignore b/tests/1-parser/.gitignore index 12288a7..1fb214d 100755 --- a/tests/1-parser/.gitignore +++ b/tests/1-parser/.gitignore @@ -1 +1,2 @@ -output_student_ast \ No newline at end of file +output_student_ast +output_student \ No newline at end of file -- GitLab