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