1 //===- DiagnosticEngine.h -------------------------------------------------===//
2 //
3 //                     The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef MCLD_LD_DIAGNOSTICENGINE_H_
10 #define MCLD_LD_DIAGNOSTICENGINE_H_
11 #include "mcld/LD/DiagnosticInfos.h"
12 
13 #include <llvm/Support/DataTypes.h>
14 
15 #include <string>
16 
17 namespace mcld {
18 
19 class DiagnosticLineInfo;
20 class DiagnosticPrinter;
21 class Input;
22 class LinkerConfig;
23 class MsgHandler;
24 
25 /** \class DiagnosticEngine
26  *  \brief DiagnosticEngine is used to report problems and issues.
27  *
28  *  DiagnosticEngine is used to report problems and issues. It creates the
29  *  Diagnostics and passes them to the DiagnosticPrinter for reporting to the
30  *  user.
31  *
32  *  DiagnosticEngine is a complex class, it is responsible for
33  *  - remember the argument string for MsgHandler
34  *  - choice the severity of a message by options
35  */
36 class DiagnosticEngine {
37  public:
38   enum Severity {
39     Unreachable,
40     Fatal,
41     Error,
42     Warning,
43     Debug,
44     Note,
45     Ignore,
46     None
47   };
48 
49   enum ArgumentKind {
50     ak_std_string,  // std::string
51     ak_c_string,    // const char *
52     ak_sint,        // int
53     ak_uint,        // unsigned int
54     ak_ulonglong,   // unsigned long long
55     ak_bool         // bool
56   };
57 
58  public:
59   DiagnosticEngine();
60 
61   ~DiagnosticEngine();
62 
63   void reset(const LinkerConfig& pConfig);
64 
65   void setLineInfo(DiagnosticLineInfo& pLineInfo);
66 
67   void setPrinter(DiagnosticPrinter& pPrinter, bool pShouldOwnPrinter = true);
68 
getPrinter()69   const DiagnosticPrinter* getPrinter() const { return m_pPrinter; }
getPrinter()70   DiagnosticPrinter* getPrinter() { return m_pPrinter; }
71 
takePrinter()72   DiagnosticPrinter* takePrinter() {
73     m_OwnPrinter = false;
74     return m_pPrinter;
75   }
76 
ownPrinter()77   bool ownPrinter() const { return m_OwnPrinter; }
78 
79   // -----  emission  ----- //
80   // emit - process the message to printer
81   bool emit();
82 
83   // report - issue the message to the printer
84   MsgHandler report(uint16_t pID, Severity pSeverity);
85 
86  private:
87   friend class MsgHandler;
88   friend class Diagnostic;
89 
90   enum {
91     /// MaxArguments - The maximum number of arguments we can hold. We currently
92     /// only support up to 10 arguments (%0-%9).
93     MaxArguments = 10
94   };
95 
96   struct State {
97    public:
StateState98     State() : numArgs(0), ID(-1), severity(None), file(NULL) {}
~StateState99     ~State() {}
100 
resetState101     void reset() {
102       numArgs = 0;
103       ID = -1;
104       severity = None;
105       file = NULL;
106     }
107 
108    public:
109     std::string ArgumentStrs[MaxArguments];
110     intptr_t ArgumentVals[MaxArguments];
111     uint8_t ArgumentKinds[MaxArguments];
112     int8_t numArgs;
113     uint16_t ID;
114     Severity severity;
115     Input* file;
116   };
117 
118  private:
state()119   State& state() { return m_State; }
120 
state()121   const State& state() const { return m_State; }
122 
infoMap()123   DiagnosticInfos& infoMap() {
124     assert(m_pInfoMap != NULL && "DiagnosticEngine was not initialized!");
125     return *m_pInfoMap;
126   }
127 
infoMap()128   const DiagnosticInfos& infoMap() const {
129     assert(m_pInfoMap != NULL && "DiagnosticEngine was not initialized!");
130     return *m_pInfoMap;
131   }
132 
133  private:
134   const LinkerConfig* m_pConfig;
135   DiagnosticLineInfo* m_pLineInfo;
136   DiagnosticPrinter* m_pPrinter;
137   DiagnosticInfos* m_pInfoMap;
138   bool m_OwnPrinter;
139 
140   State m_State;
141 };
142 
143 }  // namespace mcld
144 
145 #endif  // MCLD_LD_DIAGNOSTICENGINE_H_
146