Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – /trunk/src/producers/common/parse/parse.c – Rev 2 and 7

Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997, 1998
32
    		 Crown Copyright (c) 1997, 1998
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 57... Line 87...
57
#include "redeclare.h"
87
#include "redeclare.h"
58
#include "symbols.h"
88
#include "symbols.h"
59
#include "syntax.h"
89
#include "syntax.h"
60
#include "template.h"
90
#include "template.h"
61
#include "tokdef.h"
91
#include "tokdef.h"
62
 
92
 
63
 
93
 
64
/*
94
/*
65
    CURRENT LEXICAL TOKEN NUMBERS
95
    CURRENT LEXICAL TOKEN NUMBERS
66
 
96
 
67
    These variables are used by the parser to hold the current and former
97
    These variables are used by the parser to hold the current and former
68
    lexical token numbers.
98
    lexical token numbers.
69
*/
99
*/
70
 
100
 
71
int crt_lex_token = lex_unknown ;
101
int crt_lex_token = lex_unknown;
72
int last_lex_token = lex_unknown ;
102
int last_lex_token = lex_unknown;
73
int saved_lex_token = lex_unknown ;
103
int saved_lex_token = lex_unknown;
74
static int have_template = 0 ;
104
static int have_template = 0;
75
int have_syntax_error = 0 ;
105
int have_syntax_error = 0;
76
 
106
 
77
 
107
 
78
/*
108
/*
79
    LIST OF ACTIVE LEXICAL TOKENS
109
    LIST OF ACTIVE LEXICAL TOKENS
80
 
110
 
Line 87... Line 117...
87
    tokens to the end of the list.  The list is periodically garbage
117
    tokens to the end of the list.  The list is periodically garbage
88
    collected by setting first_token to crt_token and freeing all the
118
    collected by setting first_token to crt_token and freeing all the
89
    tokens from the old first_token.
119
    tokens from the old first_token.
90
*/
120
*/
91
 
121
 
92
PPTOKEN *crt_token = NULL ;
122
PPTOKEN *crt_token = NULL;
93
static PPTOKEN *first_token = NULL ;
123
static PPTOKEN *first_token = NULL;
94
NAMESPACE crt_lookup = NULL_nspace ;
124
NAMESPACE crt_lookup = NULL_nspace;
95
static unsigned long crt_lookup_depth = 0 ;
125
static unsigned long crt_lookup_depth = 0;
96
static OPTIONS *prev_opts = NULL ;
126
static OPTIONS *prev_opts = NULL;
97
static STACK ( int ) token_stack = NULL_stack ( int ) ;
127
static STACK(int)token_stack = NULL_stack(int);
98
static STACK ( PPTOKEN_P ) parser_stack = NULL_stack ( PPTOKEN_P ) ;
128
static STACK(PPTOKEN_P)parser_stack = NULL_stack(PPTOKEN_P);
99
static STACK ( NAMESPACE ) lookup_stack = NULL_stack ( NAMESPACE ) ;
129
static STACK(NAMESPACE)lookup_stack = NULL_stack(NAMESPACE);
100
 
130
 
101
 
131
 
102
/*
132
/*
103
    INITIALISE ACTIVE TOKEN LIST
133
    INITIALISE ACTIVE TOKEN LIST
104
 
134
 
105
    This routine initialises a new list of active lexical tokens with the
135
    This routine initialises a new list of active lexical tokens with the
106
    value toks by pushing the old values of first_token and crt_token onto
136
    value toks by pushing the old values of first_token and crt_token onto
107
    the stack parser_stack and setting them to point to a new dummy token
137
    the stack parser_stack and setting them to point to a new dummy token
108
    whose next field is toks.
138
    whose next field is toks.
109
*/
139
*/
110
 
140
 
111
void init_parser
141
void
112
    PROTO_N ( ( toks ) )
-
 
113
    PROTO_T ( PPTOKEN *toks )
142
init_parser(PPTOKEN *toks)
114
{
143
{
115
    PPTOKEN *q ;
144
	PPTOKEN *q;
116
    PUSH_int ( crt_lex_token, token_stack ) ;
145
	PUSH_int(crt_lex_token, token_stack);
117
    PUSH_int ( last_lex_token, token_stack ) ;
146
	PUSH_int(last_lex_token, token_stack);
118
    PUSH_int ( saved_lex_token, token_stack ) ;
147
	PUSH_int(saved_lex_token, token_stack);
119
    PUSH_nspace ( crt_lookup, lookup_stack ) ;
148
	PUSH_nspace(crt_lookup, lookup_stack);
120
    PUSH_pptok ( first_token, parser_stack ) ;
149
	PUSH_pptok(first_token, parser_stack);
121
    PUSH_pptok ( crt_token, parser_stack ) ;
150
	PUSH_pptok(crt_token, parser_stack);
122
    q = new_pptok () ;
151
	q = new_pptok();
123
    q->tok = lex_ignore_token ;
152
	q->tok = lex_ignore_token;
124
    q->pp_space = 0 ;
153
	q->pp_space = 0;
125
    q->next = toks ;
154
	q->next = toks;
126
    first_token = q ;
155
	first_token = q;
127
    crt_token = q ;
156
	crt_token = q;
128
    crt_lookup = NULL_nspace ;
157
	crt_lookup = NULL_nspace;
129
    crt_lookup_depth = 0 ;
158
	crt_lookup_depth = 0;
130
    crt_lex_token = lex_unknown ;
159
	crt_lex_token = lex_unknown;
131
    last_lex_token = lex_unknown ;
160
	last_lex_token = lex_unknown;
132
    saved_lex_token = lex_unknown ;
161
	saved_lex_token = lex_unknown;
133
    return ;
162
	return;
134
}
163
}
135
 
164
 
136
 
165
 
137
/*
166
/*
138
    RESTORE ACTIVE TOKEN LIST
167
    RESTORE ACTIVE TOKEN LIST
139
 
168
 
140
    This routine restores the previous list of active lexical tokens by
169
    This routine restores the previous list of active lexical tokens by
141
    popping the values of first_token and crt_token from the stack.  The
170
    popping the values of first_token and crt_token from the stack.  The
142
    previous list is returned.
171
    previous list is returned.
143
*/
172
*/
144
 
173
 
145
PPTOKEN *restore_parser
174
PPTOKEN *
146
    PROTO_Z ()
175
restore_parser(void)
147
{
176
{
148
    PPTOKEN *p = first_token ;
177
	PPTOKEN *p = first_token;
149
    POP_pptok ( crt_token, parser_stack ) ;
178
	POP_pptok(crt_token, parser_stack);
150
    POP_pptok ( first_token, parser_stack ) ;
179
	POP_pptok(first_token, parser_stack);
151
    POP_nspace ( crt_lookup, lookup_stack ) ;
180
	POP_nspace(crt_lookup, lookup_stack);
152
    POP_int ( last_lex_token, token_stack ) ;
181
	POP_int(last_lex_token, token_stack);
153
    POP_int ( saved_lex_token, token_stack ) ;
182
	POP_int(saved_lex_token, token_stack);
154
    POP_int ( crt_lex_token, token_stack ) ;
183
	POP_int(crt_lex_token, token_stack);
155
    crt_lookup_depth = 0 ;
184
	crt_lookup_depth = 0;
156
    ASSERT ( first_token != NULL ) ;
185
	ASSERT(first_token != NULL);
157
    return ( p ) ;
186
	return(p);
158
}
187
}
159
 
188
 
160
 
189
 
161
/*
190
/*
162
    REMOVE A LIST OF TOKENS FROM THE CURRENT LIST
191
    REMOVE A LIST OF TOKENS FROM THE CURRENT LIST
163
 
192
 
164
    This routine removes the tokens from p to q inclusive from the current
193
    This routine removes the tokens from p to q inclusive from the current
165
    list.  crt_token must not be included within this range.
194
    list.  crt_token must not be included within this range.
166
*/
195
*/
167
 
196
 
168
void snip_tokens
197
void
169
    PROTO_N ( ( p, q ) )
-
 
170
    PROTO_T ( PPTOKEN *p X PPTOKEN *q )
198
snip_tokens(PPTOKEN *p, PPTOKEN *q)
171
{
199
{
172
    PPTOKEN *r = first_token ;
200
	PPTOKEN *r = first_token;
173
    if ( r == p ) {
201
	if (r == p) {
174
	first_token = q->next ;
202
		first_token = q->next;
175
    } else {
203
	} else {
176
	while ( r->next != p ) r = r->next ;
204
		while (r->next != p) {
-
 
205
			r = r->next;
-
 
206
		}
177
	r->next = q->next ;
207
		r->next = q->next;
178
    }
208
	}
179
    r = new_pptok () ;
209
	r = new_pptok();
180
    r->tok = lex_eof ;
210
	r->tok = lex_eof;
181
    q->next = r ;
211
	q->next = r;
182
    r->next = NULL ;
212
	r->next = NULL;
183
    return ;
213
	return;
184
}
214
}
185
 
215
 
186
 
216
 
187
/*
217
/*
188
    PATCH A NUMBER OF TOKENS INTO THE CURRENT LIST
218
    PATCH A NUMBER OF TOKENS INTO THE CURRENT LIST
189
 
219
 
190
    This routine patches n tokens into the current list immediately after
220
    This routine patches n tokens into the current list immediately after
191
    crt_token, returning the first token.  This is used by the preprocessor
221
    crt_token, returning the first token.  This is used by the preprocessor
192
    to pass more than one token to the parser.
222
    to pass more than one token to the parser.
193
*/
223
*/
194
 
224
 
195
PPTOKEN *patch_tokens
225
PPTOKEN *
196
    PROTO_N ( ( n ) )
-
 
197
    PROTO_T ( int n )
226
patch_tokens(int n)
198
{
227
{
199
    while ( n ) {
228
	while (n) {
200
	PPTOKEN *p = new_pptok () ;
229
		PPTOKEN *p = new_pptok();
201
	p->tok = lex_ignore_token ;
230
		p->tok = lex_ignore_token;
202
	p->next = crt_token->next ;
231
		p->next = crt_token->next;
203
	p->pp_space = WHITE_SPACE ;
232
		p->pp_space = WHITE_SPACE;
204
	crt_token->next = p ;
233
		crt_token->next = p;
205
	n-- ;
234
		n--;
206
    }
235
	}
207
    return ( crt_token->next ) ;
236
	return(crt_token->next);
208
}
237
}
209
 
238
 
210
 
239
 
211
/*
240
/*
212
    CURRENT PARSER STATE DEPTH
241
    CURRENT PARSER STATE DEPTH
213
 
242
 
214
    This variable is used to record the current depth of saved parser
243
    This variable is used to record the current depth of saved parser
215
    states.
244
    states.
216
*/
245
*/
217
 
246
 
218
int crt_state_depth = 0 ;
247
int crt_state_depth = 0;
219
 
248
 
220
 
249
 
221
/*
250
/*
222
    SAVE PARSER STATE
251
    SAVE PARSER STATE
223
 
252
 
224
    This routine saves the current parser state into s, it also clears the
253
    This routine saves the current parser state into s, it also clears the
225
    syntax error flag.  col is true if column numbers are to be considered
254
    syntax error flag.  col is true if column numbers are to be considered
226
    during the parsing.
255
    during the parsing.
227
*/
256
*/
228
 
