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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [c-ppoutput.c] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* Preprocess only, using cpplib.
2
   Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007,
3
   2008, 2009 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 3, 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; see the file COPYING3.  If not see
18
   <http://www.gnu.org/licenses/>.  */
19
 
20
#include "config.h"
21
#include "system.h"
22
#include "coretypes.h"
23
#include "tm.h"
24
#include "cpplib.h"
25
#include "../libcpp/internal.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 cpp_token *prev;        /* Previous token.  */
36
  const cpp_token *source;      /* Source token for spacing.  */
37
  int src_line;                 /* Line number currently being written.  */
38
  unsigned char printed;        /* Nonzero if something output at line.  */
39
  bool first_time;              /* pp_file_change hasn't been called yet.  */
40
} print;
41
 
42
/* Defined and undefined macros being queued for output with -dU at
43
   the next newline.  */
44
typedef struct macro_queue
45
{
46
  struct macro_queue *next;     /* Next macro in the list.  */
47
  char *macro;                  /* The name of the macro if not
48
                                   defined, the full definition if
49
                                   defined.  */
50
} macro_queue;
51
static macro_queue *define_queue, *undef_queue;
52
 
53
/* General output routines.  */
54
static void scan_translation_unit (cpp_reader *);
55
static void print_lines_directives_only (int, const void *, size_t);
56
static void scan_translation_unit_directives_only (cpp_reader *);
57
static void scan_translation_unit_trad (cpp_reader *);
58
static void account_for_newlines (const unsigned char *, size_t);
59
static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
60
static void dump_queued_macros (cpp_reader *);
61
 
62
static void print_line (source_location, const char *);
63
static void maybe_print_line (source_location);
64
static void do_line_change (cpp_reader *, const cpp_token *,
65
                            source_location, int);
66
 
67
/* Callback routines for the parser.   Most of these are active only
68
   in specific modes.  */
69
static void cb_line_change (cpp_reader *, const cpp_token *, int);
70
static void cb_define (cpp_reader *, source_location, cpp_hashnode *);
71
static void cb_undef (cpp_reader *, source_location, cpp_hashnode *);
72
static void cb_used_define (cpp_reader *, source_location, cpp_hashnode *);
73
static void cb_used_undef (cpp_reader *, source_location, cpp_hashnode *);
74
static void cb_include (cpp_reader *, source_location, const unsigned char *,
75
                        const char *, int, const cpp_token **);
76
static void cb_ident (cpp_reader *, source_location, const cpp_string *);
77
static void cb_def_pragma (cpp_reader *, source_location);
78
static void cb_read_pch (cpp_reader *pfile, const char *name,
79
                         int fd, const char *orig_name);
80
 
81
/* Preprocess and output.  */
82
void
83
preprocess_file (cpp_reader *pfile)
84
{
85
  /* A successful cpp_read_main_file guarantees that we can call
86
     cpp_scan_nooutput or cpp_get_token next.  */
87
  if (flag_no_output)
88
    {
89
      /* Scan -included buffers, then the main file.  */
90
      while (pfile->buffer->prev)
91
        cpp_scan_nooutput (pfile);
92
      cpp_scan_nooutput (pfile);
93
    }
94
  else if (cpp_get_options (pfile)->traditional)
95
    scan_translation_unit_trad (pfile);
96
  else if (cpp_get_options (pfile)->directives_only
97
           && !cpp_get_options (pfile)->preprocessed)
98
    scan_translation_unit_directives_only (pfile);
99
  else
100
    scan_translation_unit (pfile);
101
 
102
  /* -dM command line option.  Should this be elsewhere?  */
103
  if (flag_dump_macros == 'M')
104
    cpp_forall_identifiers (pfile, dump_macro, NULL);
105
 
106
  /* Flush any pending output.  */
107
  if (print.printed)
108
    putc ('\n', print.outf);
109
}
110
 
