11debfc3dSmrg /* Solaris support needed only by C/C++ frontends.
2*8feb0f0bSmrg Copyright (C) 2004-2020 Free Software Foundation, Inc.
31debfc3dSmrg Contributed by CodeSourcery, LLC.
41debfc3dSmrg
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify
81debfc3dSmrg it under the terms of the GNU General Public License as published by
91debfc3dSmrg the Free Software Foundation; either version 3, or (at your option)
101debfc3dSmrg any later version.
111debfc3dSmrg
121debfc3dSmrg GCC is distributed in the hope that it will be useful,
131debfc3dSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of
141debfc3dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
151debfc3dSmrg GNU General Public License for more details.
161debfc3dSmrg
171debfc3dSmrg You should have received a copy of the GNU General Public License
181debfc3dSmrg along with GCC; see the file COPYING3. If not see
191debfc3dSmrg <http://www.gnu.org/licenses/>. */
201debfc3dSmrg
211debfc3dSmrg #include "config.h"
221debfc3dSmrg #include "system.h"
231debfc3dSmrg #include "coretypes.h"
241debfc3dSmrg #include "tm.h"
251debfc3dSmrg #include "c-family/c-common.h"
261debfc3dSmrg #include "stringpool.h"
271debfc3dSmrg #include "attribs.h"
281debfc3dSmrg
291debfc3dSmrg #include "c-family/c-format.h"
301debfc3dSmrg #include "intl.h"
311debfc3dSmrg
321debfc3dSmrg #include "c-family/c-pragma.h"
331debfc3dSmrg
341debfc3dSmrg /* cmn_err only accepts "l" and "ll". */
351debfc3dSmrg static const format_length_info cmn_err_length_specs[] =
361debfc3dSmrg {
371debfc3dSmrg { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
381debfc3dSmrg { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
391debfc3dSmrg };
401debfc3dSmrg
411debfc3dSmrg static const format_flag_spec cmn_err_flag_specs[] =
421debfc3dSmrg {
43a2dc1f3fSmrg { 'w', 0, 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
44a2dc1f3fSmrg { 'L', 0, 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
45a2dc1f3fSmrg { 0, 0, 0, 0, NULL, NULL, STD_C89 }
461debfc3dSmrg };
471debfc3dSmrg
481debfc3dSmrg
491debfc3dSmrg static const format_flag_pair cmn_err_flag_pairs[] =
501debfc3dSmrg {
511debfc3dSmrg { 0, 0, 0, 0 }
521debfc3dSmrg };
531debfc3dSmrg
541debfc3dSmrg static const format_char_info bitfield_string_type =
551debfc3dSmrg { "b", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL };
561debfc3dSmrg
571debfc3dSmrg static const format_char_info cmn_err_char_table[] =
581debfc3dSmrg {
591debfc3dSmrg /* C89 conversion specifiers. */
601debfc3dSmrg { "dD", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
611debfc3dSmrg { "oOxX",0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
621debfc3dSmrg { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
631debfc3dSmrg { "c", 0, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL },
641debfc3dSmrg { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "c", NULL },
651debfc3dSmrg { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "cR", NULL },
661debfc3dSmrg { "b", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", &bitfield_string_type },
671debfc3dSmrg { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
681debfc3dSmrg };
691debfc3dSmrg
701debfc3dSmrg EXPORTED_CONST format_kind_info solaris_format_types[] = {
711debfc3dSmrg { "cmn_err", cmn_err_length_specs, cmn_err_char_table, "", NULL,
721debfc3dSmrg cmn_err_flag_specs, cmn_err_flag_pairs,
731debfc3dSmrg FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
741debfc3dSmrg 'w', 0, 0, 0, 'L', 0,
751debfc3dSmrg &integer_type_node, &integer_type_node
761debfc3dSmrg }
771debfc3dSmrg };
781debfc3dSmrg
791debfc3dSmrg /* Handle #pragma align ALIGNMENT (VAR [, VAR]...) */
801debfc3dSmrg
811debfc3dSmrg static void
solaris_pragma_align(cpp_reader * pfile ATTRIBUTE_UNUSED)821debfc3dSmrg solaris_pragma_align (cpp_reader *pfile ATTRIBUTE_UNUSED)
831debfc3dSmrg {
841debfc3dSmrg tree t, x;
851debfc3dSmrg enum cpp_ttype ttype;
861debfc3dSmrg unsigned HOST_WIDE_INT low;
871debfc3dSmrg
881debfc3dSmrg if (pragma_lex (&x) != CPP_NUMBER
891debfc3dSmrg || pragma_lex (&t) != CPP_OPEN_PAREN)
901debfc3dSmrg {
911debfc3dSmrg warning (0, "malformed %<#pragma align%>, ignoring");
921debfc3dSmrg return;
931debfc3dSmrg }
941debfc3dSmrg
951debfc3dSmrg low = TREE_INT_CST_LOW (x);
961debfc3dSmrg if (!tree_fits_uhwi_p (x)
971debfc3dSmrg || (low != 1 && low != 2 && low != 4 && low != 8 && low != 16
981debfc3dSmrg && low != 32 && low != 64 && low != 128))
991debfc3dSmrg {
1001debfc3dSmrg warning (0, "invalid alignment for %<#pragma align%>, ignoring");
1011debfc3dSmrg return;
1021debfc3dSmrg }
1031debfc3dSmrg
1041debfc3dSmrg ttype = pragma_lex (&t);
1051debfc3dSmrg if (ttype != CPP_NAME)
1061debfc3dSmrg {
1071debfc3dSmrg warning (0, "malformed %<#pragma align%>, ignoring");
1081debfc3dSmrg return;
1091debfc3dSmrg }
1101debfc3dSmrg
1111debfc3dSmrg while (1)
1121debfc3dSmrg {
1131debfc3dSmrg tree decl = identifier_global_value (t);
1141debfc3dSmrg if (decl && DECL_P (decl))
1151debfc3dSmrg warning (0, "%<#pragma align%> must appear before the declaration of "
116a2dc1f3fSmrg "%qD, ignoring", decl);
1171debfc3dSmrg else
1181debfc3dSmrg solaris_pending_aligns = tree_cons (t, build_tree_list (NULL, x),
1191debfc3dSmrg solaris_pending_aligns);
1201debfc3dSmrg
1211debfc3dSmrg ttype = pragma_lex (&t);
1221debfc3dSmrg if (ttype == CPP_COMMA)
1231debfc3dSmrg {
1241debfc3dSmrg ttype = pragma_lex (&t);
1251debfc3dSmrg if (ttype != CPP_NAME)
1261debfc3dSmrg {
1271debfc3dSmrg warning (0, "malformed %<#pragma align%>");
1281debfc3dSmrg return;
1291debfc3dSmrg }
1301debfc3dSmrg }
1311debfc3dSmrg else if (ttype == CPP_CLOSE_PAREN)
1321debfc3dSmrg {
1331debfc3dSmrg if (pragma_lex (&t) != CPP_EOF)
1341debfc3dSmrg warning (0, "junk at end of %<#pragma align%>");
1351debfc3dSmrg return;
1361debfc3dSmrg }
1371debfc3dSmrg else
1381debfc3dSmrg {
1391debfc3dSmrg warning (0, "malformed %<#pragma align%>");
1401debfc3dSmrg return;
1411debfc3dSmrg }
1421debfc3dSmrg }
1431debfc3dSmrg }
1441debfc3dSmrg
1451debfc3dSmrg /* Handle #pragma init (function [, function]...) */
1461debfc3dSmrg
1471debfc3dSmrg static void
solaris_pragma_init(cpp_reader * pfile ATTRIBUTE_UNUSED)1481debfc3dSmrg solaris_pragma_init (cpp_reader *pfile ATTRIBUTE_UNUSED)
1491debfc3dSmrg {
1501debfc3dSmrg tree t;
1511debfc3dSmrg enum cpp_ttype ttype;
1521debfc3dSmrg
1531debfc3dSmrg if (pragma_lex (&t) != CPP_OPEN_PAREN)
1541debfc3dSmrg {
1551debfc3dSmrg warning (0, "malformed %<#pragma init%>, ignoring");
1561debfc3dSmrg return;
1571debfc3dSmrg }
1581debfc3dSmrg
1591debfc3dSmrg ttype = pragma_lex (&t);
1601debfc3dSmrg if (ttype != CPP_NAME)
1611debfc3dSmrg {
1621debfc3dSmrg warning (0, "malformed %<#pragma init%>, ignoring");
1631debfc3dSmrg return;
1641debfc3dSmrg }
1651debfc3dSmrg
1661debfc3dSmrg while (1)
1671debfc3dSmrg {
1681debfc3dSmrg tree decl = identifier_global_value (t);
1691debfc3dSmrg if (decl && DECL_P (decl))
1701debfc3dSmrg {
1711debfc3dSmrg tree attrs = build_tree_list (get_identifier ("init"),
1721debfc3dSmrg NULL);
1731debfc3dSmrg TREE_USED (decl) = 1;
1741debfc3dSmrg DECL_PRESERVE_P (decl) = 1;
1751debfc3dSmrg decl_attributes (&decl, attrs, 0);
1761debfc3dSmrg }
1771debfc3dSmrg else
1781debfc3dSmrg solaris_pending_inits = tree_cons (t, NULL, solaris_pending_inits);
1791debfc3dSmrg
1801debfc3dSmrg ttype = pragma_lex (&t);
1811debfc3dSmrg if (ttype == CPP_COMMA)
1821debfc3dSmrg {
1831debfc3dSmrg ttype = pragma_lex (&t);
1841debfc3dSmrg if (ttype != CPP_NAME)
1851debfc3dSmrg {
1861debfc3dSmrg warning (0, "malformed %<#pragma init%>");
1871debfc3dSmrg return;
1881debfc3dSmrg }
1891debfc3dSmrg }
1901debfc3dSmrg else if (ttype == CPP_CLOSE_PAREN)
1911debfc3dSmrg {
1921debfc3dSmrg if (pragma_lex (&t) != CPP_EOF)
1931debfc3dSmrg warning (0, "junk at end of %<#pragma init%>");
1941debfc3dSmrg return;
1951debfc3dSmrg }
1961debfc3dSmrg else
1971debfc3dSmrg {
1981debfc3dSmrg warning (0, "malformed %<#pragma init%>");
1991debfc3dSmrg return;
2001debfc3dSmrg }
2011debfc3dSmrg }
2021debfc3dSmrg }
2031debfc3dSmrg
2041debfc3dSmrg /* Handle #pragma fini (function [, function]...) */
2051debfc3dSmrg
2061debfc3dSmrg static void
solaris_pragma_fini(cpp_reader * pfile ATTRIBUTE_UNUSED)2071debfc3dSmrg solaris_pragma_fini (cpp_reader *pfile ATTRIBUTE_UNUSED)
2081debfc3dSmrg {
2091debfc3dSmrg tree t;
2101debfc3dSmrg enum cpp_ttype ttype;
2111debfc3dSmrg
2121debfc3dSmrg if (pragma_lex (&t) != CPP_OPEN_PAREN)
2131debfc3dSmrg {
2141debfc3dSmrg warning (0, "malformed %<#pragma fini%>, ignoring");
2151debfc3dSmrg return;
2161debfc3dSmrg }
2171debfc3dSmrg
2181debfc3dSmrg ttype = pragma_lex (&t);
2191debfc3dSmrg if (ttype != CPP_NAME)
2201debfc3dSmrg {
2211debfc3dSmrg warning (0, "malformed %<#pragma fini%>, ignoring");
2221debfc3dSmrg return;
2231debfc3dSmrg }
2241debfc3dSmrg
2251debfc3dSmrg while (1)
2261debfc3dSmrg {
2271debfc3dSmrg tree decl = identifier_global_value (t);
2281debfc3dSmrg if (decl && DECL_P (decl))
2291debfc3dSmrg {
2301debfc3dSmrg tree attrs = build_tree_list (get_identifier ("fini"),
2311debfc3dSmrg NULL);
2321debfc3dSmrg TREE_USED (decl) = 1;
2331debfc3dSmrg DECL_PRESERVE_P (decl) = 1;
2341debfc3dSmrg decl_attributes (&decl, attrs, 0);
2351debfc3dSmrg }
2361debfc3dSmrg else
2371debfc3dSmrg solaris_pending_finis = tree_cons (t, NULL, solaris_pending_finis);
2381debfc3dSmrg
2391debfc3dSmrg ttype = pragma_lex (&t);
2401debfc3dSmrg if (ttype == CPP_COMMA)
2411debfc3dSmrg {
2421debfc3dSmrg ttype = pragma_lex (&t);
2431debfc3dSmrg if (ttype != CPP_NAME)
2441debfc3dSmrg {
2451debfc3dSmrg warning (0, "malformed %<#pragma fini%>");
2461debfc3dSmrg return;
2471debfc3dSmrg }
2481debfc3dSmrg }
2491debfc3dSmrg else if (ttype == CPP_CLOSE_PAREN)
2501debfc3dSmrg {
2511debfc3dSmrg if (pragma_lex (&t) != CPP_EOF)
2521debfc3dSmrg warning (0, "junk at end of %<#pragma fini%>");
2531debfc3dSmrg return;
2541debfc3dSmrg }
2551debfc3dSmrg else
2561debfc3dSmrg {
2571debfc3dSmrg warning (0, "malformed %<#pragma fini%>");
2581debfc3dSmrg return;
2591debfc3dSmrg }
2601debfc3dSmrg }
2611debfc3dSmrg }
2621debfc3dSmrg
2631debfc3dSmrg /* Register Solaris-specific #pragma directives. */
2641debfc3dSmrg
2651debfc3dSmrg void
solaris_register_pragmas(void)2661debfc3dSmrg solaris_register_pragmas (void)
2671debfc3dSmrg {
2681debfc3dSmrg c_register_pragma_with_expansion (0, "align", solaris_pragma_align);
2691debfc3dSmrg c_register_pragma (0, "init", solaris_pragma_init);
2701debfc3dSmrg c_register_pragma (0, "fini", solaris_pragma_fini);
2711debfc3dSmrg }
272