xref: /llvm-project/lldb/source/Commands/CommandObjectDiagnostics.cpp (revision 92d8a28cc665d73d9d679b8c014dd04f95d1df18)
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