1 //===-- DiagnosticManager.cpp ---------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Expression/DiagnosticManager.h"
10 
11 #include "llvm/Support/ErrorHandling.h"
12 
13 #include "lldb/Utility/Log.h"
14 #include "lldb/Utility/StreamString.h"
15 
16 using namespace lldb_private;
17 
18 void DiagnosticManager::Dump(Log *log) {
19   if (!log)
20     return;
21 
22   std::string str = GetString();
23 
24   // GetString() puts a separator after each diagnostic. We want to remove the
25   // last '\n' because log->PutCString will add one for us.
26 
27   if (str.size() && str.back() == '\n') {
28     str.pop_back();
29   }
30 
31   log->PutCString(str.c_str());
32 }
33 
34 static const char *StringForSeverity(DiagnosticSeverity severity) {
35   switch (severity) {
36   // this should be exhaustive
37   case lldb_private::eDiagnosticSeverityError:
38     return "error: ";
39   case lldb_private::eDiagnosticSeverityWarning:
40     return "warning: ";
41   case lldb_private::eDiagnosticSeverityRemark:
42     return "";
43   }
44   llvm_unreachable("switch needs another case for DiagnosticSeverity enum");
45 }
46 
47 std::string DiagnosticManager::GetString(char separator) {
48   std::string ret;
49   llvm::raw_string_ostream stream(ret);
50 
51   for (const auto &diagnostic : Diagnostics()) {
52     llvm::StringRef severity = StringForSeverity(diagnostic->GetSeverity());
53     stream << severity;
54 
55     llvm::StringRef message = diagnostic->GetMessage();
56     std::string searchable_message = message.lower();
57     auto severity_pos = message.find(severity);
58     stream << message.take_front(severity_pos);
59 
60     if (severity_pos != llvm::StringRef::npos)
61       stream << message.drop_front(severity_pos + severity.size());
62     stream << separator;
63   }
64 
65   return ret;
66 }
67 
68 size_t DiagnosticManager::Printf(DiagnosticSeverity severity,
69                                  const char *format, ...) {
70   StreamString ss;
71 
72   va_list args;
73   va_start(args, format);
74   size_t result = ss.PrintfVarArg(format, args);
75   va_end(args);
76 
77   AddDiagnostic(ss.GetString(), severity, eDiagnosticOriginLLDB);
78 
79   return result;
80 }
81 
82 void DiagnosticManager::PutString(DiagnosticSeverity severity,
83                                   llvm::StringRef str) {
84   if (str.empty())
85     return;
86   AddDiagnostic(str, severity, eDiagnosticOriginLLDB);
87 }
88