Annotation of gcc/scan-decls.c, revision 1.1.1.2

1.1       root        1: /* scan-decls.c - Extracts declarations from cpp output.
1.1.1.2 ! root        2:    Copyright (C) 1993, 1995 Free Software Foundation, Inc.
1.1       root        3: 
                      4: This program is free software; you can redistribute it and/or modify it
                      5: under the terms of the GNU General Public License as published by the
                      6: Free Software Foundation; either version 2, or (at your option) any
                      7: later version.
                      8: 
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12: GNU General Public License for more details.
                     13: 
                     14: You should have received a copy of the GNU General Public License
                     15: along with this program; if not, write to the Free Software
1.1.1.2 ! root       16: Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1.1       root       17: 
                     18:    Written by Per Bothner <[email protected]>, July 1993.  */
                     19: 
                     20: #include <stdio.h>
                     21: #include <ctype.h>
                     22: #include "hconfig.h"
1.1.1.2 ! root       23: #include "cpplib.h"
1.1       root       24: 
                     25: int brace_nesting = 0;
                     26: 
                     27: /* The first extern_C_braces_length elements of extern_C_braces
                     28:    indicate the (brace nesting levels of) left braces that were
                     29:    prefixed by extern "C".  */
                     30: int extern_C_braces_length = 0;
                     31: char extern_C_braces[20];
                     32: #define in_extern_C_brace (extern_C_braces_length>0)
                     33: 
                     34: /* True if the function declaration currently being scanned is
                     35:    prefixed by extern "C".  */
                     36: int current_extern_C = 0;
                     37: 
                     38: static void
1.1.1.2 ! root       39: skip_to_closing_brace (pfile)
        !            40:      cpp_reader *pfile;
1.1       root       41: {
                     42:   int nesting = 1;
                     43:   for (;;)
                     44:     {
1.1.1.2 ! root       45:       enum cpp_token token = cpp_get_token (pfile);
        !            46:       if (token == CPP_EOF)
1.1       root       47:        break;
1.1.1.2 ! root       48:       if (token == CPP_LBRACE)
1.1       root       49:        nesting++;
1.1.1.2 ! root       50:       if (token == CPP_RBRACE && --nesting == 0)
1.1       root       51:        break;
                     52:     }
                     53: }
                     54: 
                     55: /* This function scans a C source file (actually, the output of cpp),
1.1.1.2 ! root       56:    reading from FP.  It looks for function declarations, and
        !            57:    external variable declarations.  
        !            58: 
        !            59:    The following grammar (as well as some extra stuff) is recognized:
        !            60: 
        !            61:    declaration:
        !            62:      (decl-specifier)* declarator ("," declarator)* ";"
        !            63:    decl-specifier:
        !            64:      identifier
        !            65:      keyword
        !            66:      extern "C"
        !            67:    declarator:
        !            68:      (ptr-operator)* dname [ "(" argument-declaration-list ")" ]
        !            69:    ptr-operator:
        !            70:      ("*" | "&") ("const" | "volatile")*
        !            71:    dname:
        !            72:      identifier
        !            73: 
        !            74: Here dname is the actual name being declared.
        !            75: */
1.1       root       76: 
                     77: int
1.1.1.2 ! root       78: scan_decls (pfile, argc, argv)
        !            79:      cpp_reader *pfile;
        !            80:      int argc;
        !            81:      char**argv;
