sol2-c.c revision 256281
1/* Solaris support needed only by C/C++ frontends. 2 Copyright (C) 2004, 2005 Free Software Foundation, Inc. 3 Contributed by CodeSourcery, LLC. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2, or (at your option) 10any later version. 11 12GCC is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING. If not, write to 19the Free Software Foundation, 51 Franklin Street, Fifth Floor, 20Boston, MA 02110-1301, USA. */ 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "tree.h" 26#include "tm.h" 27#include "tm_p.h" 28#include "toplev.h" 29 30#include "c-format.h" 31#include "intl.h" 32 33#include "cpplib.h" 34#include "c-pragma.h" 35#include "c-common.h" 36 37/* cmn_err only accepts "l" and "ll". */ 38static const format_length_info cmn_err_length_specs[] = 39{ 40 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 }, 41 { NULL, 0, 0, NULL, 0, 0 } 42}; 43 44static const format_flag_spec cmn_err_flag_specs[] = 45{ 46 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 }, 47 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, 48 { 0, 0, 0, NULL, NULL, 0 } 49}; 50 51 52static const format_flag_pair cmn_err_flag_pairs[] = 53{ 54 { 0, 0, 0, 0 } 55}; 56 57static const format_char_info bitfield_string_type = 58 { "b", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL }; 59 60static const format_char_info cmn_err_char_table[] = 61{ 62 /* C89 conversion specifiers. */ 63 { "dD", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL }, 64 { "oOxX",0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL }, 65 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL }, 66 { "c", 0, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", NULL }, 67 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "c", NULL }, 68 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "cR", NULL }, 69 { "b", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "w", "", &bitfield_string_type }, 70 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } 71}; 72 73const format_kind_info solaris_format_types[] = { 74 { "cmn_err", cmn_err_length_specs, cmn_err_char_table, "", NULL, 75 cmn_err_flag_specs, cmn_err_flag_pairs, 76 FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, 77 'w', 0, 0, 0, 'L', 78 &integer_type_node, &integer_type_node 79 } 80}; 81 82/* Handle #pragma align ALIGNMENT (VAR [, VAR]...) */ 83 84static void 85solaris_pragma_align (cpp_reader *pfile ATTRIBUTE_UNUSED) 86{ 87 tree t, x; 88 enum cpp_ttype ttype; 89 HOST_WIDE_INT low; 90 91 if (pragma_lex (&x) != CPP_NUMBER 92 || pragma_lex (&t) != CPP_OPEN_PAREN) 93 { 94 warning (0, "malformed %<#pragma align%>, ignoring"); 95 return; 96 } 97 98 low = TREE_INT_CST_LOW (x); 99 if (TREE_INT_CST_HIGH (x) != 0 100 || (low != 1 && low != 2 && low != 4 && low != 8 && low != 16 101 && low != 32 && low != 64 && low != 128)) 102 { 103 warning (0, "invalid alignment for %<#pragma align%>, ignoring"); 104 return; 105 } 106 107 ttype = pragma_lex (&t); 108 if (ttype != CPP_NAME) 109 { 110 warning (0, "malformed %<#pragma align%>, ignoring"); 111 return; 112 } 113 114 while (1) 115 { 116 tree decl = identifier_global_value (t); 117 if (decl && DECL_P (decl)) 118 warning (0, "%<#pragma align%> must appear before the declaration of " 119 "%D, ignoring", decl); 120 else 121 solaris_pending_aligns = tree_cons (t, build_tree_list (NULL, x), 122 solaris_pending_aligns); 123 124 ttype = pragma_lex (&t); 125 if (ttype == CPP_COMMA) 126 { 127 ttype = pragma_lex (&t); 128 if (ttype != CPP_NAME) 129 { 130 warning (0, "malformed %<#pragma align%>"); 131 return; 132 } 133 } 134 else if (ttype == CPP_CLOSE_PAREN) 135 { 136 if (pragma_lex (&t) != CPP_EOF) 137 warning (0, "junk at end of %<#pragma align%>"); 138 return; 139 } 140 else 141 { 142 warning (0, "malformed %<#pragma align%>"); 143 return; 144 } 145 } 146} 147 148/* Handle #pragma init (function [, function]...) */ 149 150static void 151solaris_pragma_init (cpp_reader *pfile ATTRIBUTE_UNUSED) 152{ 153 tree t; 154 enum cpp_ttype ttype; 155 156 if (pragma_lex (&t) != CPP_OPEN_PAREN) 157 { 158 warning (0, "malformed %<#pragma init%>, ignoring"); 159 return; 160 } 161 162 ttype = pragma_lex (&t); 163 if (ttype != CPP_NAME) 164 { 165 warning (0, "malformed %<#pragma init%>, ignoring"); 166 return; 167 } 168 169 while (1) 170 { 171 tree decl = identifier_global_value (t); 172 if (decl && DECL_P (decl)) 173 { 174 tree init_list = build_tree_list (get_identifier ("init"), 175 NULL); 176 tree attrs = tree_cons (get_identifier ("used"), NULL, init_list); 177 decl_attributes (&decl, attrs, 0); 178 } 179 else 180 solaris_pending_inits = tree_cons (t, NULL, solaris_pending_inits); 181 182 ttype = pragma_lex (&t); 183 if (ttype == CPP_COMMA) 184 { 185 ttype = pragma_lex (&t); 186 if (ttype != CPP_NAME) 187 { 188 warning (0, "malformed %<#pragma init%>"); 189 return; 190 } 191 } 192 else if (ttype == CPP_CLOSE_PAREN) 193 { 194 if (pragma_lex (&t) != CPP_EOF) 195 warning (0, "junk at end of %<#pragma init%>"); 196 return; 197 } 198 else 199 { 200 warning (0, "malformed %<#pragma init%>"); 201 return; 202 } 203 } 204} 205 206/* Handle #pragma fini (function [, function]...) */ 207 208static void 209solaris_pragma_fini (cpp_reader *pfile ATTRIBUTE_UNUSED) 210{ 211 tree t; 212 enum cpp_ttype ttype; 213 214 if (pragma_lex (&t) != CPP_OPEN_PAREN) 215 { 216 warning (0, "malformed %<#pragma fini%>, ignoring"); 217 return; 218 } 219 220 ttype = pragma_lex (&t); 221 if (ttype != CPP_NAME) 222 { 223 warning (0, "malformed %<#pragma fini%>, ignoring"); 224 return; 225 } 226 227 while (1) 228 { 229 tree decl = identifier_global_value (t); 230 if (decl && DECL_P (decl)) 231 { 232 tree fini_list = build_tree_list (get_identifier ("fini"), 233 NULL); 234 tree attrs = tree_cons (get_identifier ("used"), NULL, fini_list); 235 decl_attributes (&decl, attrs, 0); 236 } 237 else 238 solaris_pending_finis = tree_cons (t, NULL, solaris_pending_finis); 239 240 ttype = pragma_lex (&t); 241 if (ttype == CPP_COMMA) 242 { 243 ttype = pragma_lex (&t); 244 if (ttype != CPP_NAME) 245 { 246 warning (0, "malformed %<#pragma fini%>"); 247 return; 248 } 249 } 250 else if (ttype == CPP_CLOSE_PAREN) 251 { 252 if (pragma_lex (&t) != CPP_EOF) 253 warning (0, "junk at end of %<#pragma fini%>"); 254 return; 255 } 256 else 257 { 258 warning (0, "malformed %<#pragma fini%>"); 259 return; 260 } 261 } 262} 263 264/* Register Solaris-specific #pragma directives. */ 265 266void 267solaris_register_pragmas (void) 268{ 269 c_register_pragma_with_expansion (0, "align", solaris_pragma_align); 270 c_register_pragma (0, "init", solaris_pragma_init); 271 c_register_pragma (0, "fini", solaris_pragma_fini); 272} 273