sol2-c.cc revision 1.1.1.1 1 1.1 mrg /* Solaris support needed only by C/C++ frontends.
2 1.1 mrg Copyright (C) 2004-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by CodeSourcery, LLC.
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify
8 1.1 mrg it under the terms of the GNU General Public License as published by
9 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
10 1.1 mrg any later version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful,
13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 mrg GNU General Public License for more details.
16 1.1 mrg
17 1.1 mrg You should have received a copy of the GNU General Public License
18 1.1 mrg along with GCC; see the file COPYING3. If not see
19 1.1 mrg <http://www.gnu.org/licenses/>. */
20 1.1 mrg
21 1.1 mrg #include "config.h"
22 1.1 mrg #include "system.h"
23 1.1 mrg #include "coretypes.h"
24 1.1 mrg #include "tm.h"
25 1.1 mrg #include "c-family/c-common.h"
26 1.1 mrg #include "stringpool.h"
27 1.1 mrg #include "attribs.h"
28 1.1 mrg
29 1.1 mrg #include "c-family/c-format.h"
30 1.1 mrg #include "intl.h"
31 1.1 mrg
32 1.1 mrg #include "c-family/c-pragma.h"
33 1.1 mrg
34 1.1 mrg /* cmn_err only accepts "l" and "ll". */
35 1.1 mrg static const format_length_info cmn_err_length_specs[] =
36 1.1 mrg {
37 1.1 mrg { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
38 1.1 mrg { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
39 1.1 mrg };
40 1.1 mrg
41 1.1 mrg static const format_flag_spec cmn_err_flag_specs[] =
42 1.1 mrg {
43 1.1 mrg { 'w', 0, 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
44 1.1 mrg { 'L', 0, 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
45 1.1 mrg { 0, 0, 0, 0, NULL, NULL, STD_C89 }
46 1.1 mrg };
47 1.1 mrg
48 1.1 mrg
49 1.1 mrg static const format_flag_pair cmn_err_flag_pairs[] =
50 1.1 mrg {
51 1.1 mrg { 0, 0, 0, 0 }
52 1.1 mrg };
53 1.1 mrg
54 1.1 mrg static const format_char_info bitfield_string_type =
55 1.1 mrg { "b", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL };
56 1.1 mrg
57 1.1 mrg static const format_char_info cmn_err_char_table[] =
58 1.1 mrg {
59 1.1 mrg /* C89 conversion specifiers. */
60 1.1 mrg { "dD", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
61 1.1 mrg { "oOxX",0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
62 1.1 mrg { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
63 1.1 mrg { "c", 0, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
64 1.1 mrg { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "c", NULL },
65 1.1 mrg { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "cR", NULL },
66 1.1 mrg { "b", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", &bitfield_string_type },
67 1.1 mrg { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
68 1.1 mrg };
69 1.1 mrg
70 1.1 mrg EXPORTED_CONST format_kind_info solaris_format_types[] = {
71 1.1 mrg { "cmn_err", cmn_err_length_specs, cmn_err_char_table, "", NULL,
72 1.1 mrg cmn_err_flag_specs, cmn_err_flag_pairs,
73 1.1 mrg FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
74 1.1 mrg 'w', 0, 0, 0, 'L', 0,
75 1.1 mrg &integer_type_node, &integer_type_node
76 1.1 mrg }
77 1.1 mrg };
78 1.1 mrg
79 1.1 mrg /* Handle #pragma align ALIGNMENT (VAR [, VAR]...) */
80 1.1 mrg
81 1.1 mrg static void
82 1.1 mrg solaris_pragma_align (cpp_reader *pfile ATTRIBUTE_UNUSED)
83 1.1 mrg {
84 1.1 mrg tree t, x;
85 1.1 mrg enum cpp_ttype ttype;
86 1.1 mrg unsigned HOST_WIDE_INT low;
87 1.1 mrg
88 1.1 mrg if (pragma_lex (&x) != CPP_NUMBER
89 1.1 mrg || pragma_lex (&t) != CPP_OPEN_PAREN)
90 1.1 mrg {
91 1.1 mrg warning (0, "malformed %<#pragma align%>, ignoring");
92 1.1 mrg return;
93 1.1 mrg }
94 1.1 mrg
95 1.1 mrg low = TREE_INT_CST_LOW (x);
96 1.1 mrg if (!tree_fits_uhwi_p (x)
97 1.1 mrg || (low != 1 && low != 2 && low != 4 && low != 8 && low != 16
98 1.1 mrg && low != 32 && low != 64 && low != 128))
99 1.1 mrg {
100 1.1 mrg warning (0, "invalid alignment for %<#pragma align%>, ignoring");
101 1.1 mrg return;
102 1.1 mrg }
103 1.1 mrg
104 1.1 mrg ttype = pragma_lex (&t);
105 1.1 mrg if (ttype != CPP_NAME)
106 1.1 mrg {
107 1.1 mrg warning (0, "malformed %<#pragma align%>, ignoring");
108 1.1 mrg return;
109 1.1 mrg }
110 1.1 mrg
111 1.1 mrg while (1)
112 1.1 mrg {
113 1.1 mrg tree decl = identifier_global_value (t);
114 1.1 mrg if (decl && DECL_P (decl))
115 1.1 mrg warning (0, "%<#pragma align%> must appear before the declaration of "
116 1.1 mrg "%qD, ignoring", decl);
117 1.1 mrg else
118 1.1 mrg solaris_pending_aligns = tree_cons (t, build_tree_list (NULL, x),
119 1.1 mrg solaris_pending_aligns);
120 1.1 mrg
121 1.1 mrg ttype = pragma_lex (&t);
122 1.1 mrg if (ttype == CPP_COMMA)
123 1.1 mrg {
124 1.1 mrg ttype = pragma_lex (&t);
125 1.1 mrg if (ttype != CPP_NAME)
126 1.1 mrg {
127 1.1 mrg warning (0, "malformed %<#pragma align%>");
128 1.1 mrg return;
129 1.1 mrg }
130 1.1 mrg }
131 1.1 mrg else if (ttype == CPP_CLOSE_PAREN)
132 1.1 mrg {
133 1.1 mrg if (pragma_lex (&t) != CPP_EOF)
134 1.1 mrg warning (0, "junk at end of %<#pragma align%>");
135 1.1 mrg return;
136 1.1 mrg }
137 1.1 mrg else
138 1.1 mrg {
139 1.1 mrg warning (0, "malformed %<#pragma align%>");
140 1.1 mrg return;
141 1.1 mrg }
142 1.1 mrg }
143 1.1 mrg }
144 1.1 mrg
145 1.1 mrg /* Handle #pragma init (function [, function]...) */
146 1.1 mrg
147 1.1 mrg static void
148 1.1 mrg solaris_pragma_init (cpp_reader *pfile ATTRIBUTE_UNUSED)
149 1.1 mrg {
150 1.1 mrg tree t;
151 1.1 mrg enum cpp_ttype ttype;
152 1.1 mrg
153 1.1 mrg if (pragma_lex (&t) != CPP_OPEN_PAREN)
154 1.1 mrg {
155 1.1 mrg warning (0, "malformed %<#pragma init%>, ignoring");
156 1.1 mrg return;
157 1.1 mrg }
158 1.1 mrg
159 1.1 mrg ttype = pragma_lex (&t);
160 1.1 mrg if (ttype != CPP_NAME)
161 1.1 mrg {
162 1.1 mrg warning (0, "malformed %<#pragma init%>, ignoring");
163 1.1 mrg return;
164 1.1 mrg }
165 1.1 mrg
166 1.1 mrg while (1)
167 1.1 mrg {
168 1.1 mrg tree decl = identifier_global_value (t);
169 1.1 mrg if (decl && DECL_P (decl))
170 1.1 mrg {
171 1.1 mrg tree attrs = build_tree_list (get_identifier ("init"),
172 1.1 mrg NULL);
173 1.1 mrg TREE_USED (decl) = 1;
174 1.1 mrg DECL_PRESERVE_P (decl) = 1;
175 1.1 mrg decl_attributes (&decl, attrs, 0);
176 1.1 mrg }
177 1.1 mrg else
178 1.1 mrg solaris_pending_inits = tree_cons (t, NULL, solaris_pending_inits);
179 1.1 mrg
180 1.1 mrg ttype = pragma_lex (&t);
181 1.1 mrg if (ttype == CPP_COMMA)
182 1.1 mrg {
183 1.1 mrg ttype = pragma_lex (&t);
184 1.1 mrg if (ttype != CPP_NAME)
185 1.1 mrg {
186 1.1 mrg warning (0, "malformed %<#pragma init%>");
187 1.1 mrg return;
188 1.1 mrg }
189 1.1 mrg }
190 1.1 mrg else if (ttype == CPP_CLOSE_PAREN)
191 1.1 mrg {
192 1.1 mrg if (pragma_lex (&t) != CPP_EOF)
193 1.1 mrg warning (0, "junk at end of %<#pragma init%>");
194 1.1 mrg return;
195 1.1 mrg }
196 1.1 mrg else
197 1.1 mrg {
198 1.1 mrg warning (0, "malformed %<#pragma init%>");
199 1.1 mrg return;
200 1.1 mrg }
201 1.1 mrg }
202 1.1 mrg }
203 1.1 mrg
204 1.1 mrg /* Handle #pragma fini (function [, function]...) */
205 1.1 mrg
206 1.1 mrg static void
207 1.1 mrg solaris_pragma_fini (cpp_reader *pfile ATTRIBUTE_UNUSED)
208 1.1 mrg {
209 1.1 mrg tree t;
210 1.1 mrg enum cpp_ttype ttype;
211 1.1 mrg
212 1.1 mrg if (pragma_lex (&t) != CPP_OPEN_PAREN)
213 1.1 mrg {
214 1.1 mrg warning (0, "malformed %<#pragma fini%>, ignoring");
215 1.1 mrg return;
216 1.1 mrg }
217 1.1 mrg
218 1.1 mrg ttype = pragma_lex (&t);
219 1.1 mrg if (ttype != CPP_NAME)
220 1.1 mrg {
221 1.1 mrg warning (0, "malformed %<#pragma fini%>, ignoring");
222 1.1 mrg return;
223 1.1 mrg }
224 1.1 mrg
225 1.1 mrg while (1)
226 1.1 mrg {
227 1.1 mrg tree decl = identifier_global_value (t);
228 1.1 mrg if (decl && DECL_P (decl))
229 1.1 mrg {
230 1.1 mrg tree attrs = build_tree_list (get_identifier ("fini"),
231 1.1 mrg NULL);
232 1.1 mrg TREE_USED (decl) = 1;
233 1.1 mrg DECL_PRESERVE_P (decl) = 1;
234 1.1 mrg decl_attributes (&decl, attrs, 0);
235 1.1 mrg }
236 1.1 mrg else
237 1.1 mrg solaris_pending_finis = tree_cons (t, NULL, solaris_pending_finis);
238 1.1 mrg
239 1.1 mrg ttype = pragma_lex (&t);
240 1.1 mrg if (ttype == CPP_COMMA)
241 1.1 mrg {
242 1.1 mrg ttype = pragma_lex (&t);
243 1.1 mrg if (ttype != CPP_NAME)
244 1.1 mrg {
245 1.1 mrg warning (0, "malformed %<#pragma fini%>");
246 1.1 mrg return;
247 1.1 mrg }
248 1.1 mrg }
249 1.1 mrg else if (ttype == CPP_CLOSE_PAREN)
250 1.1 mrg {
251 1.1 mrg if (pragma_lex (&t) != CPP_EOF)
252 1.1 mrg warning (0, "junk at end of %<#pragma fini%>");
253 1.1 mrg return;
254 1.1 mrg }
255 1.1 mrg else
256 1.1 mrg {
257 1.1 mrg warning (0, "malformed %<#pragma fini%>");
258 1.1 mrg return;
259 1.1 mrg }
260 1.1 mrg }
261 1.1 mrg }
262 1.1 mrg
263 1.1 mrg /* Register Solaris-specific #pragma directives. */
264 1.1 mrg
265 1.1 mrg void
266 1.1 mrg solaris_register_pragmas (void)
267 1.1 mrg {
268 1.1 mrg c_register_pragma_with_expansion (0, "align", solaris_pragma_align);
269 1.1 mrg c_register_pragma (0, "init", solaris_pragma_init);
270 1.1 mrg c_register_pragma (0, "fini", solaris_pragma_fini);
271 1.1 mrg }
272