OSDN Git Service

PR c++/43680
[pf3gnuchains/gcc-fork.git] / libcpp / directives-only.c
1 /* CPP Library - directive only preprocessing for distributed compilation.
2    Copyright (C) 2007, 2009
3    Free Software Foundation, Inc.
4    Contributed by Ollie Wild <aaw@google.com>.
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 "cpplib.h"
23 #include "internal.h"
24
25 /* DO (Directive only) flags. */
26 #define DO_BOL           (1 << 0) /* At the beginning of a logical line. */
27 #define DO_STRING        (1 << 1) /* In a string constant. */
28 #define DO_CHAR          (1 << 2) /* In a character constant. */
29 #define DO_BLOCK_COMMENT (1 << 3) /* In a block comment. */
30 #define DO_LINE_COMMENT  (1 << 4) /* In a single line "//-style" comment. */
31
32 #define DO_LINE_SPECIAL (DO_STRING | DO_CHAR | DO_LINE_COMMENT)
33 #define DO_SPECIAL      (DO_LINE_SPECIAL | DO_BLOCK_COMMENT)
34
35 /* Writes out the preprocessed file, handling spacing and paste
36    avoidance issues.  */
37 void
38 _cpp_preprocess_dir_only (cpp_reader *pfile,
39                           const struct _cpp_dir_only_callbacks *cb)
40 {
41   struct cpp_buffer *buffer;
42   const unsigned char *cur, *base, *next_line, *rlimit;
43   cppchar_t c, last_c;
44   unsigned flags;
45   linenum_type lines;
46   int col;
47   source_location loc;
48
49  restart:
50   /* Buffer initialization ala _cpp_clean_line(). */
51   buffer = pfile->buffer;
52   buffer->cur_note = buffer->notes_used = 0;
53   buffer->cur = buffer->line_base = buffer->next_line;
54   buffer->need_line = false;
55
56   /* This isn't really needed.  It prevents a compiler warning, though. */
57   loc = pfile->line_table->highest_line;
58
59   /* Scan initialization. */
60   next_line = cur = base = buffer->cur;
61   rlimit = buffer->rlimit;
62   flags = DO_BOL;
63   lines = 0;
64   col = 1;
65
66   for (last_c = '\n', c = *cur; cur < rlimit; last_c = c, c = *++cur, ++col)
67     {
68       /* Skip over escaped newlines. */
69       if (__builtin_expect (c == '\\', false))
70         {
71           const unsigned char *tmp = cur + 1;
72
73           while (is_nvspace (*tmp) && tmp < rlimit)
74             tmp++;
75           if (*tmp == '\r')
76             tmp++;
77           if (*tmp == '\n' && tmp < rlimit)
78             {
79               CPP_INCREMENT_LINE (pfile, 0);
80               lines++;
81               col = 0;
82               cur = tmp;
83               c = last_c;
84               continue;
85             }
86         }
87
88       if (__builtin_expect (last_c == '#', false) && !(flags & DO_SPECIAL))
89         {
90           if (c != '#' && (flags & DO_BOL))
91           {
92             struct line_maps *line_table;
93
94             if (!pfile->state.skipping && next_line != base)
95               cb->print_lines (lines, base, next_line - base);
96
97             /* Prep things for directive handling. */
98             buffer->next_line = cur;
99             buffer->need_line = true;
100             _cpp_get_fresh_line (pfile);
101
102             /* Ensure proper column numbering for generated error messages. */
103             buffer->line_base -= col - 1;
104
105             _cpp_handle_directive (pfile, 0 /* ignore indented */);
106
107             /* Sanitize the line settings.  Duplicate #include's can mess
108                things up. */
109             line_table = pfile->line_table;
110             line_table->highest_location = line_table->highest_line;
111
112             /* The if block prevents us from outputing line information when
113                the file ends with a directive and no newline.  Note that we
114                must use pfile->buffer, not buffer. */
115             if (pfile->buffer->next_line < pfile->buffer->rlimit)
116               cb->maybe_print_line (pfile->line_table->highest_line);
117
118             goto restart;
119           }
120
121           flags &= ~DO_BOL;
122           pfile->mi_valid = false;
123         }
124       else if (__builtin_expect (last_c == '/', false) \
125                && !(flags & DO_SPECIAL) && c != '*' && c != '/')
126         {
127           /* If a previous slash is not starting a block comment, clear the
128              DO_BOL flag.  */
129           flags &= ~DO_BOL;
130           pfile->mi_valid = false;
131         }
132
133       switch (c)
134         {
135         case '/':
136           if ((flags & DO_BLOCK_COMMENT) && last_c == '*')
137             {
138               flags &= ~DO_BLOCK_COMMENT;
139               c = 0;
140             }
141           else if (!(flags & DO_SPECIAL) && last_c == '/')
142             flags |= DO_LINE_COMMENT;
143           else if (!(flags & DO_SPECIAL))
144             /* Mark the position for possible error reporting. */
145             LINEMAP_POSITION_FOR_COLUMN (loc, pfile->line_table, col);
146
147           break;
148
149         case '*':
150           if (!(flags & DO_SPECIAL))
151             {
152               if (last_c == '/')
153                 flags |= DO_BLOCK_COMMENT;
154               else
155                 {
156                   flags &= ~DO_BOL;
157                   pfile->mi_valid = false;
158                 }
159             }
160
161           break;
162
163         case '\'':
164         case '"':
165           {
166             unsigned state = (c == '"') ? DO_STRING : DO_CHAR;
167
168             if (!(flags & DO_SPECIAL))
169               {
170                 flags |= state;
171                 flags &= ~DO_BOL;
172                 pfile->mi_valid = false;
173               }
174             else if ((flags & state) && last_c != '\\')
175               flags &= ~state;
176
177             break;
178           }
179
180         case '\\':
181           {
182             if ((flags & (DO_STRING | DO_CHAR)) && last_c == '\\')
183               c = 0;
184
185             if (!(flags & DO_SPECIAL))
186               {
187                 flags &= ~DO_BOL;
188                 pfile->mi_valid = false;
189               }
190
191             break;
192           }
193
194         case '\n':
195           CPP_INCREMENT_LINE (pfile, 0);
196           lines++;
197           col = 0;
198           flags &= ~DO_LINE_SPECIAL;
199           if (!(flags & DO_SPECIAL))
200             flags |= DO_BOL;
201           break;
202
203         case '#':
204           next_line = cur;
205           /* Don't update DO_BOL yet. */
206           break;
207
208         case ' ': case '\t': case '\f': case '\v': case '\0':
209           break;
210
211         default:
212           if (!(flags & DO_SPECIAL))
213             {
214               flags &= ~DO_BOL;
215               pfile->mi_valid = false;
216             }
217           break;
218         }
219     }
220
221   if (flags & DO_BLOCK_COMMENT)
222     cpp_error_with_line (pfile, CPP_DL_ERROR, loc, 0, "unterminated comment");
223
224   if (!pfile->state.skipping && cur != base)
225     {
226       /* If the file was not newline terminated, add rlimit, which is
227          guaranteed to point to a newline, to the end of our range.  */
228       if (cur[-1] != '\n')
229         {
230           cur++;
231           CPP_INCREMENT_LINE (pfile, 0);
232           lines++;
233         }
234
235       cb->print_lines (lines, base, cur - base);
236     }
237
238   _cpp_pop_buffer (pfile);
239   if (pfile->buffer)
240     goto restart;
241 }