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