Sync with 5.4.0
[deliverable/titan.core.git] / compiler2 / CompilerError.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "error.h"
9 #include "CompilerError.hh"
10 #include "../common/memory.h"
11 #include "../common/path.h"
12 #include "main.hh"
13 #include "Setting.hh"
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <stdarg.h>
18 #include <errno.h>
19 #ifndef MINGW
20 # include <sys/wait.h>
21 #endif
22
23 unsigned verb_level=0x0007; /* default value */
24
25 const char *argv0; /* the programname :) */
26
27 void fatal_error(const char *filename, int lineno, const char *fmt, ...)
28 {
29 va_list parameters;
30 #ifdef FATAL_DEBUG
31 va_start(parameters, fmt);
32 Common::Location loc(filename, lineno);
33 Common::Error_Context::report_error(&loc, fmt, parameters);
34 va_end(parameters);
35 #else
36 fprintf(stderr, "FATAL ERROR: %s: In line %d of %s: ",
37 argv0, lineno, filename);
38 va_start(parameters, fmt);
39 vfprintf(stderr, fmt, parameters);
40 va_end(parameters);
41 putc('\n', stderr);
42 #endif
43 fflush(stderr);
44 abort();
45 }
46
47 void ERROR(const char *fmt, ...)
48 {
49 fprintf(stderr, "%s: error: ", argv0);
50 va_list parameters;
51 va_start(parameters, fmt);
52 vfprintf(stderr, fmt, parameters);
53 va_end(parameters);
54 putc('\n', stderr);
55 fflush(stderr);
56 Common::Error_Context::increment_error_count();
57 }
58
59 void WARNING(const char *fmt, ...)
60 {
61 if(!(verb_level & 2)) return;
62 fprintf(stderr, "%s: warning: ", argv0);
63 va_list parameters;
64 va_start(parameters, fmt);
65 vfprintf(stderr, fmt, parameters);
66 va_end(parameters);
67 putc('\n', stderr);
68 fflush(stderr);
69 Common::Error_Context::increment_warning_count();
70 }
71
72 void NOTSUPP(const char *fmt, ...)
73 {
74 if(!(verb_level & 1)) return;
75 fprintf(stderr, "%s: warning: not supported: ", argv0);
76 va_list parameters;
77 va_start(parameters, fmt);
78 vfprintf(stderr, fmt, parameters);
79 va_end(parameters);
80 putc('\n', stderr);
81 fflush(stderr);
82 Common::Error_Context::increment_warning_count();
83 }
84
85 void NOTIFY(const char *fmt, ...)
86 {
87 if(!(verb_level & 4)) return;
88 fprintf(stderr, "Notify: ");
89 va_list parameters;
90 va_start(parameters, fmt);
91 vfprintf(stderr, fmt, parameters);
92 va_end(parameters);
93 putc('\n', stderr);
94 fflush(stderr);
95 }
96
97 void DEBUG(unsigned level, const char *fmt, ...)
98 {
99 if((level>7?7:level)>((verb_level>>3)&0x07)) return;
100 fprintf(stderr, "%*sDebug: ", level, "");
101 va_list parameters;
102 va_start(parameters, fmt);
103 vfprintf(stderr, fmt, parameters);
104 va_end(parameters);
105 putc('\n', stderr);
106 fflush(stderr);
107 }
108
109 unsigned int get_error_count(void)
110 {
111 return Common::Error_Context::get_error_count();
112 }
113
114 unsigned int get_warning_count(void)
115 {
116 return Common::Error_Context::get_warning_count();
117 }
118
119 void path_error(const char *fmt, ...)
120 {
121 va_list ap;
122 va_start(ap, fmt);
123 char *err_msg = mprintf_va_list(fmt, ap);
124 va_end(ap);
125 ERROR("%s", err_msg);
126 Free(err_msg);
127 }
128
129 namespace Common {
130
131 unsigned int Error_Context::error_count = 0, Error_Context::warning_count = 0;
132 unsigned int Error_Context::max_errors = (unsigned)-1;
133
134 bool Error_Context::chain_printed = false;
135
136 Error_Context *Error_Context::head = 0, *Error_Context::tail = 0;
137
138 void Error_Context::print_context(FILE *fp)
139 {
140 int level = 0;
141 for (Error_Context *ptr = head; ptr; ptr = ptr->next) {
142 if (ptr->is_restorer) FATAL_ERROR("Error_Context::print()");
143 else if (!ptr->str) continue;
144 else if (!ptr->is_printed) {
145 for (int i = 0; i < level; i++) putc(' ', fp);
146 if (ptr->location) ptr->location->print_location(fp);
147 if (gcc_compat) fputs("note: ", fp); // CDT ignores "note"
148 fputs(ptr->str, fp);
149 fputs(":\n", fp);
150 ptr->is_printed = true;
151 }
152 level++;
153 }
154 for (int i = 0; i < level; i++) putc(' ', fp);
155 chain_printed = true;
156 }
157
158 Error_Context::Error_Context(size_t n_keep)
159 : prev(0), next(0), location(0), str(0), is_printed(false),
160 is_restorer(true), outer_printed(false)
161 {
162 Error_Context *begin = head;
163 for (size_t i = 0; i < n_keep; i++) {
164 if (!begin) break;
165 begin = begin->next;
166 }
167 if (begin == head) {
168 // complete backup
169 next = head;
170 head = 0;
171 prev = tail;
172 tail = 0;
173 } else {
174 // partial backup (only elements before begin are kept)
175 next = begin;
176 if (begin) {
177 prev = tail;
178 tail = begin->prev;
179 tail->next = 0;
180 begin->prev = 0;
181 } else prev = 0;
182 }
183 outer_printed = chain_printed;
184 chain_printed = false;
185 }
186
187 Error_Context::Error_Context(const Location *p_location)
188 : prev(0), next(0), location(p_location), str(0), is_printed(false),
189 is_restorer(false), outer_printed(false)
190 {
191 if (!head) head = this;
192 if (tail) tail->next = this;
193 prev = tail;
194 next = 0;
195 tail = this;
196 }
197
198 Error_Context::Error_Context(const Location *p_location,
199 const char *p_fmt, ...)
200 : prev(0), next(0), location(p_location), str(0), is_printed(false),
201 is_restorer(false), outer_printed(false)
202 {
203 va_list args;
204 va_start(args, p_fmt);
205 str = mprintf_va_list(p_fmt, args);
206 va_end(args);
207
208 if (!head) head = this;
209 if (tail) tail->next = this;
210 prev = tail;
211 next = 0;
212 tail = this;
213 }
214
215 Error_Context::~Error_Context()
216 {
217 if (is_restorer) {
218 if (chain_printed) {
219 for (Error_Context *ptr = next; ptr; ptr = ptr->next)
220 ptr->is_printed = false;
221 } else chain_printed = outer_printed;
222 if (head) {
223 // partial restoration
224 if (next) {
225 tail->next = next;
226 next->prev = tail;
227 tail = prev;
228 }
229 } else {
230 // full restoration
231 head = next;
232 tail = prev;
233 }
234 } else {
235 Free(str);
236 if (tail != this) FATAL_ERROR("Error_Context::~Error_Context()");
237 if (prev) prev->next = 0;
238 else head = 0;
239 tail = prev;
240 }
241 }
242
243 void Error_Context::set_message(const char *p_fmt, ...)
244 {
245 if (is_restorer) FATAL_ERROR("Error_Context::set_message()");
246 Free(str);
247 va_list args;
248 va_start(args, p_fmt);
249 str = mprintf_va_list(p_fmt, args);
250 va_end(args);
251 is_printed = false;
252 }
253
254 void Error_Context::report_error(const Location *loc, const char *fmt,
255 va_list args)
256 {
257 if (!suppress_context) print_context(stderr);
258 Location my_location;
259 if (tail != 0 && loc && loc->get_filename() == 0) {
260 // borrow location information from the innermost context
261 my_location.set_location( *(tail->location) );
262 loc = &my_location;
263 }
264 if (loc) loc->print_location(stderr);
265 fputs("error: ", stderr);
266 vfprintf(stderr, fmt, args);
267 putc('\n', stderr);
268 fflush(stderr);
269 increment_error_count();
270 }
271
272 void Error_Context::report_warning(const Location *loc, const char *fmt,
273 va_list args)
274 {
275 if(!(verb_level & 2)) return;
276 if (!suppress_context) print_context(stderr);
277 if (loc) loc->print_location(stderr);
278 fputs("warning: ", stderr);
279 vfprintf(stderr, fmt, args);
280 putc('\n', stderr);
281 fflush(stderr);
282 increment_warning_count();
283 }
284
285 void Error_Context::report_note(const Location *loc, const char *fmt,
286 va_list args)
287 {
288 if (!suppress_context) print_context(stderr);
289 if (loc) loc->print_location(stderr);
290 fputs("note: ", stderr);
291 vfprintf(stderr, fmt, args);
292 putc('\n', stderr);
293 fflush(stderr);
294 }
295
296 void Error_Context::increment_error_count()
297 {
298 if (++error_count >= max_errors) {
299 fputs("Maximum number of errors reached, aborting.\n", stderr);
300 fflush(stderr);
301 exit(EXIT_FAILURE);
302 }
303 }
304
305 void Error_Context::increment_warning_count()
306 {
307 warning_count++;
308 }
309
310 void Error_Context::print_error_statistics()
311 {
312 if (error_count == 0) {
313 if (warning_count == 0) NOTIFY("No errors or warnings were detected.");
314 else NOTIFY("No errors and %u warning%s were detected.",
315 warning_count, warning_count > 1 ? "s" : "");
316 } else {
317 if (warning_count == 0) NOTIFY("%u error%s and no warnings were "
318 "detected.", error_count, error_count > 1 ? "s" : "");
319 else NOTIFY("%u error%s and %u warning%s were detected.",
320 error_count, error_count > 1 ? "s" : "",
321 warning_count, warning_count > 1 ? "s" : "");
322 }
323 }
324
325 } // namespace Common
This page took 0.048242 seconds and 5 git commands to generate.