111
/* Set up the callbacks as appropriate.  */
112
void
113
init_pp_output (FILE *out_stream)
114
{
115
  cpp_callbacks *cb = cpp_get_callbacks (parse_in);
116
 
117
  if (!flag_no_output)
118
    {
119
      cb->line_change = cb_line_change;
120
      /* Don't emit #pragma or #ident directives if we are processing
121
         assembly language; the assembler may choke on them.  */
122
      if (cpp_get_options (parse_in)->lang != CLK_ASM)
123
        {
124
          cb->ident      = cb_ident;
125
          cb->def_pragma = cb_def_pragma;
126
        }
127
    }
128
 
129
  if (flag_dump_includes)
130
    cb->include  = cb_include;
131
 
132
  if (flag_pch_preprocess)
133
    {
134
      cb->valid_pch = c_common_valid_pch;
135
      cb->read_pch = cb_read_pch;
136
    }
137
 
138
  if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
139
    {
140
      cb->define = cb_define;
141
      cb->undef  = cb_undef;
142
    }
143
 
144
  if (flag_dump_macros == 'U')
145
    {
146
      cb->before_define = dump_queued_macros;
147
      cb->used_define = cb_used_define;
148
      cb->used_undef = cb_used_undef;
149
    }
150
 
151
  /* Initialize the print structure.  */
152
  print.src_line = 1;
153
  print.printed = 0;
154
  print.prev = 0;
155
  print.outf = out_stream;
156
  print.first_time = 1;
157
}
158
 
159
/* Writes out the preprocessed file, handling spacing and paste
160
   avoidance issues.  */
161
static void
162
scan_translation_unit (cpp_reader *pfile)
163
{
164
  bool avoid_paste = false;
165
  bool do_line_adjustments
166
    = cpp_get_options (parse_in)->lang != CLK_ASM
167
      && !flag_no_line_commands;
168
  bool in_pragma = false;
169
 
170
  print.source = NULL;
171
  for (;;)
172
    {
173
      source_location loc;
174
      const cpp_token *token = cpp_get_token_with_location (pfile, &loc);
175
 
176
      if (token->type == CPP_PADDING)
177
        {
178
          avoid_paste = true;
179
          if (print.source == NULL
180
              || (!(print.source->flags & PREV_WHITE)
181
                  && token->val.source == NULL))
182
            print.source = token->val.source;
183
          continue;
184
        }
185
 
186
      if (token->type == CPP_EOF)
187
        break;
188
 
189
      /* Subtle logic to output a space if and only if necessary.  */
190
      if (avoid_paste)
191
        {
192
          const struct line_map *map
193
            = linemap_lookup (line_table, loc);
194
          int src_line = SOURCE_LINE (map, loc);
195
 
196
          if (print.source == NULL)
197
            print.source = token;
198
 
199
          if (src_line != print.src_line
200
              && do_line_adjustments
201
              && !in_pragma)
202
            {
203
              do_line_change (pfile, token, loc, false);
204
              putc (' ', print.outf);
205
            }
206
          else if (print.source->flags & PREV_WHITE
207
                   || (print.prev
208
                       && cpp_avoid_paste (pfile, print.prev, token))
209
                   || (print.prev == NULL && token->type == CPP_HASH))
210
            putc (' ', print.outf);
211
        }
212
      else if (token->flags & PREV_WHITE)
213
        {
214
          const struct line_map *map
215
            = linemap_lookup (line_table, loc);
216
          int src_line = SOURCE_LINE (map, loc);
217
 
218
          if (src_line != print.src_line
219
              && do_line_adjustments
220
              && !in_pragma)
221
            do_line_change (pfile, token, loc, false);
222
          putc (' ', print.outf);
223
        }
224
 
225
      avoid_paste = false;
226
      print.source = NULL;
227
      print.prev = token;
228
      if (token->type == CPP_PRAGMA)
229
        {
230
          const char *space;
231
          const char *name;
232
 
233
          maybe_print_line (token->src_loc);
234
          fputs ("#pragma ", print.outf);
235
          c_pp_lookup_pragma (token->val.pragma, &space, &name);
236
          if (space)
237
            fprintf (print.outf, "%s %s", space, name);
238
          else
239
            fprintf (print.outf, "%s", name);
240
          print.printed = 1;
241
          in_pragma = true;
242
        }
243
      else if (token->type == CPP_PRAGMA_EOL)
244
        {
245
          maybe_print_line (token->src_loc);
246
          in_pragma = false;
247
        }
248
      else
249
        cpp_output_token (token, print.outf);
250
 
251
      if (token->type == CPP_COMMENT)
252
        account_for_newlines (token->val.str.text, token->val.str.len);
253
    }
254
}
255
 
