00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026 #include "system.h"
00027 #include "coretypes.h"
00028 #include "tm.h"
00029 #include "flags.h"
00030 #include "tree.h"
00031 #include "c-tree.h"
00032 #include "toplev.h"
00033
00034 enum formals_style_enum {
00035 ansi,
00036 k_and_r_names,
00037 k_and_r_decls
00038 };
00039 typedef enum formals_style_enum formals_style;
00040
00041
00042 static const char *data_type;
00043
00044 static char *affix_data_type (const char *) ATTRIBUTE_MALLOC;
00045 static const char *gen_formal_list_for_type (tree, formals_style);
00046 static int deserves_ellipsis (tree);
00047 static const char *gen_formal_list_for_func_def (tree, formals_style);
00048 static const char *gen_type (const char *, tree, formals_style);
00049 static const char *gen_decl (tree, int, formals_style);
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 static char *
00066 affix_data_type (const char *param)
00067 {
00068 char *const type_or_decl = ASTRDUP (param);
00069 char *p = type_or_decl;
00070 char *qualifiers_then_data_type;
00071 char saved;
00072
00073
00074
00075 for (;;)
00076 {
00077 if (!strncmp (p, "volatile ", 9))
00078 {
00079 p += 9;
00080 continue;
00081 }
00082 if (!strncmp (p, "const ", 6))
00083 {
00084 p += 6;
00085 continue;
00086 }
00087 break;
00088 }
00089
00090
00091
00092
00093 if (p == type_or_decl)
00094 return concat (data_type, " ", type_or_decl, NULL);
00095
00096 saved = *p;
00097 *p = '\0';
00098 qualifiers_then_data_type = concat (type_or_decl, data_type, NULL);
00099 *p = saved;
00100 return reconcat (qualifiers_then_data_type,
00101 qualifiers_then_data_type, " ", p, NULL);
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111 static const char *
00112 gen_formal_list_for_type (tree fntype, formals_style style)
00113 {
00114 const char *formal_list = "";
00115 tree formal_type;
00116
00117 if (style != ansi)
00118 return "()";
00119
00120 formal_type = TYPE_ARG_TYPES (fntype);
00121 while (formal_type && TREE_VALUE (formal_type) != void_type_node)
00122 {
00123 const char *this_type;
00124
00125 if (*formal_list)
00126 formal_list = concat (formal_list, ", ", NULL);
00127
00128 this_type = gen_type ("", TREE_VALUE (formal_type), ansi);
00129 formal_list
00130 = ((strlen (this_type))
00131 ? concat (formal_list, affix_data_type (this_type), NULL)
00132 : concat (formal_list, data_type, NULL));
00133
00134 formal_type = TREE_CHAIN (formal_type);
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 if (!*formal_list)
00168 {
00169 if (TYPE_ARG_TYPES (fntype))
00170
00171 formal_list = "void";
00172 else
00173 formal_list = "/* ??? */";
00174 }
00175 else
00176 {
00177
00178
00179
00180 if (!formal_type)
00181 formal_list = concat (formal_list, ", ...", NULL);
00182 }
00183
00184 return concat (" (", formal_list, ")", NULL);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 static int
00194 deserves_ellipsis (tree fntype)
00195 {
00196 tree formal_type;
00197
00198 formal_type = TYPE_ARG_TYPES (fntype);
00199 while (formal_type && TREE_VALUE (formal_type) != void_type_node)
00200 formal_type = TREE_CHAIN (formal_type);
00201
00202
00203
00204
00205
00206 return (!formal_type && TYPE_ARG_TYPES (fntype));
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 static const char *
00229 gen_formal_list_for_func_def (tree fndecl, formals_style style)
00230 {
00231 const char *formal_list = "";
00232 tree formal_decl;
00233
00234 formal_decl = DECL_ARGUMENTS (fndecl);
00235 while (formal_decl)
00236 {
00237 const char *this_formal;
00238
00239 if (*formal_list && ((style == ansi) || (style == k_and_r_names)))
00240 formal_list = concat (formal_list, ", ", NULL);
00241 this_formal = gen_decl (formal_decl, 0, style);
00242 if (style == k_and_r_decls)
00243 formal_list = concat (formal_list, this_formal, "; ", NULL);
00244 else
00245 formal_list = concat (formal_list, this_formal, NULL);
00246 formal_decl = TREE_CHAIN (formal_decl);
00247 }
00248 if (style == ansi)
00249 {
00250 if (!DECL_ARGUMENTS (fndecl))
00251 formal_list = concat (formal_list, "void", NULL);
00252 if (deserves_ellipsis (TREE_TYPE (fndecl)))
00253 formal_list = concat (formal_list, ", ...", NULL);
00254 }
00255 if ((style == ansi) || (style == k_and_r_names))
00256 formal_list = concat (" (", formal_list, ")", NULL);
00257 return formal_list;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 static const char *
00302 gen_type (const char *ret_val, tree t, formals_style style)
00303 {
00304 tree chain_p;
00305
00306
00307 if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
00308 data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
00309 else
00310 {
00311 switch (TREE_CODE (t))
00312 {
00313 case POINTER_TYPE:
00314 if (TYPE_READONLY (t))
00315 ret_val = concat ("const ", ret_val, NULL);
00316 if (TYPE_VOLATILE (t))
00317 ret_val = concat ("volatile ", ret_val, NULL);
00318
00319 ret_val = concat ("*", ret_val, NULL);
00320
00321 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
00322 ret_val = concat ("(", ret_val, ")", NULL);
00323
00324 ret_val = gen_type (ret_val, TREE_TYPE (t), style);
00325
00326 return ret_val;
00327
00328 case ARRAY_TYPE:
00329 if (!COMPLETE_TYPE_P (t) || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
00330 ret_val = gen_type (concat (ret_val, "[]", NULL),
00331 TREE_TYPE (t), style);
00332 else if (int_size_in_bytes (t) == 0)
00333 ret_val = gen_type (concat (ret_val, "[0]", NULL),
00334 TREE_TYPE (t), style);
00335 else
00336 {
00337 int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t)));
00338 char buff[10];
00339 sprintf (buff, "[%d]", size);
00340 ret_val = gen_type (concat (ret_val, buff, NULL),
00341 TREE_TYPE (t), style);
00342 }
00343 break;
00344
00345 case FUNCTION_TYPE:
00346 ret_val = gen_type (concat (ret_val,
00347 gen_formal_list_for_type (t, style),
00348 NULL),
00349 TREE_TYPE (t), style);
00350 break;
00351
00352 case IDENTIFIER_NODE:
00353 data_type = IDENTIFIER_POINTER (t);
00354 break;
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 case RECORD_TYPE:
00368 if (TYPE_NAME (t))
00369 data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
00370 else
00371 {
00372 data_type = "";
00373 chain_p = TYPE_FIELDS (t);
00374 while (chain_p)
00375 {
00376 data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
00377 NULL);
00378 chain_p = TREE_CHAIN (chain_p);
00379 data_type = concat (data_type, "; ", NULL);
00380 }
00381 data_type = concat ("{ ", data_type, "}", NULL);
00382 }
00383 data_type = concat ("struct ", data_type, NULL);
00384 break;
00385
00386 case UNION_TYPE:
00387 if (TYPE_NAME (t))
00388 data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
00389 else
00390 {
00391 data_type = "";
00392 chain_p = TYPE_FIELDS (t);
00393 while (chain_p)
00394 {
00395 data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
00396 NULL);
00397 chain_p = TREE_CHAIN (chain_p);
00398 data_type = concat (data_type, "; ", NULL);
00399 }
00400 data_type = concat ("{ ", data_type, "}", NULL);
00401 }
00402 data_type = concat ("union ", data_type, NULL);
00403 break;
00404
00405 case ENUMERAL_TYPE:
00406 if (TYPE_NAME (t))
00407 data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
00408 else
00409 {
00410 data_type = "";
00411 chain_p = TYPE_VALUES (t);
00412 while (chain_p)
00413 {
00414 data_type = concat (data_type,
00415 IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL);
00416 chain_p = TREE_CHAIN (chain_p);
00417 if (chain_p)
00418 data_type = concat (data_type, ", ", NULL);
00419 }
00420 data_type = concat ("{ ", data_type, " }", NULL);
00421 }
00422 data_type = concat ("enum ", data_type, NULL);
00423 break;
00424
00425 case TYPE_DECL:
00426 data_type = IDENTIFIER_POINTER (DECL_NAME (t));
00427 break;
00428
00429 case INTEGER_TYPE:
00430 data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
00431
00432
00433 if (TYPE_UNSIGNED (t) && TYPE_QUALS (t))
00434 data_type = concat ("unsigned ", data_type, NULL);
00435 break;
00436
00437 case REAL_TYPE:
00438 data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
00439 break;
00440
00441 case VOID_TYPE:
00442 data_type = "void";
00443 break;
00444
00445 case ERROR_MARK:
00446 data_type = "[ERROR]";
00447 break;
00448
00449 default:
00450 gcc_unreachable ();
00451 }
00452 }
00453 if (TYPE_READONLY (t))
00454 ret_val = concat ("const ", ret_val, NULL);
00455 if (TYPE_VOLATILE (t))
00456 ret_val = concat ("volatile ", ret_val, NULL);
00457 if (TYPE_RESTRICT (t))
00458 ret_val = concat ("restrict ", ret_val, NULL);
00459 return ret_val;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 static const char *
00473 gen_decl (tree decl, int is_func_definition, formals_style style)
00474 {
00475 const char *ret_val;
00476
00477 if (DECL_NAME (decl))
00478 ret_val = IDENTIFIER_POINTER (DECL_NAME (decl));
00479 else
00480 ret_val = "";
00481
00482
00483
00484
00485
00486 if (style == k_and_r_names)
00487 return ret_val;
00488
00489
00490
00491
00492
00493
00494
00495
00496 if (TREE_THIS_VOLATILE (decl))
00497 ret_val = concat ("volatile ", ret_val, NULL);
00498 if (TREE_READONLY (decl))
00499 ret_val = concat ("const ", ret_val, NULL);
00500
00501 data_type = "";
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition)
00516 {
00517 ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi),
00518 NULL);
00519
00520
00521
00522
00523
00524
00525
00526
00527 ret_val = gen_type (ret_val, TREE_TYPE (TREE_TYPE (decl)), style);
00528 }
00529 else
00530 ret_val = gen_type (ret_val, TREE_TYPE (decl), style);
00531
00532 ret_val = affix_data_type (ret_val);
00533
00534 if (TREE_CODE (decl) != FUNCTION_DECL && C_DECL_REGISTER (decl))
00535 ret_val = concat ("register ", ret_val, NULL);
00536 if (TREE_PUBLIC (decl))
00537 ret_val = concat ("extern ", ret_val, NULL);
00538 if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl))
00539 ret_val = concat ("static ", ret_val, NULL);
00540
00541 return ret_val;
00542 }
00543
00544 extern FILE *aux_info_file;
00545
00546
00547
00548
00549
00550 void
00551 gen_aux_info_record (tree fndecl, int is_definition, int is_implicit,
00552 int is_prototyped)
00553 {
00554 if (flag_gen_aux_info)
00555 {
00556 static int compiled_from_record = 0;
00557 expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (fndecl));
00558
00559
00560
00561
00562 if (!compiled_from_record++)
00563 {
00564
00565
00566
00567 fprintf (aux_info_file, "/* compiled from: . */\n");
00568 }
00569
00570
00571
00572 fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;",
00573 xloc.file, xloc.line,
00574 (is_implicit) ? 'I' : (is_prototyped) ? 'N' : 'O',
00575 (is_definition) ? 'F' : 'C',
00576 gen_decl (fndecl, is_definition, ansi));
00577
00578
00579
00580
00581
00582 if (is_definition)
00583 {
00584 fprintf (aux_info_file, " /*%s %s*/",
00585 gen_formal_list_for_func_def (fndecl, k_and_r_names),
00586 gen_formal_list_for_func_def (fndecl, k_and_r_decls));
00587 }
00588
00589 fprintf (aux_info_file, "\n");
00590 }
00591 }