257
 
229
void save_state
258
void
230
    PROTO_N ( ( s, col ) )
-
 
231
    PROTO_T ( PARSE_STATE *s X int col )
259
save_state(PARSE_STATE *s, int col)
232
{
260
{
233
    /* Save current location */
261
	/* Save current location */
234
    s->loc = crt_loc ;
262
	s->loc = crt_loc;
235
 
263
 
236
    /* Save current namespace */
264
	/* Save current namespace */
237
    s->nspace [0] = crt_namespace ;
265
	s->nspace[0] = crt_namespace;
238
    s->nspace [1] = templ_namespace ;
266
	s->nspace[1] = templ_namespace;
239
    s->nstack [0] = namespace_stack ;
267
	s->nstack[0] = namespace_stack;
240
    s->nstack [1] = crt_nspace_stack ;
268
	s->nstack[1] = crt_nspace_stack;
241
    s->nstack [2] = local_nspace_stack ;
269
	s->nstack[2] = local_nspace_stack;
242
 
270
 
243
    /* Save flag values */
271
	/* Save flag values */
244
    s->flag [0] = in_class_defn ;
272
	s->flag[0] = in_class_defn;
245
    s->flag [1] = in_function_defn ;
273
	s->flag[1] = in_function_defn;
246
    s->flag [2] = really_in_class_defn ;
274
	s->flag[2] = really_in_class_defn;
247
    s->flag [3] = really_in_function_defn ;
275
	s->flag[3] = really_in_function_defn;
248
    s->flag [4] = in_declaration ;
276
	s->flag[4] = in_declaration;
249
    s->flag [5] = in_template_decl ;
277
	s->flag[5] = in_template_decl;
250
    s->flag [6] = have_syntax_error ;
278
	s->flag[6] = have_syntax_error;
251
    s->flag [7] = cache_lookup ;
279
	s->flag[7] = cache_lookup;
252
    s->flag [8] = crt_col_changed ;
280
	s->flag[8] = crt_col_changed;
253
    have_syntax_error = 0 ;
281
	have_syntax_error = 0;
254
    cache_lookup = old_cache_lookup ;
282
	cache_lookup = old_cache_lookup;
255
    crt_col_changed = col ;
283
	crt_col_changed = col;
256
 
284
 
257
    /* Save declaration specifiers */
285
	/* Save declaration specifiers */
258
    s->dspec [0] = crt_access ;
286
	s->dspec[0] = crt_access;
259
    s->dspec [1] = crt_linkage ;
287
	s->dspec[1] = crt_linkage;
260
    crt_access = dspec_public ;
288
	crt_access = dspec_public;
261
    crt_state_depth++ ;
289
	crt_state_depth++;
262
    bad_crt_loc++ ;
290
	bad_crt_loc++;
263
    return ;
291
	return;
264
}
292
}
265
 
293
 
266
 
294
 
267
/*
295
/*
268
    RESTORE PARSER STATE
296
    RESTORE PARSER STATE
269
 
297
 
Line 271... Line 299...
271
    Note that there is some attempt at recovering the state following
299
    Note that there is some attempt at recovering the state following
272
    some intervening error, particularly with regard to resetting the
300
    some intervening error, particularly with regard to resetting the
273
    current namespace.
301
    current namespace.
274
*/
302
*/
275
 
303
 
276
void restore_state
304
void
277
    PROTO_N ( ( s ) )
-
 
278
    PROTO_T ( PARSE_STATE *s )
305
restore_state(PARSE_STATE *s)
279
{
306
{
280
    /* Restore current namespace */
307
	/* Restore current namespace */
281
    NAMESPACE ns = s->nspace [0] ;
308
	NAMESPACE ns = s->nspace[0];
282
    NAMESPACE cns = crt_namespace ;
309
	NAMESPACE cns = crt_namespace;
283
    LIST ( NAMESPACE ) pns = LIST_stack ( s->nstack [0] ) ;
310
	LIST(NAMESPACE)pns = LIST_stack(s->nstack[0]);
284
    cache_lookup = old_cache_lookup ;
311
	cache_lookup = old_cache_lookup;
285
    while ( !EQ_list ( pns, LIST_stack ( namespace_stack ) ) ) {
312
	while (!EQ_list(pns, LIST_stack(namespace_stack))) {
286
	/* Reset name look-up stack */
313
		/* Reset name look-up stack */
287
	remove_namespace () ;
314
		remove_namespace();
288
    }
315
	}
289
    crt_namespace = ns ;
316
	crt_namespace = ns;
290
    crt_nspace_stack = s->nstack [1] ;
317
	crt_nspace_stack = s->nstack[1];
291
    local_nspace_stack = s->nstack [2] ;
318
	local_nspace_stack = s->nstack[2];
292
    if ( !EQ_nspace ( ns, cns ) ) {
319
	if (!EQ_nspace(ns, cns)) {
293
	/* Recalculate namespaces if necessary */
320
		/* Recalculate namespaces if necessary */
294
	update_namespace () ;
321
		update_namespace();
295
    }
322
	}
296
    templ_namespace = s->nspace [1] ;
323
	templ_namespace = s->nspace[1];
297
 
324
 
298
    /* Restore current location */
325
	/* Restore current location */
299
    crt_loc = s->loc ;
326
	crt_loc = s->loc;
300
    crt_line_changed = 1 ;
327
	crt_line_changed = 1;
301
    crt_file_changed = 1 ;
328
	crt_file_changed = 1;
302
 
329
 
303
    /* Restore flag values */
330
	/* Restore flag values */
304
    in_class_defn = s->flag [0] ;
331
	in_class_defn = s->flag[0];
305
    in_function_defn = s->flag [1] ;
332
	in_function_defn = s->flag[1];
306
    really_in_class_defn = s->flag [2] ;
333
	really_in_class_defn = s->flag[2];
307
    really_in_function_defn = s->flag [3] ;
334
	really_in_function_defn = s->flag[3];
308
    in_declaration = s->flag [4] ;
335
	in_declaration = s->flag[4];
309
    in_template_decl = s->flag [5] ;
336
	in_template_decl = s->flag[5];
310
    have_syntax_error = s->flag [6] ;
337
	have_syntax_error = s->flag[6];
311
    cache_lookup = s->flag [7] ;
338
	cache_lookup = s->flag[7];
312
    crt_col_changed = s->flag [8] ;
339
	crt_col_changed = s->flag[8];
313
 
340
 
314
    /* Restore declaration specifiers */
341
	/* Restore declaration specifiers */
315
    crt_access = s->dspec [0] ;
342
	crt_access = s->dspec[0];
316
    crt_linkage = s->dspec [1] ;
343
	crt_linkage = s->dspec[1];
317
    crt_state_depth-- ;
344
	crt_state_depth--;
318
    bad_crt_loc-- ;
345
	bad_crt_loc--;
319
    return ;
346
	return;
320
}
347
}
321
 
348
 
322
 
349
 
323
/*
350
/*
324
    SET UP FILE LOCATION TOKENS
351
    SET UP FILE LOCATION TOKENS
325
 
352
 
326
    This routine sets up preprocessing tokens recording the current file
353
    This routine sets up preprocessing tokens recording the current file
327
    position immediately following p.
354
    position immediately following p.
328
*/
355
*/
329
 
356
 
330
static void make_loc_tokens
357
static void
331
    PROTO_N ( ( p ) )
-
 
332
    PROTO_T ( PPTOKEN *p )
358
make_loc_tokens(PPTOKEN *p)
333
{
359
{
334
    PPTOKEN *q = new_pptok () ;
360
	PPTOKEN *q = new_pptok();
335
    if ( crt_file_changed ) {
361
	if (crt_file_changed) {
336
	q->tok = lex_builtin_Hfile ;
362
		q->tok = lex_builtin_Hfile;
337
	crt_file_changed = 0 ;
363
		crt_file_changed = 0;
338
    } else {
364
	} else {
339
	q->tok = lex_builtin_Hline ;
365
		q->tok = lex_builtin_Hline;
340
    }
366
	}
341
    crt_line_changed = 0 ;
367
	crt_line_changed = 0;
342
    q->pp_space = crt_loc.column ;
368
	q->pp_space = crt_loc.column;
343
    q->pp_data.loc.line = crt_loc.line ;
369
	q->pp_data.loc.line = crt_loc.line;
344
    q->pp_data.loc.posn = crt_loc.posn ;
370
	q->pp_data.loc.posn = crt_loc.posn;
345
    q->next = p->next ;
371
	q->next = p->next;
346
    p->next = q ;
372
	p->next = q;
347
    return ;
373
	return;
348
}
374
}
349
 
375
 
350
 
376
 
351
/*
377
/*
352
    READ FILE LOCATION TOKENS
378
    READ FILE LOCATION TOKENS
353
 
379
 
354
    This routine adjusts the current line number according to the
380
    This routine adjusts the current line number according to the
355
    preprocessing tokens p.
381
    preprocessing tokens p.
356
*/
382
*/
357
 
383
 
358
PPTOKEN *read_loc_tokens
384
PPTOKEN *
359
    PROTO_N ( ( p ) )
-
 
360
    PROTO_T ( PPTOKEN *p )
385
read_loc_tokens(PPTOKEN *p)
361
{
386
{
362
    if ( p ) {
387
	if (p) {
363
	int t = p->tok ;
388
		int t = p->tok;
364
	if ( t == lex_builtin_Hline ) {
389
		if (t == lex_builtin_Hline) {
365
	    /* Set line number */
390
			/* Set line number */
366
	    crt_loc.column = p->pp_space ;
391
			crt_loc.column = p->pp_space;
367
	    crt_loc.line = p->pp_data.loc.line ;
392
			crt_loc.line = p->pp_data.loc.line;
368
	    crt_loc.posn = p->pp_data.loc.posn ;
393
			crt_loc.posn = p->pp_data.loc.posn;
369
	    crt_line_changed = 1 ;
394
			crt_line_changed = 1;
370
	    p = p->next ;
395
			p = p->next;
371
	} else if ( t == lex_builtin_Hfile ) {
396
		} else if (t == lex_builtin_Hfile) {
372
	    /* Set file name */
397
			/* Set file name */
373
	    crt_loc.column = p->pp_space ;
398
			crt_loc.column = p->pp_space;
374
	    crt_loc.line = p->pp_data.loc.line ;
399
			crt_loc.line = p->pp_data.loc.line;
375
	    crt_loc.posn = p->pp_data.loc.posn ;
400
			crt_loc.posn = p->pp_data.loc.posn;
376
	    crt_line_changed = 1 ;
401
			crt_line_changed = 1;
377
	    crt_file_changed = 1 ;
402
			crt_file_changed = 1;
378
	    p = p->next ;
403
			p = p->next;
379
	} else if ( crt_col_changed ) {
404
		} else if (crt_col_changed) {
380
	    unsigned long sp = p->pp_space ;
405
			unsigned long sp = p->pp_space;
381
	    if ( sp ) crt_loc.column = sp ;
406
			if (sp)crt_loc.column = sp;
382
	}
407
		}
383
    }
408
	}
384
    return ( p ) ;
409
	return(p);
385
}
410
}
386
 
411
 
387
 
412
 
