diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py index 93a44ccce215..6b1c1c961b54 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py @@ -760,6 +760,16 @@ class DebugCommunication(object): } return self.send_recv(command_dict) + def request_getCompileUnits(self, moduleId): + args_dict = {'moduleId': moduleId} + command_dict = { + 'command': 'getCompileUnits', + 'type': 'request', + 'arguments': args_dict + } + response = self.send_recv(command_dict) + return response + def request_completions(self, text): args_dict = { 'text': text, diff --git a/lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py b/lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py index 480826e46ef9..1de461ef9efa 100644 --- a/lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py +++ b/lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py @@ -46,4 +46,22 @@ class TestVSCode_module(lldbvscode_testcase.VSCodeTestCaseBase): self.assertIn('symbolFilePath', program_module) self.assertEqual(symbol_path, program_module['symbolFilePath']) self.assertIn('addressRange', program_module) - \ No newline at end of file + + def test_compile_units(self): + program= self.getBuildArtifact("a.out") + self.build_and_launch(program) + source = "main.cpp" + main_source_path = self.getSourcePath(source) + breakpoint1_line = line_number(source, '// breakpoint 1') + lines = [breakpoint1_line] + breakpoint_ids = self.set_source_breakpoints(source, lines) + self.continue_to_breakpoints(breakpoint_ids) + moduleId = self.vscode.get_active_modules()['a.out']['id'] + response = self.vscode.request_getCompileUnits(moduleId) + print(response['body']) + self.assertTrue(response['body']) + self.assertTrue(len(response['body']['compileUnits']) == 1, + 'Only one source file should exist') + self.assertTrue(response['body']['compileUnits'][0]['compileUnitPath'] == main_source_path, + 'Real path to main.cpp matches') + \ No newline at end of file diff --git a/lldb/tools/lldb-vscode/JSONUtils.cpp b/lldb/tools/lldb-vscode/JSONUtils.cpp index 1bb9480c510a..86c29fb23811 100644 --- a/lldb/tools/lldb-vscode/JSONUtils.cpp +++ b/lldb/tools/lldb-vscode/JSONUtils.cpp @@ -937,4 +937,13 @@ llvm::json::Value CreateVariable(lldb::SBValue v, int64_t variablesReference, return llvm::json::Value(std::move(object)); } +llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit unit) { + llvm::json::Object object; + char unit_path_arr[PATH_MAX]; + unit.GetFileSpec().GetPath(unit_path_arr, sizeof(unit_path_arr)); + std::string unit_path(unit_path_arr); + object.try_emplace("compileUnitPath", unit_path); + return llvm::json::Value(std::move(object)); +} + } // namespace lldb_vscode diff --git a/lldb/tools/lldb-vscode/JSONUtils.h b/lldb/tools/lldb-vscode/JSONUtils.h index 71aa87e3d523..e2ccfdb1fb2b 100644 --- a/lldb/tools/lldb-vscode/JSONUtils.h +++ b/lldb/tools/lldb-vscode/JSONUtils.h @@ -441,6 +441,8 @@ llvm::json::Value CreateThreadStopped(lldb::SBThread &thread, uint32_t stop_id); llvm::json::Value CreateVariable(lldb::SBValue v, int64_t variablesReference, int64_t varID, bool format_hex); +llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit unit); + } // namespace lldb_vscode #endif diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp index cdaaa896d4fe..27ee832677d7 100644 --- a/lldb/tools/lldb-vscode/lldb-vscode.cpp +++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -1174,6 +1174,72 @@ void request_evaluate(const llvm::json::Object &request) { g_vsc.SendJSON(llvm::json::Value(std::move(response))); } +// "getCompileUnitsRequest": { +// "allOf": [ { "$ref": "#/definitions/Request" }, { +// "type": "object", +// "description": "Compile Unit request; value of command field is +// 'getCompileUnits'.", +// "properties": { +// "command": { +// "type": "string", +// "enum": [ "getCompileUnits" ] +// }, +// "arguments": { +// "$ref": "#/definitions/getCompileUnitRequestArguments" +// } +// }, +// "required": [ "command", "arguments" ] +// }] +// }, +// "getCompileUnitsRequestArguments": { +// "type": "object", +// "description": "Arguments for 'getCompileUnits' request.", +// "properties": { +// "moduleId": { +// "type": "string", +// "description": "The ID of the module." +// } +// }, +// "required": [ "moduleId" ] +// }, +// "getCompileUnitsResponse": { +// "allOf": [ { "$ref": "#/definitions/Response" }, { +// "type": "object", +// "description": "Response to 'getCompileUnits' request.", +// "properties": { +// "body": { +// "description": "Response to 'getCompileUnits' request. Array of +// paths of compile units." +// } +// } +// }] +// } + +void request_getCompileUnits(const llvm::json::Object &request) { + llvm::json::Object response; + FillResponse(request, response); + lldb::SBProcess process = g_vsc.target.GetProcess(); + llvm::json::Object body; + llvm::json::Array units; + auto arguments = request.getObject("arguments"); + std::string module_id = std::string(GetString(arguments, "moduleId")); + int num_modules = g_vsc.target.GetNumModules(); + for (int i = 0; i < num_modules; i++) { + auto curr_module = g_vsc.target.GetModuleAtIndex(i); + if (module_id == curr_module.GetUUIDString()) { + int num_units = curr_module.GetNumCompileUnits(); + for (int j = 0; j < num_units; j++) { + auto curr_unit = curr_module.GetCompileUnitAtIndex(j);\ + units.emplace_back(CreateCompileUnit(curr_unit));\ + } + body.try_emplace("compileUnits", std::move(units)); + break; + } + } + response.try_emplace("body", std::move(body)); + g_vsc.SendJSON(llvm::json::Value(std::move(response))); +} + // "InitializeRequest": { // "allOf": [ { "$ref": "#/definitions/Request" }, { // "type": "object", @@ -2759,6 +2825,7 @@ const std::map &GetRequestHandlers() { REQUEST_CALLBACK(disconnect), REQUEST_CALLBACK(evaluate), REQUEST_CALLBACK(exceptionInfo), + REQUEST_CALLBACK(getCompileUnits), REQUEST_CALLBACK(initialize), REQUEST_CALLBACK(launch), REQUEST_CALLBACK(next),