256
static void
257
print_lines_directives_only (int lines, const void *buf, size_t size)
258
{
259
  print.src_line += lines;
260
  fwrite (buf, 1, size, print.outf);
261
}
262
 
263
/* Writes out the preprocessed file, handling spacing and paste
264
   avoidance issues.  */
265
static void
266
scan_translation_unit_directives_only (cpp_reader *pfile)
267
{
268
  struct _cpp_dir_only_callbacks cb;
269
 
270
  cb.print_lines = print_lines_directives_only;
271
  cb.maybe_print_line = maybe_print_line;
272
 
273
  _cpp_preprocess_dir_only (pfile, &cb);
274
}
275
 
276
/* Adjust print.src_line for newlines embedded in output.  */
277
static void
278
account_for_newlines (const unsigned char *str, size_t len)
279
{
280
  while (len--)
281
    if (*str++ == '\n')
282
      print.src_line++;
283
}
284
 
285
/* Writes out a traditionally preprocessed file.  */
286
static void
287
scan_translation_unit_trad (cpp_reader *pfile)
288
{
289
  while (_cpp_read_logical_line_trad (pfile))
290
    {
291
      size_t len = pfile->out.cur - pfile->out.base;
292
      maybe_print_line (pfile->out.first_line);
293
      fwrite (pfile->out.base, 1, len, print.outf);
294
      print.printed = 1;
295
      if (!CPP_OPTION (pfile, discard_comments))
296
        account_for_newlines (pfile->out.base, len);
297
    }
298
}
299
 
300
/* If the token read on logical line LINE needs to be output on a
301
   different line to the current one, output the required newlines or
302
   a line marker, and return 1.  Otherwise return 0.  */
303
static void
304
maybe_print_line (source_location src_loc)
305
{
306
  const struct line_map *map = linemap_lookup (line_table, src_loc);
307
  int src_line = SOURCE_LINE (map, src_loc);
308
  /* End the previous line of text.  */
309
  if (print.printed)
310
    {
311
      putc ('\n', print.outf);
312
      print.src_line++;
313
      print.printed = 0;
314
    }
315
 
316
  if (src_line >= print.src_line && src_line < print.src_line + 8)
317
    {
318
      while (src_line > print.src_line)
319
        {
320
          putc ('\n', print.outf);
321
          print.src_line++;
322
        }
323
    }
324
  else
325
    print_line (src_loc, "");
326
}
327
 
328
/* Output a line marker for logical line LINE.  Special flags are "1"
329
   or "2" indicating entering or leaving a file.  */
330
static void
331
print_line (source_location src_loc, const char *special_flags)
332
{
333
  /* End any previous line of text.  */
334
  if (print.printed)
335
    putc ('\n', print.outf);
336
  print.printed = 0;
337
 
338
  if (!flag_no_line_commands)
339
    {
340
      const struct line_map *map = linemap_lookup (line_table, src_loc);
341
 
342
      size_t to_file_len = strlen (map->to_file);
343
      unsigned char *to_file_quoted =
344
         (unsigned char *) alloca (to_file_len * 4 + 1);
345
      unsigned char *p;
346
 
347
      print.src_line = SOURCE_LINE (map, src_loc);
348
 
349
      /* cpp_quote_string does not nul-terminate, so we have to do it
350
         ourselves.  */
351
      p = cpp_quote_string (to_file_quoted,
352
                            (const unsigned char *) map->to_file, to_file_len);
353
      *p = '\0';
354
      fprintf (print.outf, "# %u \"%s\"%s",
355
               print.src_line == 0 ? 1 : print.src_line,
356
               to_file_quoted, special_flags);
357
 
358
      if (map->sysp == 2)
359
        fputs (" 3 4", print.outf);
360
      else if (map->sysp == 1)
361
        fputs (" 3", print.outf);
362
 
363
      putc ('\n', print.outf);
364
    }
365
}
366
 