388
/*
413
/*
389
    FIND A DESTRUCTOR NAME
414
    FIND A DESTRUCTOR NAME
390
 
415
 
391
    This routine returns the destructor name for the class name cid or the
416
    This routine returns the destructor name for the class name cid or the
392
    null identifier if cid is not a class name.
417
    null identifier if cid is not a class name.
393
*/
418
*/
394
 
419
 
395
#if LANGUAGE_CPP
420
#if LANGUAGE_CPP
396
 
421
 
397
static IDENTIFIER find_destr_id
422
static IDENTIFIER
398
    PROTO_N ( ( cid ) )
-
 
399
    PROTO_T ( IDENTIFIER cid )
423
find_destr_id(IDENTIFIER cid)
400
{
424
{
401
    CLASS_TYPE ct = NULL_ctype ;
425
	CLASS_TYPE ct = NULL_ctype;
402
    if ( IS_id_class_name_etc ( cid ) ) {
426
	if (IS_id_class_name_etc(cid)) {
403
	TYPE t = DEREF_type ( id_class_name_etc_defn ( cid ) ) ;
427
		TYPE t = DEREF_type(id_class_name_etc_defn(cid));
404
	unsigned tag = TAG_type ( t ) ;
428
		unsigned tag = TAG_type(t);
405
	while ( tag == type_templ_tag ) {
429
		while (tag == type_templ_tag) {
406
	    t = DEREF_type ( type_templ_defn ( t ) ) ;
430
			t = DEREF_type(type_templ_defn(t));
407
	    tag = TAG_type ( t ) ;
431
			tag = TAG_type(t);
408
	}
432
		}
409
	if ( tag == type_compound_tag ) {
433
		if (tag == type_compound_tag) {
410
	    ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
434
			ct = DEREF_ctype(type_compound_defn(t));
411
	}
435
		}
412
    } else {
436
	} else {
413
	ct = find_class ( cid ) ;
437
		ct = find_class(cid);
414
    }
438
	}
415
    if ( !IS_NULL_ctype ( ct ) ) {
439
	if (!IS_NULL_ctype(ct)) {
416
	/* Find destructor name */
440
		/* Find destructor name */
417
	IDENTIFIER tid = DEREF_id ( ctype_destr ( ct ) ) ;
441
		IDENTIFIER tid = DEREF_id(ctype_destr(ct));
418
	HASHID nm = DEREF_hashid ( id_name ( tid ) ) ;
442
		HASHID nm = DEREF_hashid(id_name(tid));
419
	tid = DEREF_id ( hashid_id ( nm ) ) ;
443
		tid = DEREF_id(hashid_id(nm));
420
	set_hashid_loc ( tid, cid ) ;
444
		set_hashid_loc(tid, cid);
421
	return ( tid ) ;
445
		return(tid);
422
    }
-
 
423
    return ( NULL_id ) ;
-
 
424
}
-
 
425
 
-
 
426
#endif
-
 
427
 
-
 
428
 
-
 
429
/*
-
 
430
    CHECK A DESTRUCTOR NAME
-
 
431
 
-
 
432
    This routine checks whether the destructor name cid specified using
-
 
433
    nm is legal.  For example, nm might be a typedef-name for the class
-
 
434
    rather than the class itself.  d is the result of the previous call
-
 
435
    to predict_destr.
-
 
436
*/
-
 
437
 
-
 
438
#if LANGUAGE_CPP
-
 
439
 
-
 
440
static void check_destr_id
-
 
441
    PROTO_N ( ( cid, nm, d ) )
-
 
442
    PROTO_T ( IDENTIFIER cid X HASHID nm X int d )
-
 
443
{
-
 
444
    if ( d <= 2 ) {
-
 
445
	HASHID cnm = DEREF_hashid ( id_name ( cid ) ) ;
-
 
446
	IDENTIFIER tid = DEREF_id ( hashid_destr_tid ( cnm ) ) ;
-
 
447
	HASHID tnm = DEREF_hashid ( id_name ( tid ) ) ;
-
 
448
	if ( !EQ_hashid ( tnm, nm ) ) {
-
 
449
	    /* Destructor names don't match */
-
 
450
	    IDENTIFIER id = DEREF_id ( hashid_id ( nm ) ) ;
-
 
451
	    report ( crt_loc, ERR_dcl_typedef_destr ( id, cnm ) ) ;
-
 
452
	}
446
	}
453
    }
-
 
454
    return ;
447
	return(NULL_id);
455
}
448
}
456
 
449
 
457
#endif
450
#endif
458
 
451
 
459
 
452
 
460
/*
453
/*
-
 
454
    CHECK A DESTRUCTOR NAME
-
 
455
 
-
 
456
    This routine checks whether the destructor name cid specified using
-
 
457
    nm is legal.  For example, nm might be a typedef-name for the class
-
 
458
    rather than the class itself.  d is the result of the previous call
-
 
459
    to predict_destr.
-
 
460
*/
-
 
461
 
-
 
462
#if LANGUAGE_CPP
-
 
463
 
-
 
464
static void
-
 
465
check_destr_id(IDENTIFIER cid, HASHID nm, int d)
-
 
466
{
-
 
467
	if (d <= 2) {
-
 
468
		HASHID cnm = DEREF_hashid(id_name(cid));
-
 
469
		IDENTIFIER tid = DEREF_id(hashid_destr_tid(cnm));
-
 
470
		HASHID tnm = DEREF_hashid(id_name(tid));
-
 
471
		if (!EQ_hashid(tnm, nm)) {
-
 
472
			/* Destructor names don't match */
-
 
473
			IDENTIFIER id = DEREF_id(hashid_id(nm));
-
 
474
			report(crt_loc, ERR_dcl_typedef_destr(id, cnm));
-
 
475
		}
-
 
476
	}
-
 
477
	return;
-
 
478
}
-
 
479
 
-
 
480
#endif
-
 
481
 
-
 
482
 
-
 
483
/*
461
    READ AND EXPAND THE NEXT TOKEN
484
    READ AND EXPAND THE NEXT TOKEN
462
 
485
 
463
    This routine reads the next token from the list of all active tokens,
486
    This routine reads the next token from the list of all active tokens,
464
    first_token (see above).  This consists either of advancing crt_token
487
    first_token (see above).  This consists either of advancing crt_token
465
    along this list, or reading and expanding a new token from the input
488
    along this list, or reading and expanding a new token from the input
466
    file, appending the result to the list.  The argument store gives the
489
    file, appending the result to the list.  The argument store gives the
Line 501... Line 524...
501
    already read the following token and resolved it as g.  Thus in these
524
    already read the following token and resolved it as g.  Thus in these
502
    cases it is necessary to insert an explicit rescan of the current token
525
    cases it is necessary to insert an explicit rescan of the current token
503
    (with a store value of EXPAND_RESCAN) after the close brace so that
526
    (with a store value of EXPAND_RESCAN) after the close brace so that
504
    g is seen not to be in scope.  This problem only ever occurs one
527
    g is seen not to be in scope.  This problem only ever occurs one
505
    token ahead of the current token.
528
    token ahead of the current token.
792
		}
571
		}
793
#endif
-
 
794
	    }
572
		expand = 1;
795
 
573
 
796
#if LANGUAGE_CPP
-
 
797
	    /* Allow for destructors (C++ only) */
-
 
798
	    if ( store == EXPAND_DESTRUCTOR && t != lex_colon_Hcolon ) {
-
 
799
		int level = 2 ;
-
 
800
		IDENTIFIER cid = id ;
-
 
801
		do {
574
	} else {
802
		    switch ( TAG_id ( cid ) ) {
575
		/* Use a previously stored token */
803
			case id_class_name_tag :
-
 
804
			case id_class_alias_tag :
-
 
805
			case id_token_tag : {
576
		t = this_tok->tok;
806
			    IDENTIFIER tid ;
577
		if (t == lex_ignore_token) {
807
			    if ( tt == lex_template_Htype ) {
578
			/* Step over any ignored tokens */
808
				this_tok->tok = tt ;
579
			prev_tok = this_tok;
809
				t = lex_destructor_Hname ;
580
			this_tok = this_tok->next;
810
				return ( t ) ;
581
			goto start_label;
811
			    }
-
 
812
			    tid = find_destr_id ( cid ) ;
-
 
813
			    if ( !IS_NULL_id ( tid ) ) {
582
		} else if (t == lex_builtin_Hline || t == lex_builtin_Hfile) {
814
				this_tok->pp_data.id.use = tid ;
-
 
815
				t = lex_destructor_Hname ;
583
			/* Set line number */
816
				return ( t ) ;
584
			prev_tok = this_tok;
817
			    }
-
 
818
			    level = 0 ;
585
			this_tok = read_loc_tokens(this_tok);
819
			    break ;
586
			goto start_label;
820
			}
-
 
821
			default : {
-
 
822
			    if ( level == 2 && !IS_NULL_nspace ( ns ) ) {
587
		} else if (crt_col_changed) {
823
				cid = find_id ( nm ) ;
588
			unsigned long sp = this_tok->pp_space;
824
				level = 1 ;
-
 
825
			    } else {
589
			if (sp) {
826
				level = 0 ;
590
				crt_loc.column = sp;
827
			    }
-
 
828
			    break ;
-
 
829
			}
591
			}
830
		    }
592
		}
831
		} while ( level ) ;
593
		crt_token = this_tok;
-
 
594
		expand = 0;
-
 
595
	}
-
 
596
	crt_lookup = NULL_nspace;
-
 
597
 
-
 
598
	/* Deal with context switch */
-
 
599
	if (store == EXPAND_NORMAL) {
-
 
600
		OPTIONS *opts = prev_opts;
-
 
601
		if (opts != crt_opts) {
-
 
602
			set_mode(opts);
832
	    }
603
		}
-
 
604
		prev_opts = this_tok->pp_opts;
-
 
605
	}
-
 
606
 
-
 
607
	/* Analyse the token */
-
 
