1# Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011 2# Free Software Foundation, Inc. 3# Contributed by Kelley Cook, June 2004. 4# Original code from Neil Booth, May 2003. 5# 6# This program is free software; you can redistribute it and/or modify it 7# under the terms of the GNU General Public License as published by the 8# Free Software Foundation; either version 3, or (at your option) any 9# later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; see the file COPYING3. If not see 18# <http://www.gnu.org/licenses/>. 19 20# Some common subroutines for use by opt[ch]-gen.awk. 21 22# Define some helpful character classes, for portability. 23BEGIN { 24 lower = "abcdefghijklmnopqrstuvwxyz" 25 upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 26 digit = "0123456789" 27 alnum = lower "" upper "" digit 28} 29 30# Return nonzero if FLAGS contains a flag matching REGEX. 31function flag_set_p(regex, flags) 32{ 33 return (" " flags " ") ~ (" " regex " ") 34} 35 36# Return STRING if FLAGS contains a flag matching regexp REGEX, 37# otherwise return the empty string. 38function test_flag(regex, flags, string) 39{ 40 if (flag_set_p(regex, flags)) 41 return string 42 return "" 43} 44 45# Return a field initializer, with trailing comma, for a field that is 46# 1 if FLAGS contains a flag matching REGEX and 0 otherwise. 47function flag_init(regex, flags) 48{ 49 if (flag_set_p(regex, flags)) 50 return "1 /* " regex " */, " 51 else 52 return "0, " 53} 54 55# If FLAGS contains a "NAME(...argument...)" flag, return the value 56# of the argument. Return the empty string otherwise. 57function opt_args(name, flags) 58{ 59 flags = " " flags 60 if (flags !~ " " name "\\(") 61 return "" 62 sub(".* " name "\\(", "", flags) 63 if (flags ~ "^{") 64 { 65 sub ("^{", "", flags) 66 sub("}\\).*", "", flags) 67 } 68 else 69 sub("\\).*", "", flags) 70 71 return flags 72} 73 74# Return the Nth comma-separated element of S. Return the empty string 75# if S does not contain N elements. 76function nth_arg(n, s) 77{ 78 while (n-- > 0) { 79 if (s !~ ",") 80 return "" 81 sub("[^,]*, *", "", s) 82 } 83 sub(",.*", "", s) 84 return s 85} 86 87# Return a bitmask of CL_* values for option flags FLAGS. 88function switch_flags (flags) 89{ 90 result = "0" 91 for (j = 0; j < n_langs; j++) { 92 regex = langs[j] 93 gsub ( "\\+", "\\+", regex ) 94 result = result test_flag(regex, flags, " | " macros[j]) 95 } 96 result = result \ 97 test_flag("Common", flags, " | CL_COMMON") \ 98 test_flag("Target", flags, " | CL_TARGET") \ 99 test_flag("Driver", flags, " | CL_DRIVER") \ 100 test_flag("Joined", flags, " | CL_JOINED") \ 101 test_flag("JoinedOrMissing", flags, " | CL_JOINED") \ 102 test_flag("Separate", flags, " | CL_SEPARATE") \ 103 test_flag("Undocumented", flags, " | CL_UNDOCUMENTED") \ 104 test_flag("Warning", flags, " | CL_WARNING") \ 105 test_flag("Optimization", flags, " | CL_OPTIMIZATION") 106 sub( "^0 \\| ", "", result ) 107 return result 108} 109 110# Return bit-field initializers for option flags FLAGS. 111function switch_bit_fields (flags) 112{ 113 vn = var_name(flags); 114 if (host_wide_int[vn] == "yes") 115 hwi = "Host_Wide_Int" 116 else 117 hwi = "" 118 result = "" 119 sep_args = opt_args("Args", flags) 120 if (sep_args == "") 121 sep_args = 0 122 else 123 sep_args-- 124 result = result sep_args ", " 125 126 result = result \ 127 flag_init("SeparateAlias", flags) \ 128 flag_init("NegativeAlias", flags) \ 129 flag_init("NoDriverArg", flags) \ 130 flag_init("RejectDriver", flags) \ 131 flag_init("RejectNegative", flags) \ 132 flag_init("JoinedOrMissing", flags) \ 133 flag_init("UInteger", flags) \ 134 flag_init("Host_Wide_Int", hwi) \ 135 flag_init("ToLower", flags) \ 136 flag_init("Report", flags) 137 138 sub(", $", "", result) 139 return result 140} 141 142# If FLAGS includes a Var flag, return the name of the variable it specifies. 143# Return the empty string otherwise. 144function var_name(flags) 145{ 146 return nth_arg(0, opt_args("Var", flags)) 147} 148 149# Return the name of the variable if FLAGS has a HOST_WIDE_INT variable. 150# Return the empty string otherwise. 151function host_wide_int_var_name(flags) 152{ 153 split (flags, array, "[ \t]+") 154 if (array[1] == "HOST_WIDE_INT") 155 return array[2] 156 else 157 return "" 158} 159 160# Return true if the option described by FLAGS has a globally-visible state. 161function global_state_p(flags) 162{ 163 return (var_name(flags) != "" \ 164 || opt_args("Mask", flags) != "" \ 165 || opt_args("InverseMask", flags) != "") 166} 167 168# Return true if the option described by FLAGS must have some state 169# associated with it. 170function needs_state_p(flags) 171{ 172 return (flag_set_p("Target", flags) \ 173 && !flag_set_p("Alias.*", flags) \ 174 && !flag_set_p("Ignore", flags)) 175} 176 177# If FLAGS describes an option that needs state without a public 178# variable name, return the name of that field, minus the initial 179# "x_", otherwise return "". NAME is the name of the option. 180function static_var(name, flags) 181{ 182 if (global_state_p(flags) || !needs_state_p(flags)) 183 return "" 184 gsub ("[^" alnum "]", "_", name) 185 return "VAR_" name 186} 187 188# Return the type of variable that should be associated with the given flags. 189function var_type(flags) 190{ 191 if (flag_set_p("Defer", flags)) 192 return "void *" 193 else if (flag_set_p("Enum.*", flags)) { 194 en = opt_args("Enum", flags); 195 return enum_type[en] " " 196 } 197 else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) 198 return "int " 199 else if (flag_set_p("UInteger", flags)) 200 return "int " 201 else 202 return "const char *" 203} 204 205# Return the type of variable that should be associated with the given flags 206# for use within a structure. Simple variables are changed to signed char 207# type instead of int to save space. 208function var_type_struct(flags) 209{ 210 if (flag_set_p("UInteger", flags)) 211 return "int " 212 else if (flag_set_p("Enum.*", flags)) { 213 en = opt_args("Enum", flags); 214 return enum_type[en] " " 215 } 216 else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) { 217 if (flag_set_p(".*Mask.*", flags)) { 218 if (host_wide_int[var_name(flags)] == "yes") 219 return "HOST_WIDE_INT " 220 else 221 return "int " 222 } 223 else 224 return "signed char " 225 } 226 else 227 return "const char *" 228} 229 230# Given that an option has flags FLAGS, return an initializer for the 231# "var_enum", "var_type" and "var_value" fields of its cl_options[] entry. 232function var_set(flags) 233{ 234 if (flag_set_p("Defer", flags)) 235 return "0, CLVC_DEFER, 0" 236 s = nth_arg(1, opt_args("Var", flags)) 237 if (s != "") 238 return "0, CLVC_EQUAL, " s 239 s = opt_args("Mask", flags); 240 if (s != "") { 241 vn = var_name(flags); 242 if (vn) 243 return "0, CLVC_BIT_SET, OPTION_MASK_" s 244 else 245 return "0, CLVC_BIT_SET, MASK_" s 246 } 247 s = nth_arg(0, opt_args("InverseMask", flags)); 248 if (s != "") { 249 vn = var_name(flags); 250 if (vn) 251 return "0, CLVC_BIT_CLEAR, OPTION_MASK_" s 252 else 253 return "0, CLVC_BIT_CLEAR, MASK_" s 254 } 255 if (flag_set_p("Enum.*", flags)) { 256 en = opt_args("Enum", flags); 257 return enum_index[en] ", CLVC_ENUM, 0" 258 } 259 if (var_type(flags) == "const char *") 260 return "0, CLVC_STRING, 0" 261 return "0, CLVC_BOOLEAN, 0" 262} 263 264# Given that an option called NAME has flags FLAGS, return an initializer 265# for the "flag_var" field of its cl_options[] entry. 266function var_ref(name, flags) 267{ 268 name = var_name(flags) static_var(name, flags) 269 if (name != "") 270 return "offsetof (struct gcc_options, x_" name ")" 271 if (opt_args("Mask", flags) != "") 272 return "offsetof (struct gcc_options, x_target_flags)" 273 if (opt_args("InverseMask", flags) != "") 274 return "offsetof (struct gcc_options, x_target_flags)" 275 return "-1" 276} 277 278# Given the option called NAME return a sanitized version of its name. 279function opt_sanitized_name(name) 280{ 281 gsub ("[^" alnum "]", "_", name) 282 return name 283} 284 285# Given the option called NAME return the appropriate enum for it. 286function opt_enum(name) 287{ 288 return "OPT_" opt_sanitized_name(name) 289} 290