]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/vms/vms-c.c
gen-mul-tables.cc: Adjust include files.
[thirdparty/gcc.git] / gcc / config / vms / vms-c.c
1 /* VMS specific, C compiler specific functions.
2 Copyright (C) 2011-2015 Free Software Foundation, Inc.
3 Contributed by Tristan Gingold (gingold@adacore.com).
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 "tm.h"
25 #include "tree.h"
26 #include "c-family/c-common.h"
27 #include "c/c-tree.h"
28 #include "tm_p.h"
29 #include "c-family/c-pragma.h"
30 #include "toplev.h"
31 #include "incpath.h"
32
33 /* '#pragma __nostandard' is simply ignored. */
34
35 static void
36 vms_pragma_nostandard (cpp_reader *pfile ATTRIBUTE_UNUSED)
37 {
38 tree x;
39
40 if (pragma_lex (&x) != CPP_EOF)
41 warning (OPT_Wpragmas, "junk at end of #pragma __nostandard");
42 }
43
44 /* '#pragma __standard' is simply ignored. */
45
46 static void
47 vms_pragma_standard (cpp_reader *pfile ATTRIBUTE_UNUSED)
48 {
49 tree x;
50
51 if (pragma_lex (&x) != CPP_EOF)
52 warning (OPT_Wpragmas, "junk at end of #pragma __standard");
53 }
54
55 /* Saved member alignment. */
56 static int saved_member_alignment;
57
58 /* Handle '#pragma member_alignment'. */
59
60 static void
61 vms_pragma_member_alignment (cpp_reader *pfile ATTRIBUTE_UNUSED)
62 {
63 tree x;
64 int tok;
65 const char *arg;
66
67 tok = pragma_lex (&x);
68
69 if (tok == CPP_EOF)
70 {
71 /* Disable packing. */
72 maximum_field_alignment = initial_max_fld_align;
73 return;
74 }
75 if (tok != CPP_NAME)
76 {
77 warning (OPT_Wpragmas, "malformed '#pragma member_alignment', ignoring");
78 return;
79 }
80
81 arg = IDENTIFIER_POINTER (x);
82 /* Accept '__' prefix. */
83 if (arg[0] == '_' && arg[1] == '_')
84 arg += 2;
85
86 if (strcmp (arg, "save") == 0)
87 saved_member_alignment = maximum_field_alignment;
88 else if (strcmp (arg, "restore") == 0)
89 maximum_field_alignment = saved_member_alignment;
90 else
91 {
92 error ("unknown '#pragma member_alignment' name %s", arg);
93 return;
94 }
95 if (pragma_lex (&x) != CPP_EOF)
96 {
97 error ("malformed '#pragma member_alignment'");
98 return;
99 }
100 }
101
102 /* Handle '#pragma nomember_alignment'. */
103
104 static void
105 vms_pragma_nomember_alignment (cpp_reader *pfile ATTRIBUTE_UNUSED)
106 {
107 tree x;
108 int tok;
109
110 tok = pragma_lex (&x);
111 if (tok == CPP_NAME)
112 {
113 const char *arg = IDENTIFIER_POINTER (x);
114
115 /* Accept '__' prefix. */
116 if (arg[0] == '_' && arg[1] == '_')
117 arg += 2;
118
119 if (strcmp (arg, "byte") == 0)
120 maximum_field_alignment = 1 * BITS_PER_UNIT;
121 else if (strcmp (arg, "word") == 0)
122 maximum_field_alignment = 2 * BITS_PER_UNIT;
123 else if (strcmp (arg, "longword") == 0)
124 maximum_field_alignment = 4 * BITS_PER_UNIT;
125 else if (strcmp (arg, "quadword") == 0)
126 maximum_field_alignment = 8 * BITS_PER_UNIT;
127 else if (strcmp (arg, "octaword") == 0)
128 maximum_field_alignment = 16 * BITS_PER_UNIT;
129 else
130 {
131 error ("unhandled alignment for '#pragma nomember_alignment'");
132 }
133
134 tok = pragma_lex (&x);
135 }
136 else
137 {
138 /* Enable packing. */
139 maximum_field_alignment = BITS_PER_UNIT;
140 }
141
142 if (tok != CPP_EOF)
143 {
144 error ("garbage at end of '#pragma nomember_alignment'");
145 return;
146 }
147 }
148
149 /* The 'extern model' for public data. This drives how the following
150 declarations are handled:
151 1) extern int name;
152 2) int name;
153 3) int name = 5;
154 See below for the behaviour as implemented by the native compiler.
155 */
156
157 enum extern_model_kind
158 {
159 /* Create one overlaid section per variable. All the above declarations (1,
160 2 and 3) are handled the same way: they create an overlaid section named
161 NAME (and initialized only for 3). No global symbol is created.
162 This is the VAX C behavior. */
163 extern_model_common_block,
164
165 /* Like unix: multiple not-initialized declarations are allowed.
166 Only one initialized definition (case 3) is allows, but multiple
167 uninitialize definition (case 2) are allowed.
168 For case 2, this creates both a section named NAME and a global symbol.
169 For case 3, this creates a conditional global symbol defenition and a
170 conditional section definition.
171 This is the traditional UNIX C behavior. */
172 extern_model_relaxed_refdef,
173
174 /* Like -fno-common. Only one definition (cases 2 and 3) are allowed.
175 This is the ANSI-C model. */
176 extern_model_strict_refdef,
177
178 /* Declarations creates symbols without storage. */
179 extern_model_globalvalue
180 };
181
182 /* Current and saved extern model. */
183 static enum extern_model_kind current_extern_model;
184 static enum extern_model_kind saved_extern_model;
185
186 /* Partial handling of '#pragma extern_model'. */
187
188 static void
189 vms_pragma_extern_model (cpp_reader *pfile ATTRIBUTE_UNUSED)
190 {
191 tree x;
192 int tok;
193 const char *arg;
194
195 tok = pragma_lex (&x);
196
197 if (tok != CPP_NAME)
198 {
199 warning (OPT_Wpragmas, "malformed '#pragma extern_model', ignoring");
200 return;
201 }
202
203 arg = IDENTIFIER_POINTER (x);
204 /* Accept "__" prefix. */
205 if (arg[0] == '_' && arg[1] == '_')
206 arg += 2;
207
208 if (strcmp (arg, "save") == 0)
209 saved_extern_model = current_extern_model;
210 else if (strcmp (arg, "restore") == 0)
211 current_extern_model = saved_extern_model;
212 else if (strcmp (arg, "relaxed_refdef") == 0)
213 current_extern_model = extern_model_relaxed_refdef;
214 else if (strcmp (arg, "strict_refdef") == 0)
215 current_extern_model = extern_model_strict_refdef;
216 else if (strcmp (arg, "common_block") == 0)
217 current_extern_model = extern_model_common_block;
218 else if (strcmp (arg, "globalvalue") == 0)
219 {
220 sorry ("extern model globalvalue");
221 return;
222 }
223 else
224 {
225 error ("unknown '#pragma extern_model' model '%s'", arg);
226 return;
227 }
228 #if 0
229 if (pragma_lex (&x) != CPP_EOF)
230 {
231 permerror (input_location, "junk at end of '#pragma extern_model'");
232 return;
233 }
234 #endif
235 }
236
237 /* Ignore '#pragma message'. */
238
239 static void
240 vms_pragma_message (cpp_reader *pfile ATTRIBUTE_UNUSED)
241 {
242 /* Completly ignored. */
243 #if 0
244 pedwarn (input_location, OPT_Wpragmas,
245 "vms '#pragma __message' is ignored");
246 #endif
247 }
248
249 /* Handle '#pragma __extern_prefix' */
250
251 static GTY(()) tree saved_extern_prefix;
252
253 static void
254 vms_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy))
255 {
256 enum cpp_ttype tok;
257 tree x;
258
259 tok = pragma_lex (&x);
260 if (tok == CPP_NAME)
261 {
262 const char *op = IDENTIFIER_POINTER (x);
263
264 if (!strcmp (op, "__save"))
265 saved_extern_prefix = pragma_extern_prefix;
266 else if (!strcmp (op, "__restore"))
267 pragma_extern_prefix = saved_extern_prefix;
268 else
269 warning (OPT_Wpragmas,
270 "malformed '#pragma __extern_prefix', ignoring");
271 return;
272 }
273 else if (tok != CPP_STRING)
274 {
275 warning (OPT_Wpragmas,
276 "malformed '#pragma __extern_prefix', ignoring");
277 }
278 else
279 {
280 /* Note that the length includes the null terminator. */
281 pragma_extern_prefix = (TREE_STRING_LENGTH (x) > 1 ? x : NULL);
282 }
283 }
284
285 /* #pragma __pointer_size */
286
287 static machine_mode saved_pointer_mode;
288
289 static void
290 handle_pragma_pointer_size (const char *pragma_name)
291 {
292 enum cpp_ttype tok;
293 tree x;
294
295 tok = pragma_lex (&x);
296 if (tok == CPP_NAME)
297 {
298 const char *op = IDENTIFIER_POINTER (x);
299
300 if (!strcmp (op, "__save"))
301 saved_pointer_mode = c_default_pointer_mode;
302 else if (!strcmp (op, "__restore"))
303 c_default_pointer_mode = saved_pointer_mode;
304 else if (!strcmp (op, "__short"))
305 c_default_pointer_mode = SImode;
306 else if (!strcmp (op, "__long"))
307 c_default_pointer_mode = DImode;
308 else
309 error ("malformed %<#pragma %s%>, ignoring", pragma_name);
310 }
311 else if (tok == CPP_NUMBER)
312 {
313 int val;
314
315 if (TREE_CODE (x) == INTEGER_CST)
316 val = TREE_INT_CST_LOW (x);
317 else
318 val = -1;
319
320 if (val == 32)
321 c_default_pointer_mode = SImode;
322 else if (val == 64)
323 c_default_pointer_mode = DImode;
324 else
325 error ("invalid constant in %<#pragma %s%>", pragma_name);
326 }
327 else
328 {
329 error ("malformed %<#pragma %s%>, ignoring", pragma_name);
330 }
331 }
332
333 static void
334 vms_pragma_pointer_size (cpp_reader * ARG_UNUSED (dummy))
335 {
336 /* Ignore if no -mpointer-size option. */
337 if (flag_vms_pointer_size == VMS_POINTER_SIZE_NONE)
338 return;
339
340 handle_pragma_pointer_size ("pointer_size");
341 }
342
343 static void
344 vms_pragma_required_pointer_size (cpp_reader * ARG_UNUSED (dummy))
345 {
346 handle_pragma_pointer_size ("required_pointer_size");
347 }
348
349 /* Add vms-specific pragma. */
350
351 void
352 vms_c_register_pragma (void)
353 {
354 c_register_pragma (NULL, "__nostandard", vms_pragma_nostandard);
355 c_register_pragma (NULL, "nostandard", vms_pragma_nostandard);
356 c_register_pragma (NULL, "__standard", vms_pragma_standard);
357 c_register_pragma (NULL, "standard", vms_pragma_standard);
358 c_register_pragma (NULL, "__member_alignment", vms_pragma_member_alignment);
359 c_register_pragma (NULL, "member_alignment", vms_pragma_member_alignment);
360 c_register_pragma_with_expansion (NULL, "__nomember_alignment",
361 vms_pragma_nomember_alignment);
362 c_register_pragma_with_expansion (NULL, "nomember_alignment",
363 vms_pragma_nomember_alignment);
364 c_register_pragma (NULL, "__pointer_size",
365 vms_pragma_pointer_size);
366 c_register_pragma (NULL, "__required_pointer_size",
367 vms_pragma_required_pointer_size);
368 c_register_pragma (NULL, "__extern_model", vms_pragma_extern_model);
369 c_register_pragma (NULL, "extern_model", vms_pragma_extern_model);
370 c_register_pragma (NULL, "__message", vms_pragma_message);
371 c_register_pragma (NULL, "__extern_prefix", vms_pragma_extern_prefix);
372 }
373
374 /* Canonicalize the filename (remove directory prefix, force the .h extension),
375 and append it to the directory to create the path, but don't
376 turn / into // or // into ///; // may be a namespace escape. */
377
378 static char *
379 vms_construct_include_filename (const char *fname, cpp_dir *dir)
380 {
381 size_t dlen, flen;
382 char *path;
383 const char *fbasename = lbasename (fname);
384 size_t i;
385
386 dlen = dir->len;
387 flen = strlen (fbasename) + 2;
388 path = XNEWVEC (char, dlen + 1 + flen + 1);
389 memcpy (path, dir->name, dlen);
390 if (dlen && !IS_DIR_SEPARATOR (path[dlen - 1]))
391 path[dlen++] = '/';
392 for (i = 0; i < flen; i++)
393 if (fbasename[i] == '.')
394 break;
395 else
396 path[dlen + i] = TOLOWER (fbasename[i]);
397 path[dlen + i + 0] = '.';
398 path[dlen + i + 1] = 'h';
399 path[dlen + i + 2] = 0;
400
401 return path;
402 }
403
404 /* Standard modules list. */
405 static const char * const vms_std_modules[] = { "rtldef", "starlet_c", NULL };
406
407 /* Find include modules in the include path. */
408
409 void
410 vms_c_register_includes (const char *sysroot,
411 const char *iprefix ATTRIBUTE_UNUSED, int stdinc)
412 {
413 static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
414 struct cpp_dir *dir;
415
416 /* Add on standard include pathes. */
417 if (!stdinc)
418 return;
419
420 for (dir = get_added_cpp_dirs (SYSTEM); dir != NULL; dir = dir->next)
421 {
422 const char * const *lib;
423 for (lib = vms_std_modules; *lib != NULL; lib++)
424 {
425 char *path;
426 struct stat st;
427
428 if (sysroot != NULL)
429 path = concat (sysroot, dir->name, dir_separator_str, *lib, NULL);
430 else
431 path = concat (dir->name, dir_separator_str, *lib, NULL);
432
433 if (stat (path, &st) == 0 && S_ISDIR (st.st_mode))
434 {
435 cpp_dir *p;
436
437 p = XNEW (cpp_dir);
438 p->next = NULL;
439 p->name = path;
440 p->sysp = 1;
441 p->construct = vms_construct_include_filename;
442 p->user_supplied_p = 0;
443 add_cpp_dir_path (p, SYSTEM);
444 }
445 else
446 free (path);
447 }
448 }
449 }
450
451 void
452 vms_c_common_override_options (void)
453 {
454 /* Allow variadic functions without parameters (as declared in starlet). */
455 flag_allow_parameterless_variadic_functions = TRUE;
456
457 /* Initialize c_default_pointer_mode. */
458 switch (flag_vms_pointer_size)
459 {
460 case VMS_POINTER_SIZE_NONE:
461 break;
462 case VMS_POINTER_SIZE_32:
463 c_default_pointer_mode = SImode;
464 break;
465 case VMS_POINTER_SIZE_64:
466 c_default_pointer_mode = DImode;
467 break;
468 }
469 }
470
471 /* The default value for _CRTL_VER macro. */
472
473 int
474 vms_c_get_crtl_ver (void)
475 {
476 return VMS_DEFAULT_CRTL_VER;
477 }
478
479 /* The default value for _VMS_VER macro. */
480
481 int
482 vms_c_get_vms_ver (void)
483 {
484 return VMS_DEFAULT_VMS_VER;
485 }