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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [c-family/] [c-ppoutput.c] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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