]>
Commit | Line | Data |
---|---|---|
711b8824 ZW |
1 | /* Part of CPP library. (Macro handling.) |
2 | Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, | |
3 | 1999, 2000 Free Software Foundation, Inc. | |
4 | Written by Per Bothner, 1994. | |
5 | Based on CCCP program by Paul Rubin, June 1986 | |
6 | Adapted to ANSI C, Richard Stallman, Jan 1987 | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify it | |
9 | under the terms of the GNU General Public License as published by the | |
10 | Free Software Foundation; either version 2, or (at your option) any | |
11 | later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; if not, write to the Free Software | |
20 | Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
21 | ||
22 | In other words, you are welcome to use, share and improve this program. | |
23 | You are forbidden to forbid anyone else to use, share and improve | |
24 | what you give them. Help stamp out software-hoarding! */ | |
25 | ||
26 | #include "config.h" | |
27 | #include "system.h" | |
28 | #include "cpplib.h" | |
29 | #include "cpphash.h" | |
30 | ||
31 | /* Stores basic information about a macro, before it is allocated. */ | |
32 | struct macro_info | |
33 | { | |
34 | const cpp_token *first_param; /* First parameter token. */ | |
35 | const cpp_token *first; /* First expansion token. */ | |
36 | unsigned int paramlen; /* Length of parameter names. */ | |
37 | unsigned int len; /* Length of token strings. */ | |
38 | unsigned int ntokens; /* Number of tokens in expansion. */ | |
39 | short paramc; /* Number of parameters. */ | |
40 | unsigned char flags; | |
41 | }; | |
42 | ||
43 | static void dump_funlike_macro PARAMS ((cpp_reader *, cpp_hashnode *)); | |
44 | static void count_params PARAMS ((cpp_reader *, struct macro_info *)); | |
45 | static int is__va_args__ PARAMS ((cpp_reader *, const cpp_token *)); | |
46 | ||
47 | static int parse_define PARAMS((cpp_reader *, struct macro_info *)); | |
48 | static int check_macro_redefinition PARAMS((cpp_reader *, cpp_hashnode *hp, | |
49 | const cpp_toklist *)); | |
50 | static const cpp_toklist * save_expansion PARAMS((cpp_reader *, | |
51 | struct macro_info *)); | |
52 | static unsigned int find_param PARAMS ((const cpp_token *, | |
53 | const cpp_token *)); | |
54 | static cpp_toklist * alloc_macro PARAMS ((cpp_reader *, struct macro_info *)); | |
55 | ||
56 | ||
57 | /* Scans for a given token, returning the parameter number if found, | |
58 | or 0 if not found. Scans from FIRST to TOKEN - 1 or the first | |
59 | CPP_CLOSE_PAREN for TOKEN. */ | |
60 | static unsigned int | |
61 | find_param (first, token) | |
62 | const cpp_token *first, *token; | |
63 | { | |
64 | unsigned int param = 0; | |
65 | ||
66 | for (; first < token && first->type != CPP_CLOSE_PAREN; first++) | |
67 | if (first->type == CPP_NAME) | |
68 | { | |
69 | param++; | |
70 | if (first->val.node == token->val.node) | |
71 | return param; | |
72 | } | |
73 | ||
74 | return 0; | |
75 | } | |
76 | ||
77 | /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the | |
78 | replacement list of a variable-arguments macro. TOKEN is assumed | |
79 | to be of type CPP_NAME. */ | |
80 | static int | |
81 | is__va_args__ (pfile, token) | |
82 | cpp_reader *pfile; | |
83 | const cpp_token *token; | |
84 | { | |
85 | if (!CPP_PEDANTIC (pfile) | |
86 | || token->val.node != pfile->spec_nodes->n__VA_ARGS__) | |
87 | return 0; | |
88 | ||
89 | cpp_pedwarn_with_line (pfile, token->line, token->col, | |
90 | "\"%s\" is only valid in the replacement list of a function-like macro", | |
91 | token->val.node->name); | |
92 | return 1; | |
93 | } | |
94 | ||
95 | /* Counts the parameters to a function-like macro, the length of their | |
96 | null-terminated names, and whether the macro is a variable-argument | |
97 | one. FIRST is the token immediately after the open parenthesis, | |
98 | INFO stores the data. | |
99 | ||
100 | On success, info->first is updated to the token after the closing | |
101 | parenthesis, i.e. the first token of the expansion. Otherwise | |
102 | there was an error, which has been reported. */ | |
103 | static void | |
104 | count_params (pfile, info) | |
105 | cpp_reader *pfile; | |
106 | struct macro_info *info; | |
107 | { | |
108 | unsigned int prev_ident = 0; | |
109 | const cpp_token *token; | |
110 | ||
111 | info->paramc = 0; | |
112 | info->paramlen = 0; | |
113 | info->flags = 0; | |
114 | info->first = info->first_param; /* Not a ')' indicating success. */ | |
115 | ||
116 | for (token = info->first_param;; token++) | |
117 | { | |
118 | switch (token->type) | |
119 | { | |
120 | default: | |
121 | cpp_error_with_line (pfile, token->line, token->col, | |
122 | "illegal token in macro parameter list"); | |
123 | return; | |
124 | ||
125 | case CPP_EOF: | |
126 | missing_paren: | |
127 | cpp_error_with_line (pfile, token->line, token->col, | |
128 | "missing ')' in macro parameter list"); | |
129 | return; | |
130 | ||
131 | case CPP_COMMENT: | |
132 | continue; /* Ignore -C comments. */ | |
133 | ||
134 | case CPP_NAME: | |
135 | if (prev_ident) | |
136 | { | |
137 | cpp_error_with_line (pfile, token->line, token->col, | |
138 | "macro parameters must be comma-separated"); | |
139 | return; | |
140 | } | |
141 | ||
142 | /* Constraint 6.10.3.5 */ | |
143 | if (is__va_args__ (pfile, token)) | |
144 | return; | |
145 | ||
146 | /* Constraint 6.10.3.6 - duplicate parameter names. */ | |
147 | if (find_param (info->first, token)) | |
148 | { | |
149 | cpp_error_with_line (pfile, token->line, token->col, | |
150 | "duplicate macro parameter \"%s\"", | |
151 | token->val.node->name); | |
152 | return; | |
153 | } | |
154 | ||
155 | prev_ident = 1; | |
156 | info->paramc++; | |
157 | info->paramlen += token->val.node->length + 1; | |
158 | continue; | |
159 | ||
160 | case CPP_CLOSE_PAREN: | |
161 | if (prev_ident || info->paramc == 0) | |
162 | break; | |
163 | ||
164 | /* Fall through to pick up the error. */ | |
165 | case CPP_COMMA: | |
166 | if (!prev_ident) | |
167 | { | |
168 | cpp_error_with_line (pfile, token->line, token->col, | |
169 | "parameter name expected"); | |
170 | return; | |
171 | } | |
172 | prev_ident = 0; | |
173 | continue; | |
174 | ||
175 | case CPP_ELLIPSIS: | |
176 | /* Convert ISO-style var_args to named varargs by changing | |
177 | the ellipsis into an identifier with name __VA_ARGS__. | |
178 | This simplifies other handling. */ | |
179 | if (!prev_ident) | |
180 | { | |
181 | cpp_token *tok = (cpp_token *) token; | |
182 | ||
183 | tok->type = CPP_NAME; | |
184 | tok->val.node = pfile->spec_nodes->n__VA_ARGS__; | |
185 | ||
186 | info->paramc++; | |
187 | info->paramlen += tok->val.node->length + 1; | |
188 | ||
189 | if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99)) | |
190 | cpp_pedwarn (pfile, | |
191 | "C89 does not permit anon varargs macros"); | |
192 | } | |
193 | else | |
194 | { | |
195 | info->flags |= GNU_REST_ARGS; | |
196 | if (CPP_PEDANTIC (pfile)) | |
197 | cpp_pedwarn (pfile, | |
198 | "ISO C does not permit named varargs parameters"); | |
199 | } | |
200 | ||
201 | info->flags |= VAR_ARGS; | |
202 | token++; | |
203 | if (token->type == CPP_CLOSE_PAREN) | |
204 | break; | |
205 | goto missing_paren; | |
206 | } | |
207 | ||
208 | /* Success. */ | |
209 | info->first = token + 1; | |
210 | if (!pfile->save_parameter_spellings) | |
211 | info->paramlen = 0; | |
212 | return; | |
213 | } | |
214 | } | |
215 | ||
216 | /* Parses a #define directive. On success, returns zero, and INFO is | |
217 | filled in appropriately. */ | |
218 | static int | |
219 | parse_define (pfile, info) | |
220 | cpp_reader *pfile; | |
221 | struct macro_info *info; | |
222 | { | |
223 | const cpp_token *token; | |
224 | int prev_white = 0; | |
225 | ||
226 | /* The first token after the macro's name. */ | |
227 | token = _cpp_get_token (pfile); | |
228 | ||
229 | /* Constraint 6.10.3.5 */ | |
230 | if (is__va_args__ (pfile, token - 1)) | |
231 | return 1; | |
232 | ||
233 | while (token->type == CPP_COMMENT) | |
234 | token++, prev_white = 1; | |
235 | prev_white |= token->flags & PREV_WHITE; | |
236 | ||
237 | if (token->type == CPP_OPEN_PAREN && !prev_white) | |
238 | { | |
239 | /* A function-like macro. */ | |
240 | info->first_param = token + 1; | |
241 | count_params (pfile, info); | |
242 | if (info->first[-1].type != CPP_CLOSE_PAREN) | |
243 | return 1; | |
244 | } | |
245 | else | |
246 | { | |
247 | /* An object-like macro. */ | |
248 | info->paramc = -1; | |
249 | info->paramlen = 0; | |
250 | info->flags = 0; | |
251 | info->first = token; | |
252 | if (!prev_white && token->type != CPP_EOF) | |
253 | cpp_pedwarn (pfile, "ISO C requires whitespace after the macro name"); | |
254 | } | |
255 | ||
256 | /* Count tokens in expansion. We drop paste tokens, and stringize | |
257 | tokens, so don't count them. */ | |
258 | info->ntokens = info->len = 0; | |
259 | for (token = info->first; token->type != CPP_EOF; token++) | |
260 | { | |
261 | if (token->type == CPP_PASTE) | |
262 | { | |
263 | /* Token-paste ##, can appear in both object-like and | |
264 | function-like macros, but not at the ends. Constraint | |
265 | 6.10.3.3.1 */ | |
266 | if (token == info->first || token[1].type == CPP_EOF) | |
267 | { | |
268 | cpp_error_with_line (pfile, token->line, token->col, | |
269 | "'##' cannot appear at either end of a macro expansion"); | |
270 | return 1; | |
271 | } | |
272 | continue; | |
273 | } | |
274 | else if (token->type == CPP_HASH) | |
275 | { | |
276 | /* Stringifying #, but a normal character in object-like | |
277 | macros. Must come before a parameter name. Constraint | |
278 | 6.10.3.2.1. */ | |
279 | if (info->paramc >= 0) | |
280 | { | |
281 | if (token[1].type == CPP_NAME | |
282 | && find_param (info->first_param, token + 1)) | |
283 | continue; | |
284 | if (! CPP_OPTION (pfile, lang_asm)) | |
285 | { | |
286 | cpp_error_with_line (pfile, token->line, token->col, | |
287 | "'#' is not followed by a macro parameter"); | |
288 | return 1; | |
289 | } | |
290 | } | |
291 | } | |
292 | else if (token->type == CPP_NAME) | |
293 | { | |
294 | /* Constraint 6.10.3.5 */ | |
295 | if (!(info->flags & VAR_ARGS) && is__va_args__ (pfile, token)) | |
296 | return 1; | |
297 | /* It might be worth doing a check here that we aren't a | |
298 | macro argument, since we don't store the text of macro | |
299 | arguments. This would reduce "len" and save space. */ | |
300 | } | |
301 | info->ntokens++; | |
302 | if (TOKEN_SPELL (token) == SPELL_STRING) | |
303 | info->len += token->val.str.len; | |
304 | } | |
305 | ||
306 | return 0; | |
307 | } | |
308 | ||
309 | /* Returns non-zero if a macro redefinition is trivial. */ | |
310 | static int | |
311 | check_macro_redefinition (pfile, hp, list2) | |
312 | cpp_reader *pfile; | |
313 | cpp_hashnode *hp; | |
314 | const cpp_toklist *list2; | |
315 | { | |
316 | const cpp_toklist *list1; | |
317 | ||
318 | if (hp->type != T_MACRO) | |
319 | return ! pfile->done_initializing; | |
320 | ||
321 | /* Clear the whitespace and BOL flags of the first tokens. They get | |
322 | altered during macro expansion, but is not significant here. */ | |
323 | list1 = hp->value.expansion; | |
324 | list1->tokens[0].flags &= ~(PREV_WHITE|BOL); | |
325 | list2->tokens[0].flags &= ~(PREV_WHITE|BOL); | |
326 | ||
327 | if (!_cpp_equiv_toklists (list1, list2)) | |
328 | return 0; | |
329 | ||
330 | if (CPP_OPTION (pfile, pedantic) | |
331 | && list1->paramc > 0 | |
332 | && (list1->params_len != list2->params_len | |
333 | || memcmp (list1->namebuf, list2->namebuf, list1->params_len))) | |
334 | return 0; | |
335 | ||
336 | return 1; | |
337 | } | |
338 | ||
339 | /* This is a dummy structure whose only purpose is getting alignment | |
340 | correct. */ | |
341 | struct toklist_dummy | |
342 | { | |
343 | cpp_toklist list; | |
344 | cpp_token first_token; | |
345 | }; | |
346 | ||
347 | /* Allocate space to hold the token list, its tokens, their text, and | |
348 | the parameter names if needed. Empty expansions are stored as a | |
349 | single placemarker token. | |
350 | ||
351 | These are all allocated in a block together for performance | |
352 | reasons. Therefore, this token list cannot be expanded like a | |
353 | normal token list. Try to do so, and you lose. */ | |
354 | static cpp_toklist * | |
355 | alloc_macro (pfile, info) | |
356 | cpp_reader *pfile; | |
357 | struct macro_info *info; | |
358 | { | |
359 | unsigned int size; | |
360 | struct toklist_dummy *dummy; | |
361 | cpp_toklist *list; | |
362 | ||
363 | /* Empty macros become a single placemarker token. */ | |
364 | if (info->ntokens == 0) | |
365 | info->ntokens = 1; | |
366 | ||
367 | size = sizeof (struct toklist_dummy); | |
368 | size += (info->ntokens - 1) * sizeof(cpp_token); | |
369 | size += info->len + info->paramlen; | |
370 | ||
371 | dummy = (struct toklist_dummy *) xmalloc (size); | |
372 | list = (cpp_toklist *) dummy; | |
373 | ||
374 | /* Initialize the monster. */ | |
375 | list->tokens = &dummy->first_token; | |
376 | list->tokens_used = list->tokens_cap = info->ntokens; | |
377 | ||
378 | list->namebuf = (unsigned char *) &list->tokens[info->ntokens]; | |
379 | list->name_used = list->name_cap = info->len + info->paramlen; | |
380 | ||
381 | list->directive = 0; | |
382 | list->line = pfile->token_list.line; | |
383 | list->file = pfile->token_list.file; | |
384 | list->params_len = info->paramlen; | |
385 | list->paramc = info->paramc; | |
386 | list->flags = info->flags; | |
387 | ||
388 | return list; | |
389 | } | |
390 | ||
391 | /* Free the definition of macro H. */ | |
392 | ||
393 | void | |
394 | _cpp_free_definition (h) | |
395 | cpp_hashnode *h; | |
396 | { | |
397 | if (h->type == T_MACRO) | |
398 | free ((PTR) h->value.expansion); | |
399 | h->value.expansion = NULL; | |
400 | } | |
401 | ||
402 | /* Copy the tokens of the expansion, beginning with info->first until | |
403 | CPP_EOF. INFO contains information about the macro. | |
404 | ||
405 | Change the type of macro arguments in the expansion from CPP_NAME | |
406 | to CPP_MACRO_ARG. Remove #'s that represent stringification, | |
407 | flagging the CPP_MACRO_ARG it operates on STRINGIFY. Remove ##'s, | |
408 | flagging the token on its immediate left PASTE_LEFT. Returns the | |
409 | token list for the macro expansion. */ | |
410 | static const cpp_toklist * | |
411 | save_expansion (pfile, info) | |
412 | cpp_reader *pfile; | |
413 | struct macro_info *info; | |
414 | { | |
415 | const cpp_token *token; | |
416 | cpp_toklist *list; | |
417 | cpp_token *dest; | |
418 | unsigned char *buf; | |
419 | ||
420 | list = alloc_macro (pfile, info); | |
421 | buf = list->namebuf; | |
422 | ||
423 | /* Store the null-terminated parameter spellings of a macro, to | |
424 | provide pedantic warnings to satisfy 6.10.3.2, or for use when | |
425 | dumping macro definitions. They must go first. */ | |
426 | if (list->params_len) | |
427 | for (token = info->first_param; token < info->first; token++) | |
428 | if (token->type == CPP_NAME) | |
429 | { | |
430 | /* Copy null too. */ | |
431 | memcpy (buf, token->val.node->name, token->val.node->length + 1); | |
432 | buf += token->val.node->length + 1; | |
433 | } | |
434 | ||
435 | dest = list->tokens; | |
436 | for (token = info->first; token->type != CPP_EOF; token++) | |
437 | { | |
438 | unsigned int param_no; | |
439 | ||
440 | switch (token->type) | |
441 | { | |
442 | case CPP_NAME: | |
443 | if (list->paramc == -1) | |
444 | break; | |
445 | ||
446 | /* Check if the name is a macro parameter. */ | |
447 | param_no = find_param (info->first_param, token); | |
448 | if (param_no == 0) | |
449 | break; | |
450 | dest->val.aux = param_no - 1; | |
451 | ||
452 | dest->type = CPP_MACRO_ARG; | |
453 | if (token[-1].type == CPP_HASH) | |
454 | dest->flags = token[-1].flags | STRINGIFY_ARG; | |
455 | else | |
456 | dest->flags = token->flags; /* Particularly PREV_WHITE. */ | |
457 | /* Turn off PREV_WHITE if we immediately follow a paste. | |
458 | That way, even if the paste turns out to be illegal, there | |
459 | will be no space between the two tokens in the output. */ | |
460 | if (token[-1].type == CPP_PASTE) | |
461 | dest->flags &= ~PREV_WHITE; | |
462 | dest++; | |
463 | continue; | |
464 | ||
465 | case CPP_PASTE: | |
466 | dest[-1].flags |= PASTE_LEFT; | |
467 | continue; | |
468 | ||
469 | case CPP_HASH: | |
470 | /* Stringifying #. Constraint 6.10.3.2.1 */ | |
471 | if (list->paramc >= 0 && token[1].type == CPP_NAME | |
472 | && find_param (info->first_param, token + 1)) | |
473 | continue; | |
474 | break; | |
475 | ||
476 | default: | |
477 | break; | |
478 | } | |
479 | ||
480 | /* Copy the token. */ | |
481 | *dest = *token; | |
482 | if (TOKEN_SPELL (token) == SPELL_STRING) | |
483 | { | |
484 | memcpy (buf, token->val.str.text, token->val.str.len); | |
485 | dest->val.str.text = buf; | |
486 | buf += dest->val.str.len; | |
487 | } | |
488 | if (token[-1].type == CPP_PASTE) | |
489 | dest->flags &= ~PREV_WHITE; | |
490 | dest++; | |
491 | } | |
492 | ||
493 | /* Empty macros become a single placemarker token. */ | |
494 | if (dest == list->tokens) | |
495 | { | |
496 | dest->type = CPP_PLACEMARKER; | |
497 | dest->flags = 0; | |
498 | } | |
499 | ||
500 | return list; | |
501 | } | |
502 | ||
503 | /* Parse a macro and save its expansion. Returns non-zero on success. */ | |
504 | int | |
505 | _cpp_create_definition (pfile, hp) | |
506 | cpp_reader *pfile; | |
507 | cpp_hashnode *hp; | |
508 | { | |
509 | struct macro_info info; | |
510 | const cpp_toklist *list; | |
511 | ||
512 | if (parse_define (pfile, &info)) | |
513 | return 0; | |
514 | list = save_expansion (pfile, &info); | |
515 | ||
516 | /* Check for a redefinition. Redefinition of a macro is allowed if | |
517 | and only if the old and new definitions are the same. | |
518 | (6.10.3 paragraph 2). */ | |
519 | ||
520 | if (hp->type != T_VOID) | |
521 | { | |
522 | if (!check_macro_redefinition (pfile, hp, list)) | |
523 | { | |
524 | cpp_pedwarn (pfile, "\"%s\" redefined", hp->name); | |
525 | if (pfile->done_initializing && hp->type == T_MACRO) | |
526 | cpp_pedwarn_with_file_and_line (pfile, | |
527 | hp->value.expansion->file, | |
528 | hp->value.expansion->line, 1, | |
529 | "this is the location of the previous definition"); | |
530 | } | |
531 | _cpp_free_definition (hp); | |
532 | } | |
533 | ||
534 | /* Enter definition in hash table. */ | |
535 | hp->type = T_MACRO; | |
536 | hp->value.expansion = list; | |
537 | ||
538 | return 1; | |
539 | } | |
540 | ||
541 | /* Dump the definition of macro MACRO on stdout. The format is suitable | |
542 | to be read back in again. */ | |
543 | ||
544 | void | |
545 | _cpp_dump_definition (pfile, hp) | |
546 | cpp_reader *pfile; | |
547 | cpp_hashnode *hp; | |
548 | { | |
549 | CPP_RESERVE (pfile, hp->length + sizeof "#define "); | |
550 | CPP_PUTS_Q (pfile, "#define ", sizeof "#define " - 1); | |
551 | CPP_PUTS_Q (pfile, hp->name, hp->length); | |
552 | ||
553 | if (hp->type == T_MACRO) | |
554 | { | |
555 | if (hp->value.expansion->paramc >= 0) | |
556 | dump_funlike_macro (pfile, hp); | |
557 | else | |
558 | { | |
559 | const cpp_toklist *list = hp->value.expansion; | |
560 | list->tokens[0].flags &= ~BOL; | |
561 | list->tokens[0].flags |= PREV_WHITE; | |
562 | _cpp_dump_list (pfile, list, list->tokens, 1); | |
563 | } | |
564 | } | |
565 | else | |
566 | cpp_ice (pfile, "invalid hash type %d in dump_definition", hp->type); | |
567 | ||
568 | if (CPP_BUFFER (pfile) == 0 || ! pfile->done_initializing) | |
569 | CPP_PUTC (pfile, '\n'); | |
570 | } | |
571 | ||
572 | static void | |
573 | dump_funlike_macro (pfile, node) | |
574 | cpp_reader *pfile; | |
575 | cpp_hashnode *node; | |
576 | { | |
577 | int i = 0; | |
578 | const cpp_toklist * list = node->value.expansion; | |
579 | const U_CHAR *param; | |
580 | ||
581 | param = list->namebuf; | |
582 | CPP_PUTC_Q (pfile, '('); | |
583 | for (i = 0; i++ < list->paramc;) | |
584 | { | |
585 | unsigned int len; | |
586 | ||
587 | len = ustrlen (param); | |
588 | CPP_PUTS (pfile, param, len); | |
589 | if (i < list->paramc) | |
590 | CPP_PUTS(pfile, ", ", 2); | |
591 | else if (list->flags & VAR_ARGS) | |
592 | { | |
593 | if (!ustrcmp (param, U"__VA_ARGS__")) | |
594 | pfile->limit -= sizeof (U"__VA_ARGS__") - 1; | |
595 | CPP_PUTS_Q (pfile, "...", 3); | |
596 | } | |
597 | param += len + 1; | |
598 | } | |
599 | CPP_PUTC (pfile, ')'); | |
600 | list->tokens[0].flags &= ~BOL; | |
601 | list->tokens[0].flags |= PREV_WHITE; | |
602 | _cpp_dump_list (pfile, list, list->tokens, 1); | |
603 | } |