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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [scan-decls.c] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* scan-decls.c - Extracts declarations from cpp output.
2
   Copyright (C) 1993, 1995, 1997, 1998,
3
   1999, 2000, 2003, 2004, 2007 Free Software Foundation, Inc.
4
 
5
   This program is free software; you can redistribute it and/or modify it
6
   under the terms of the GNU General Public License as published by the
7
   Free Software Foundation; either version 3, or (at your option) any
8
   later version.
9
 
10
   This program is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU General Public License for more details.
14
 
15
   You should have received a copy of the GNU General Public License
16
   along with this program; see the file COPYING3.  If not see
17
   <http://www.gnu.org/licenses/>.
18
 
19
   Written by Per Bothner <bothner@cygnus.com>, July 1993.  */
20
 
21
#include "bconfig.h"
22
#include "system.h"
23
#include "coretypes.h"
24
#include "tm.h"
25
#include "cpplib.h"
26
#include "scan.h"
27
 
28
static void skip_to_closing_brace (cpp_reader *);
29
static const cpp_token *get_a_token (cpp_reader *);
30
 
31
int brace_nesting = 0;
32
 
33
/* The first extern_C_braces_length elements of extern_C_braces
34
   indicate the (brace nesting levels of) left braces that were
35
   prefixed by extern "C".  */
36
int extern_C_braces_length = 0;
37
/* 20 is not enough anymore on Solaris 9.  */
38
#define MAX_EXTERN_C_BRACES  200
39
char extern_C_braces[MAX_EXTERN_C_BRACES];
40
#define in_extern_C_brace (extern_C_braces_length>0)
41
 
42
/* True if the function declaration currently being scanned is
43
   prefixed by extern "C".  */
44
int current_extern_C = 0;
45
 
46
/* Get a token but skip padding.  */
47
static const cpp_token *
48
get_a_token (cpp_reader *pfile)
49
{
50
  for (;;)
51
    {
52
      const cpp_token *result = cpp_get_token (pfile);
53
      if (result->type != CPP_PADDING)
54
        return result;
55
    }
56
}
57
 
58
static void
59
skip_to_closing_brace (cpp_reader *pfile)
60
{
61
  int nesting = 1;
62
  for (;;)
63
    {
64
      enum cpp_ttype token = get_a_token (pfile)->type;
65
 
66
      if (token == CPP_EOF)
67
        break;
68
      if (token == CPP_OPEN_BRACE)
69
        nesting++;
70
      if (token == CPP_CLOSE_BRACE && --nesting == 0)
71
        break;
72
    }
73
}
74
 
75
/* This function scans a C source file (actually, the output of cpp),
76
   reading from FP.  It looks for function declarations, and
77
   external variable declarations.
78
 
79
   The following grammar (as well as some extra stuff) is recognized:
80
 
81
   declaration:
82
     (decl-specifier)* declarator ("," declarator)* ";"
83
   decl-specifier:
84
     identifier
85
     keyword
86
     extern "C"
87
   declarator:
88
     (ptr-operator)* dname [ "(" argument-declaration-list ")" ]
89
   ptr-operator:
90
     ("*" | "&") ("const" | "volatile")*
91
   dname:
92
     identifier
93
 
94
Here dname is the actual name being declared.
95
*/
96
 
97
int
98
scan_decls (cpp_reader *pfile, int argc ATTRIBUTE_UNUSED,
99
            char **argv ATTRIBUTE_UNUSED)
