10d01300aSJonas Devlieghere //===-- CommandObjectDiagnostics.cpp --------------------------------------===//
20d01300aSJonas Devlieghere //
30d01300aSJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40d01300aSJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information.
50d01300aSJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60d01300aSJonas Devlieghere //
70d01300aSJonas Devlieghere //===----------------------------------------------------------------------===//
80d01300aSJonas Devlieghere
90d01300aSJonas Devlieghere #include "CommandObjectDiagnostics.h"
100d01300aSJonas Devlieghere #include "lldb/Host/OptionParser.h"
110d01300aSJonas Devlieghere #include "lldb/Interpreter/CommandOptionArgumentTable.h"
120d01300aSJonas Devlieghere #include "lldb/Interpreter/CommandReturnObject.h"
130d01300aSJonas Devlieghere #include "lldb/Interpreter/OptionArgParser.h"
140d01300aSJonas Devlieghere #include "lldb/Interpreter/OptionValueEnumeration.h"
150d01300aSJonas Devlieghere #include "lldb/Interpreter/OptionValueUInt64.h"
160d01300aSJonas Devlieghere #include "lldb/Interpreter/Options.h"
170d01300aSJonas Devlieghere #include "lldb/Utility/Diagnostics.h"
180d01300aSJonas Devlieghere
190d01300aSJonas Devlieghere using namespace lldb;
200d01300aSJonas Devlieghere using namespace lldb_private;
210d01300aSJonas Devlieghere
220d01300aSJonas Devlieghere #define LLDB_OPTIONS_diagnostics_dump
230d01300aSJonas Devlieghere #include "CommandOptions.inc"
240d01300aSJonas Devlieghere
250d01300aSJonas Devlieghere class CommandObjectDiagnosticsDump : public CommandObjectParsed {
260d01300aSJonas Devlieghere public:
270d01300aSJonas Devlieghere // Constructors and Destructors
CommandObjectDiagnosticsDump(CommandInterpreter & interpreter)280d01300aSJonas Devlieghere CommandObjectDiagnosticsDump(CommandInterpreter &interpreter)
290d01300aSJonas Devlieghere : CommandObjectParsed(interpreter, "diagnostics dump",
300d01300aSJonas Devlieghere "Dump diagnostics to disk", nullptr) {}
310d01300aSJonas Devlieghere
320d01300aSJonas Devlieghere ~CommandObjectDiagnosticsDump() override = default;
330d01300aSJonas Devlieghere
340d01300aSJonas Devlieghere class CommandOptions : public Options {
350d01300aSJonas Devlieghere public:
360d01300aSJonas Devlieghere CommandOptions() = default;
370d01300aSJonas Devlieghere
380d01300aSJonas Devlieghere ~CommandOptions() override = default;
390d01300aSJonas Devlieghere
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)400d01300aSJonas Devlieghere Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
410d01300aSJonas Devlieghere ExecutionContext *execution_context) override {
420d01300aSJonas Devlieghere Status error;
430d01300aSJonas Devlieghere const int short_option = m_getopt_table[option_idx].val;
440d01300aSJonas Devlieghere
450d01300aSJonas Devlieghere switch (short_option) {
460d01300aSJonas Devlieghere case 'd':
470d01300aSJonas Devlieghere directory.SetDirectory(option_arg);
480d01300aSJonas Devlieghere break;
490d01300aSJonas Devlieghere default:
500d01300aSJonas Devlieghere llvm_unreachable("Unimplemented option");
510d01300aSJonas Devlieghere }
520d01300aSJonas Devlieghere return error;
530d01300aSJonas Devlieghere }
540d01300aSJonas Devlieghere
OptionParsingStarting(ExecutionContext * execution_context)550d01300aSJonas Devlieghere void OptionParsingStarting(ExecutionContext *execution_context) override {
560d01300aSJonas Devlieghere directory.Clear();
570d01300aSJonas Devlieghere }
580d01300aSJonas Devlieghere
GetDefinitions()590d01300aSJonas Devlieghere llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
60984b800aSserge-sans-paille return llvm::ArrayRef(g_diagnostics_dump_options);
610d01300aSJonas Devlieghere }
620d01300aSJonas Devlieghere
630d01300aSJonas Devlieghere FileSpec directory;
640d01300aSJonas Devlieghere };
650d01300aSJonas Devlieghere
GetOptions()660d01300aSJonas Devlieghere Options *GetOptions() override { return &m_options; }
670d01300aSJonas Devlieghere
680d01300aSJonas Devlieghere protected:
GetDirectory()690d01300aSJonas Devlieghere llvm::Expected<FileSpec> GetDirectory() {
700d01300aSJonas Devlieghere if (m_options.directory) {
710d01300aSJonas Devlieghere auto ec =
720d01300aSJonas Devlieghere llvm::sys::fs::create_directories(m_options.directory.GetPath());
730d01300aSJonas Devlieghere if (ec)
740d01300aSJonas Devlieghere return llvm::errorCodeToError(ec);
750d01300aSJonas Devlieghere return m_options.directory;
760d01300aSJonas Devlieghere }
770d01300aSJonas Devlieghere return Diagnostics::CreateUniqueDirectory();
780d01300aSJonas Devlieghere }
790d01300aSJonas Devlieghere
DoExecute(Args & args,CommandReturnObject & result)80*92d8a28cSPete Lawrence void DoExecute(Args &args, CommandReturnObject &result) override {
810d01300aSJonas Devlieghere llvm::Expected<FileSpec> directory = GetDirectory();
820d01300aSJonas Devlieghere
830d01300aSJonas Devlieghere if (!directory) {
840d01300aSJonas Devlieghere result.AppendError(llvm::toString(directory.takeError()));
85*92d8a28cSPete Lawrence return;
860d01300aSJonas Devlieghere }
870d01300aSJonas Devlieghere
880d01300aSJonas Devlieghere llvm::Error error = Diagnostics::Instance().Create(*directory);
890d01300aSJonas Devlieghere if (error) {
900d01300aSJonas Devlieghere result.AppendErrorWithFormat("failed to write diagnostics to %s",
910d01300aSJonas Devlieghere directory->GetPath().c_str());
920d01300aSJonas Devlieghere result.AppendError(llvm::toString(std::move(error)));
93*92d8a28cSPete Lawrence return;
940d01300aSJonas Devlieghere }
950d01300aSJonas Devlieghere
960d01300aSJonas Devlieghere result.GetOutputStream() << "diagnostics written to " << *directory << '\n';
970d01300aSJonas Devlieghere
980d01300aSJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishResult);
99*92d8a28cSPete Lawrence return;
1000d01300aSJonas Devlieghere }
1010d01300aSJonas Devlieghere
1020d01300aSJonas Devlieghere CommandOptions m_options;
1030d01300aSJonas Devlieghere };
1040d01300aSJonas Devlieghere
CommandObjectDiagnostics(CommandInterpreter & interpreter)1050d01300aSJonas Devlieghere CommandObjectDiagnostics::CommandObjectDiagnostics(
1060d01300aSJonas Devlieghere CommandInterpreter &interpreter)
1070d01300aSJonas Devlieghere : CommandObjectMultiword(interpreter, "diagnostics",
1080d01300aSJonas Devlieghere "Commands controlling LLDB diagnostics.",
1090d01300aSJonas Devlieghere "diagnostics <subcommand> [<command-options>]") {
1100d01300aSJonas Devlieghere LoadSubCommand(
1110d01300aSJonas Devlieghere "dump", CommandObjectSP(new CommandObjectDiagnosticsDump(interpreter)));
1120d01300aSJonas Devlieghere }
1130d01300aSJonas Devlieghere
1140d01300aSJonas Devlieghere CommandObjectDiagnostics::~CommandObjectDiagnostics() = default;
115