608
	switch (t) {
-
 
609
 
-
 
610
	case lex_identifier: {
-
 
611
		/* Deal with identifiers */
-
 
612
		unsigned tag;
-
 
613
		int tt = lex_identifier;
-
 
614
 
-
 
615
		/* Check for macro expansion */
-
 
616
		HASHID nm = this_tok->pp_data.id.hash;
-
 
617
		IDENTIFIER id = DEREF_id(hashid_id(nm));
-
 
618
expand_label:
-
 
619
		tag = TAG_id(id);
-
 
620
		switch (tag) {
-
 
621
 
-
 
622
		case id_obj_macro_tag:
-
 
623
		case id_func_macro_tag:
-
 
624
			/* Check for expansion of macros */
-
 
625
			if (expand) {
-
 
626
				PPTOKEN *toks;
-
 
627
				toks = expand_macro(nm, file_loc, 1);
-
 
628
				this_tok->tok = lex_ignore_token;
-
 
629
				this_tok->next = toks;
-
 
630
				prev_tok = this_tok;
-
 
631
				this_tok = toks;
-
 
632
				goto start_label;
833
#endif
633
			}
-
 
634
			id = DEREF_id(id_alias(id));
-
 
635
			goto expand_label;
834
 
636
 
835
#if LANGUAGE_CPP
637
		case id_keyword_tag:
836
	    /* Look ahead for further qualifiers (C++ only) */
638
			/* Check on keywords */
837
	    if ( t == lex_colon_Hcolon ) {
639
			this_tok->pp_data.id.use = id;
838
		/* Following token is '::' */
640
			t = (int)DEREF_ulong(id_no(id));
839
		int level = 2 ;
641
			this_tok->tok = t;
840
		IDENTIFIER cid = id ;
-
 
841
		do {
642
			return(t);
842
		    switch ( TAG_id ( cid ) ) {
-
 
843
 
643
 
844
			case id_class_name_tag :
-
 
845
			case id_class_alias_tag :
-
 
846
			case id_nspace_name_tag :
644
		case id_iso_keyword_tag:
847
			case id_nspace_alias_tag : {
-
 
848
			    /* Have namespace or class name */
645
			/* Check on ISO keywords */
849
			    ns = find_namespace ( cid ) ;
646
			this_tok->pp_data.id.use = id;
850
			    if ( !IS_NULL_nspace ( ns ) ) {
647
			if (!in_pragma_dir) {
851
				crt_lookup = ns ;
-
 
852
				t = expand_token ( EXPAND_IDENTIFIER ) ;
-
 
853
				switch ( t ) {
648
				ERROR err;
854
				    case lex_full_Hname :
-
 
855
				    case lex_colon_Hcolon : {
649
				t = (int)DEREF_ulong(id_no(id));
856
					t = lex_nested_Hname ;
650
				t = primary_form(t);
857
					this_tok->tok = lex_ignore_token ;
-
 
858
					crt_token->tok = t ;
-
 
859
					return ( t ) ;
-
 
860
				    }
-
 
861
				    case lex_full_Hname_Hstar : {
-
 
862
					t = lex_nested_Hname_Hstar ;
651
				err = ERR_lex_digraph_iso(nm, t);
863
					this_tok->tok = lex_ignore_token ;
-
 
864
					crt_token->tok = t ;
652
				if (!IS_NULL_err(err)) {
865
					return ( t ) ;
653
					report(crt_loc, err);
866
				    }
-
 
867
				}
654
				}
868
				crt_token = this_tok ;
655
				this_tok->tok = t;
-
 
656
#if LANGUAGE_CPP
-
 
657
				if (t == lex_compl_H1)goto compl_label;
869
			    }
658
#endif
870
			    level = 0 ;
659
				return(t);
-
 
660
			}
871
			    break ;
661
			break;
-
 
662
 
-
 
663
		case id_reserved_tag:
-
 
664
			/* Report reserved identifiers */
-
 
665
			if (store == EXPAND_NORMAL && !in_pragma_dir) {
-
 
666
				ERROR err = ERR_lex_key_reserve(nm);
-
 
667
				report(crt_loc, err);
872
			}
668
			}
-
 
669
			break;
-
 
670
		}
-
 
671
 
-
 
672
		/* Perform name look-up */
-
 
673
#if LANGUAGE_CPP
-
 
674
		if (IS_NULL_nspace(ns)) {
-
 
675
			id = find_id(nm);
-
 
676
		} else {
-
 
677
			IDENTIFIER mid = find_qual_id(ns, nm, 0, 0);
-
 
678
			if (!IS_NULL_id(mid))id = mid;
-
 
679
		}
-
 
680
#else
-
 
681
		id = find_op_id(nm);
-
 
682
#endif
-
 
683
		tag = TAG_id(id);
-
 
684
 
-
 
685
#if LANGUAGE_CPP
-
 
686
		/* Look ahead for following '::' (C++ only) */
-
 
687
		t = expand_token(EXPAND_CHECK_COLON);
-
 
688
		crt_token = this_tok;
-
 
689
#endif
873
 
690
 
-
 
691
		/* Allow for tokens and templates */
-
 
692
		if (tag == id_token_tag) {
-
 
693
			TOKEN sort = DEREF_tok(id_token_sort(id));
874
			default : {
694
			if (IS_tok_proc(sort)) {
-
 
695
				/* Procedure token application */
-
 
696
#if LANGUAGE_CPP
875
			    /* Look up namespace or class name */
697
				/* Following token already read */
-
 
698
#else
-
 
699
				/* Check for following '(' */
-
 
700
				t = expand_token(EXPAND_CHECK_COLON);
-
 
701
				crt_token = this_tok;
-
 
702
#endif
876
			    if ( level == 2 ) {
703
				if (t == lex_open_Hround) {
877
				CLASS_TYPE ct = find_class ( cid ) ;
704
					PPTOKEN *args = skip_token_args(id);
878
				if ( !IS_NULL_ctype ( ct ) ) {
705
					id = DEREF_id(id_token_alt(id));
-
 
706
					this_tok->pp_data.tok.id = id;
-
 
707
					this_tok->pp_data.tok.args = args;
879
				    cid = DEREF_id ( ctype_name ( ct ) ) ;
708
					sort = DEREF_tok(tok_proc_res(sort));
-
 
709
					switch (TAG_tok(sort)) {
-
 
710
					case tok_exp_tag:
-
 
711
					case tok_nat_tag:
-
 
712
					case tok_snat_tag: {
-
 
713
						tt = lex_complex_Hexp;
880
				} else {
714
						break;
-
 
715
					}
881
				    if ( IS_NULL_nspace ( ns ) ) {
716
					case tok_stmt_tag: {
882
					cid = find_type_id ( nm, 3 ) ;
717
						tt = lex_complex_Hstmt;
883
				    } else {
718
						break;
-
 
719
					}
-
 
720
					case tok_member_tag: {
-
 
721
						/* NOT YET IMPLEMENTED */
884
					cid = find_qual_id ( ns, nm, 0, 3 ) ;
722
						tt = lex_complex_Hexp;
885
				    }
723
						break;
886
				}
724
					}
-
 
725
					default : {
-
 
726
						tt = lex_complex_Htype;
-
 
727
#if LANGUAGE_CPP
887
				if ( IS_NULL_id ( cid ) ) {
728
						/* Check again for following
888
				    level = 0 ;
729
						 * '::' */
-
 
730
						t = expand_token(EXPAND_CHECK_COLON);
-
 
731
						crt_token = this_tok;
-
 
732
#endif
-
 
733
						break;
-
 
734
					}
-
 
735
					}
889
				} else {
736
				} else {
-
 
737
					tt = DEREF_int(tok_proc_key(sort));
-
 
738
					if (store == EXPAND_NORMAL) {
-
 
739
						if (tt != lex_identifier &&
890
				    level = 1 ;
740
						    !in_pragma_dir) {
-
 
741
							ERROR err = ERR_cpp_replace_arg_none(nm);
-
 
742
							report(crt_loc, err);
-
 
743
						}
-
 
744
					}
891
				}
745
				}
892
			    } else {
-
 
893
				level = 0 ;
-
 
894
			    }
-
 
895
			    break ;
-
 
896
			}
746
			}
-
 
747
 
-
 
748
#if LANGUAGE_CPP
-
 
749
		} else if (t == lex_less) {
-
 
750
			/* Check for templates (C++ only) */
-
 
751
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
-
 
752
			if (ds & dspec_template) {
-
 
753
				/* Template application */
-
 
754
				PPTOKEN *args;
-
 
755
				if (ds & dspec_implicit) {
-
 
756
					/* Allow for injected template names */
-
 
757
					IDENTIFIER tid = find_template(id, 0);
-
 
758
					if (!IS_NULL_id(tid)) {
-
 
759
						id = tid;
-
 
760
						tag = TAG_id(id);
-
 
761
					}
-
 
762
				}
-
 
763
				args = skip_template_args(id, 0);
-
 
764
				if (store == EXPAND_TEMPLATE) {
-
 
765
					have_template = 1;
-
 
766
				}
-
 
767
				switch (tag) {
-
 
768
				case id_class_name_tag:
-
 
769
					tt = lex_template_Htype;
-
 
770
					goto class_template_lab;
-
 
771
				case id_class_alias_tag:
-
 
772
					tt = lex_complex_Htype;
-
 
773
					goto class_template_lab;
-
 
774
				case id_type_alias_tag: {
-
 
775
					CLASS_TYPE ct = find_class(id);
-
 
776
					tt = lex_complex_Htype;
-
 
777
					if (!IS_NULL_ctype(ct)) {
-
 
778
						goto class_template_lab;
-
 
779
					}
-
 
780
					break;
-
 
781
				}
-
 
782
class_template_lab:	{
-
 
783
				t = expand_token(EXPAND_CHECK_COLON);
-
 
784
				crt_token = this_tok;
-
 
785
				if (t == lex_colon_Hcolon) {
-
 
786
					/* Expand the template class now */
-
 
787
					id = parse_type_template(id, args, 1);
-
 
788
					tt = lex_identifier;
-
 
789
				}
-
 
790
				break;
-
 
791
			}
-
 
792
				case id_enum_name_tag:
-
 
793
				case id_enum_alias_tag:
-
 
794
			tt = lex_complex_Htype;
-
 
795
			break;
-
 
796
				default:
-
 
797
			/* Function template */
-
 
798
			tt = lex_template_Hid;
-
 
799
			break;
-
 
800
				}
-
 
801
				if (tt != lex_identifier) {
-
 
802
					this_tok->pp_data.tok.id = id;
-
 
803
					this_tok->pp_data.tok.args = args;
-
 
804
				}
-
 
805
			} else if (store == EXPAND_TEMPLATE) {
-
 
806
				/* Have 'template id < ... >' */
-
 
807
				PPTOKEN *args = skip_template_args(id, 0);
-
 
808
				this_tok->pp_data.tok.id = id;
-
 
809
				this_tok->pp_data.tok.args = args;
-
 
810
				tt = lex_template_Hid;
-
 
811
				have_template = 1;
-
 
812
			}
-
 
813
#endif
-
 
814
		}
-
 
815
 
-
 
816
#if LANGUAGE_CPP
-
 
817
		/* Allow for destructors (C++ only) */
-
 
818
		if (store == EXPAND_DESTRUCTOR && t != lex_colon_Hcolon) {
-
 
819
			int level = 2;
-
 
820
			IDENTIFIER cid = id;
897
		    }
821
			do {
-
 
822
				switch (TAG_id(cid)) {
-
 
823
				case id_class_name_tag:
-
 
824
				case id_class_alias_tag:
-
 
825
				case id_token_tag: {
-
 
826
					IDENTIFIER tid;
-
 
827
					if (tt == lex_template_Htype) {
-
 
828
						this_tok->tok = tt;
-
 
829
						t = lex_destructor_Hname;
-
 
830
						return(t);
-
 
831
					}
-
 
832
					tid = find_destr_id(cid);
-
 
833
					if (!IS_NULL_id(tid)) {
-
 
834
						this_tok->pp_data.id.use = tid;
-
 
835
						t = lex_destructor_Hname;
-
 
836
						return(t);
-
 
837
					}
-
 
838
					level = 0;
-
 
839
					break;
-
 
840
				}
-
 
841
				default:
-
 
842
					if (level == 2 && !IS_NULL_nspace(ns)) {
-
 
843
						cid = find_id(nm);
-
 
844
						level = 1;
-
 
845
					} else {
-
 
846
						level = 0;
-
 
847
					}
-
 
848
					break;
-
 
849
				}
898
		} while ( level ) ;
850
			} while (level);
899
	    }
851
		}
900
#endif
852
#endif
901
 
-
 
902
	    /* Deal with context dependent identifiers */
-
 
903
	    switch ( tag ) {
-
 
904
 
853
 
905
#if LANGUAGE_CPP
854
#if LANGUAGE_CPP
-
 
855
		/* Look ahead for further qualifiers (C++ only) */
-
 
856
		if (t == lex_colon_Hcolon) {
-
 
857
			/* Following token is '::' */
-
 
858
			int level = 2;
-
 
859
			IDENTIFIER cid = id;
-
 
860
			do {
-
 
861
				switch (TAG_id(cid)) {
906
		case id_class_name_tag :
862
				case id_class_name_tag:
-
 
863
				case id_class_alias_tag:
907
		case id_enum_name_tag : {
864
				case id_nspace_name_tag:
-
 
865
				case id_nspace_alias_tag: {
908
		    /* Type names (C++ only) */
866
					/* Have namespace or class name */
-
 
867
					ns = find_namespace(cid);
-
 
868
					if (!IS_NULL_nspace(ns)) {
-
 
869
						crt_lookup = ns;
-
 
870
						t = expand_token(EXPAND_IDENTIFIER);
-
 
871
						switch (t) {
-
 
872
						case lex_full_Hname:
-
 
873
						case lex_colon_Hcolon:
909
		    t = lex_type_Hname ;
874
							t = lex_nested_Hname;
-
 
875
							this_tok->tok =
-
 
876
							    lex_ignore_token;
-
 
877
							crt_token->tok = t;
-
 
878
							return(t);
-
 
879
						case lex_full_Hname_Hstar:
-
 
880
							t = lex_nested_Hname_Hstar;
-
 
881
							this_tok->tok =
-
 
882
							    lex_ignore_token;
-
 
883
							crt_token->tok = t;
-
 
884
							return(t);
-
 
885
						}
-
 
886
						crt_token = this_tok;
-
 
887
					}
-
 
888
					level = 0;
-
 
889
					break;
-
 
890
				}
-
 
891
 
-
 
892
				default: {
-
 
893
					/* Look up namespace or class name */
-
 
894
					if (level == 2) {
-
 
895
						CLASS_TYPE ct = find_class(cid);
-
 
896
						if (!IS_NULL_ctype(ct)) {
-
 
897
							cid = DEREF_id(ctype_name(ct));
-
 
898
						} else {
-
 
899
							if (IS_NULL_nspace(ns)) {
-
 
900
								cid = find_type_id(nm, 3);
-
 
901
							} else {
-
 
902
								cid = find_qual_id(ns, nm, 0, 3);
-
 
903
							}
-
 
904
						}
-
 
905
						if (IS_NULL_id(cid)) {
-
 
906
							level = 0;
-
 
907
						} else {
-
 
908
							level = 1;
-
 
909
						}
-
 
910
					} else {
-
 
911
						level = 0;
-
 
912
					}
910
		    break ;
913
					break;
-
 
914
				}
-
 
915
				}
-
 
916
			} while (level);
911
		}
917
		}
912
#endif
918
#endif
913
 
919
 
-
 
920
		/* Deal with context dependent identifiers */
-
 
921
		switch (tag) {
-
 
922
 
-
 
923
#if LANGUAGE_CPP
-
 
924
		case id_class_name_tag:
-
 
925
		case id_enum_name_tag:
-
 
926
			/* Type names (C++ only) */
-
 
927
			t = lex_type_Hname;
-
 
928
			break;
-
 
929
#endif
914
		case id_class_alias_tag :
930
		case id_class_alias_tag:
915
		case id_enum_alias_tag :
931
		case id_enum_alias_tag:
916
		case id_type_alias_tag : {
932
		case id_type_alias_tag:
917
		    /* Type aliases */
933
			/* Type aliases */
918
		    t = lex_type_Hname ;
934
			t = lex_type_Hname;
-
 
935
			break;
-
 
936
#if LANGUAGE_CPP
-
 
937
		case id_nspace_name_tag:
-
 
938
		case id_nspace_alias_tag:
-
 
939
			/* Namespace names (C++ only) */
-
 
940
			t = lex_namespace_Hname;
-
 
941
			break;
-
 
942
#endif
-
 
943
		case id_token_tag: {
-
 
944
			/* Token names */
-
 
945
			TOKEN sort = DEREF_tok(id_token_sort(id));
-
 
946
			if (IS_tok_stmt(sort)) {
-
 
947
				t = lex_statement_Hname;
-
 
948
			} else {
-
 
949
				t = lex_identifier;
-
 
950
			}
-
 
951
			break;
-
 
952
		}
-
 
953
 
-
 
954
		default:
-
 
955
			/* Other names */
-
 
956
			t = lex_identifier;
919
		    break ;
957
			break;
-
 
958
		}
-
 
959
		if (tt == lex_identifier) {
-
 
960
			this_tok->pp_data.id.use = id;
-
 
961
		} else {
-
 
962
			this_tok->tok = tt;
-
 
963
			t = tt;
-
 
964
		}
-
 
965
		break;
-
 
966
	}
-
 
967
 
-
 
968
#if LANGUAGE_CPP
-
 
969
	case lex_colon_Hcolon: {
-
 
970
		/* Deal with qualified names (C++ only) */
-
 
971
		int nt;
-
 
972
		unsigned long depth;
-
 
973
		if (store == EXPAND_CHECK_COLON) {
-
 
974
			/* Look ahead for '::' */
-
 
975
			return(t);
-
 
976
		} else if (IS_NULL_nspace(ns)) {
-
 
977
			/* Initial '::' */
-
 
978
			ns = global_namespace;
-
 
979
			depth = 0;
-
 
980
		} else if (store == EXPAND_IDENTIFIER) {
-
 
981
			/* Following a namespace identifier */
-
 
982
			depth = crt_lookup_depth + 1;
-
 
983
		} else {
-
 
984
			/* Badly placed '::' */
-
 
985
			return(t);
-
 
986
		}
-
 
987
 
-
 
988
		/* Look ahead to further tokens */
-
 
989
		crt_lookup = ns;
-
 
990
		crt_lookup_depth = depth;
-
 
991
		nt = expand_token(EXPAND_COLON_COLON);
-
 
992
		crt_lookup_depth = 0;
-
 
993
		if (nt == lex_nested_Hname) {
-
 
994
			nt = lex_full_Hname;
-
 
995
			this_tok->tok = lex_ignore_token;
-
 
996
			crt_token->tok = nt;
-
 
997
			return(nt);
-
 
998
		}
-
 
999
		if (nt == lex_nested_Hname_Hstar) {
-
 
1000
			if (crt_token == this_tok->next) {
-
 
1001
				IGNORE check_value(OPT_VAL_scope_qualifiers,
-
 
1002
						   depth);
-
 
1003
			}
-
 
1004
			nt = lex_full_Hname_Hstar;
-
 
1005
			this_tok->tok = lex_ignore_token;
-
 
1006
			crt_token->tok = nt;
-
 
1007
			return(nt);
920
		}
1008
		}
-
 
1009
		IGNORE check_value(OPT_VAL_scope_qualifiers, depth);
-
 
1010
		this_tok->pp_data.ns = ns;
-
 
1011
		crt_lookup = ns;
-
 
1012
		crt_token = this_tok;
-
 
1013
		break;
-
 
1014
	}
-
 
1015
#endif
-
 
1016
 
-
 
1017
#if LANGUAGE_CPP
-
 
1018
	case lex_full_Hname:
-
 
1019
	case lex_nested_Hname: {
-
 
1020
		/* Deal with stored nested names (C++ only) */
-
 
1021
		int nt;
-
 
1022
		ns = this_tok->pp_data.ns;
-
 
1023
		crt_lookup = ns;
-
 
1024
		crt_lookup_depth++;
-
 
1025
		nt = expand_token(EXPAND_COLON_COLON);
-
 
1026
		crt_lookup_depth = 0;
-
 
1027
		if (nt == lex_nested_Hname) {
-
 
1028
			this_tok->tok = lex_ignore_token;
-
 
1029
			crt_token->tok = t;
-
 
1030
			return(nt);
-
 
1031
		}
-
 
1032
		if (nt == lex_nested_Hname_Hstar) {
-
 
1033
			if (t == lex_full_Hname)nt = lex_full_Hname_Hstar;
-
 
1034
			this_tok->tok = lex_ignore_token;
-
 
1035
			crt_token->tok = nt;
-
 
1036
			return(nt);
-
 
1037
		}
-
 
1038
		crt_lookup = ns;
-
 
1039
		crt_token = this_tok;
-
 
1040
		break;
-
 
1041
	}
-
 
1042
#endif
921
 
1043
 
922
#if LANGUAGE_CPP
1044
#if LANGUAGE_CPP
923
		case id_nspace_name_tag :
1045
	case lex_star:
924
		case id_nspace_alias_tag : {
-
 
925
		    /* Namespace names (C++ only) */
1046
		/* Deal with pointer to members (C++ only) */
926
		    t = lex_namespace_Hname ;
1047
		if (store == EXPAND_COLON_COLON && crt_lookup_depth) {
927
		    break ;
-
 
928
		}
-
 
929
#endif
-
 
930
 
-
 
931
		case id_token_tag : {
-
 
932
		    /* Token names */
-
 
933
		    TOKEN sort = DEREF_tok ( id_token_sort ( id ) ) ;
1048
			IDENTIFIER cid = DEREF_id(nspace_name(ns));
934
		    if ( IS_tok_stmt ( sort ) ) {
-
 
935
			t = lex_statement_Hname ;
1049
			t = lex_nested_Hname_Hstar;
936
		    } else {
1050
			this_tok->tok = t;
937
			t = lex_identifier ;
1051
			this_tok->pp_data.id.use = cid;
938
		    }
-
 
939
		    break ;
-
 
940
		}
1052
		}
-
 
1053
		break;
-
 
1054
#endif
941
 
1055
 
-
 
1056
#if LANGUAGE_CPP
-
 
1057
	case lex_compl_H1:
-
 
1058
compl_label:
-
 
1059
		/* Deal with destructors (C++ only) */
-
 
1060
		if (store != EXPAND_COLON_COLON) {
-
 
1061
			int nt;
-
 
1062
			crt_lookup = ns;
-
 
1063
			nt = expand_token(EXPAND_DESTRUCTOR);
-
 
1064
			if (nt == lex_destructor_Hname) {
-
 
1065
				int d = predict_destr(ns);
942
		default : {
1066
				if (d) {
-
 
1067
					this_tok->tok = lex_ignore_token;
-
 
1068
					this_tok = crt_token;
-
 
1069
					t = this_tok->tok;
-
 
1070
					if (t == lex_template_Htype) {
-
 
1071
						/* Template class destructors */
-
 
1072
						IDENTIFIER id =
-
 
1073
						    this_tok->pp_data.tok.id;
943
		    /* Other names */
1074
						PPTOKEN *args =
-
 
1075
						    this_tok->pp_data.tok.args;
-
 
1076
						HASHID nm =
-
 
1077
						    DEREF_hashid(id_name(id));
-
 
1078
						id = parse_type_template(id,
-
 
1079
									 args,
-
 
1080
									 1);
944
		    t = lex_identifier ;
1081
						id = find_destr_id(id);
-
 
1082
						this_tok->pp_data.id.hash = nm;
-
 
1083
						this_tok->pp_data.id.use = id;
945
		    break ;
1084
					} else {
-
 
1085
						/* Simple destructors */
-
 
1086
						IDENTIFIER id =
-
 
1087
						    this_tok->pp_data.id.use;
-
 
1088
						HASHID nm =
-
 
1089
						    this_tok->pp_data.id.hash;
-
 
1090
						check_destr_id(id, nm, d);
-
 
1091
					}
-
 
1092
					this_tok->tok = nt;
-
 
1093
					return(nt);
-
 
1094
				}
-
 
1095
			}
-
 
1096
			crt_token = this_tok;
946
		}
1097
		}
947
	    }
-
 
948
	    if ( tt == lex_identifier ) {
-
 
949
		this_tok->pp_data.id.use = id ;
-
 
950
	    } else {
-
 
951
		this_tok->tok = tt ;
-
 
952
		t = tt ;
1098
		break;
953
	    }
1099
#endif
954
	    break ;
-
 
955
	}
