OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [scan-decls.c] - Diff between revs 38 and 154

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 38 Rev 154
/* scan-decls.c - Extracts declarations from cpp output.
/* scan-decls.c - Extracts declarations from cpp output.
   Copyright (C) 1993, 1995, 1997, 1998,
   Copyright (C) 1993, 1995, 1997, 1998,
   1999, 2000, 2003, 2004, 2007 Free Software Foundation, Inc.
   1999, 2000, 2003, 2004, 2007 Free Software Foundation, Inc.
 
 
   This program is free software; you can redistribute it and/or modify it
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 3, or (at your option) any
   Free Software Foundation; either version 3, or (at your option) any
   later version.
   later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING3.  If not see
   along with this program; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.
   <http://www.gnu.org/licenses/>.
 
 
   Written by Per Bothner <bothner@cygnus.com>, July 1993.  */
   Written by Per Bothner <bothner@cygnus.com>, July 1993.  */
 
 
#include "bconfig.h"
#include "bconfig.h"
#include "system.h"
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
#include "tm.h"
#include "tm.h"
#include "cpplib.h"
#include "cpplib.h"
#include "scan.h"
#include "scan.h"
 
 
static void skip_to_closing_brace (cpp_reader *);
static void skip_to_closing_brace (cpp_reader *);
static const cpp_token *get_a_token (cpp_reader *);
static const cpp_token *get_a_token (cpp_reader *);
 
 
int brace_nesting = 0;
int brace_nesting = 0;
 
 
/* The first extern_C_braces_length elements of extern_C_braces
/* The first extern_C_braces_length elements of extern_C_braces
   indicate the (brace nesting levels of) left braces that were
   indicate the (brace nesting levels of) left braces that were
   prefixed by extern "C".  */
   prefixed by extern "C".  */
int extern_C_braces_length = 0;
int extern_C_braces_length = 0;
/* 20 is not enough anymore on Solaris 9.  */
/* 20 is not enough anymore on Solaris 9.  */
#define MAX_EXTERN_C_BRACES  200
#define MAX_EXTERN_C_BRACES  200
char extern_C_braces[MAX_EXTERN_C_BRACES];
char extern_C_braces[MAX_EXTERN_C_BRACES];
#define in_extern_C_brace (extern_C_braces_length>0)
#define in_extern_C_brace (extern_C_braces_length>0)
 
 
/* True if the function declaration currently being scanned is
/* True if the function declaration currently being scanned is
   prefixed by extern "C".  */
   prefixed by extern "C".  */
