|
|
1.1 ! root 1: /* Generate information regarding function declarations and definitions based ! 2: on information stored in GCC's tree structure. This code implements the ! 3: -aux-info option. ! 4: ! 5: This code was written by Ron Guilmette ([email protected]). ! 6: ! 7: Copyright (C) 1989, 1991 Free Software Foundation, Inc. ! 8: ! 9: This file is part of GNU CC. ! 10: ! 11: GNU CC is free software; you can redistribute it and/or modify ! 12: it under the terms of the GNU General Public License as published by ! 13: the Free Software Foundation; either version 2, or (at your option) ! 14: any later version. ! 15: ! 16: GNU CC is distributed in the hope that it will be useful, ! 17: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 18: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 19: GNU General Public License for more details. ! 20: ! 21: You should have received a copy of the GNU General Public License ! 22: along with GNU CC; see the file COPYING. If not, write to ! 23: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 24: ! 25: #include <stdio.h> ! 26: #include "config.h" ! 27: #include "flags.h" ! 28: #include "tree.h" ! 29: #include "c-tree.h" ! 30: ! 31: extern char* xmalloc (); ! 32: ! 33: enum formals_style_enum { ! 34: ansi, ! 35: k_and_r_names, ! 36: k_and_r_decls ! 37: }; ! 38: typedef enum formals_style_enum formals_style; ! 39: ! 40: ! 41: static char* data_type; ! 42: ! 43: static char * concat (); ! 44: static char * concat3 (); ! 45: static char * gen_formal_list_for_type (); ! 46: static int deserves_ellipsis (); ! 47: static char * gen_formal_list_for_func_def (); ! 48: static char * gen_type (); ! 49: static char * gen_decl (); ! 50: void gen_aux_info_record (); ! 51: ! 52: /* Take two strings and mash them together into a newly allocated area. */ ! 53: ! 54: static char* ! 55: concat (s1, s2) ! 56: char* s1; ! 57: char* s2; ! 58: { ! 59: int size1, size2; ! 60: char* ret_val; ! 61: ! 62: if (!s1) ! 63: s1 = ""; ! 64: if (!s2) ! 65: s2 = ""; ! 66: ! 67: size1 = strlen (s1); ! 68: size2 = strlen (s2); ! 69: ret_val = xmalloc (size1 + size2 + 1); ! 70: strcpy (ret_val, s1); ! 71: strcpy (&ret_val[size1], s2); ! 72: return ret_val; ! 73: } ! 74: ! 75: /* Take three strings and mash them together into a newly allocated area. */ ! 76: ! 77: static char* ! 78: concat3 (s1, s2, s3) ! 79: char* s1; ! 80: char* s2; ! 81: char* s3; ! 82: { ! 83: int size1, size2, size3; ! 84: char* ret_val; ! 85: ! 86: if (!s1) ! 87: s1 = ""; ! 88: if (!s2) ! 89: s2 = ""; ! 90: if (!s3) ! 91: s3 = ""; ! 92: ! 93: size1 = strlen (s1); ! 94: size2 = strlen (s2); ! 95: size3 = strlen (s3); ! 96: ret_val = xmalloc (size1 + size2 + size3 + 1); ! 97: strcpy (ret_val, s1); ! 98: strcpy (&ret_val[size1], s2); ! 99: strcpy (&ret_val[size1+size2], s3); ! 100: return ret_val; ! 101: } ! 102: ! 103: /* Given a string representing an entire type or an entire declaration ! 104: which only lacks the actual "data-type" specifier (at its left end), ! 105: affix the data-type specifier to the left end of the given type ! 106: specification or object declaration. ! 107: ! 108: Because of C language weirdness, the data-type specifier (which normally ! 109: goes in at the very left end) may have to be slipped in just to the ! 110: right of any leading "const" or "volatile" qualifiers (there may be more ! 111: than one). Actually this may not be strictly necessary because it seems ! 112: that GCC (at least) accepts `<data-type> const foo;' and treats it the ! 113: same as `const <data-type> foo;' but people are accustomed to seeing ! 114: `const char *foo;' and *not* `char const *foo;' so we try to create types ! 115: that look as expected. */ ! 116: ! 117: static char* ! 118: affix_data_type (type_or_decl) ! 119: char *type_or_decl; ! 120: { ! 121: char *p = type_or_decl; ! 122: char *qualifiers_then_data_type; ! 123: char saved; ! 124: ! 125: /* Skip as many leading const's or volatile's as there are. */ ! 126: ! 127: for (;;) ! 128: { ! 129: if (!strncmp (p, "volatile ", 9)) ! 130: { ! 131: p += 9; ! 132: continue; ! 133: } ! 134: if (!strncmp (p, "const ", 6)) ! 135: { ! 136: p += 6; ! 137: continue; ! 138: } ! 139: break; ! 140: } ! 141: ! 142: /* p now points to the place where we can insert the data type. We have to ! 143: add a blank after the data-type of course. */ ! 144: ! 145: if (p == type_or_decl) ! 146: return concat3 (data_type, " ", type_or_decl); ! 147: ! 148: saved = *p; ! 149: *p = '\0'; ! 150: qualifiers_then_data_type = concat (type_or_decl, data_type); ! 151: *p = saved; ! 152: return concat3 (qualifiers_then_data_type, " ", p); ! 153: } ! 154: ! 155: /* Given a tree node which represents some "function type", generate the ! 156: source code version of a formal parameter list (of some given style) for ! 157: this function type. Return the whole formal parameter list (including ! 158: a pair of surrounding parens) as a string. Note that if the style ! 159: we are currently aiming for is non-ansi, then we just return a pair ! 160: of empty parens here. */ ! 161: ! 162: static char* ! 163: gen_formal_list_for_type (fntype, style) ! 164: tree fntype; ! 165: formals_style style; ! 166: { ! 167: char* formal_list = ""; ! 168: tree formal_type; ! 169: ! 170: if (style != ansi) ! 171: return "()"; ! 172: ! 173: formal_type = TYPE_ARG_TYPES (fntype); ! 174: while (formal_type && TREE_VALUE (formal_type) != void_type_node) ! 175: { ! 176: char* this_type; ! 177: ! 178: if (*formal_list) ! 179: formal_list = concat (formal_list, ", "); ! 180: ! 181: this_type = gen_type ("", TREE_VALUE (formal_type), ansi); ! 182: formal_list = ! 183: (strlen (this_type)) ! 184: ? concat (formal_list, affix_data_type (this_type)) ! 185: : concat (formal_list, data_type); ! 186: ! 187: formal_type = TREE_CHAIN (formal_type); ! 188: } ! 189: ! 190: /* If we got to here, then we are trying to generate an ANSI style formal ! 191: parameters list. ! 192: ! 193: New style prototyped ANSI formal parameter lists should in theory always ! 194: contain some stuff between the opening and closing parens, even if it is ! 195: only "void". ! 196: ! 197: The brutal truth though is that there is lots of old K&R code out there ! 198: which contains declarations of "pointer-to-function" parameters and ! 199: these almost never have fully specified formal parameter lists associated ! 200: with them. That is, the pointer-to-function parameters are declared ! 201: with just empty parameter lists. ! 202: ! 203: In cases such as these, protoize should really insert *something* into ! 204: the vacant parameter lists, but what? It has no basis on which to insert ! 205: anything in particular. ! 206: ! 207: Here, we make life easy for protoize by trying to distinguish between ! 208: K&R empty parameter lists and new-style prototyped parameter lists ! 209: that actually contain "void". In the latter case we (obviously) want ! 210: to output the "void" verbatim, and that what we do. In the former case, ! 211: we do our best to give protoize something nice to insert. ! 212: ! 213: This "something nice" should be something that is still legal (when ! 214: re-compiled) but something that can clearly indicate to the user that ! 215: more typing information (for the parameter list) should be added (by ! 216: hand) at some convenient moment. ! 217: ! 218: The string chosen here is a comment with question marks in it. */ ! 219: ! 220: if (!*formal_list) ! 221: { ! 222: if (TYPE_ARG_TYPES (fntype)) ! 223: /* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node); */ ! 224: formal_list = "void"; ! 225: else ! 226: formal_list = "/* ??? */"; ! 227: } ! 228: else ! 229: { ! 230: /* If there were at least some parameters, and if the formals-types-list ! 231: petered out to a NULL (i.e. without being terminated by a ! 232: void_type_node) then we need to tack on an ellipsis. */ ! 233: if (!formal_type) ! 234: formal_list = concat (formal_list, ", ..."); ! 235: } ! 236: ! 237: return concat3 (" (", formal_list, ")"); ! 238: } ! 239: ! 240: /* For the generation of an ANSI prototype for a function definition, we have ! 241: to look at the formal parameter list of the function's own "type" to ! 242: determine if the function's formal parameter list should end with an ! 243: ellipsis. Given a tree node, the following function will return non-zero ! 244: if the "function type" parameter list should end with an ellipsis. */ ! 245: ! 246: static int ! 247: deserves_ellipsis (fntype) ! 248: tree fntype; ! 249: { ! 250: tree formal_type; ! 251: ! 252: formal_type = TYPE_ARG_TYPES (fntype); ! 253: while (formal_type && TREE_VALUE (formal_type) != void_type_node) ! 254: formal_type = TREE_CHAIN (formal_type); ! 255: ! 256: /* If there were at least some parameters, and if the formals-types-list ! 257: petered out to a NULL (i.e. without being terminated by a void_type_node) ! 258: then we need to tack on an ellipsis. */ ! 259: ! 260: return (!formal_type && TYPE_ARG_TYPES (fntype)); ! 261: } ! 262: ! 263: /* Generate a parameter list for a function definition (in some given style). ! 264: ! 265: Note that this routine has to be separate (and different) from the code that ! 266: generates the prototype parameter lists for function declarations, because ! 267: in the case of a function declaration, all we have to go on is a tree node ! 268: representing the function's own "function type". This can tell us the types ! 269: of all of the formal parameters for the function, but it cannot tell us the ! 270: actual *names* of each of the formal parameters. We need to output those ! 271: parameter names for each function definition. ! 272: ! 273: This routine gets a pointer to a tree node which represents the actual ! 274: declaration of the given function, and this DECL node has a list of formal ! 275: parameter (variable) declarations attached to it. These formal parameter ! 276: (variable) declaration nodes give us the actual names of the formal ! 277: parameters for the given function definition. ! 278: ! 279: This routine returns a string which is the source form for the entire ! 280: function formal parameter list. */ ! 281: ! 282: static char* ! 283: gen_formal_list_for_func_def (fndecl, style) ! 284: tree fndecl; ! 285: formals_style style; ! 286: { ! 287: char* formal_list = ""; ! 288: tree formal_decl; ! 289: ! 290: formal_decl = DECL_ARGUMENTS (fndecl); ! 291: while (formal_decl) ! 292: { ! 293: char *this_formal; ! 294: ! 295: if (*formal_list && ((style == ansi) || (style == k_and_r_names))) ! 296: formal_list = concat (formal_list, ", "); ! 297: this_formal = gen_decl (formal_decl, 0, style); ! 298: if (style == k_and_r_decls) ! 299: formal_list = concat3 (formal_list, this_formal, "; "); ! 300: else ! 301: formal_list = concat (formal_list, this_formal); ! 302: formal_decl = TREE_CHAIN (formal_decl); ! 303: } ! 304: if (style == ansi) ! 305: { ! 306: if (!DECL_ARGUMENTS (fndecl)) ! 307: formal_list = concat (formal_list, "void"); ! 308: if (deserves_ellipsis (TREE_TYPE (fndecl))) ! 309: formal_list = concat (formal_list, ", ..."); ! 310: } ! 311: if ((style == ansi) || (style == k_and_r_names)) ! 312: formal_list = concat3 (" (", formal_list, ")"); ! 313: return formal_list; ! 314: } ! 315: ! 316: /* Generate a string which is the source code form for a given type (t). This ! 317: routine is ugly and complex because the C syntax for declarations is ugly ! 318: and complex. This routine is straightforward so long as *no* pointer types, ! 319: array types, or function types are involved. ! 320: ! 321: In the simple cases, this routine will return the (string) value which was ! 322: passed in as the "ret_val" argument. Usually, this starts out either as an ! 323: empty string, or as the name of the declared item (i.e. the formal function ! 324: parameter variable). ! 325: ! 326: This routine will also return with the global variable "data_type" set to ! 327: some string value which is the "basic" data-type of the given complete type. ! 328: This "data_type" string can be concatenated onto the front of the returned ! 329: string after this routine returns to its caller. ! 330: ! 331: In complicated cases involving pointer types, array types, or function ! 332: types, the C declaration syntax requires an "inside out" approach, i.e. if ! 333: you have a type which is a "pointer-to-function" type, you need to handle ! 334: the "pointer" part first, but it also has to be "innermost" (relative to ! 335: the declaration stuff for the "function" type). Thus, is this case, you ! 336: must prepend a "(*" and append a ")" to the name of the item (i.e. formal ! 337: variable). Then you must append and prepend the other info for the ! 338: "function type" part of the overall type. ! 339: ! 340: To handle the "innermost precedence" rules of complicated C declarators, we ! 341: do the following (in this routine). The input parameter called "ret_val" ! 342: is treated as a "seed". Each time gen_type is called (perhaps recursively) ! 343: some additional strings may be appended or prepended (or both) to the "seed" ! 344: string. If yet another (lower) level of the GCC tree exists for the given ! 345: type (as in the case of a pointer type, an array type, or a function type) ! 346: then the (wrapped) seed is passed to a (recursive) invocation of gen_type() ! 347: this recursive invocation may again "wrap" the (new) seed with yet more ! 348: declarator stuff, by appending, prepending (or both). By the time the ! 349: recursion bottoms out, the "seed value" at that point will have a value ! 350: which is (almost) the complete source version of the declarator (except ! 351: for the data_type info). Thus, this deepest "seed" value is simply passed ! 352: back up through all of the recursive calls until it is given (as the return ! 353: value) to the initial caller of the gen_type() routine. All that remains ! 354: to do at this point is for the initial caller to prepend the "data_type" ! 355: string onto the returned "seed". */ ! 356: ! 357: static char* ! 358: gen_type (ret_val, t, style) ! 359: char* ret_val; ! 360: tree t; ! 361: formals_style style; ! 362: { ! 363: tree chain_p; ! 364: ! 365: if (TYPE_NAME (t) && DECL_NAME (TYPE_NAME (t))) ! 366: data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); ! 367: else ! 368: { ! 369: switch (TREE_CODE (t)) ! 370: { ! 371: case POINTER_TYPE: ! 372: if (TYPE_READONLY (t)) ! 373: ret_val = concat ("const ", ret_val); ! 374: if (TYPE_VOLATILE (t)) ! 375: ret_val = concat ("volatile ", ret_val); ! 376: ! 377: ret_val = concat ("*", ret_val); ! 378: ! 379: if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) ! 380: ret_val = concat3 ("(", ret_val, ")"); ! 381: ! 382: ret_val = gen_type (ret_val, TREE_TYPE (t), style); ! 383: ! 384: return ret_val; ! 385: ! 386: case ARRAY_TYPE: ! 387: if (TYPE_SIZE (t) == 0 || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST) ! 388: ret_val = gen_type (concat (ret_val, "[]"), TREE_TYPE (t), style); ! 389: else if (int_size_in_bytes (t) == 0) ! 390: ret_val = gen_type (concat (ret_val, "[0]"), TREE_TYPE (t), style); ! 391: else ! 392: { ! 393: int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t))); ! 394: char buff[10]; ! 395: sprintf (buff, "[%d]", size); ! 396: ret_val = gen_type (concat (ret_val, buff), ! 397: TREE_TYPE (t), style); ! 398: } ! 399: break; ! 400: ! 401: case FUNCTION_TYPE: ! 402: ret_val = gen_type (concat (ret_val, gen_formal_list_for_type (t, style)), TREE_TYPE (t), style); ! 403: break; ! 404: ! 405: case IDENTIFIER_NODE: ! 406: data_type = IDENTIFIER_POINTER (t); ! 407: break; ! 408: ! 409: /* The following three cases are complicated by the fact that a ! 410: user may do something really stupid, like creating a brand new ! 411: "anonymous" type specification in a formal argument list (or as ! 412: part of a function return type specification). For example: ! 413: ! 414: int f (enum { red, green, blue } color); ! 415: ! 416: In such cases, we have no name that we can put into the prototype ! 417: to represent the (anonymous) type. Thus, we have to generate the ! 418: whole darn type specification. Yuck! */ ! 419: ! 420: case RECORD_TYPE: ! 421: if (TYPE_NAME (t)) ! 422: data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); ! 423: else ! 424: { ! 425: data_type = ""; ! 426: chain_p = TYPE_FIELDS (t); ! 427: while (chain_p) ! 428: { ! 429: data_type = concat (data_type, gen_decl (chain_p, 0, ansi)); ! 430: chain_p = TREE_CHAIN (chain_p); ! 431: data_type = concat (data_type, "; "); ! 432: } ! 433: data_type = concat3 ("{ ", data_type, "}"); ! 434: } ! 435: data_type = concat ("struct ", data_type); ! 436: break; ! 437: ! 438: case UNION_TYPE: ! 439: if (TYPE_NAME (t)) ! 440: data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); ! 441: else ! 442: { ! 443: data_type = ""; ! 444: chain_p = TYPE_FIELDS (t); ! 445: while (chain_p) ! 446: { ! 447: data_type = concat (data_type, gen_decl (chain_p, 0, ansi)); ! 448: chain_p = TREE_CHAIN (chain_p); ! 449: data_type = concat (data_type, "; "); ! 450: } ! 451: data_type = concat3 ("{ ", data_type, "}"); ! 452: } ! 453: data_type = concat ("union ", data_type); ! 454: break; ! 455: ! 456: case ENUMERAL_TYPE: ! 457: if (TYPE_NAME (t)) ! 458: data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); ! 459: else ! 460: { ! 461: data_type = ""; ! 462: chain_p = TYPE_VALUES (t); ! 463: while (chain_p) ! 464: { ! 465: data_type = concat (data_type, ! 466: IDENTIFIER_POINTER (TREE_PURPOSE (chain_p))); ! 467: chain_p = TREE_CHAIN (chain_p); ! 468: if (chain_p) ! 469: data_type = concat (data_type, ", "); ! 470: } ! 471: data_type = concat3 ("{ ", data_type, " }"); ! 472: } ! 473: data_type = concat ("enum ", data_type); ! 474: break; ! 475: ! 476: case TYPE_DECL: ! 477: data_type = IDENTIFIER_POINTER (DECL_NAME (t)); ! 478: break; ! 479: ! 480: case INTEGER_TYPE: ! 481: data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); ! 482: /* Normally, `unsigned' is part of the deal. Not so if it comes ! 483: with `const' or `volatile'. */ ! 484: if (TREE_UNSIGNED (t) && (TYPE_READONLY (t) || TYPE_VOLATILE (t))) ! 485: data_type = concat ("unsigned ", data_type); ! 486: break; ! 487: ! 488: case REAL_TYPE: ! 489: data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); ! 490: break; ! 491: ! 492: case VOID_TYPE: ! 493: data_type = "void"; ! 494: break; ! 495: ! 496: default: ! 497: abort (); ! 498: } ! 499: } ! 500: if (TYPE_READONLY (t)) ! 501: ret_val = concat ("const ", ret_val); ! 502: if (TYPE_VOLATILE (t)) ! 503: ret_val = concat ("volatile ", ret_val); ! 504: return ret_val; ! 505: } ! 506: ! 507: /* Generate a string (source) representation of an entire entity declaration ! 508: (using some particular style for function types). ! 509: ! 510: The given entity may be either a variable or a function. ! 511: ! 512: If the "is_func_definition" parameter is non-zero, assume that the thing ! 513: we are generating a declaration for is a FUNCTION_DECL node which is ! 514: associated with a function definition. In this case, we can assume that ! 515: an attached list of DECL nodes for function formal arguments is present. */ ! 516: ! 517: static char* ! 518: gen_decl (decl, is_func_definition, style) ! 519: tree decl; ! 520: int is_func_definition; ! 521: formals_style style; ! 522: { ! 523: char* ret_val; ! 524: char* outer_modifier = ""; ! 525: ! 526: if (DECL_NAME (decl)) ! 527: ret_val = IDENTIFIER_POINTER (DECL_NAME (decl)); ! 528: else ! 529: ret_val = ""; ! 530: ! 531: /* If we are just generating a list of names of formal parameters, we can ! 532: simply return the formal parameter name (with no typing information ! 533: attached to it) now. */ ! 534: ! 535: if (style == k_and_r_names) ! 536: return ret_val; ! 537: ! 538: /* Note that for the declaration of some entity (either a function or a ! 539: data object, like for instance a parameter) if the entity itself was ! 540: declared as either const or volatile, then const and volatile properties ! 541: are associated with just the declaration of the entity, and *not* with ! 542: the `type' of the entity. Thus, for such declared entities, we have to ! 543: generate the qualifiers here. */ ! 544: ! 545: if (TREE_THIS_VOLATILE (decl)) ! 546: ret_val = concat ("volatile ", ret_val); ! 547: if (TREE_READONLY (decl)) ! 548: ret_val = concat ("const ", ret_val); ! 549: ! 550: data_type = ""; ! 551: ! 552: /* For FUNCTION_DECL nodes, there are two possible cases here. First, if ! 553: this FUNCTION_DECL node was generated from a function "definition", then ! 554: we will have a list of DECL_NODE's, one for each of the function's formal ! 555: parameters. In this case, we can print out not only the types of each ! 556: formal, but also each formal's name. In the second case, this ! 557: FUNCTION_DECL node came from an actual function declaration (and *not* ! 558: a definition). In this case, we do nothing here because the formal ! 559: argument type-list will be output later, when the "type" of the function ! 560: is added to the string we are building. Note that the ANSI-style formal ! 561: parameter list is considered to be a (suffix) part of the "type" of the ! 562: function. */ ! 563: ! 564: if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition) ! 565: { ! 566: ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi)); ! 567: ! 568: /* Since we have already added in the formals list stuff, here we don't ! 569: add the whole "type" of the function we are considering (which ! 570: would include its parameter-list info), rather, we only add in ! 571: the "type" of the "type" of the function, which is really just ! 572: the return-type of the function (and does not include the parameter ! 573: list info). */ ! 574: ! 575: ret_val = gen_type (ret_val, TREE_TYPE (TREE_TYPE (decl)), style); ! 576: } ! 577: else ! 578: ret_val = gen_type (ret_val, TREE_TYPE (decl), style); ! 579: ! 580: ret_val = affix_data_type (ret_val); ! 581: ! 582: if (DECL_REGISTER (decl)) ! 583: ret_val = concat ("register ", ret_val); ! 584: if (TREE_PUBLIC (decl)) ! 585: ret_val = concat ("extern ", ret_val); ! 586: if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl)) ! 587: ret_val = concat ("static ", ret_val); ! 588: ! 589: return ret_val; ! 590: } ! 591: ! 592: extern FILE* aux_info_file; ! 593: ! 594: /* Generate and write a new line of info to the aux-info (.X) file. This ! 595: routine is called once for each function declaration, and once for each ! 596: function definition (even the implicit ones). */ ! 597: ! 598: void ! 599: gen_aux_info_record (fndecl, is_definition, is_implicit, is_prototyped) ! 600: tree fndecl; ! 601: int is_definition; ! 602: int is_implicit; ! 603: int is_prototyped; ! 604: { ! 605: if (flag_gen_aux_info) ! 606: { ! 607: static int compiled_from_record = 0; ! 608: ! 609: /* Each output .X file must have a header line. Write one now if we ! 610: have not yet done so. */ ! 611: ! 612: if (! compiled_from_record++) ! 613: { ! 614: /* The first line tells which directory file names are relative to. ! 615: Currently, -aux-info works only for files in the working ! 616: directory, so just use a `.' as a placeholder for now. */ ! 617: fprintf (aux_info_file, "/* compiled from: . */\n"); ! 618: } ! 619: ! 620: /* Write the actual line of auxiliary info. */ ! 621: ! 622: fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;", ! 623: DECL_SOURCE_FILE (fndecl), ! 624: DECL_SOURCE_LINE (fndecl), ! 625: (is_implicit) ? 'I' : (is_prototyped) ? 'N' : 'O', ! 626: (is_definition) ? 'F' : 'C', ! 627: gen_decl (fndecl, is_definition, ansi)); ! 628: ! 629: /* If this is an explicit function declaration, we need to also write ! 630: out an old-style (i.e. K&R) function header, just in case the user ! 631: wants to run unprotoize. */ ! 632: ! 633: if (is_definition) ! 634: { ! 635: fprintf (aux_info_file, " /*%s %s*/", ! 636: gen_formal_list_for_func_def (fndecl, k_and_r_names), ! 637: gen_formal_list_for_func_def (fndecl, k_and_r_decls)); ! 638: } ! 639: ! 640: fprintf (aux_info_file, "\n"); ! 641: } ! 642: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.