-
 
956
 
1100
 
957
#if LANGUAGE_CPP
-
 
958
	case lex_colon_Hcolon : {
1101
	case lex_integer_Hlit: {
959
	    /* Deal with qualified names (C++ only) */
1102
		/* Deal with integer and floating point literals */
960
	    int nt ;
1103
		int nt;
961
	    unsigned long depth ;
-
 
962
	    if ( store == EXPAND_CHECK_COLON ) {
-
 
963
		/* Look ahead for '::' */
-
 
964
		return ( t ) ;
-
 
965
	    } else if ( IS_NULL_nspace ( ns ) ) {
-
 
966
		/* Initial '::' */
-
 
967
		ns = global_namespace ;
-
 
968
		depth = 0 ;
-
 
969
	    } else if ( store == EXPAND_IDENTIFIER ) {
-
 
970
		/* Following a namespace identifier */
-
 
971
		depth = crt_lookup_depth + 1 ;
-
 
972
	    } else {
-
 
973
		/* Badly placed '::' */
-
 
974
		return ( t ) ;
-
 
975
	    }
-
 
976
 
-
 
977
	    /* Look ahead to further tokens */
-
 
978
	    crt_lookup = ns ;
-
 
979
	    crt_lookup_depth = depth ;
-
 
980
	    nt = expand_token ( EXPAND_COLON_COLON ) ;
-
 
981
	    crt_lookup_depth = 0 ;
-
 
982
	    if ( nt == lex_nested_Hname ) {
-
 
983
		nt = lex_full_Hname ;
1104
		int pn = pragma_number;
984
		this_tok->tok = lex_ignore_token ;
-
 
985
		crt_token->tok = nt ;
1105
		OPTIONS *opts = crt_opts;
986
		return ( nt ) ;
-
 
987
	    }
-
 
988
	    if ( nt == lex_nested_Hname_Hstar ) {
-
 
989
		if ( crt_token == this_tok->next ) {
1106
		OPTIONS *nopts = this_tok->pp_opts;
990
		    IGNORE check_value ( OPT_VAL_scope_qualifiers, depth ) ;
-
 
991
		}
-
 
992
		nt = lex_full_Hname_Hstar ;
-
 
993
		this_tok->tok = lex_ignore_token ;
-
 
994
		crt_token->tok = nt ;
-
 
995
		return ( nt ) ;
-
 
996
	    }
-
 
997
	    IGNORE check_value ( OPT_VAL_scope_qualifiers, depth ) ;
-
 
998
	    this_tok->pp_data.ns = ns ;
-
 
999
	    crt_lookup = ns ;
-
 
1000
	    crt_token = this_tok ;
-
 
1001
	    break ;
-
 
1002
	}
-
 
1003
#endif
-
 
1004
 
-
 
1005
#if LANGUAGE_CPP
-
 
1006
	case lex_full_Hname :
-
 
1007
	case lex_nested_Hname : {
-
 
1008
	    /* Deal with stored nested names (C++ only) */
-
 
1009
	    int nt ;
-
 
1010
	    ns = this_tok->pp_data.ns ;
1107
		string n = this_tok->pp_data.text;
1011
	    crt_lookup = ns ;
-
 
1012
	    crt_lookup_depth++ ;
-
 
1013
	    nt = expand_token ( EXPAND_COLON_COLON ) ;
-
 
1014
	    crt_lookup_depth = 0 ;
-
 
1015
	    if ( nt == lex_nested_Hname ) {
1108
		if (opts != nopts)set_mode(nopts);
1016
		this_tok->tok = lex_ignore_token ;
1109
		this_tok->pp_data.exp = make_literal_exp(n, &nt, pn);
1017
		crt_token->tok = t ;
1110
		this_tok->tok = nt;
1018
		return ( nt ) ;
-
 
1019
	    }
-
 
1020
	    if ( nt == lex_nested_Hname_Hstar ) {
1111
		if (opts != nopts)set_mode(opts);
1021
		if ( t == lex_full_Hname ) nt = lex_full_Hname_Hstar ;
-
 
1022
		this_tok->tok = lex_ignore_token ;
-
 
1023
		crt_token->tok = nt ;
-
 
1024
		return ( nt ) ;
1112
		t = nt;
1025
	    }
-
 
1026
	    crt_lookup = ns ;
-
 
1027
	    crt_token = this_tok ;
-
 
1028
	    break ;
1113
		break;
1029
	}
1114
	}