367
/* Helper function for cb_line_change and scan_translation_unit.  */
368
static void
369
do_line_change (cpp_reader *pfile, const cpp_token *token,
370
                source_location src_loc, int parsing_args)
371
{
372
  if (define_queue || undef_queue)
373
    dump_queued_macros (pfile);
374
 
375
  if (token->type == CPP_EOF || parsing_args)
376
    return;
377
 
378
  maybe_print_line (src_loc);
379
  print.prev = 0;
380
  print.source = 0;
381
 
382
  /* Supply enough spaces to put this token in its original column,
383
     one space per column greater than 2, since scan_translation_unit
384
     will provide a space if PREV_WHITE.  Don't bother trying to
385
     reconstruct tabs; we can't get it right in general, and nothing
386
     ought to care.  Some things do care; the fault lies with them.  */
387
  if (!CPP_OPTION (pfile, traditional))
388
    {
389
      const struct line_map *map = linemap_lookup (line_table, src_loc);
390
      int spaces = SOURCE_COLUMN (map, src_loc) - 2;
391
      print.printed = 1;
392
 
393
      while (-- spaces >= 0)
394
        putc (' ', print.outf);
395
    }
396
}
397
 
398
/* Called when a line of output is started.  TOKEN is the first token
399
   of the line, and at end of file will be CPP_EOF.  */
400
static void
401
cb_line_change (cpp_reader *pfile, const cpp_token *token,
402
                int parsing_args)
403
{
404
  do_line_change (pfile, token, token->src_loc, parsing_args);
405
}
406
 
407
static void
408
cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
409
          const cpp_string *str)
410
{
411
  maybe_print_line (line);
412
  fprintf (print.outf, "#ident %s\n", str->text);
413
  print.src_line++;
414
}
415
 
416
static void
417
cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node)
418
{
419
  maybe_print_line (line);
420
  fputs ("#define ", print.outf);
421
 
422
  /* 'D' is whole definition; 'N' is name only.  */
423
  if (flag_dump_macros == 'D')
424
    fputs ((const char *) cpp_macro_definition (pfile, node),
425
           print.outf);
426
  else
427
    fputs ((const char *) NODE_NAME (node), print.outf);
428
 
429
  putc ('\n', print.outf);
430
  if (linemap_lookup (line_table, line)->to_line != 0)
431
    print.src_line++;
432
}
433
 
434
static void
435
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
436
          cpp_hashnode *node)
437
{
438
  maybe_print_line (line);
439
  fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
440
  print.src_line++;
441
}
442
 
443
static void
444
cb_used_define (cpp_reader *pfile, source_location line ATTRIBUTE_UNUSED,
445
                cpp_hashnode *node)
446
{
447
  macro_queue *q;
448
  if (node->flags & NODE_BUILTIN)
449
    return;
450
  q = XNEW (macro_queue);
451
  q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node));
452
  q->next = define_queue;
453
  define_queue = q;
454
}
455
 
456
static void
457
cb_used_undef (cpp_reader *pfile ATTRIBUTE_UNUSED,
458
               source_location line ATTRIBUTE_UNUSED,
459
               cpp_hashnode *node)
460
{
461
  macro_queue *q;
462
  q = XNEW (macro_queue);
463
  q->macro = xstrdup ((const char *) NODE_NAME (node));
464
  q->next = undef_queue;
465
  undef_queue = q;
466
}
467
 
468
static void
469
dump_queued_macros (cpp_reader *pfile ATTRIBUTE_UNUSED)
470
{
471
  macro_queue *q;
472
 
473
  /* End the previous line of text.  */
474
  if (print.printed)
475
    {
476
      putc ('\n', print.outf);
477
      print.src_line++;
478
      print.printed = 0;
479
    }
480
 
481
  for (q = define_queue; q;)
482
    {
483
      macro_queue *oq;
484
      fputs ("#define ", print.outf);
485
      fputs (q->macro, print.outf);
486
      putc ('\n', print.outf);
487
      print.src_line++;
488
      oq = q;
489
      q = q->next;
490
      free (oq->macro);
491
      free (oq);
492
    }
493
  define_queue = NULL;
494
  for (q = undef_queue; q;)
495
    {
496
      macro_queue *oq;
497
      fprintf (print.outf, "#undef %s\n", q->macro);
498
      print.src_line++;
499
      oq = q;
500
      q = q->next;
501
      free (oq->macro);
502
      free (oq);
503
    }
504
  undef_queue = NULL;
505
}
506
 
