1 /* VMS specific, C compiler specific functions.
2 Copyright (C) 2011-2018 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)
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 #define IN_TARGET_CODE 1
25 #include "coretypes.h"
28 #include "c-family/c-common.h"
32 #include "c-family/c-pragma.h"
36 /* '#pragma __nostandard' is simply ignored. */
39 vms_pragma_nostandard (cpp_reader
*pfile ATTRIBUTE_UNUSED
)
43 if (pragma_lex (&x
) != CPP_EOF
)
44 warning (OPT_Wpragmas
, "junk at end of #pragma __nostandard");
47 /* '#pragma __standard' is simply ignored. */
50 vms_pragma_standard (cpp_reader
*pfile ATTRIBUTE_UNUSED
)
54 if (pragma_lex (&x
) != CPP_EOF
)
55 warning (OPT_Wpragmas
, "junk at end of #pragma __standard");
58 /* Saved member alignment. */
59 static int saved_member_alignment
;
61 /* Handle '#pragma member_alignment'. */
64 vms_pragma_member_alignment (cpp_reader
*pfile ATTRIBUTE_UNUSED
)
70 tok
= pragma_lex (&x
);
74 /* Disable packing. */
75 maximum_field_alignment
= initial_max_fld_align
;
80 warning (OPT_Wpragmas
, "malformed '#pragma member_alignment', ignoring");
84 arg
= IDENTIFIER_POINTER (x
);
85 /* Accept '__' prefix. */
86 if (arg
[0] == '_' && arg
[1] == '_')
89 if (strcmp (arg
, "save") == 0)
90 saved_member_alignment
= maximum_field_alignment
;
91 else if (strcmp (arg
, "restore") == 0)
92 maximum_field_alignment
= saved_member_alignment
;
95 error ("unknown '#pragma member_alignment' name %s", arg
);
98 if (pragma_lex (&x
) != CPP_EOF
)
100 error ("malformed '#pragma member_alignment'");
105 /* Handle '#pragma nomember_alignment'. */
108 vms_pragma_nomember_alignment (cpp_reader
*pfile ATTRIBUTE_UNUSED
)
113 tok
= pragma_lex (&x
);
116 const char *arg
= IDENTIFIER_POINTER (x
);
118 /* Accept '__' prefix. */
119 if (arg
[0] == '_' && arg
[1] == '_')
122 if (strcmp (arg
, "byte") == 0)
123 maximum_field_alignment
= 1 * BITS_PER_UNIT
;
124 else if (strcmp (arg
, "word") == 0)
125 maximum_field_alignment
= 2 * BITS_PER_UNIT
;
126 else if (strcmp (arg
, "longword") == 0)
127 maximum_field_alignment
= 4 * BITS_PER_UNIT
;
128 else if (strcmp (arg
, "quadword") == 0)
129 maximum_field_alignment
= 8 * BITS_PER_UNIT
;
130 else if (strcmp (arg
, "octaword") == 0)
131 maximum_field_alignment
= 16 * BITS_PER_UNIT
;
134 error ("unhandled alignment for '#pragma nomember_alignment'");
137 tok
= pragma_lex (&x
);
141 /* Enable packing. */
142 maximum_field_alignment
= BITS_PER_UNIT
;
147 error ("garbage at end of '#pragma nomember_alignment'");
152 /* The 'extern model' for public data. This drives how the following
153 declarations are handled:
157 See below for the behavior as implemented by the native compiler.
160 enum extern_model_kind
162 /* Create one overlaid section per variable. All the above declarations (1,
163 2 and 3) are handled the same way: they create an overlaid section named
164 NAME (and initialized only for 3). No global symbol is created.
165 This is the VAX C behavior. */
166 extern_model_common_block
,
168 /* Like unix: multiple not-initialized declarations are allowed.
169 Only one initialized definition (case 3) is allows, but multiple
170 uninitialize definition (case 2) are allowed.
171 For case 2, this creates both a section named NAME and a global symbol.
172 For case 3, this creates a conditional global symbol defenition and a
173 conditional section definition.
174 This is the traditional UNIX C behavior. */
175 extern_model_relaxed_refdef
,
177 /* Like -fno-common. Only one definition (cases 2 and 3) are allowed.
178 This is the ANSI-C model. */
179 extern_model_strict_refdef
,
181 /* Declarations creates symbols without storage. */
182 extern_model_globalvalue
185 /* Current and saved extern model. */
186 static enum extern_model_kind current_extern_model
;
187 static enum extern_model_kind saved_extern_model
;
189 /* Partial handling of '#pragma extern_model'. */
192 vms_pragma_extern_model (cpp_reader
*pfile ATTRIBUTE_UNUSED
)
198 tok
= pragma_lex (&x
);
202 warning (OPT_Wpragmas
, "malformed '#pragma extern_model', ignoring");
206 arg
= IDENTIFIER_POINTER (x
);
207 /* Accept "__" prefix. */
208 if (arg
[0] == '_' && arg
[1] == '_')
211 if (strcmp (arg
, "save") == 0)
212 saved_extern_model
= current_extern_model
;
213 else if (strcmp (arg
, "restore") == 0)
214 current_extern_model
= saved_extern_model
;
215 else if (strcmp (arg
, "relaxed_refdef") == 0)
216 current_extern_model
= extern_model_relaxed_refdef
;
217 else if (strcmp (arg
, "strict_refdef") == 0)
218 current_extern_model
= extern_model_strict_refdef
;
219 else if (strcmp (arg
, "common_block") == 0)
220 current_extern_model
= extern_model_common_block
;
221 else if (strcmp (arg
, "globalvalue") == 0)
223 sorry ("extern model globalvalue");
228 error ("unknown '#pragma extern_model' model '%s'", arg
);
232 if (pragma_lex (&x
) != CPP_EOF
)
234 permerror (input_location
, "junk at end of '#pragma extern_model'");
240 /* Ignore '#pragma message'. */
243 vms_pragma_message (cpp_reader
*pfile ATTRIBUTE_UNUSED
)
245 /* Completly ignored. */
247 pedwarn (input_location
, OPT_Wpragmas
,
248 "vms '#pragma __message' is ignored");
252 /* Handle '#pragma __extern_prefix' */
254 static GTY(()) tree saved_extern_prefix
;
257 vms_pragma_extern_prefix (cpp_reader
* ARG_UNUSED (dummy
))
262 tok
= pragma_lex (&x
);
265 const char *op
= IDENTIFIER_POINTER (x
);
267 if (!strcmp (op
, "__save"))
268 saved_extern_prefix
= pragma_extern_prefix
;
269 else if (!strcmp (op
, "__restore"))
270 pragma_extern_prefix
= saved_extern_prefix
;
272 warning (OPT_Wpragmas
,
273 "malformed '#pragma __extern_prefix', ignoring");
276 else if (tok
!= CPP_STRING
)
278 warning (OPT_Wpragmas
,
279 "malformed '#pragma __extern_prefix', ignoring");
283 /* Note that the length includes the null terminator. */
284 pragma_extern_prefix
= (TREE_STRING_LENGTH (x
) > 1 ? x
: NULL
);
288 /* #pragma __pointer_size */
290 static machine_mode saved_pointer_mode
;
293 handle_pragma_pointer_size (const char *pragma_name
)
298 tok
= pragma_lex (&x
);
301 const char *op
= IDENTIFIER_POINTER (x
);
303 if (!strcmp (op
, "__save"))
304 saved_pointer_mode
= c_default_pointer_mode
;
305 else if (!strcmp (op
, "__restore"))
306 c_default_pointer_mode
= saved_pointer_mode
;
307 else if (!strcmp (op
, "__short"))
308 c_default_pointer_mode
= SImode
;
309 else if (!strcmp (op
, "__long"))
310 c_default_pointer_mode
= DImode
;
312 error ("malformed %<#pragma %s%>, ignoring", pragma_name
);
314 else if (tok
== CPP_NUMBER
)
318 if (TREE_CODE (x
) == INTEGER_CST
)
319 val
= TREE_INT_CST_LOW (x
);
324 c_default_pointer_mode
= SImode
;
326 c_default_pointer_mode
= DImode
;
328 error ("invalid constant in %<#pragma %s%>", pragma_name
);
332 error ("malformed %<#pragma %s%>, ignoring", pragma_name
);
337 vms_pragma_pointer_size (cpp_reader
* ARG_UNUSED (dummy
))
339 /* Ignore if no -mpointer-size option. */
340 if (flag_vms_pointer_size
== VMS_POINTER_SIZE_NONE
)
343 handle_pragma_pointer_size ("pointer_size");
347 vms_pragma_required_pointer_size (cpp_reader
* ARG_UNUSED (dummy
))
349 handle_pragma_pointer_size ("required_pointer_size");
352 /* Add vms-specific pragma. */
355 vms_c_register_pragma (void)
357 c_register_pragma (NULL
, "__nostandard", vms_pragma_nostandard
);
358 c_register_pragma (NULL
, "nostandard", vms_pragma_nostandard
);
359 c_register_pragma (NULL
, "__standard", vms_pragma_standard
);
360 c_register_pragma (NULL
, "standard", vms_pragma_standard
);
361 c_register_pragma (NULL
, "__member_alignment", vms_pragma_member_alignment
);
362 c_register_pragma (NULL
, "member_alignment", vms_pragma_member_alignment
);
363 c_register_pragma_with_expansion (NULL
, "__nomember_alignment",
364 vms_pragma_nomember_alignment
);
365 c_register_pragma_with_expansion (NULL
, "nomember_alignment",
366 vms_pragma_nomember_alignment
);
367 c_register_pragma (NULL
, "__pointer_size",
368 vms_pragma_pointer_size
);
369 c_register_pragma (NULL
, "__required_pointer_size",
370 vms_pragma_required_pointer_size
);
371 c_register_pragma (NULL
, "__extern_model", vms_pragma_extern_model
);
372 c_register_pragma (NULL
, "extern_model", vms_pragma_extern_model
);
373 c_register_pragma (NULL
, "__message", vms_pragma_message
);
374 c_register_pragma (NULL
, "__extern_prefix", vms_pragma_extern_prefix
);
377 /* Canonicalize the filename (remove directory prefix, force the .h extension),
378 and append it to the directory to create the path, but don't
379 turn / into // or // into ///; // may be a namespace escape. */
382 vms_construct_include_filename (const char *fname
, cpp_dir
*dir
)
386 const char *fbasename
= lbasename (fname
);
390 flen
= strlen (fbasename
) + 2;
391 path
= XNEWVEC (char, dlen
+ 1 + flen
+ 1);
392 memcpy (path
, dir
->name
, dlen
);
393 if (dlen
&& !IS_DIR_SEPARATOR (path
[dlen
- 1]))
395 for (i
= 0; i
< flen
; i
++)
396 if (fbasename
[i
] == '.')
399 path
[dlen
+ i
] = TOLOWER (fbasename
[i
]);
400 path
[dlen
+ i
+ 0] = '.';
401 path
[dlen
+ i
+ 1] = 'h';
402 path
[dlen
+ i
+ 2] = 0;
407 /* Standard modules list. */
408 static const char * const vms_std_modules
[] = { "rtldef", "starlet_c", NULL
};
410 /* Find include modules in the include path. */
413 vms_c_register_includes (const char *sysroot
,
414 const char *iprefix ATTRIBUTE_UNUSED
, int stdinc
)
416 static const char dir_separator_str
[] = { DIR_SEPARATOR
, 0 };
419 /* Add on standard include pathes. */
423 for (dir
= get_added_cpp_dirs (INC_SYSTEM
); dir
!= NULL
; dir
= dir
->next
)
425 const char * const *lib
;
426 for (lib
= vms_std_modules
; *lib
!= NULL
; lib
++)
432 path
= concat (sysroot
, dir
->name
, dir_separator_str
, *lib
, NULL
);
434 path
= concat (dir
->name
, dir_separator_str
, *lib
, NULL
);
436 if (stat (path
, &st
) == 0 && S_ISDIR (st
.st_mode
))
444 p
->construct
= vms_construct_include_filename
;
445 p
->user_supplied_p
= 0;
446 add_cpp_dir_path (p
, INC_SYSTEM
);
455 vms_c_common_override_options (void)
457 /* Allow variadic functions without parameters (as declared in starlet). */
458 flag_allow_parameterless_variadic_functions
= TRUE
;
460 /* Initialize c_default_pointer_mode. */
461 switch (flag_vms_pointer_size
)
463 case VMS_POINTER_SIZE_NONE
:
465 case VMS_POINTER_SIZE_32
:
466 c_default_pointer_mode
= SImode
;
468 case VMS_POINTER_SIZE_64
:
469 c_default_pointer_mode
= DImode
;
474 /* The default value for _CRTL_VER macro. */
477 vms_c_get_crtl_ver (void)
479 return VMS_DEFAULT_CRTL_VER
;
482 /* The default value for _VMS_VER macro. */
485 vms_c_get_vms_ver (void)
487 return VMS_DEFAULT_VMS_VER
;