1030
#endif
-
 
1031
 
-
 
1032
#if LANGUAGE_CPP
-
 
1033
	case lex_star : {
-
 
1034
	    /* Deal with pointer to members (C++ only) */
-
 
1035
	    if ( store == EXPAND_COLON_COLON && crt_lookup_depth ) {
-
 
1036
		IDENTIFIER cid = DEREF_id ( nspace_name ( ns ) ) ;
-
 
1037
		t = lex_nested_Hname_Hstar ;
-
 
1038
		this_tok->tok = t ;
-
 
1039
		this_tok->pp_data.id.use = cid ;
-
 
1040
	    }
-
 
1041
	    break ;
-
 
1042
	}
-
 
1043
#endif
-
 
1044
 
1115
 
1045
#if LANGUAGE_CPP
-
 
1046
	case lex_compl_H1 :
1116
	case lex_char_Hlit:
1047
	compl_label : {
1117
	case lex_wchar_Hlit: {
1048
	    /* Deal with destructors (C++ only) */
1118
		/* Deal with character literals */
1049
	    if ( store != EXPAND_COLON_COLON ) {
-
 
1050
		int nt ;
1119
		STRING s;
1051
		crt_lookup = ns ;
1120
		OPTIONS *opts = crt_opts;
1052
		nt = expand_token ( EXPAND_DESTRUCTOR ) ;
1121
		OPTIONS *nopts = this_tok->pp_opts;
-
 
1122
		string sb = this_tok->pp_data.str.start;
-
 
1123
		string se = this_tok->pp_data.str.end;
-
 
1124
		if (opts != nopts)set_mode(nopts);
-
 
1125
		s = new_string_lit(sb, se, t);
1053
		if ( nt == lex_destructor_Hname ) {
1126
		if (t == lex_char_Hlit) {
1054
		    int d = predict_destr ( ns ) ;
1127
			t = lex_char_Hexp;
1055
		    if ( d ) {
1128
		} else {
1056
			this_tok->tok = lex_ignore_token ;
1129
			t = lex_wchar_Hexp;
-
 
1130
		}
1057
			this_tok = crt_token ;
1131
		this_tok->pp_data.exp = make_string_exp(s);
1058
			t = this_tok->tok ;
1132
		this_tok->tok = t;
1059
			if ( t == lex_template_Htype ) {
1133
		if (opts != nopts)set_mode(opts);
-
 
1134
		break;
-
 
1135
	}
-
 
1136
 
-
 
1137
	case lex_string_Hlit:
-
 
1138
	case lex_wstring_Hlit: {
1060
			    /* Template class destructors */
1139
		/* Deal with string literals */
-
 
1140
		int nt;
-
 
1141
		STRING s;
-
 
1142
		OPTIONS *opts = crt_opts;
-
 
1143
		OPTIONS *nopts = this_tok->pp_opts;
1061
			    IDENTIFIER id = this_tok->pp_data.tok.id ;
1144
		string sb = this_tok->pp_data.str.start;
1062
			    PPTOKEN *args = this_tok->pp_data.tok.args ;
1145
		string se = this_tok->pp_data.str.end;
-
 
1146
		if (opts != nopts) {
-
 
1147
			set_mode(nopts);
-
 
1148
		}
-
 
1149
		s = new_string_lit(sb, se, t);
-
 
1150
 
-
 
1151
		/* Concatenate adjacent strings */
-
 
1152
		nt = expand_token(EXPAND_STRING);
-
 
1153
		if (nt == lex_string_Hlit || nt == lex_wstring_Hlit) {
1063
			    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
1154
			/* Combine the following string with this one */
-
 
1155
			if (nt != t) {
-
 
1156
				/* String types don't match */
1064
			    id = parse_type_template ( id, args, 1 ) ;
1157
				report(crt_loc, ERR_lex_string_concat());
1065
			    id = find_destr_id ( id ) ;
1158
				t = lex_wstring_Hlit;
-
 
1159
			}
1066
			    this_tok->pp_data.id.hash = nm ;
1160
			s = concat_string_lit(s, crt_token->pp_data.strlit);
-
 
1161
			crt_token->tok = lex_ignore_token;
-
 
1162
		}
-
 
1163
		crt_token = this_tok;
-
 
1164
		if (store == EXPAND_STRING) {
-
 
1165
			/* Continue concatenation */
1067
			    this_tok->pp_data.id.use = id ;
1166
			this_tok->pp_data.strlit = s;
-
 
1167
		} else {
-
 
1168
			/* Transform string literal into expression */
-
 
1169
			if (t == lex_string_Hlit) {
-
 
1170
				t = lex_string_Hexp;
1068
			} else {
1171
			} else {
1069
			    /* Simple destructors */
1172
				t = lex_wstring_Hexp;
1070
			    IDENTIFIER id = this_tok->pp_data.id.use ;
-
 
1071
			    HASHID nm = this_tok->pp_data.id.hash ;
-
 
1072
			    check_destr_id ( id, nm, d ) ;
-
 
1073
			}
1173
			}
1074
			this_tok->tok = nt ;
1174
			this_tok->pp_data.exp = make_string_exp(s);
1075
			return ( nt ) ;
1175
			this_tok->tok = t;
1076
		    }
-
 
1077
		}
1176
		}
1078
		crt_token = this_tok ;
1177
		if (opts != nopts) {
-
 
1178
			set_mode(opts);
1079
	    }
1179
		}
1080
	    break ;
1180
		break;
1081
	}
1181
	}
1082
#endif
-
 
1083
 
1182
 