507
static void
508
cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
509
            const unsigned char *dir, const char *header, int angle_brackets,
510
            const cpp_token **comments)
511
{
512
  maybe_print_line (line);
513
  if (angle_brackets)
514
    fprintf (print.outf, "#%s <%s>", dir, header);
515
  else
516
    fprintf (print.outf, "#%s \"%s\"", dir, header);
517
 
518
  if (comments != NULL)
519
    {
520
      while (*comments != NULL)
521
        {
522
          if ((*comments)->flags & PREV_WHITE)
523
            putc (' ', print.outf);
524
          cpp_output_token (*comments, print.outf);
525
          ++comments;
526
        }
527
    }
528
 
529
  putc ('\n', print.outf);
530
  print.src_line++;
531
}
532
 
533
/* Callback called when -fworking-director and -E to emit working
534
   directory in cpp output file.  */
535
 
536
void
537
pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
538
{
539
  size_t to_file_len = strlen (dir);
540
  unsigned char *to_file_quoted =
541
     (unsigned char *) alloca (to_file_len * 4 + 1);
542
  unsigned char *p;
543
 
544
  /* cpp_quote_string does not nul-terminate, so we have to do it ourselves.  */
545
  p = cpp_quote_string (to_file_quoted, (const unsigned char *) dir, to_file_len);
546
  *p = '\0';
547
  fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
548
}
549
 
550
/* The file name, line number or system header flags have changed, as
551
   described in MAP.  */
552
 
553
void
554
pp_file_change (const struct line_map *map)
555
{
556
  const char *flags = "";
557
 
558
  if (flag_no_line_commands)
559
    return;
560
 
561
  if (map != NULL)
562
    {
563
      input_location = map->start_location;
564
      if (print.first_time)
565
        {
566
          /* Avoid printing foo.i when the main file is foo.c.  */
567
          if (!cpp_get_options (parse_in)->preprocessed)
568
            print_line (map->start_location, flags);
569
          print.first_time = 0;
570
        }
571
      else
572
        {
573
          /* Bring current file to correct line when entering a new file.  */
574
          if (map->reason == LC_ENTER)
575
            {
576
              const struct line_map *from = INCLUDED_FROM (line_table, map);
577
              maybe_print_line (LAST_SOURCE_LINE_LOCATION (from));
578
            }
579
          if (map->reason == LC_ENTER)
580
            flags = " 1";
581
          else if (map->reason == LC_LEAVE)
582
            flags = " 2";
583
          print_line (map->start_location, flags);
584
        }
585
    }
586
}
587
 
588
/* Copy a #pragma directive to the preprocessed output.  */
589
static void
590
cb_def_pragma (cpp_reader *pfile, source_location line)
591
{
592
  maybe_print_line (line);
593
  fputs ("#pragma ", print.outf);
594
  cpp_output_line (pfile, print.outf);
595
  print.src_line++;
596
}
597
 
598
/* Dump out the hash table.  */
599
static int
600
dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
601
{
602
  if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
603
    {
604
      fputs ("#define ", print.outf);
605
      fputs ((const char *) cpp_macro_definition (pfile, node),
606
             print.outf);
607
      putc ('\n', print.outf);
608
      print.src_line++;
609
    }
610
 
611
  return 1;
612
}
613
 
614
/* Load in the PCH file NAME, open on FD.  It was originally searched for
615
   by ORIG_NAME.  Also, print out a #include command so that the PCH
616
   file can be loaded when the preprocessed output is compiled.  */
617
 
618
static void
619
cb_read_pch (cpp_reader *pfile, const char *name,
620
             int fd, const char *orig_name ATTRIBUTE_UNUSED)
621
{
622
  c_common_read_pch (pfile, name, fd, orig_name);
623
 
624
  fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name);
625
  print.src_line++;
626
}

powered by: WebSVN 2.1.0

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