OSDN Git Service

* real.h (ieee_extended_intel_96_round_53_format): New.
[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   unsigned int 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 uchar *, size_t);
46 static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
47
48 static void print_line (const struct line_map *, unsigned int,
49                         const char *);
50 static void maybe_print_line (const struct line_map *, unsigned int);
51
52 /* Callback routines for the parser.   Most of these are active only
53    in specific modes.  */
54 static void cb_line_change (cpp_reader *, const cpp_token *, int);
55 static void cb_define (cpp_reader *, unsigned int, cpp_hashnode *);
56 static void cb_undef (cpp_reader *, unsigned int, cpp_hashnode *);
57 static void cb_include (cpp_reader *, unsigned int, const unsigned char *,
58                         const char *, int);
59 static void cb_ident (cpp_reader *, unsigned int, const cpp_string *);
60 static void cb_def_pragma (cpp_reader *, unsigned int);
61
62 /* Preprocess and output.  */
63 void
64 preprocess_file (cpp_reader *pfile)
65 {
66   /* A successful cpp_read_main_file guarantees that we can call
67      cpp_scan_nooutput or cpp_get_token next.  */
68   if (flag_no_output)
69     {
70       /* Scan -included buffers, then the main file.  */
71       while (pfile->buffer->prev)
72         cpp_scan_nooutput (pfile);
73       cpp_scan_nooutput (pfile);
74     }
75   else if (cpp_get_options (pfile)->traditional)
76     scan_translation_unit_trad (pfile);
77   else
78     scan_translation_unit (pfile);
79
80   /* -dM command line option.  Should this be elsewhere?  */
81   if (flag_dump_macros == 'M')
82     cpp_forall_identifiers (pfile, dump_macro, NULL);
83
84   /* Flush any pending output.  */
85   if (print.printed)
86     putc ('\n', print.outf);
87 }
88
89 /* Set up the callbacks as appropriate.  */
90 void
91 init_pp_output (FILE *out_stream)
92 {
93   cpp_callbacks *cb = cpp_get_callbacks (parse_in);
94
95   if (!flag_no_output)
96     {
97       cb->line_change = cb_line_change;
98       /* Don't emit #pragma or #ident directives if we are processing
99          assembly language; the assembler may choke on them.  */
100       if (cpp_get_options (parse_in)->lang != CLK_ASM)
101         {
102           cb->ident      = cb_ident;
103           cb->def_pragma = cb_def_pragma;
104         }
105     }
106
107   if (flag_dump_includes)
108     cb->include  = cb_include;
109
110   if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
111     {
112       cb->define = cb_define;
113       cb->undef  = cb_undef;
114     }
115
116   /* Initialize the print structure.  Setting print.line to -1 here is
117      a trick to guarantee that the first token of the file will cause
118      a linemarker to be output by maybe_print_line.  */
119   print.line = (unsigned int) -1;
120   print.printed = 0;
121   print.prev = 0;
122   print.map = 0;
123   print.outf = out_stream;
124 }
125
126 /* Writes out the preprocessed file, handling spacing and paste
127    avoidance issues.  */
128 static void
129 scan_translation_unit (cpp_reader *pfile)
130 {
131   bool avoid_paste = false;
132
133   print.source = NULL;
134   for (;;)
135     {
136       const cpp_token *token = cpp_get_token (pfile);
137
138       if (token->type == CPP_PADDING)
139         {
140           avoid_paste = true;
141           if (print.source == NULL
142               || (!(print.source->flags & PREV_WHITE)
143                   && token->val.source == NULL))
144             print.source = token->val.source;
145           continue;
146         }
147
148       if (token->type == CPP_EOF)
149         break;
150
151       /* Subtle logic to output a space if and only if necessary.  */
152       if (avoid_paste)
153         {
154           if (print.source == NULL)
155             print.source = token;
156           if (print.source->flags & PREV_WHITE
157               || (print.prev
158                   && cpp_avoid_paste (pfile, print.prev, token))
159               || (print.prev == NULL && token->type == CPP_HASH))
160             putc (' ', print.outf);
161         }
162       else if (token->flags & PREV_WHITE)
163         putc (' ', print.outf);
164
165       avoid_paste = false;
166       print.source = NULL;
167       print.prev = token;
168       cpp_output_token (token, print.outf);
169
170       if (token->type == CPP_COMMENT)
171         account_for_newlines (token->val.str.text, token->val.str.len);
172     }
173 }
174
175 /* Adjust print.line for newlines embedded in output.  */
176 static void
177 account_for_newlines (const uchar *str, size_t len)
178 {
179   while (len--)
180     if (*str++ == '\n')
181       print.line++;
182 }
183
184 /* Writes out a traditionally preprocessed file.  */
185 static void
186 scan_translation_unit_trad (cpp_reader *pfile)
187 {
188   while (_cpp_read_logical_line_trad (pfile))
189     {
190       size_t len = pfile->out.cur - pfile->out.base;
191       maybe_print_line (print.map, pfile->out.first_line);
192       fwrite (pfile->out.base, 1, len, print.outf);
193       print.printed = 1;
194       if (!CPP_OPTION (pfile, discard_comments))
195         account_for_newlines (pfile->out.base, len);
196     }
197 }
198
199 /* If the token read on logical line LINE needs to be output on a
200    different line to the current one, output the required newlines or
201    a line marker, and return 1.  Otherwise return 0.  */
202 static void
203 maybe_print_line (const struct line_map *map, unsigned int line)
204 {
205   /* End the previous line of text.  */
206   if (print.printed)
207     {
208       putc ('\n', print.outf);
209       print.line++;
210       print.printed = 0;
211     }
212
213   if (line >= print.line && line < print.line + 8)
214     {
215       while (line > print.line)
216         {
217           putc ('\n', print.outf);
218           print.line++;
219         }
220     }
221   else
222     print_line (map, line, "");
223 }
224
225 /* Output a line marker for logical line LINE.  Special flags are "1"
226    or "2" indicating entering or leaving a file.  */
227 static void
228 print_line (const struct line_map *map, unsigned int line, const char *special_flags)
229 {
230   /* End any previous line of text.  */
231   if (print.printed)
232     putc ('\n', print.outf);
233   print.printed = 0;
234
235   print.line = line;
236   if (!flag_no_line_commands)
237     {
238       size_t to_file_len = strlen (map->to_file);
239       unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
240       unsigned char *p;
241
242       /* cpp_quote_string does not nul-terminate, so we have to do it
243          ourselves.  */
244       p = cpp_quote_string (to_file_quoted,
245                             (unsigned char *)map->to_file, to_file_len);
246       *p = '\0';
247       fprintf (print.outf, "# %u \"%s\"%s",
248                SOURCE_LINE (map, print.line),
249                to_file_quoted, special_flags);
250
251       if (map->sysp == 2)
252         fputs (" 3 4", print.outf);
253       else if (map->sysp == 1)
254         fputs (" 3", print.outf);
255
256       putc ('\n', print.outf);
257     }
258 }
259
260 /* Called when a line of output is started.  TOKEN is the first token
261    of the line, and at end of file will be CPP_EOF.  */
262 static void
263 cb_line_change (cpp_reader *pfile, const cpp_token *token, 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, unsigned int 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, unsigned int 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, unsigned int 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, unsigned int 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   /* First time?  */
350   if (print.map == NULL)
351     {
352       /* Avoid printing foo.i when the main file is foo.c.  */
353       if (!cpp_get_options (parse_in)->preprocessed)
354         print_line (map, map->from_line, flags);
355     }
356   else
357     {
358       /* Bring current file to correct line when entering a new file.  */
359       if (map->reason == LC_ENTER)
360         maybe_print_line (map - 1, map->from_line - 1);
361
362       if (map->reason == LC_ENTER)
363         flags = " 1";
364       else if (map->reason == LC_LEAVE)
365         flags = " 2";
366       print_line (map, map->from_line, flags);
367     }
368
369   print.map = map;
370 }
371
372 /* Copy a #pragma directive to the preprocessed output.  */
373 static void
374 cb_def_pragma (cpp_reader *pfile, unsigned int line)
375 {
376   maybe_print_line (print.map, line);
377   fputs ("#pragma ", print.outf);
378   cpp_output_line (pfile, print.outf);
379   print.line++;
380 }
381
382 /* Dump out the hash table.  */
383 static int
384 dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
385 {
386   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
387     {
388       fputs ("#define ", print.outf);
389       fputs ((const char *) cpp_macro_definition (pfile, node),
390              print.outf);
391       putc ('\n', print.outf);
392       print.line++;
393     }
394
395   return 1;
396 }