1084
	case lex_integer_Hlit : {
1183
	case lex_ellipsis:
1085
	    /* Deal with integer and floating point literals */
-
 
1086
	    int nt ;
1184
		/* Ellipses */
1087
	    int pn = pragma_number ;
1185
		if (store == EXPAND_NORMAL) {
1088
	    OPTIONS *opts = crt_opts ;
-
 
1089
	    OPTIONS *nopts = this_tok->pp_opts ;
1186
			OPTION opt = option(OPT_ellipsis_ident);
1090
	    string n = this_tok->pp_data.text ;
1187
			NAMESPACE cns = crt_namespace;
1091
	    if ( opts != nopts ) set_mode ( nopts ) ;
1188
			if (opt != OPTION_DISALLOW && IS_nspace_block(cns)) {
1092
	    this_tok->pp_data.exp = make_literal_exp ( n, &nt, pn ) ;
1189
				t = lex_ellipsis_Hexp;
1093
	    this_tok->tok = nt ;
1190
				this_tok->tok = t;
1094
	    if ( opts != nopts ) set_mode ( opts ) ;
-
 
1095
	    t = nt ;
-
 
1096
	    break ;
-
 
1097
	}
1191
			}
1098
 
-
 
1099
	case lex_char_Hlit :
-
 
1100
	case lex_wchar_Hlit : {
-
 
1101
	    /* Deal with character literals */
-
 
1102
	    STRING s ;
-
 
1103
	    OPTIONS *opts = crt_opts ;
-
 
1104
	    OPTIONS *nopts = this_tok->pp_opts ;
-
 
1105
	    string sb = this_tok->pp_data.str.start ;
-
 
1106
	    string se = this_tok->pp_data.str.end ;
-
 
1107
	    if ( opts != nopts ) set_mode ( nopts ) ;
-
 
1108
	    s = new_string_lit ( sb, se, t ) ;
-
 
1109
	    if ( t == lex_char_Hlit ) {
-
 
1110
		t = lex_char_Hexp ;
-
 
1111
	    } else {
-
 
1112
		t = lex_wchar_Hexp ;
-
 
1113
	    }
1192
		}
1114
	    this_tok->pp_data.exp = make_string_exp ( s ) ;
-
 
1115
	    this_tok->tok = t ;
-
 
1116
	    if ( opts != nopts ) set_mode ( opts ) ;
-
 
1117
	    break ;
1193
		break;
1118
	}
-
 
1119
 
1194
 
1120
	case lex_string_Hlit :
1195
	case lex_hash_H2:
1121
	case lex_wstring_Hlit : {
1196
	case lex_hash_Hhash_H2:
1122
	    /* Deal with string literals */
1197
	case lex_open_Hbrace_H2:
1123
	    int nt ;
1198
	case lex_open_Hsquare_H2:
1124
	    STRING s ;
1199
	case lex_close_Hbrace_H2:
1125
	    OPTIONS *opts = crt_opts ;
1200
	case lex_close_Hsquare_H2:
1126
	    OPTIONS *nopts = this_tok->pp_opts ;
1201
		/* Digraphs */
1127
	    string sb = this_tok->pp_data.str.start ;
1202
		t = get_digraph(t);
1128
	    string se = this_tok->pp_data.str.end ;
1203
		this_tok->tok = t;
1129
	    if ( opts != nopts ) set_mode ( nopts ) ;
-
 
1130
	    s = new_string_lit ( sb, se, t ) ;
1204
		break;
1131
 
1205
 
-
 
1206
	case lex_and_H2:
-
 
1207
	case lex_and_Heq_H2:
-
 
1208
	case lex_compl_H2:
1132
	    /* Concatenate adjacent strings */
1209
	case lex_logical_Hand_H2:
-
 
1210
	case lex_logical_Hor_H2:
-
 
1211
	case lex_not_H2:
-
 
1212
	case lex_not_Heq_H2:
-
 
1213
	case lex_or_H2:
-
 
1214
	case lex_or_Heq_H2:
-
 
1215
	case lex_xor_H2:
1133
	    nt = expand_token ( EXPAND_STRING ) ;
1216
	case lex_xor_Heq_H2: {
-
 
1217
		/* ISO keywords */
-
 
1218
		int tt;
1134
	    if ( nt == lex_string_Hlit || nt == lex_wstring_Hlit ) {
1219
		IDENTIFIER id = this_tok->pp_data.id.use;
1135
		/* Combine the following string with this one */
1220
		t = (int)DEREF_ulong(id_no(id));
-
 
1221
		tt = primary_form(t);
1136
		if ( nt != t ) {
1222
		if (tt != t) {
-
 
1223
			HASHID nm;
-
 
1224
			if (in_pragma_dir) {
-
 
1225
				break;
-
 
1226
			}
1137
		    /* String types don't match */
1227
			nm = this_tok->pp_data.id.hash;
1138
		    report ( crt_loc, ERR_lex_string_concat () ) ;
1228
			report(crt_loc, ERR_lex_digraph_iso(nm, tt));
-
 
1229
			t = tt;
-
 
1230
		}
-
 
1231
		this_tok->tok = t;
-
 
1232
#if LANGUAGE_CPP
1139
		    t = lex_wstring_Hlit ;
1233
		if (t == lex_compl_H1) {
-
 
1234
			goto compl_label;
1140
		}
1235
		}
1141
		s = concat_string_lit ( s, crt_token->pp_data.strlit ) ;
-
 
1142
		crt_token->tok = lex_ignore_token ;
-
 
1143
	    }
-
 
1144
	    crt_token = this_tok ;
-
 
1145
	    if ( store == EXPAND_STRING ) {
-
 
1146
		/* Continue concatenation */
-
 
1147
		this_tok->pp_data.strlit = s ;
-
 
1148
	    } else {
-
 
1149
		/* Transform string literal into expression */
-
 
1150
		if ( t == lex_string_Hlit ) {
-
 
1151
		    t = lex_string_Hexp ;
-
 
1152
		} else {
-
 
1153
		    t = lex_wstring_Hexp ;
-
 
1154
		}
-
 
1155
		this_tok->pp_data.exp = make_string_exp ( s ) ;
-
 
1156
		this_tok->tok = t ;
-
 
1157
	    }
-
 
1158
	    if ( opts != nopts ) set_mode ( opts ) ;
-
 
1159
	    break ;
-
 
1160
	}
-
 
1161
 
-
 
1162
	case lex_ellipsis : {
-
 
1163
	    /* Ellipses */
-
 
1164
	    if ( store == EXPAND_NORMAL ) {
-
 
1165
		OPTION opt = option ( OPT_ellipsis_ident ) ;
-
 
1166
		NAMESPACE cns = crt_namespace ;
-
 
1167
		if ( opt != OPTION_DISALLOW && IS_nspace_block ( cns ) ) {
-
 
1168
		    t = lex_ellipsis_Hexp ;
-
 
1169
		    this_tok->tok = t ;
-
 
1170
		}
-
 
1171
	    }
-
 
1172
	    break ;
-
 
1173
	}
-
 
1174
 
-
 
1175
	case lex_hash_H2 :
-
 
1176
	case lex_hash_Hhash_H2 :
-
 
1177
	case lex_open_Hbrace_H2 :
-
 
1178
	case lex_open_Hsquare_H2 :
-
 
1179
	case lex_close_Hbrace_H2 :
-
 
1180
	case lex_close_Hsquare_H2 : {
-
 
1181
	    /* Digraphs */
-
 
1182
	    t = get_digraph ( t ) ;
-
 
1183
	    this_tok->tok = t ;
-
 
1184
	    break ;
-
 
1185
	}
-
 
1186
 
-
 
1187
	case lex_and_H2 :
-
 
1188
	case lex_and_Heq_H2 :
-
 
1189
	case lex_compl_H2 :
-
 
1190
	case lex_logical_Hand_H2 :
-
 
1191
	case lex_logical_Hor_H2 :
-
 
1192
	case lex_not_H2 :
-
 
1193
	case lex_not_Heq_H2 :
-
 
1194
	case lex_or_H2 :
-
 
1195
	case lex_or_Heq_H2 :
-
 
1196
	case lex_xor_H2 :
-
 
1197
	case lex_xor_Heq_H2 : {
-
 
1198
	    /* ISO keywords */
-
 
1199
	    int tt ;
-
 
1200
	    IDENTIFIER id = this_tok->pp_data.id.use ;
-
 
1201
	    t = ( int ) DEREF_ulong ( id_no ( id ) ) ;
-
 
1202
	    tt = primary_form ( t ) ;
-
 
1203
	    if ( tt != t ) {
-
 
1204
		HASHID nm ;
-
 
1205
		if ( in_pragma_dir ) break ;
-
 
1206
		nm = this_tok->pp_data.id.hash ;
-
 
1207
		report ( crt_loc, ERR_lex_digraph_iso ( nm, tt ) ) ;
-
 
1208
		t = tt ;
-
 
1209
	    }
-
 
1210
	    this_tok->tok = t ;
-
 
1211
#if LANGUAGE_CPP
-
 
1212
	    if ( t == lex_compl_H1 ) goto compl_label ;
-
 
1213
#endif
1236
#endif
1214
	    break ;
1237
		break;
1215
	}
-
 
1216
 
-
 
1217
	case lex_unknown : {
-
 
1218
	    /* Unknown characters */
-
 
1219
	    unsigned long u ;
-
 
1220
	    int ch = CHAR_SIMPLE ;
-
 
1221
	    u = get_multi_char ( this_tok->pp_data.buff, &ch ) ;
-
 
1222
	    if ( ch == CHAR_SIMPLE ) {
-
 
1223
		if ( is_legal_char ( u ) ) {
-
 
1224
		    if ( !is_white_char ( u ) ) break ;
-
 
1225
		} else {
-
 
1226
		    int c = ( int ) u ;
-
 
1227
		    report ( crt_loc, ERR_lex_pptoken_unknown ( c ) ) ;
-
 
1228
		}
-
 
1229
	    } else {
-
 
1230
		report ( crt_loc, ERR_lex_pptoken_unicode ( u ) ) ;
-
 
1231
	    }
-
 
1232
	    this_tok->tok = lex_ignore_token ;
-
 
1233
	    t = expand_token ( store ) ;
-
 
1234
	    break ;
-
 
1235
	}
1238
	}
-
 
1239
 
-
 
1240
	case lex_unknown: {
-
 
1241
		/* Unknown characters */
-
 
1242
		unsigned long u;
-
 
1243
		int ch = CHAR_SIMPLE;
-
 
1244
		u = get_multi_char(this_tok->pp_data.buff, &ch);
-
 
1245
		if (ch == CHAR_SIMPLE) {
-
 
1246
			if (is_legal_char(u)) {
-
 
1247
				if (!is_white_char(u)) {
-
 
1248
					break;
1236
    }
1249
				}
-
 
1250
			} else {
-
 
1251
				int c = (int)u;
-
 
1252
				report(crt_loc, ERR_lex_pptoken_unknown(c));
-
 
1253
			}
-
 
1254
		} else {
-
 
1255
			report(crt_loc, ERR_lex_pptoken_unicode(u));
-
 
1256
		}
-
 
1257
		this_tok->tok = lex_ignore_token;
-
 
1258
		t = expand_token(store);
-
 
1259
		break;
-
 
1260
	}
-
 
1261
	}
1237
    return ( t ) ;
1262
	return(t);
1238
}
1263
}
1239
 
1264
 
1240
 
1265
 
