1 /* scan-decls.c - Extracts declarations from cpp output.
2 Copyright (C) 1993, 1995, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
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 2, or (at your option) any
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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 Written by Per Bothner <bothner@cygnus.com>, July 1993. */
26 static void skip_to_closing_brace
PARAMS ((cpp_reader
*));
28 int brace_nesting
= 0;
30 /* The first extern_C_braces_length elements of extern_C_braces
31 indicate the (brace nesting levels of) left braces that were
32 prefixed by extern "C". */
33 int extern_C_braces_length
= 0;
34 char extern_C_braces
[20];
35 #define in_extern_C_brace (extern_C_braces_length>0)
37 /* True if the function declaration currently being scanned is
38 prefixed by extern "C". */
39 int current_extern_C
= 0;
42 skip_to_closing_brace (pfile
)
51 cpp_get_token (pfile
, &tok
);
55 if (token
== CPP_OPEN_BRACE
)
57 if (token
== CPP_CLOSE_BRACE
&& --nesting
== 0)
62 /* This function scans a C source file (actually, the output of cpp),
63 reading from FP. It looks for function declarations, and
64 external variable declarations.
66 The following grammar (as well as some extra stuff) is recognized:
69 (decl-specifier)* declarator ("," declarator)* ";"
75 (ptr-operator)* dname [ "(" argument-declaration-list ")" ]
77 ("*" | "&") ("const" | "volatile")*
81 Here dname is the actual name being declared.
85 scan_decls (pfile
, argc
, argv
)
87 int argc ATTRIBUTE_UNUSED
;
88 char **argv ATTRIBUTE_UNUSED
;
90 int saw_extern
, saw_inline
;
91 cpp_token token
, prev_id
;
94 cpp_get_token (pfile
, &token
);
100 if (token
.type
== CPP_OPEN_BRACE
)
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
--;
109 if (token
.type
== CPP_OPEN_BRACE
)
115 if (token
.type
== CPP_EOF
)
118 if (token
.type
== CPP_SEMICOLON
)
120 if (token
.type
!= CPP_NAME
)
123 prev_id
.type
= CPP_EOF
;
129 goto handle_statement
;
137 if (prev_id
.type
!= CPP_EOF
&& saw_extern
)
139 recognized_extern (&prev_id
);
141 if (token
.type
== CPP_COMMA
)
143 /* ... fall through ... */
144 case CPP_OPEN_BRACE
: case CPP_CLOSE_BRACE
:
151 /* Looks like this is the start of a formal parameter list. */
152 if (prev_id
.type
!= CPP_EOF
)
155 int have_arg_list
= 0;
158 cpp_get_token (pfile
, &token
);
159 if (token
.type
== CPP_OPEN_PAREN
)
161 else if (token
.type
== CPP_CLOSE_PAREN
)
167 else if (token
.type
== CPP_EOF
)
169 else if (token
.type
== CPP_NAME
170 || token
.type
== CPP_ELLIPSIS
)
173 recognized_function (&prev_id
,
174 cpp_get_line (pfile
)->line
,
176 : in_extern_C_brace
|| current_extern_C
177 ? 'F' : 'f'), have_arg_list
);
178 cpp_get_token (pfile
, &token
);
179 if (token
.type
== CPP_OPEN_BRACE
)
181 /* skip body of (normally) inline function */
182 skip_to_closing_brace (pfile
);
186 /* skip a possible __attribute__ or throw expression after the
188 while (token
.type
!= CPP_SEMICOLON
&& token
.type
!= CPP_EOF
)
189 cpp_get_token (pfile
, &token
);
194 /* "inline" and "extern" are recognized but skipped */
195 if (cpp_ideq (&token
, "inline"))
199 else if (cpp_ideq (&token
, "extern"))
202 cpp_get_token (pfile
, &token
);
203 if (token
.type
== CPP_STRING
204 && token
.val
.str
.len
== 1
205 && token
.val
.str
.text
[0] == 'C')
207 current_extern_C
= 1;
208 cpp_get_token (pfile
, &token
);
209 if (token
.type
== CPP_OPEN_BRACE
)
212 extern_C_braces
[extern_C_braces_length
++]
221 /* This may be the name of a variable or function. */
225 cpp_get_token (pfile
, &token
);