xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/sol2-c.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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 "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "options.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "stringpool.h"
36 #include "attribs.h"
37 #include "tm.h"
38 #include "tm_p.h"
39 
40 #include "c-family/c-format.h"
41 #include "intl.h"
42 
43 #include "cpplib.h"
44 #include "c-family/c-pragma.h"
45 #include "c-family/c-common.h"
46 
47 /* cmn_err only accepts "l" and "ll".  */
48 static const format_length_info cmn_err_length_specs[] =
49 {
50   { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
51   { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
52 };
53 
54 static const format_flag_spec cmn_err_flag_specs[] =
55 {
56   { 'w',  0, 0, N_("field width"),     N_("field width in printf format"),     STD_C89 },
57   { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
58   { 0, 0, 0, NULL, NULL, STD_C89 }
59 };
60 
61 
62 static const format_flag_pair cmn_err_flag_pairs[] =
63 {
64   { 0, 0, 0, 0 }
65 };
66 
67 static const format_char_info bitfield_string_type =
68   { "b",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   "cR", NULL };
69 
70 static const format_char_info cmn_err_char_table[] =
71 {
72   /* C89 conversion specifiers.  */
73   { "dD",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "w",  "",   NULL },
74   { "oOxX",0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "w",  "",   NULL },
75   { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "w",  "",   NULL },
76   { "c",   0, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "w",  "",   NULL },
77   { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "w", "c",  NULL },
78   { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "w",  "cR", NULL },
79   { "b",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "w",   "",   &bitfield_string_type },
80   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
81 };
82 
83 EXPORTED_CONST format_kind_info solaris_format_types[] = {
84   { "cmn_err",  cmn_err_length_specs,  cmn_err_char_table, "", NULL,
85     cmn_err_flag_specs, cmn_err_flag_pairs,
86     FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
87     'w', 0, 0, 0, 'L', 0,
88     &integer_type_node, &integer_type_node
89   }
90 };
91 
92 /* Handle #pragma align ALIGNMENT (VAR [, VAR]...)  */
93 
94 static void
95 solaris_pragma_align (cpp_reader *pfile ATTRIBUTE_UNUSED)
96 {
97   tree t, x;
98   enum cpp_ttype ttype;
99   unsigned HOST_WIDE_INT low;
100 
101   if (pragma_lex (&x) != CPP_NUMBER
102       || pragma_lex (&t) != CPP_OPEN_PAREN)
103     {
104       warning (0, "malformed %<#pragma align%>, ignoring");
105       return;
106     }
107 
108   low = TREE_INT_CST_LOW (x);
109   if (!tree_fits_uhwi_p (x)
110       || (low != 1 && low != 2 && low != 4 && low != 8 && low != 16
111 	  && low != 32 && low != 64 && low != 128))
112     {
113       warning (0, "invalid alignment for %<#pragma align%>, ignoring");
114       return;
115     }
116 
117   ttype = pragma_lex (&t);
118   if (ttype != CPP_NAME)
119     {
120       warning (0, "malformed %<#pragma align%>, ignoring");
121       return;
122     }
123 
124   while (1)
125     {
126       tree decl = identifier_global_value (t);
127       if (decl && DECL_P (decl))
128 	warning (0, "%<#pragma align%> must appear before the declaration of "
129 		 "%D, ignoring", decl);
130       else
131 	solaris_pending_aligns = tree_cons (t, build_tree_list (NULL, x),
132 					    solaris_pending_aligns);
133 
134       ttype = pragma_lex (&t);
135       if (ttype == CPP_COMMA)
136 	{
137 	  ttype = pragma_lex (&t);
138 	  if (ttype != CPP_NAME)
139 	    {
140 	      warning (0, "malformed %<#pragma align%>");
141 	      return;
142 	    }
143 	}
144       else if (ttype == CPP_CLOSE_PAREN)
145 	{
146 	  if (pragma_lex (&t) != CPP_EOF)
147 	    warning (0, "junk at end of %<#pragma align%>");
148 	  return;
149 	}
150       else
151 	{
152 	  warning (0, "malformed %<#pragma align%>");
153 	  return;
154 	}
155     }
156 }
157 
158 /* Handle #pragma init (function [, function]...)  */
159 
160 static void
161 solaris_pragma_init (cpp_reader *pfile ATTRIBUTE_UNUSED)
162 {
163   tree t;
164   enum cpp_ttype ttype;
165 
166   if (pragma_lex (&t) != CPP_OPEN_PAREN)
167     {
168       warning (0, "malformed %<#pragma init%>, ignoring");
169       return;
170     }
171 
172   ttype = pragma_lex (&t);
173   if (ttype != CPP_NAME)
174     {
175       warning (0, "malformed %<#pragma init%>, ignoring");
176       return;
177     }
178 
179   while (1)
180     {
181       tree decl = identifier_global_value (t);
182       if (decl && DECL_P (decl))
183 	{
184 	  tree attrs = build_tree_list (get_identifier ("init"),
185 					NULL);
186 	  TREE_USED (decl) = 1;
187 	  DECL_PRESERVE_P (decl) = 1;
188 	  decl_attributes (&decl, attrs, 0);
189 	}
190       else
191 	solaris_pending_inits = tree_cons (t, NULL, solaris_pending_inits);
192 
193       ttype = pragma_lex (&t);
194       if (ttype == CPP_COMMA)
195 	{
196 	  ttype = pragma_lex (&t);
197 	  if (ttype != CPP_NAME)
198 	    {
199 	      warning (0, "malformed %<#pragma init%>");
200 	      return;
201 	    }
202 	}
203       else if (ttype == CPP_CLOSE_PAREN)
204 	{
205 	  if (pragma_lex (&t) != CPP_EOF)
206 	    warning (0, "junk at end of %<#pragma init%>");
207 	  return;
208 	}
209       else
210 	{
211 	  warning (0, "malformed %<#pragma init%>");
212 	  return;
213 	}
214     }
215 }
216 
217 /* Handle #pragma fini (function [, function]...)  */
218 
219 static void
220 solaris_pragma_fini (cpp_reader *pfile ATTRIBUTE_UNUSED)
221 {
222   tree t;
223   enum cpp_ttype ttype;
224 
225   if (pragma_lex (&t) != CPP_OPEN_PAREN)
226     {
227       warning (0, "malformed %<#pragma fini%>, ignoring");
228       return;
229     }
230 
231   ttype = pragma_lex (&t);
232   if (ttype != CPP_NAME)
233     {
234       warning (0, "malformed %<#pragma fini%>, ignoring");
235       return;
236     }
237 
238   while (1)
239     {
240       tree decl = identifier_global_value (t);
241       if (decl && DECL_P (decl))
242 	{
243 	  tree attrs = build_tree_list (get_identifier ("fini"),
244 					NULL);
245 	  TREE_USED (decl) = 1;
246 	  DECL_PRESERVE_P (decl) = 1;
247 	  decl_attributes (&decl, attrs, 0);
248 	}
249       else
250 	solaris_pending_finis = tree_cons (t, NULL, solaris_pending_finis);
251 
252       ttype = pragma_lex (&t);
253       if (ttype == CPP_COMMA)
254 	{
255 	  ttype = pragma_lex (&t);
256 	  if (ttype != CPP_NAME)
257 	    {
258 	      warning (0, "malformed %<#pragma fini%>");
259 	      return;
260 	    }
261 	}
262       else if (ttype == CPP_CLOSE_PAREN)
263 	{
264 	  if (pragma_lex (&t) != CPP_EOF)
265 	    warning (0, "junk at end of %<#pragma fini%>");
266 	  return;
267 	}
268       else
269 	{
270 	  warning (0, "malformed %<#pragma fini%>");
271 	  return;
272 	}
273     }
274 }
275 
276 /* Register Solaris-specific #pragma directives.  */
277 
278 void
279 solaris_register_pragmas (void)
280 {
281   c_register_pragma_with_expansion (0, "align", solaris_pragma_align);
282   c_register_pragma (0, "init", solaris_pragma_init);
283   c_register_pragma (0, "fini", solaris_pragma_fini);
284 }
285