1241
/*
1266
/*
1242
    READ AND EXPAND THE NEXT TOKEN (PREPROCESSOR VERSION)
1267
    READ AND EXPAND THE NEXT TOKEN (PREPROCESSOR VERSION)
1243
 
1268
 
1244
    This routine is a cut-down version of expand_token with only the macro
1269
    This routine is a cut-down version of expand_token with only the macro
1245
    expansion and keyword actions.  This is for use with the stand-alone
1270
    expansion and keyword actions.  This is for use with the stand-alone
1246
    preprocessor and in the rewriting rules.
1271
    preprocessor and in the rewriting rules.
1247
*/
1272
*/
1248
 
1273
 
1249
int expand_preproc
1274
int
1250
    PROTO_N ( ( store ) )
-
 
1251
    PROTO_T ( int store )
1275
expand_preproc(int store)
1252
{
1276
{
1253
    int t ;
1277
	int t;
1254
    int expand ;
1278
	int expand;
1255
    PPTOKEN *prev_tok = crt_token ;
1279
	PPTOKEN *prev_tok = crt_token;
1256
    PPTOKEN *this_tok = prev_tok->next ;
1280
	PPTOKEN *this_tok = prev_tok->next;
1257
 
1281
 
1258
    /* Get the next token */
1282
	/* Get the next token */
1259
    start_label : {
1283
start_label:
1260
	if ( this_tok == NULL ) {
1284
	if (this_tok == NULL) {
1261
	    /* Read the token from the file */
1285
		/* Read the token from the file */
1262
	    this_tok = new_pptok () ;
1286
		this_tok = new_pptok();
1263
	    this_tok->next = NULL ;
1287
		this_tok->next = NULL;
1264
	    prev_tok->next = this_tok ;
1288
		prev_tok->next = this_tok;
1265
	    crt_token = this_tok ;
1289
		crt_token = this_tok;
1266
	    t = read_token () ;
1290
		t = read_token();
1267
	    update_column () ;
1291
		update_column();
1268
	    this_tok->tok = t ;
1292
		this_tok->tok = t;
1269
	    if ( t <= LAST_COMPLEX_TOKEN ) token_parts ( t, this_tok ) ;
1293
		if (t <= LAST_COMPLEX_TOKEN) {
-
 
1294
			token_parts(t, this_tok);
-
 
1295
		}
1270
 
1296
 
1271
	    if ( store == EXPAND_NORMAL ) {
1297
		if (store == EXPAND_NORMAL) {
1272
		/* Garbage collect stored tokens */
1298
			/* Garbage collect stored tokens */
1273
		this_tok->pp_space = 0 ;
1299
			this_tok->pp_space = 0;
1274
		prev_tok->next = free_tokens ;
1300
			prev_tok->next = free_tokens;
1275
		free_tokens = first_token ;
1301
			free_tokens = first_token;
1276
		first_token = this_tok ;
1302
			first_token = this_tok;
1277
	    } else {
1303
		} else {
1278
		this_tok->pp_space = crt_loc.column ;
1304
			this_tok->pp_space = crt_loc.column;
1279
		if ( crt_line_changed ) {
1305
			if (crt_line_changed) {
1280
		    /* Record file position */
1306
				/* Record file position */
1281
		    make_loc_tokens ( prev_tok ) ;
1307
				make_loc_tokens(prev_tok);
-
 
1308
			}
1282
		}
1309
		}
1283
	    }
-
 
1284
	    expand = 1 ;
1310
		expand = 1;
1285
 
1311
 
1286
	} else {
1312
	} else {
1287
	    /* Use a previously stored token */
1313
		/* Use a previously stored token */
1288
	    if ( this_tok->pp_space ) {
1314
		if (this_tok->pp_space) {
1289
		/* Increase space count if necessary */
1315
			/* Increase space count if necessary */
1290
		if ( !crt_line_changed ) crt_spaces++ ;
1316
			if (!crt_line_changed) {
1291
		if ( store == EXPAND_AHEAD ) this_tok->pp_space = 0 ;
1317
				crt_spaces++;
1292
	    }
1318
			}
1293
	    t = this_tok->tok ;
-
 
1294
	    if ( t == lex_ignore_token ) {
1319
			if (store == EXPAND_AHEAD) {
1295
		/* Step over any ignored tokens */
-
 
1296
		prev_tok = this_tok ;
-
 
1297
		this_tok = this_tok->next ;
1320
				this_tok->pp_space = 0;
1298
		goto start_label ;
-
 
1299
	    }
1321
			}
1300
	    crt_token = this_tok ;
-
 
1301
	    expand = 0 ;
-
 
1302
	}
1322
		}
1303
    }
-
 
1304
 
-
 
1305
    /* Deal with context switch */
-
 
1306
    if ( store == EXPAND_NORMAL ) {
-
 
1307
	OPTIONS *opts = prev_opts ;
-
 
1308
	if ( opts != crt_opts ) set_mode ( opts ) ;
-
 
1309
	prev_opts = this_tok->pp_opts ;
1323
		t = this_tok->tok;
1310
    }
-
 
1311
 
-
 
1312
    /* Deal with identifiers */
-
 
1313
    if ( t == lex_identifier ) {
1324
		if (t == lex_ignore_token) {
1314
	HASHID nm = this_tok->pp_data.id.hash ;
-
 
1315
	IDENTIFIER id = DEREF_id ( hashid_id ( nm ) ) ;
-
 
1316
	expand_label : {
-
 
1317
	    switch ( TAG_id ( id ) ) {
-
 
1318
		case id_obj_macro_tag :
-
 
1319
		case id_func_macro_tag : {
-
 
1320
		    if ( expand ) {
-
 
1321
			PPTOKEN *toks = expand_macro ( nm, file_loc, 1 ) ;
-
 
1322
			if ( !crt_line_changed ) crt_spaces++ ;
-
 
1323
			this_tok->tok = lex_ignore_token ;
1325
			/* Step over any ignored tokens */
1324
			this_tok->next = toks ;
-
 
1325
			prev_tok = this_tok ;
1326
			prev_tok = this_tok;
1326
			this_tok = toks ;
1327
			this_tok = this_tok->next;
1327
			goto start_label ;
1328
			goto start_label;
1328
		    }
-
 
1329
		    id = DEREF_id ( id_alias ( id ) ) ;
-
 
1330
		    goto expand_label ;
-
 
1331
		}
-
 
1332
		case id_keyword_tag : {
-
 
1333
		    if ( store == EXPAND_AHEAD ) {
-
 
1334
			t = ( int ) DEREF_ulong ( id_no ( id ) ) ;
-
 
1335
			this_tok->tok = t ;
-
 
1336
		    }
-
 
1337
		    break ;
-
 
1338
		}
1329
		}
-
 
1330
		crt_token = this_tok;
-
 
1331
		expand = 0;
-
 
1332
	}
-
 
1333
 
-
 
1334
	/* Deal with context switch */
-
 
1335
	if (store == EXPAND_NORMAL) {
-
 
1336
		OPTIONS *opts = prev_opts;
-
 
1337
		if (opts != crt_opts) {
-
 
1338
			set_mode(opts);
-
 
1339
		}
-
 
1340
		prev_opts = this_tok->pp_opts;
-
 
1341
	}
-
 
1342
 
-
 
1343
	/* Deal with identifiers */
-
 
1344
	if (t == lex_identifier) {
-
 
1345
		HASHID nm = this_tok->pp_data.id.hash;
-
 
1346
		IDENTIFIER id = DEREF_id(hashid_id(nm));
-
 
1347
expand_label:
-
 
1348
		switch (TAG_id(id)) {
-
 
1349
		case id_obj_macro_tag:
-
 
1350
		case id_func_macro_tag:
-
 
1351
			if (expand) {
-
 
1352
				PPTOKEN *toks = expand_macro(nm, file_loc, 1);
-
 
1353
				if (!crt_line_changed)crt_spaces++;
-
 
1354
				this_tok->tok = lex_ignore_token;
-
 
1355
				this_tok->next = toks;
-
 
1356
				prev_tok = this_tok;
-
 
1357
				this_tok = toks;
-
 
1358
				goto start_label;
-
 
1359
			}
-
 
1360
			id = DEREF_id(id_alias(id));
-
 
1361
			goto expand_label;
-
 
1362
		case id_keyword_tag:
-
 
1363
			if (store == EXPAND_AHEAD) {
-
 
1364
				t = (int)DEREF_ulong(id_no(id));
-
 
1365
				this_tok->tok = t;
-
 
1366
			}
-
 
1367
			break;
1339
		case id_iso_keyword_tag : {
1368
		case id_iso_keyword_tag:
1340
		    if ( store == EXPAND_AHEAD ) {
1369
			if (store == EXPAND_AHEAD) {
1341
			t = ( int ) DEREF_ulong ( id_no ( id ) ) ;
1370
				t = (int)DEREF_ulong(id_no(id));
1342
			if ( t >= FIRST_SYMBOL && t <= LAST_SYMBOL ) {
1371
				if (t >= FIRST_SYMBOL && t <= LAST_SYMBOL) {
1343
			    /* Will be reinterpreted later */
1372
					/* Will be reinterpreted later */
1344
			    t = lex_and_H2 ;
1373
					t = lex_and_H2;
-
 
1374
				}
-
 
1375
				this_tok->tok = t;
1345
			}
1376
			}
1346
			this_tok->tok = t ;
-
 
1347
		    }
-
 
1348
		    break ;
1377
			break;
1349
		}
1378
		}
1350
	    }
1379
		this_tok->pp_data.id.use = id;
1351
	}
1380
	}
1352
	this_tok->pp_data.id.use = id ;
-
 
1353
    }
-
 
1354
    return ( t ) ;
1381
	return(t);
1355
}
1382
}
1356
 
1383
 
1357
 
1384
 
1358
/*
1385
/*
1359
    PARSE A TEMPLATE IDENTIFIER
1386
    PARSE A TEMPLATE IDENTIFIER
1360
 
1387
 
1361
    This routine is called after the optional 'template' at the start of
1388
    This routine is called after the optional 'template' at the start of
1362
    a qualified identifier or a field member selector.  It forces the
1389
    a qualified identifier or a field member selector.  It forces the
1363
    following identifier to be treated as a template-id even if it doesn't
1390
    following identifier to be treated as a template-id even if it doesn't
1364
    seem to be one.
1391
    seem to be one.
1365
*/
1392
*/
1366
 
1393
 
1367
void rescan_template
1394
void
1368
    PROTO_N ( ( ns ) )
-
 
1369
    PROTO_T ( NAMESPACE ns )
1395
rescan_template(NAMESPACE ns)
1370
{
1396
{
1371
    PPTOKEN *p = crt_token ;
1397
	PPTOKEN *p = crt_token;
1372
    crt_lookup = ns ;
1398
	crt_lookup = ns;
1373
    have_template = 0 ;
1399
	have_template = 0;
1374
    IGNORE expand_token ( EXPAND_TEMPLATE ) ;
1400
	IGNORE expand_token(EXPAND_TEMPLATE);
1375
    if ( !have_template ) {
1401
	if (!have_template) {
1376
	/* Didn't read template-id */
1402
		/* Didn't read template-id */
1377
	report ( crt_loc, ERR_temp_names_bad () ) ;
1403
		report(crt_loc, ERR_temp_names_bad());
1378
    }
1404
	}
1379
    crt_token = p ;
1405
	crt_token = p;
1380
    crt_lookup = ns ;
1406
	crt_lookup = ns;
1381
    return ;
1407
	return;
1382
}
1408
}