100
{
101
  int saw_extern, saw_inline;
102
  cpp_token prev_id;
103
  const cpp_token *token;
104
 
105
 new_statement:
106
  token = get_a_token (pfile);
107
 
108
 handle_statement:
109
  current_extern_C = 0;
110
  saw_extern = 0;
111
  saw_inline = 0;
112
  if (token->type == CPP_OPEN_BRACE)
113
    {
114
      /* Pop an 'extern "C"' nesting level, if appropriate.  */
115
      if (extern_C_braces_length
116
          && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
117
        extern_C_braces_length--;
118
      brace_nesting--;
119
      goto new_statement;
120
    }
121
  if (token->type == CPP_OPEN_BRACE)
122
    {
123
      brace_nesting++;
124
      goto new_statement;
125
    }
126
 
127
  if (token->type == CPP_EOF)
128
    return 0;
129
 
130
  if (token->type == CPP_SEMICOLON)
131
    goto new_statement;
132
  if (token->type != CPP_NAME)
133
    goto new_statement;
134
 
135
  prev_id.type = CPP_EOF;
136
  for (;;)
137
    {
138
      switch (token->type)
139
        {
140
        default:
141
          goto handle_statement;
142
        case CPP_MULT:
143
        case CPP_AND:
144
          /* skip */
145
          break;
146
 
147
        case CPP_COMMA:
148
        case CPP_SEMICOLON:
149
          if (prev_id.type != CPP_EOF && saw_extern)
150
            {
151
              recognized_extern (&prev_id);
152
            }
153
          if (token->type == CPP_COMMA)
154
            break;
155
          /* ... fall through ...  */
156
        case CPP_OPEN_BRACE:  case CPP_CLOSE_BRACE:
157
          goto new_statement;
158
 
159
        case CPP_EOF:
160
          return 0;
161
 
162
        case CPP_OPEN_PAREN:
163
          /* Looks like this is the start of a formal parameter list.  */
164
          if (prev_id.type != CPP_EOF)
165
            {
166
              int nesting = 1;
167
              int have_arg_list = 0;
168
              const struct line_map *map;
169
              unsigned int line;
170
              for (;;)
171
                {
172
                  token = get_a_token (pfile);
173
                  if (token->type == CPP_OPEN_PAREN)
174
                    nesting++;
175
                  else if (token->type == CPP_CLOSE_PAREN)
176
                    {
177
                      nesting--;
178
                      if (nesting == 0)
179
                        break;
180
                    }
181
                  else if (token->type == CPP_EOF)
182
                    break;
183
                  else if (token->type == CPP_NAME
184
                           || token->type == CPP_ELLIPSIS)
185
                    have_arg_list = 1;
186
                }
187
              map = linemap_lookup (&line_table, token->src_loc);
188
              line = SOURCE_LINE (map, token->src_loc);
189
              recognized_function (&prev_id, line,
190
                                   (saw_inline ? 'I'
191
                                    : in_extern_C_brace || current_extern_C
192
                                    ? 'F' : 'f'), have_arg_list);
193
              token = get_a_token (pfile);
194
              if (token->type == CPP_OPEN_BRACE)
195
                {
196
                  /* skip body of (normally) inline function */
197
                  skip_to_closing_brace (pfile);
198
                  goto new_statement;
199
                }
200
 
201
              /* skip a possible __attribute__ or throw expression after the
202
                 parameter list */
203
              while (token->type != CPP_SEMICOLON && token->type != CPP_EOF)
204
                token = get_a_token (pfile);
205
              if (token->type == CPP_EOF)
206
                return 0;
207
              goto new_statement;
208
            }
209
          break;
210
        case CPP_NAME:
211
          /* "inline" and "extern" are recognized but skipped */
212
          if (cpp_ideq (token, "inline"))
213
            {
214
              saw_inline = 1;
215
            }
216
          else if (cpp_ideq (token, "extern"))
217
            {
218
              saw_extern = 1;
219
              token = get_a_token (pfile);
220
              if (token->type == CPP_STRING
221
                  && token->val.str.len == 1
222
                  && token->val.str.text[0] == 'C')
223
                {
224
                  current_extern_C = 1;
225
                  token = get_a_token (pfile);
226
                  if (token->type == CPP_OPEN_BRACE)
227
                    {
228
                      brace_nesting++;
229
                      extern_C_braces[extern_C_braces_length++]
230
                        = brace_nesting;
231
                      if (extern_C_braces_length >= MAX_EXTERN_C_BRACES)
232
                        {
233
                          fprintf (stderr,
234
                                   "Internal error: out-of-bounds index\n");
235
                          exit (FATAL_EXIT_CODE);
236
                        }
237
                      goto new_statement;
238
                    }
239
                }
240
              else
241
                continue;
242
              break;
243
            }
244
          /* This may be the name of a variable or function.  */
245
          prev_id = *token;
246
          break;
247
        }
248
      token = get_a_token (pfile);
249
    }
250
}

powered by: WebSVN 2.1.0

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