1.1       root       82: {
                     83:   int saw_extern, saw_inline;
1.1.1.2 ! root       84:   int old_written;
        !            85:   /* If declarator_start is non-zero, it marks the start of the current
        !            86:      declarator.  If it is zero, we are either still parsing the
        !            87:      decl-specs, or prev_id_start marks the start of the declarator. */
        !            88:   int declarator_start;
        !            89:   int prev_id_start, prev_id_end;
        !            90:   enum cpp_token token;
1.1       root       91: 
                     92:  new_statement:
1.1.1.2 ! root       93:   CPP_SET_WRITTEN (pfile, 0);
        !            94:   token = cpp_get_token (pfile);
        !            95: 
1.1       root       96:  handle_statement:
                     97:   current_extern_C = 0;
                     98:   saw_extern = 0;
                     99:   saw_inline = 0;
1.1.1.2 ! root      100:   if (token == CPP_RBRACE)
1.1       root      101:     {
                    102:       /* Pop an 'extern "C"' nesting level, if appropriate.  */
                    103:       if (extern_C_braces_length
                    104:          && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
                    105:        extern_C_braces_length--;
                    106:       brace_nesting--;
                    107:       goto new_statement;
                    108:     }
1.1.1.2 ! root      109:   if (token == CPP_LBRACE)
1.1       root      110:     {
                    111:       brace_nesting++;
                    112:       goto new_statement;
                    113:     }
1.1.1.2 ! root      114:   if (token == CPP_EOF)
1.1       root      115:     return 0;
1.1.1.2 ! root      116:   if (token == CPP_SEMICOLON)
1.1       root      117:     goto new_statement;
1.1.1.2 ! root      118:   if (token != CPP_NAME)
1.1       root      119:     goto new_statement;
1.1.1.2 ! root      120: 
        !           121:   prev_id_start = 0;
        !           122:   declarator_start = 0;
1.1       root      123:   for (;;)
                    124:     {
1.1.1.2 ! root      125:       int start_written = CPP_WRITTEN (pfile);
        !           126:       token = cpp_get_token (pfile);
        !           127:     handle_token:
        !           128:       switch (token)
1.1       root      129:        {
1.1.1.2 ! root      130:        case CPP_LPAREN:
        !           131:          /* Looks like this is the start of a formal parameter list. */
        !           132:          if (prev_id_start)
1.1       root      133:            {
                    134:              int nesting = 1;
1.1.1.2 ! root      135:              int have_arg_list = 0;
        !           136:              cpp_buffer *fbuf = cpp_file_buffer (pfile);
        !           137:              long func_lineno;
        !           138:              cpp_buf_line_and_col (fbuf, &func_lineno, NULL);
1.1       root      139:              for (;;)
                    140:                {
1.1.1.2 ! root      141:                  token = cpp_get_token (pfile);
        !           142:                  if (token == CPP_LPAREN)
1.1       root      143:                    nesting++;
1.1.1.2 ! root      144:                  else if (token == CPP_RPAREN)
1.1       root      145:                    {
1.1.1.2 ! root      146:                      nesting--;
        !           147:                      if (nesting == 0)
        !           148:                        break;
1.1       root      149:                    }
1.1.1.2 ! root      150:                  else if (token == CPP_EOF)
        !           151:                    break;
        !           152:                  else if (token == CPP_NAME || token == CPP_3DOTS)
        !           153:                    have_arg_list = 1;
1.1       root      154:                }
1.1.1.2 ! root      155:              recognized_function (pfile->token_buffer + prev_id_start,
        !           156:                                   prev_id_end - prev_id_start,
1.1       root      157:                                   (saw_inline ? 'I'
                    158:                                    : in_extern_C_brace || current_extern_C
                    159:                                    ? 'F' : 'f'),
1.1.1.2 ! root      160:                                   pfile->token_buffer, prev_id_start,
        !           161:                                   have_arg_list,
        !           162:                                   fbuf->nominal_fname, func_lineno);
        !           163:              token = cpp_get_non_space_token (pfile);
        !           164:              if (token == CPP_LBRACE)
1.1       root      165:                {
                    166:                  /* skip body of (normally) inline function */
1.1.1.2 ! root      167:                  skip_to_closing_brace (pfile);
1.1       root      168:                  goto new_statement;
                    169:                }
1.1.1.2 ! root      170:              goto maybe_handle_comma;
1.1       root      171:            }
1.1.1.2 ! root      172:          break;
        !           173:        case CPP_OTHER:
        !           174:          if (CPP_WRITTEN (pfile) == start_written + 1
        !           175:              && (CPP_PWRITTEN (pfile)[-1] == '*'
        !           176:                  || CPP_PWRITTEN (pfile)[-1] == '&'))
        !           177:            declarator_start = start_written;
        !           178:          else
        !           179:            goto handle_statement;
        !           180:          break;
        !           181:        case CPP_COMMA:
        !           182:        case CPP_SEMICOLON:
        !           183:          if (prev_id_start && saw_extern)
1.1       root      184:            {
1.1.1.2 ! root      185:              recognized_extern (pfile->token_buffer + prev_id_start,
        !           186:                                 prev_id_end - prev_id_start,
        !           187:                                 pfile->token_buffer,
        !           188:                                 prev_id_start);
1.1       root      189:            }
1.1.1.2 ! root      190:          /* ... fall through ... */
        !           191:        maybe_handle_comma:
        !           192:          if (token != CPP_COMMA)
        !           193:            goto new_statement;
        !           194:        handle_comma:
        !           195:          /* Handle multiple declarators in a single declaration,
        !           196:             as in:  extern char *strcpy (), *strcat (), ... ; */
        !           197:          if (declarator_start == 0)
        !           198:            declarator_start = prev_id_start;
        !           199:          CPP_SET_WRITTEN (pfile, declarator_start);
        !           200:          break;
        !           201:        case CPP_NAME:
        !           202:          /* "inline" and "extern" are recognized but skipped */
        !           203:          if (strcmp (pfile->token_buffer, "inline") == 0)
        !           204:            {
        !           205:              saw_inline = 1;
        !           206:              CPP_SET_WRITTEN (pfile, start_written);
        !           207:            }
        !           208:          if (strcmp (pfile->token_buffer, "extern") == 0)
        !           209:            {
        !           210:              saw_extern = 1;
        !           211:              CPP_SET_WRITTEN (pfile, start_written);
        !           212:              token = cpp_get_non_space_token (pfile);
        !           213:              if (token == CPP_STRING
        !           214:                  && strcmp (pfile->token_buffer, "\"C\"") == 0)
        !           215:                {
        !           216:                  CPP_SET_WRITTEN (pfile, start_written);
        !           217:                  current_extern_C = 1;
        !           218:                  token = cpp_get_non_space_token (pfile);
        !           219:                  if (token == CPP_LBRACE)
        !           220:                    {
        !           221:                      brace_nesting++;
        !           222:                      extern_C_braces[extern_C_braces_length++]
        !           223:                        = brace_nesting;
        !           224:                      goto new_statement;
        !           225:                    }
        !           226:                }
        !           227:              else
        !           228:                goto handle_token;
        !           229:              break;
        !           230:            }
        !           231:          /* This may be the name of a variable or function. */
        !           232:          prev_id_start = start_written;
        !           233:          prev_id_end = CPP_WRITTEN (pfile);
        !           234:          break;
        !           235: 
        !           236:        case CPP_EOF:
        !           237:          return;  /* ??? FIXME */
        !           238: 
        !           239:        case CPP_LBRACE:  case CPP_RBRACE:  case CPP_DIRECTIVE:
        !           240:          goto new_statement;  /* handle_statement? */
        !           241:          
        !           242:        case CPP_HSPACE:  case CPP_VSPACE:  case CPP_COMMENT:  case CPP_POP:
        !           243:          /* Skip initial white space. */
        !           244:          if (start_written == 0)
        !           245:            CPP_SET_WRITTEN (pfile, 0);
        !           246:          break;
        !           247: 
        !           248:         default:
        !           249:          prev_id_start = 0;
1.1       root      250:        }
                    251:     }
                    252: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.