OSDN Git Service

* c-lex.c (fe_file_change): Handle a NULL new_map.
[pf3gnuchains/gcc-fork.git] / gcc / c-ppoutput.c
1 /* Preprocess only, using cpplib.
2    Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3    Free Software Foundation, Inc.
4    Written by Per Bothner, 1994-95.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "cpplib.h"
25 #include "cpphash.h"
26 #include "tree.h"
27 #include "c-common.h"           /* For flags.  */
28 #include "c-pragma.h"           /* For parse_in.  */
29
30 /* Encapsulates state used to convert a stream of tokens into a text
31    file.  */
32 static struct
33 {
34   FILE *outf;                   /* Stream to write to.  */
35   const struct line_map *map;   /* Logical to physical line mappings.  */
36   const cpp_token *prev;        /* Previous token.  */
37   const cpp_token *source;      /* Source token for spacing.  */
38   fileline line;                /* Line currently being written.  */
39   unsigned char printed;        /* Nonzero if something output at line.  */
40 } print;
41
42 /* General output routines.  */
43 static void scan_translation_unit (cpp_reader *);
44 static void scan_translation_unit_trad (cpp_reader *);
45 static void account_for_newlines (const unsigned char *, size_t);
46 static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
47
48 static void print_line (const struct line_map *, fileline, const char *);
49 static void maybe_print_line (const struct line_map *, fileline);
50
51 /* Callback routines for the parser.   Most of these are active only
52    in specific modes.  */
53 static void cb_line_change (cpp_reader *, const cpp_token *, int);
54 static void cb_define (cpp_reader *, fileline, cpp_hashnode *);
55 static void cb_undef (cpp_reader *, fileline, cpp_hashnode *);
56 static void cb_include (cpp_reader *, fileline, const unsigned char *,
57                         const char *, int);
58 static void cb_ident (cpp_reader *, fileline, const cpp_string *);
59 static void cb_def_pragma (cpp_reader *, fileline);
60
61 /* Preprocess and output.  */
62 void
63 preprocess_file (cpp_reader *pfile)
64 {
65   /* A successful cpp_read_main_file guarantees that we can call
66      cpp_scan_nooutput or cpp_get_token next.  */
67   if (flag_no_output)
68     {
69       /* Scan -included buffers, then the main file.  */
70       while (pfile->buffer->prev)
71         cpp_scan_nooutput (pfile);
72       cpp_scan_nooutput (pfile);
73     }
74   else if (cpp_get_options (pfile)->traditional)
75     scan_translation_unit_trad (pfile);
76   else
77     scan_translation_unit (pfile);
78
79   /* -dM command line option.  Should this be elsewhere?  */
80   if (flag_dump_macros == 'M')
81     cpp_forall_identifiers (pfile, dump_macro, NULL);
82
83   /* Flush any pending output.  */
84   if (print.printed)
85     putc ('\n', print.outf);
86 }
87
88 /* Set up the callbacks as appropriate.  */
89 void
90 init_pp_output (FILE *out_stream)
91 {
92   cpp_callbacks *cb = cpp_get_callbacks (parse_in);
93
94   if (!flag_no_output)
95     {
96       cb->line_change = cb_line_change;
97       /* Don't emit #pragma or #ident directives if we are processing
98          assembly language; the assembler may choke on them.  */
99       if (cpp_get_options (parse_in)->lang != CLK_ASM)
100         {
101           cb->ident      = cb_ident;
102           cb->def_pragma = cb_def_pragma;
103         }
104     }
105
106   if (flag_dump_includes)
107     cb->include  = cb_include;
108
109   if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
110     {
111       cb->define = cb_define;
112       cb->undef  = cb_undef;
113     }
114
115   /* Initialize the print structure.  Setting print.line to -1 here is
116      a trick to guarantee that the first token of the file will cause
117      a linemarker to be output by maybe_print_line.  */
118   print.line = (fileline) -1;
119   print.printed = 0;
120   print.prev = 0;
121   print.map = 0;
122   print.outf = out_stream;
123 }
124
125 /* Writes out the preprocessed file, handling spacing and paste
126    avoidance issues.  */
127 static void
128 scan_translation_unit (cpp_reader *pfile)
129 {
130   bool avoid_paste = false;
131
132   print.source = NULL;
133   for (;;)
134     {
135       const cpp_token *token = cpp_get_token (pfile);
136
137       if (token->type == CPP_PADDING)
138         {
139           avoid_paste = true;
140           if (print.source == NULL
141               || (!(print.source->flags & PREV_WHITE)
142                   && token->val.source == NULL))
143             print.source = token->val.source;
144           continue;
145         }
146
147       if (token->type == CPP_EOF)
148         break;
149
150       /* Subtle logic to output a space if and only if necessary.  */
151       if (avoid_paste)
152         {
153           if (print.source == NULL)
154             print.source = token;
155           if (print.source->flags & PREV_WHITE
156               || (print.prev
157                   && cpp_avoid_paste (pfile, print.prev, token))
158               || (print.prev == NULL && token->type == CPP_HASH))
159             putc (' ', print.outf);
160         }
161       else if (token->flags & PREV_WHITE)
162         putc (' ', print.outf);
163
164       avoid_paste = false;
165       print.source = NULL;
166       print.prev = token;
167       cpp_output_token (token, print.outf);
168
169       if (token->type == CPP_COMMENT)
170         account_for_newlines (token->val.str.text, token->val.str.len);
171     }
172 }
173
174 /* Adjust print.line for newlines embedded in output.  */
175 static void
176 account_for_newlines (const unsigned char *str, size_t len)
177 {
178   while (len--)
179     if (*str++ == '\n')
180       print.line++;
181 }
182
183 /* Writes out a traditionally preprocessed file.  */
184 static void
185 scan_translation_unit_trad (cpp_reader *pfile)
186 {
187   while (_cpp_read_logical_line_trad (pfile))
188     {
189       size_t len = pfile->out.cur - pfile->out.base;
190       maybe_print_line (print.map, pfile->out.first_line);
191       fwrite (pfile->out.base, 1, len, print.outf);
192       print.printed = 1;
193       if (!CPP_OPTION (pfile, discard_comments))
194         account_for_newlines (pfile->out.base, len);
195     }
196 }
197
198 /* If the token read on logical line LINE needs to be output on a
199    different line to the current one, output the required newlines or
200    a line marker, and return 1.  Otherwise return 0.  */
201 static void
202 maybe_print_line (const struct line_map *map, fileline line)
203 {
204   /* End the previous line of text.  */
205   if (print.printed)
206     {
207       putc ('\n', print.outf);
208       print.line++;
209       print.printed = 0;
210     }
211
212   if (line >= print.line && line < print.line + 8)
213     {
214       while (line > print.line)
215         {
216           putc ('\n', print.outf);
217           print.line++;
218         }
219     }
220   else
221     print_line (map, line, "");
222 }
223
224 /* Output a line marker for logical line LINE.  Special flags are "1"
225    or "2" indicating entering or leaving a file.  */
226 static void
227 print_line (const struct line_map *map, fileline line, const char *special_flags)
228 {
229   /* End any previous line of text.  */
230   if (print.printed)
231     putc ('\n', print.outf);
232   print.printed = 0;
233
234   print.line = line;
235   if (!flag_no_line_commands)
236     {
237       size_t to_file_len = strlen (map->to_file);
238       unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
239       unsigned char *p;
240
241       /* cpp_quote_string does not nul-terminate, so we have to do it
242          ourselves.  */
243       p = cpp_quote_string (to_file_quoted,
244                             (unsigned char *)map->to_file, to_file_len);
245       *p = '\0';
246       fprintf (print.outf, "# %u \"%s\"%s",
247                SOURCE_LINE (map, print.line),
248                to_file_quoted, special_flags);
249
250       if (map->sysp == 2)
251         fputs (" 3 4", print.outf);
252       else if (map->sysp == 1)
253         fputs (" 3", print.outf);
254
255       putc ('\n', print.outf);
256     }
257 }
258
259 /* Called when a line of output is started.  TOKEN is the first token
260    of the line, and at end of file will be CPP_EOF.  */
261 static void
262 cb_line_change (cpp_reader *pfile, const cpp_token *token,
263                 int parsing_args)
264 {
265   if (token->type == CPP_EOF || parsing_args)
266     return;
267
268   maybe_print_line (print.map, token->line);
269   print.prev = 0;
270   print.source = 0;
271
272   /* Supply enough spaces to put this token in its original column,
273      one space per column greater than 2, since scan_translation_unit
274      will provide a space if PREV_WHITE.  Don't bother trying to
275      reconstruct tabs; we can't get it right in general, and nothing
276      ought to care.  Some things do care; the fault lies with them.  */
277   if (!CPP_OPTION (pfile, traditional))
278     {
279       print.printed = 1;
280       if (token->col > 2)
281         {
282           unsigned int spaces = token->col - 2;
283
284           while (spaces--)
285             putc (' ', print.outf);
286         }
287     }
288 }
289
290 static void
291 cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
292           const cpp_string *str)
293 {
294   maybe_print_line (print.map, line);
295   fprintf (print.outf, "#ident \"%s\"\n", str->text);
296   print.line++;
297 }
298
299 static void
300 cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
301 {
302   maybe_print_line (print.map, line);
303   fputs ("#define ", print.outf);
304
305   /* 'D' is whole definition; 'N' is name only.  */
306   if (flag_dump_macros == 'D')
307     fputs ((const char *) cpp_macro_definition (pfile, node),
308            print.outf);
309   else
310     fputs ((const char *) NODE_NAME (node), print.outf);
311
312   putc ('\n', print.outf);
313   print.line++;
314 }
315
316 static void
317 cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
318           cpp_hashnode *node)
319 {
320   maybe_print_line (print.map, line);
321   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
322   print.line++;
323 }
324
325 static void
326 cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
327             const unsigned char *dir, const char *header, int angle_brackets)
328 {
329   maybe_print_line (print.map, line);
330   if (angle_brackets)
331     fprintf (print.outf, "#%s <%s>\n", dir, header);
332   else
333     fprintf (print.outf, "#%s \"%s\"\n", dir, header);
334   print.line++;
335 }
336
337 /* The file name, line number or system header flags have changed, as
338    described in MAP.  From this point on, the old print.map might be
339    pointing to freed memory, and so must not be dereferenced.  */
340
341 void
342 pp_file_change (const struct line_map *map)
343 {
344   const char *flags = "";
345
346   if (flag_no_line_commands || flag_no_output)
347     return;
348
349   if (map != NULL)
350     {
351       /* First time?  */
352       if (print.map == NULL)
353         {
354           /* Avoid printing foo.i when the main file is foo.c.  */
355           if (!cpp_get_options (parse_in)->preprocessed)
356             print_line (map, map->from_line, flags);
357         }
358       else
359         {
360           /* Bring current file to correct line when entering a new file.  */
361           if (map->reason == LC_ENTER)
362             maybe_print_line (map - 1, map->from_line - 1);
363
364           if (map->reason == LC_ENTER)
365             flags = " 1";
366           else if (map->reason == LC_LEAVE)
367             flags = " 2";
368           print_line (map, map->from_line, flags);
369         }
370     }
371
372   print.map = map;
373 }
374
375 /* Copy a #pragma directive to the preprocessed output.  */
376 static void
377 cb_def_pragma (cpp_reader *pfile, fileline line)
378 {
379   maybe_print_line (print.map, line);
380   fputs ("#pragma ", print.outf);
381   cpp_output_line (pfile, print.outf);
382   print.line++;
383 }
384
385 /* Dump out the hash table.  */
386 static int
387 dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
388 {
389   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
390     {
391       fputs ("#define ", print.outf);
392       fputs ((const char *) cpp_macro_definition (pfile, node),
393              print.outf);
394       putc ('\n', print.outf);
395       print.line++;
396     }
397
398   return 1;
399 }