* gcc-interface/trans.c (process_freeze_entity): Be prepared for a
[official-gcc.git] / gcc / config / vms / vms-c.c
blob278c8e236be5e494f8111298ebc3f7074d60eb23
1 /* VMS specific, C compiler specific functions.
2 Copyright (C) 2011-2017 Free Software Foundation, Inc.
3 Contributed by Tristan Gingold (gingold@adacore.com).
5 This file is part of GCC.
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.
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.
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/>. */
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 "memmodel.h"
29 #include "tm_p.h"
30 #include "c-family/c-pragma.h"
31 #include "toplev.h"
32 #include "incpath.h"
34 /* '#pragma __nostandard' is simply ignored. */
36 static void
37 vms_pragma_nostandard (cpp_reader *pfile ATTRIBUTE_UNUSED)
39 tree x;
41 if (pragma_lex (&x) != CPP_EOF)
42 warning (OPT_Wpragmas, "junk at end of #pragma __nostandard");
45 /* '#pragma __standard' is simply ignored. */
47 static void
48 vms_pragma_standard (cpp_reader *pfile ATTRIBUTE_UNUSED)
50 tree x;
52 if (pragma_lex (&x) != CPP_EOF)
53 warning (OPT_Wpragmas, "junk at end of #pragma __standard");
56 /* Saved member alignment. */
57 static int saved_member_alignment;
59 /* Handle '#pragma member_alignment'. */
61 static void
62 vms_pragma_member_alignment (cpp_reader *pfile ATTRIBUTE_UNUSED)
64 tree x;
65 int tok;
66 const char *arg;
68 tok = pragma_lex (&x);
70 if (tok == CPP_EOF)
72 /* Disable packing. */
73 maximum_field_alignment = initial_max_fld_align;
74 return;
76 if (tok != CPP_NAME)
78 warning (OPT_Wpragmas, "malformed '#pragma member_alignment', ignoring");
79 return;
82 arg = IDENTIFIER_POINTER (x);
83 /* Accept '__' prefix. */
84 if (arg[0] == '_' && arg[1] == '_')
85 arg += 2;
87 if (strcmp (arg, "save") == 0)
88 saved_member_alignment = maximum_field_alignment;
89 else if (strcmp (arg, "restore") == 0)
90 maximum_field_alignment = saved_member_alignment;
91 else
93 error ("unknown '#pragma member_alignment' name %s", arg);
94 return;
96 if (pragma_lex (&x) != CPP_EOF)
98 error ("malformed '#pragma member_alignment'");
99 return;
103 /* Handle '#pragma nomember_alignment'. */
105 static void
106 vms_pragma_nomember_alignment (cpp_reader *pfile ATTRIBUTE_UNUSED)
108 tree x;
109 int tok;
111 tok = pragma_lex (&x);
112 if (tok == CPP_NAME)
114 const char *arg = IDENTIFIER_POINTER (x);
116 /* Accept '__' prefix. */
117 if (arg[0] == '_' && arg[1] == '_')
118 arg += 2;
120 if (strcmp (arg, "byte") == 0)
121 maximum_field_alignment = 1 * BITS_PER_UNIT;
122 else if (strcmp (arg, "word") == 0)
123 maximum_field_alignment = 2 * BITS_PER_UNIT;
124 else if (strcmp (arg, "longword") == 0)
125 maximum_field_alignment = 4 * BITS_PER_UNIT;
126 else if (strcmp (arg, "quadword") == 0)
127 maximum_field_alignment = 8 * BITS_PER_UNIT;
128 else if (strcmp (arg, "octaword") == 0)
129 maximum_field_alignment = 16 * BITS_PER_UNIT;
130 else
132 error ("unhandled alignment for '#pragma nomember_alignment'");
135 tok = pragma_lex (&x);
137 else
139 /* Enable packing. */
140 maximum_field_alignment = BITS_PER_UNIT;
143 if (tok != CPP_EOF)
145 error ("garbage at end of '#pragma nomember_alignment'");
146 return;
150 /* The 'extern model' for public data. This drives how the following
151 declarations are handled:
152 1) extern int name;
153 2) int name;
154 3) int name = 5;
155 See below for the behavior as implemented by the native compiler.
158 enum extern_model_kind
160 /* Create one overlaid section per variable. All the above declarations (1,
161 2 and 3) are handled the same way: they create an overlaid section named
162 NAME (and initialized only for 3). No global symbol is created.
163 This is the VAX C behavior. */
164 extern_model_common_block,
166 /* Like unix: multiple not-initialized declarations are allowed.
167 Only one initialized definition (case 3) is allows, but multiple
168 uninitialize definition (case 2) are allowed.
169 For case 2, this creates both a section named NAME and a global symbol.
170 For case 3, this creates a conditional global symbol defenition and a
171 conditional section definition.
172 This is the traditional UNIX C behavior. */
173 extern_model_relaxed_refdef,
175 /* Like -fno-common. Only one definition (cases 2 and 3) are allowed.
176 This is the ANSI-C model. */
177 extern_model_strict_refdef,
179 /* Declarations creates symbols without storage. */
180 extern_model_globalvalue
183 /* Current and saved extern model. */
184 static enum extern_model_kind current_extern_model;
185 static enum extern_model_kind saved_extern_model;
187 /* Partial handling of '#pragma extern_model'. */
189 static void
190 vms_pragma_extern_model (cpp_reader *pfile ATTRIBUTE_UNUSED)
192 tree x;
193 int tok;
194 const char *arg;
196 tok = pragma_lex (&x);
198 if (tok != CPP_NAME)
200 warning (OPT_Wpragmas, "malformed '#pragma extern_model', ignoring");
201 return;
204 arg = IDENTIFIER_POINTER (x);
205 /* Accept "__" prefix. */
206 if (arg[0] == '_' && arg[1] == '_')
207 arg += 2;
209 if (strcmp (arg, "save") == 0)
210 saved_extern_model = current_extern_model;
211 else if (strcmp (arg, "restore") == 0)
212 current_extern_model = saved_extern_model;
213 else if (strcmp (arg, "relaxed_refdef") == 0)
214 current_extern_model = extern_model_relaxed_refdef;
215 else if (strcmp (arg, "strict_refdef") == 0)
216 current_extern_model = extern_model_strict_refdef;
217 else if (strcmp (arg, "common_block") == 0)
218 current_extern_model = extern_model_common_block;
219 else if (strcmp (arg, "globalvalue") == 0)
221 sorry ("extern model globalvalue");
222 return;
224 else
226 error ("unknown '#pragma extern_model' model '%s'", arg);
227 return;
229 #if 0
230 if (pragma_lex (&x) != CPP_EOF)
232 permerror (input_location, "junk at end of '#pragma extern_model'");
233 return;
235 #endif
238 /* Ignore '#pragma message'. */
240 static void
241 vms_pragma_message (cpp_reader *pfile ATTRIBUTE_UNUSED)
243 /* Completly ignored. */
244 #if 0
245 pedwarn (input_location, OPT_Wpragmas,
246 "vms '#pragma __message' is ignored");
247 #endif
250 /* Handle '#pragma __extern_prefix' */
252 static GTY(()) tree saved_extern_prefix;
254 static void
255 vms_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy))
257 enum cpp_ttype tok;
258 tree x;
260 tok = pragma_lex (&x);
261 if (tok == CPP_NAME)
263 const char *op = IDENTIFIER_POINTER (x);
265 if (!strcmp (op, "__save"))
266 saved_extern_prefix = pragma_extern_prefix;
267 else if (!strcmp (op, "__restore"))
268 pragma_extern_prefix = saved_extern_prefix;
269 else
270 warning (OPT_Wpragmas,
271 "malformed '#pragma __extern_prefix', ignoring");
272 return;
274 else if (tok != CPP_STRING)
276 warning (OPT_Wpragmas,
277 "malformed '#pragma __extern_prefix', ignoring");
279 else
281 /* Note that the length includes the null terminator. */
282 pragma_extern_prefix = (TREE_STRING_LENGTH (x) > 1 ? x : NULL);
286 /* #pragma __pointer_size */
288 static machine_mode saved_pointer_mode;
290 static void
291 handle_pragma_pointer_size (const char *pragma_name)
293 enum cpp_ttype tok;
294 tree x;
296 tok = pragma_lex (&x);
297 if (tok == CPP_NAME)
299 const char *op = IDENTIFIER_POINTER (x);
301 if (!strcmp (op, "__save"))
302 saved_pointer_mode = c_default_pointer_mode;
303 else if (!strcmp (op, "__restore"))
304 c_default_pointer_mode = saved_pointer_mode;
305 else if (!strcmp (op, "__short"))
306 c_default_pointer_mode = SImode;
307 else if (!strcmp (op, "__long"))
308 c_default_pointer_mode = DImode;
309 else
310 error ("malformed %<#pragma %s%>, ignoring", pragma_name);
312 else if (tok == CPP_NUMBER)
314 int val;
316 if (TREE_CODE (x) == INTEGER_CST)
317 val = TREE_INT_CST_LOW (x);
318 else
319 val = -1;
321 if (val == 32)
322 c_default_pointer_mode = SImode;
323 else if (val == 64)
324 c_default_pointer_mode = DImode;
325 else
326 error ("invalid constant in %<#pragma %s%>", pragma_name);
328 else
330 error ("malformed %<#pragma %s%>, ignoring", pragma_name);
334 static void
335 vms_pragma_pointer_size (cpp_reader * ARG_UNUSED (dummy))
337 /* Ignore if no -mpointer-size option. */
338 if (flag_vms_pointer_size == VMS_POINTER_SIZE_NONE)
339 return;
341 handle_pragma_pointer_size ("pointer_size");
344 static void
345 vms_pragma_required_pointer_size (cpp_reader * ARG_UNUSED (dummy))
347 handle_pragma_pointer_size ("required_pointer_size");
350 /* Add vms-specific pragma. */
352 void
353 vms_c_register_pragma (void)
355 c_register_pragma (NULL, "__nostandard", vms_pragma_nostandard);
356 c_register_pragma (NULL, "nostandard", vms_pragma_nostandard);
357 c_register_pragma (NULL, "__standard", vms_pragma_standard);
358 c_register_pragma (NULL, "standard", vms_pragma_standard);
359 c_register_pragma (NULL, "__member_alignment", vms_pragma_member_alignment);
360 c_register_pragma (NULL, "member_alignment", vms_pragma_member_alignment);
361 c_register_pragma_with_expansion (NULL, "__nomember_alignment",
362 vms_pragma_nomember_alignment);
363 c_register_pragma_with_expansion (NULL, "nomember_alignment",
364 vms_pragma_nomember_alignment);
365 c_register_pragma (NULL, "__pointer_size",
366 vms_pragma_pointer_size);
367 c_register_pragma (NULL, "__required_pointer_size",
368 vms_pragma_required_pointer_size);
369 c_register_pragma (NULL, "__extern_model", vms_pragma_extern_model);
370 c_register_pragma (NULL, "extern_model", vms_pragma_extern_model);
371 c_register_pragma (NULL, "__message", vms_pragma_message);
372 c_register_pragma (NULL, "__extern_prefix", vms_pragma_extern_prefix);
375 /* Canonicalize the filename (remove directory prefix, force the .h extension),
376 and append it to the directory to create the path, but don't
377 turn / into // or // into ///; // may be a namespace escape. */
379 static char *
380 vms_construct_include_filename (const char *fname, cpp_dir *dir)
382 size_t dlen, flen;
383 char *path;
384 const char *fbasename = lbasename (fname);
385 size_t i;
387 dlen = dir->len;
388 flen = strlen (fbasename) + 2;
389 path = XNEWVEC (char, dlen + 1 + flen + 1);
390 memcpy (path, dir->name, dlen);
391 if (dlen && !IS_DIR_SEPARATOR (path[dlen - 1]))
392 path[dlen++] = '/';
393 for (i = 0; i < flen; i++)
394 if (fbasename[i] == '.')
395 break;
396 else
397 path[dlen + i] = TOLOWER (fbasename[i]);
398 path[dlen + i + 0] = '.';
399 path[dlen + i + 1] = 'h';
400 path[dlen + i + 2] = 0;
402 return path;
405 /* Standard modules list. */
406 static const char * const vms_std_modules[] = { "rtldef", "starlet_c", NULL };
408 /* Find include modules in the include path. */
410 void
411 vms_c_register_includes (const char *sysroot,
412 const char *iprefix ATTRIBUTE_UNUSED, int stdinc)
414 static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
415 struct cpp_dir *dir;
417 /* Add on standard include pathes. */
418 if (!stdinc)
419 return;
421 for (dir = get_added_cpp_dirs (INC_SYSTEM); dir != NULL; dir = dir->next)
423 const char * const *lib;
424 for (lib = vms_std_modules; *lib != NULL; lib++)
426 char *path;
427 struct stat st;
429 if (sysroot != NULL)
430 path = concat (sysroot, dir->name, dir_separator_str, *lib, NULL);
431 else
432 path = concat (dir->name, dir_separator_str, *lib, NULL);
434 if (stat (path, &st) == 0 && S_ISDIR (st.st_mode))
436 cpp_dir *p;
438 p = XNEW (cpp_dir);
439 p->next = NULL;
440 p->name = path;
441 p->sysp = 1;
442 p->construct = vms_construct_include_filename;
443 p->user_supplied_p = 0;
444 add_cpp_dir_path (p, INC_SYSTEM);
446 else
447 free (path);
452 void
453 vms_c_common_override_options (void)
455 /* Allow variadic functions without parameters (as declared in starlet). */
456 flag_allow_parameterless_variadic_functions = TRUE;
458 /* Initialize c_default_pointer_mode. */
459 switch (flag_vms_pointer_size)
461 case VMS_POINTER_SIZE_NONE:
462 break;
463 case VMS_POINTER_SIZE_32:
464 c_default_pointer_mode = SImode;
465 break;
466 case VMS_POINTER_SIZE_64:
467 c_default_pointer_mode = DImode;
468 break;
472 /* The default value for _CRTL_VER macro. */
475 vms_c_get_crtl_ver (void)
477 return VMS_DEFAULT_CRTL_VER;
480 /* The default value for _VMS_VER macro. */
483 vms_c_get_vms_ver (void)
485 return VMS_DEFAULT_VMS_VER;