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