int current_extern_C = 0;
int current_extern_C = 0;
 
 
/* Get a token but skip padding.  */
/* Get a token but skip padding.  */
static const cpp_token *
static const cpp_token *
get_a_token (cpp_reader *pfile)
get_a_token (cpp_reader *pfile)
{
{
  for (;;)
  for (;;)
    {
    {
      const cpp_token *result = cpp_get_token (pfile);
      const cpp_token *result = cpp_get_token (pfile);
      if (result->type != CPP_PADDING)
      if (result->type != CPP_PADDING)
        return result;
        return result;
    }
    }
}
}
 
 
static void
static void
skip_to_closing_brace (cpp_reader *pfile)
skip_to_closing_brace (cpp_reader *pfile)
{
{
  int nesting = 1;
  int nesting = 1;
  for (;;)
  for (;;)
    {
    {
      enum cpp_ttype token = get_a_token (pfile)->type;
      enum cpp_ttype token = get_a_token (pfile)->type;
 
 
      if (token == CPP_EOF)
      if (token == CPP_EOF)
        break;
        break;
      if (token == CPP_OPEN_BRACE)
      if (token == CPP_OPEN_BRACE)
        nesting++;
        nesting++;
      if (token == CPP_CLOSE_BRACE && --nesting == 0)
      if (token == CPP_CLOSE_BRACE && --nesting == 0)
        break;
        break;
    }
    }
}
}
 
 
/* This function scans a C source file (actually, the output of cpp),
/* This function scans a C source file (actually, the output of cpp),
   reading from FP.  It looks for function declarations, and
   reading from FP.  It looks for function declarations, and
   external variable declarations.
   external variable declarations.
 
 
   The following grammar (as well as some extra stuff) is recognized:
   The following grammar (as well as some extra stuff) is recognized:
 
 
   declaration:
   declaration:
     (decl-specifier)* declarator ("," declarator)* ";"
     (decl-specifier)* declarator ("," declarator)* ";"
   decl-specifier:
   decl-specifier:
     identifier
     identifier
     keyword
     keyword
     extern "C"
     extern "C"
   declarator:
   declarator:
     (ptr-operator)* dname [ "(" argument-declaration-list ")" ]
     (ptr-operator)* dname [ "(" argument-declaration-list ")" ]
   ptr-operator:
   ptr-operator:
     ("*" | "&") ("const" | "volatile")*
     ("*" | "&") ("const" | "volatile")*
   dname:
   dname:
     identifier
     identifier
 
 
Here dname is the actual name being declared.
Here dname is the actual name being declared.
*/
*/
 
 
int
int
scan_decls (cpp_reader *pfile, int argc ATTRIBUTE_UNUSED,
scan_decls (cpp_reader *pfile, int argc ATTRIBUTE_UNUSED,
            char **argv ATTRIBUTE_UNUSED)
            char **argv ATTRIBUTE_UNUSED)
{
{
  int saw_extern, saw_inline;
  int saw_extern, saw_inline;
  cpp_token prev_id;
  cpp_token prev_id;
  const cpp_token *token;
  const cpp_token *token;
 
 
 new_statement:
 new_statement:
  token = get_a_token (pfile);
  token = get_a_token (pfile);
 
 
 handle_statement:
 handle_statement:
  current_extern_C = 0;
  current_extern_C = 0;
  saw_extern = 0;
  saw_extern = 0;
  saw_inline = 0;
  saw_inline = 0;
  if (token->type == CPP_OPEN_BRACE)
  if (token->type == CPP_OPEN_BRACE)
    {
    {
      /* Pop an 'extern "C"' nesting level, if appropriate.  */
      /* Pop an 'extern "C"' nesting level, if appropriate.  */
      if (extern_C_braces_length
      if (extern_C_braces_length
          && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
          && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
        extern_C_braces_length--;
        extern_C_braces_length--;
      brace_nesting--;
      brace_nesting--;
      goto new_statement;
      goto new_statement;
    }
    }
  if (token->type == CPP_OPEN_BRACE)
  if (token->type == CPP_OPEN_BRACE)
    {
    {
      brace_nesting++;
      brace_nesting++;
      goto new_statement;
      goto new_statement;
    }
    }
 
 
  if (token->type == CPP_EOF)
  if (token->type == CPP_EOF)
    return 0;
    return 0;
 
 
  if (token->type == CPP_SEMICOLON)
  if (token->type == CPP_SEMICOLON)
    goto new_statement;
    goto new_statement;
  if (token->type != CPP_NAME)
  if (token->type != CPP_NAME)
    goto new_statement;
    goto new_statement;
 
 
  prev_id.type = CPP_EOF;
  prev_id.type = CPP_EOF;
  for (;;)
  for (;;)
    {
    {
      switch (token->type)
      switch (token->type)
        {
        {
        default:
        default:
          goto handle_statement;
          goto handle_statement;
        case CPP_MULT:
        case CPP_MULT:
        case CPP_AND:
        case CPP_AND:
          /* skip */
          /* skip */
          break;
          break;
 
 
        case CPP_COMMA:
        case CPP_COMMA:
        case CPP_SEMICOLON:
        case CPP_SEMICOLON:
          if (prev_id.type != CPP_EOF && saw_extern)
          if (prev_id.type != CPP_EOF && saw_extern)
            {
            {
              recognized_extern (&prev_id);
              recognized_extern (&prev_id);
            }
            }
          if (token->type == CPP_COMMA)
          if (token->type == CPP_COMMA)
            break;
            break;
          /* ... fall through ...  */
          /* ... fall through ...  */
        case CPP_OPEN_BRACE:  case CPP_CLOSE_BRACE:
        case CPP_OPEN_BRACE:  case CPP_CLOSE_BRACE:
          goto new_statement;
          goto new_statement;
 
 
        case CPP_EOF:
        case CPP_EOF:
          return 0;
          return 0;
 
 
        case CPP_OPEN_PAREN:
        case CPP_OPEN_PAREN:
          /* Looks like this is the start of a formal parameter list.  */
          /* Looks like this is the start of a formal parameter list.  */
          if (prev_id.type != CPP_EOF)
          if (prev_id.type != CPP_EOF)
            {
            {
              int nesting = 1;
              int nesting = 1;
              int have_arg_list = 0;
              int have_arg_list = 0;
              const struct line_map *map;
              const struct line_map *map;
              unsigned int line;
              unsigned int line;
              for (;;)
              for (;;)
                {
                {
                  token = get_a_token (pfile);
                  token = get_a_token (pfile);
                  if (token->type == CPP_OPEN_PAREN)
                  if (token->type == CPP_OPEN_PAREN)
                    nesting++;
                    nesting++;
                  else if (token->type == CPP_CLOSE_PAREN)
                  else if (token->type == CPP_CLOSE_PAREN)
                    {
                    {
                      nesting--;
                      nesting--;
                      if (nesting == 0)
                      if (nesting == 0)
                        break;
                        break;
                    }
                    }
                  else if (token->type == CPP_EOF)
                  else if (token->type == CPP_EOF)
                    break;
                    break;
                  else if (token->type == CPP_NAME
                  else if (token->type == CPP_NAME
                           || token->type == CPP_ELLIPSIS)
                           || token->type == CPP_ELLIPSIS)
                    have_arg_list = 1;
                    have_arg_list = 1;
                }
                }
              map = linemap_lookup (&line_table, token->src_loc);
              map = linemap_lookup (&line_table, token->src_loc);
              line = SOURCE_LINE (map, token->src_loc);
              line = SOURCE_LINE (map, token->src_loc);
              recognized_function (&prev_id, line,
              recognized_function (&prev_id, line,
                                   (saw_inline ? 'I'
                                   (saw_inline ? 'I'
                                    : in_extern_C_brace || current_extern_C
                                    : in_extern_C_brace || current_extern_C
                                    ? 'F' : 'f'), have_arg_list);
                                    ? 'F' : 'f'), have_arg_list);
              token = get_a_token (pfile);
              token = get_a_token (pfile);
              if (token->type == CPP_OPEN_BRACE)
              if (token->type == CPP_OPEN_BRACE)
                {
                {
                  /* skip body of (normally) inline function */
                  /* skip body of (normally) inline function */
                  skip_to_closing_brace (pfile);
                  skip_to_closing_brace (pfile);
                  goto new_statement;
                  goto new_statement;
                }
                }
 
 
              /* skip a possible __attribute__ or throw expression after the
              /* skip a possible __attribute__ or throw expression after the
                 parameter list */
                 parameter list */
              while (token->type != CPP_SEMICOLON && token->type != CPP_EOF)
              while (token->type != CPP_SEMICOLON && token->type != CPP_EOF)
                token = get_a_token (pfile);
                token = get_a_token (pfile);
              if (token->type == CPP_EOF)
              if (token->type == CPP_EOF)
                return 0;
                return 0;
              goto new_statement;
              goto new_statement;
            }
            }
          break;
          break;
        case CPP_NAME:
        case CPP_NAME:
          /* "inline" and "extern" are recognized but skipped */
          /* "inline" and "extern" are recognized but skipped */
          if (cpp_ideq (token, "inline"))
          if (cpp_ideq (token, "inline"))
            {
            {
              saw_inline = 1;
              saw_inline = 1;
            }
            }
          else if (cpp_ideq (token, "extern"))
          else if (cpp_ideq (token, "extern"))
            {
            {
              saw_extern = 1;
              saw_extern = 1;
              token = get_a_token (pfile);
              token = get_a_token (pfile);
              if (token->type == CPP_STRING
              if (token->type == CPP_STRING
                  && token->val.str.len == 1
                  && token->val.str.len == 1
                  && token->val.str.text[0] == 'C')
                  && token->val.str.text[0] == 'C')
                {
                {
                  current_extern_C = 1;
                  current_extern_C = 1;
                  token = get_a_token (pfile);
                  token = get_a_token (pfile);
                  if (token->type == CPP_OPEN_BRACE)
                  if (token->type == CPP_OPEN_BRACE)
                    {
                    {
                      brace_nesting++;
                      brace_nesting++;
                      extern_C_braces[extern_C_braces_length++]
                      extern_C_braces[extern_C_braces_length++]
                        = brace_nesting;
                        = brace_nesting;
                      if (extern_C_braces_length >= MAX_EXTERN_C_BRACES)
                      if (extern_C_braces_length >= MAX_EXTERN_C_BRACES)
                        {
                        {
                          fprintf (stderr,
                          fprintf (stderr,
                                   "Internal error: out-of-bounds index\n");
                                   "Internal error: out-of-bounds index\n");
                          exit (FATAL_EXIT_CODE);
                          exit (FATAL_EXIT_CODE);
                        }
                        }
                      goto new_statement;
                      goto new_statement;
                    }
                    }
                }
                }
              else
              else
                continue;
                continue;
              break;
              break;
            }
            }
          /* This may be the name of a variable or function.  */
          /* This may be the name of a variable or function.  */
          prev_id = *token;
          prev_id = *token;
          break;
          break;
        }
        }
      token = get_a_token (pfile);
      token = get_a_token (pfile);
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.