annotate gcc/go/gofrontend/go-diagnostics.cc @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 // go-diagnostics.cc -- Go error/warning diagnostics utilities.
kono
parents:
diff changeset
2
kono
parents:
diff changeset
3 // Copyright 2016 The Go Authors. All rights reserved.
kono
parents:
diff changeset
4 // Use of this source code is governed by a BSD-style
kono
parents:
diff changeset
5 // license that can be found in the LICENSE file.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 #include "go-diagnostics.h"
kono
parents:
diff changeset
8
kono
parents:
diff changeset
9 static std::string
kono
parents:
diff changeset
10 mformat_value()
kono
parents:
diff changeset
11 {
kono
parents:
diff changeset
12 return std::string(xstrerror(errno));
kono
parents:
diff changeset
13 }
kono
parents:
diff changeset
14
kono
parents:
diff changeset
15 // Rewrite a format string to expand any extensions not
kono
parents:
diff changeset
16 // supported by sprintf(). See comments in go-diagnostics.h
kono
parents:
diff changeset
17 // for list of supported format specifiers.
kono
parents:
diff changeset
18
kono
parents:
diff changeset
19 static std::string
kono
parents:
diff changeset
20 expand_format(const char* fmt)
kono
parents:
diff changeset
21 {
kono
parents:
diff changeset
22 std::stringstream ss;
kono
parents:
diff changeset
23 for (const char* c = fmt; *c; ++c)
kono
parents:
diff changeset
24 {
kono
parents:
diff changeset
25 if (*c != '%')
kono
parents:
diff changeset
26 {
kono
parents:
diff changeset
27 ss << *c;
kono
parents:
diff changeset
28 continue;
kono
parents:
diff changeset
29 }
kono
parents:
diff changeset
30 c++;
kono
parents:
diff changeset
31 switch (*c)
kono
parents:
diff changeset
32 {
kono
parents:
diff changeset
33 case '\0':
kono
parents:
diff changeset
34 {
kono
parents:
diff changeset
35 // malformed format string
kono
parents:
diff changeset
36 go_unreachable();
kono
parents:
diff changeset
37 }
kono
parents:
diff changeset
38 case '%':
kono
parents:
diff changeset
39 {
kono
parents:
diff changeset
40 ss << "%";
kono
parents:
diff changeset
41 break;
kono
parents:
diff changeset
42 }
kono
parents:
diff changeset
43 case 'm':
kono
parents:
diff changeset
44 {
kono
parents:
diff changeset
45 ss << mformat_value();
kono
parents:
diff changeset
46 break;
kono
parents:
diff changeset
47 }
kono
parents:
diff changeset
48 case '<':
kono
parents:
diff changeset
49 {
kono
parents:
diff changeset
50 ss << go_open_quote();
kono
parents:
diff changeset
51 break;
kono
parents:
diff changeset
52 }
kono
parents:
diff changeset
53 case '>':
kono
parents:
diff changeset
54 {
kono
parents:
diff changeset
55 ss << go_close_quote();
kono
parents:
diff changeset
56 break;
kono
parents:
diff changeset
57 }
kono
parents:
diff changeset
58 case 'q':
kono
parents:
diff changeset
59 {
kono
parents:
diff changeset
60 ss << go_open_quote();
kono
parents:
diff changeset
61 c++;
kono
parents:
diff changeset
62 if (*c == 'm')
kono
parents:
diff changeset
63 {
kono
parents:
diff changeset
64 ss << mformat_value();
kono
parents:
diff changeset
65 }
kono
parents:
diff changeset
66 else
kono
parents:
diff changeset
67 {
kono
parents:
diff changeset
68 ss << "%" << *c;
kono
parents:
diff changeset
69 }
kono
parents:
diff changeset
70 ss << go_close_quote();
kono
parents:
diff changeset
71 break;
kono
parents:
diff changeset
72 }
kono
parents:
diff changeset
73 default:
kono
parents:
diff changeset
74 {
kono
parents:
diff changeset
75 ss << "%" << *c;
kono
parents:
diff changeset
76 }
kono
parents:
diff changeset
77 }
kono
parents:
diff changeset
78 }
kono
parents:
diff changeset
79 return ss.str();
kono
parents:
diff changeset
80 }
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 // Expand message format specifiers, using a combination of
kono
parents:
diff changeset
83 // expand_format above to handle extensions (ex: %m, %q) and vasprintf()
kono
parents:
diff changeset
84 // to handle regular printf-style formatting. A pragma is being used here to
kono
parents:
diff changeset
85 // suppress this warning:
kono
parents:
diff changeset
86 //
kono
parents:
diff changeset
87 // warning: function ‘std::__cxx11::string expand_message(const char*, __va_list_tag*)’ might be a candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format]
kono
parents:
diff changeset
88 //
kono
parents:
diff changeset
89 // What appears to be happening here is that the checker is deciding that
kono
parents:
diff changeset
90 // because of the call to vasprintf() (which has attribute gnu_printf), the
kono
parents:
diff changeset
91 // calling function must need to have attribute gnu_printf as well, even
kono
parents:
diff changeset
92 // though there is already an attribute declaration for it.
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 static std::string
kono
parents:
diff changeset
95 expand_message(const char* fmt, va_list ap) GO_ATTRIBUTE_GCC_DIAG(1,0);
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 #pragma GCC diagnostic push
kono
parents:
diff changeset
98 #pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 static std::string
kono
parents:
diff changeset
101 expand_message(const char* fmt, va_list ap)
kono
parents:
diff changeset
102 {
kono
parents:
diff changeset
103 char* mbuf = 0;
kono
parents:
diff changeset
104 std::string expanded_fmt = expand_format(fmt);
kono
parents:
diff changeset
105 int nwr = vasprintf(&mbuf, expanded_fmt.c_str(), ap);
kono
parents:
diff changeset
106 if (nwr == -1)
kono
parents:
diff changeset
107 {
kono
parents:
diff changeset
108 // memory allocation failed
kono
parents:
diff changeset
109 go_be_error_at(Linemap::unknown_location(),
kono
parents:
diff changeset
110 "memory allocation failed in vasprintf");
kono
parents:
diff changeset
111 go_assert(0);
kono
parents:
diff changeset
112 }
kono
parents:
diff changeset
113 std::string rval = std::string(mbuf);
kono
parents:
diff changeset
114 free(mbuf);
kono
parents:
diff changeset
115 return rval;
kono
parents:
diff changeset
116 }
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 #pragma GCC diagnostic pop
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 static const char* cached_open_quote = NULL;
kono
parents:
diff changeset
121 static const char* cached_close_quote = NULL;
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 const char*
kono
parents:
diff changeset
124 go_open_quote()
kono
parents:
diff changeset
125 {
kono
parents:
diff changeset
126 if (cached_open_quote == NULL)
kono
parents:
diff changeset
127 go_be_get_quotechars(&cached_open_quote, &cached_close_quote);
kono
parents:
diff changeset
128 return cached_open_quote;
kono
parents:
diff changeset
129 }
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 const char*
kono
parents:
diff changeset
132 go_close_quote()
kono
parents:
diff changeset
133 {
kono
parents:
diff changeset
134 if (cached_close_quote == NULL)
kono
parents:
diff changeset
135 go_be_get_quotechars(&cached_open_quote, &cached_close_quote);
kono
parents:
diff changeset
136 return cached_close_quote;
kono
parents:
diff changeset
137 }
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 void
kono
parents:
diff changeset
140 go_error_at(const Location location, const char* fmt, ...)
kono
parents:
diff changeset
141 {
kono
parents:
diff changeset
142 va_list ap;
kono
parents:
diff changeset
143
kono
parents:
diff changeset
144 va_start(ap, fmt);
kono
parents:
diff changeset
145 go_be_error_at(location, expand_message(fmt, ap));
kono
parents:
diff changeset
146 va_end(ap);
kono
parents:
diff changeset
147 }
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 void
kono
parents:
diff changeset
150 go_warning_at(const Location location, int opt, const char* fmt, ...)
kono
parents:
diff changeset
151 {
kono
parents:
diff changeset
152 va_list ap;
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 va_start(ap, fmt);
kono
parents:
diff changeset
155 go_be_warning_at(location, opt, expand_message(fmt, ap));
kono
parents:
diff changeset
156 va_end(ap);
kono
parents:
diff changeset
157 }
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 void
kono
parents:
diff changeset
160 go_fatal_error(const Location location, const char* fmt, ...)
kono
parents:
diff changeset
161 {
kono
parents:
diff changeset
162 va_list ap;
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 va_start(ap, fmt);
kono
parents:
diff changeset
165 go_be_fatal_error(location, expand_message(fmt, ap));
kono
parents:
diff changeset
166 va_end(ap);
kono
parents:
diff changeset
167 }
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 void
kono
parents:
diff changeset
170 go_inform(const Location location, const char* fmt, ...)
kono
parents:
diff changeset
171 {
kono
parents:
diff changeset
172 va_list ap;
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 va_start(ap, fmt);
kono
parents:
diff changeset
175 go_be_inform(location, expand_message(fmt, ap));
kono
parents:
diff changeset
176 va_end(ap);
kono
parents:
diff changeset
177 }