diff options
author | Zack Weinberg <zack@wolery.cumb.org> | 2000-07-08 19:00:39 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 2000-07-08 19:00:39 +0000 |
commit | bfb9dc7faa9330d05c109e8a40710b752dddea14 (patch) | |
tree | a059282fddfed885a943028a39f8275bd50d44e0 /gcc/cpplex.c | |
parent | ffc14f31599c19980371b165a7f6ad2e0a93015c (diff) | |
download | gcc-bfb9dc7faa9330d05c109e8a40710b752dddea14.zip gcc-bfb9dc7faa9330d05c109e8a40710b752dddea14.tar.gz gcc-bfb9dc7faa9330d05c109e8a40710b752dddea14.tar.bz2 |
cpplib.h (struct cpp_name): Now struct cpp_string.
* cpplib.h (struct cpp_name): Now struct cpp_string.
(CPP_INT, CPP_FLOAT, CPP_NUMBER, CPP_COMMENT,
CPP_HEADER_NAME): Change to type S.
(struct cpp_token): Rename 'name' field to 'str'. Add 'node'
field, a cpp_hashnode *. All references to val.name updated
to use val.str or val.node as appropriate.
(struct cpp_reader): Add spec_nodes field.
(cpp_idcmp): Now cpp_ideq; takes a token * and a char *.
* cpphash.h (struct spec_nodes): New.
(enum spell_type): Reorder. Only SPELL_STRING tokens use
val.str. All references to 'spelling > SPELL_NONE' updated to
match.
(CPP_IN_SYSTEM_HEADER): Check pfile->buffer and
pfile->buffer->inc are not NULL before dereferencing them.
* cpplex.c (parse_name): Take a pointer to the current token,
plus current position and limit as args; return the new
position; don't copy the text of a name into the string
buffer, instead call cpp_lookup and store the node pointer.
If extending a token, copy out the text of the old into a
scratch buffer, append the new, look that up and store the new
node pointer. Inline.
(maybe_paste_with_next): If the result of paste is a NAME,
then look up the pasted text and store its node pointer.
(lex_line): Adjust for new parse_name interface.
Check for L"str", L'str' using spec_nodes->n_L.
(spell_token): SPELL_IDENT tokens have their spelling in
val.node->name. Handle SPELL_STRING tokens that don't have
string delimiters.
(_cpp_expand_name_space,
(can_paste): Check for L ## "str" using spec_nodes->n_L.
(cpp_get_token, special_symbol): No need to call cpp_lookup.
(cpp_idcmp): Now cpp_ideq; take a token * and a const char *;
return 1=equal 0=not, not a tristate.
* cpphash.c (var_args_str): Delete.
(find_param): Compare node fields directly.
(is__va_args__): Use CPP_PEDANTIC. Just compare
token->val.node with spec_nodes->n__VA_ARGS__.
(dump_funlike_macro): Don't use var_args_str.
* cpplib.c (_cpp_check_directive): Just walk through
spec_nodes->dirs comparing pointers.
(get_define_node, do_pragma_poison, detect_if_not_defined,
parse_ifdef): The identifier has already been looked up.
(do_ifdef, do_ifndef): parse_ifdef won't return a poisoned
node.
(do_if): Only call detect_if_not_defined at beginning of file.
(_cpp_parse_assertion): Only copy string pointers for
SPELL_STRING tokens.
(pragma_dispatch): Take a node pointer and examine its name
field.
(_cpp_init_stacks): Also initialize the spec_nodes structure.
* cppinit.c (cpp_reader_init): Call _cpp_init_stacks after
_cpp_init_macros.
(cpp_cleanup): Free pfile->spec_nodes. Call _cpp_cleanup_* in
reverse order from the corresponding _cpp_init_* routines.
* cppexp.c (parse_number, parse_charconst, parse_defined,
lex): Check val.node->type instead of calling cpp_defined.
Use spec_nodes entries where appropriate.
* fix-header.c, scan-decls.c: Update for interface changes.
From-SVN: r34926
Diffstat (limited to 'gcc/cpplex.c')
-rw-r--r-- | gcc/cpplex.c | 242 |
1 files changed, 114 insertions, 128 deletions
diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 23d6540..5b22627 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -73,8 +73,9 @@ static const unsigned char *backslash_start PARAMS ((cpp_reader *, static int skip_block_comment PARAMS ((cpp_reader *)); static int skip_line_comment PARAMS ((cpp_reader *)); static void skip_whitespace PARAMS ((cpp_reader *, int)); -static void parse_name PARAMS ((cpp_reader *, cpp_toklist *, cpp_name *)); -static void parse_number PARAMS ((cpp_reader *, cpp_toklist *, cpp_name *)); +static const U_CHAR *parse_name PARAMS ((cpp_reader *, cpp_token *, + const U_CHAR *, const U_CHAR *)); +static void parse_number PARAMS ((cpp_reader *, cpp_toklist *, cpp_string *)); static void parse_string PARAMS ((cpp_reader *, cpp_toklist *, cpp_token *, unsigned int)); static int trigraph_ok PARAMS ((cpp_reader *, const unsigned char *)); @@ -111,9 +112,9 @@ static void release_temp_tokens PARAMS ((cpp_reader *)); static U_CHAR * quote_string PARAMS ((U_CHAR *, const U_CHAR *, unsigned int)); static void process_directive PARAMS ((cpp_reader *, const cpp_token *)); -#define INIT_TOKEN_NAME(list, token) \ - do {(token)->val.name.len = 0; \ - (token)->val.name.text = (list)->namebuf + (list)->name_used; \ +#define INIT_TOKEN_STR(list, token) \ + do {(token)->val.str.len = 0; \ + (token)->val.str.text = (list)->namebuf + (list)->name_used; \ } while (0) #define VALID_SIGN(c, prevc) \ @@ -148,8 +149,12 @@ static void process_directive PARAMS ((cpp_reader *, const cpp_token *)); /* An upper bound on the number of bytes needed to spell a token, including preceding whitespace. */ -#define TOKEN_LEN(token) (5 + (token_spellings[(token)->type].type > \ - SPELL_NONE ? (token)->val.name.len: 0)) +#define TOKEN_SPELL(token) token_spellings[(token)->type].type +#define TOKEN_LEN(token) (5 + (TOKEN_SPELL(token) == SPELL_STRING \ + ? (token)->val.str.len \ + : (TOKEN_SPELL(token) == SPELL_IDENT \ + ? (token)->val.node->length \ + : 0))) #define T(e, s) {SPELL_OPERATOR, (const U_CHAR *) s}, #define I(e, s) {SPELL_IDENT, s}, @@ -443,8 +448,8 @@ _cpp_glue_header_name (pfile) hdr = get_temp_token (pfile); hdr->type = CPP_HEADER_NAME; hdr->flags = 0; - hdr->val.name.text = buf; - hdr->val.name.len = len; + hdr->val.str.text = buf; + hdr->val.str.len = len; return hdr; } @@ -469,8 +474,8 @@ _cpp_expand_name_space (list, len) unsigned int i; for (i = 0; i < list->tokens_used; i++) - if (token_spellings[list->tokens[i].type].type > SPELL_NONE) - list->tokens[i].val.name.text += (list->namebuf - old_namebuf); + if (token_spellings[list->tokens[i].type].type == SPELL_STRING) + list->tokens[i].val.str.text += (list->namebuf - old_namebuf); } } @@ -583,10 +588,11 @@ _cpp_equiv_tokens (a, b) case SPELL_NONE: return a->val.aux == b->val.aux; /* arg_no or character. */ case SPELL_IDENT: + return a->val.node == b->val.node; case SPELL_STRING: - return (a->val.name.len == b->val.name.len - && !memcmp (a->val.name.text, b->val.name.text, - a->val.name.len)); + return (a->val.str.len == b->val.str.len + && !memcmp (a->val.str.text, b->val.str.text, + a->val.str.len)); } return 0; @@ -611,34 +617,19 @@ _cpp_equiv_toklists (a, b) } /* Utility routine: - Compares, in the manner of strcmp(3), the token beginning at TOKEN - and extending for LEN characters to the NUL-terminated string - STRING. Typical usage: - if (! cpp_idcmp (pfile->token_buffer + here, CPP_WRITTEN (pfile) - here, - "inline")) - { ... } - */ + Compares, the token TOKEN to the NUL-terminated string STRING. + TOKEN must be a CPP_NAME. Returns 1 for equal, 0 for unequal. */ int -cpp_idcmp (token, len, string) - const U_CHAR *token; - size_t len; +cpp_ideq (token, string) + const cpp_token *token; const char *string; { - size_t len2 = strlen (string); - int r; - - if ((r = memcmp (token, string, MIN (len, len2)))) - return r; - - /* The longer of the two strings sorts after the shorter. */ - if (len == len2) + if (token->type != CPP_NAME) return 0; - else if (len < len2) - return -1; - else - return 1; + + return !ustrcmp (token->val.node->name, (const U_CHAR *)string); } /* Lexing algorithm. @@ -965,51 +956,43 @@ skip_whitespace (pfile, in_directive) } /* Parse (append) an identifier. */ -static void -parse_name (pfile, list, name) +static inline const U_CHAR * +parse_name (pfile, tok, cur, rlimit) cpp_reader *pfile; - cpp_toklist *list; - cpp_name *name; + cpp_token *tok; + const U_CHAR *cur, *rlimit; { - const unsigned char *name_limit; - unsigned char *namebuf; - cpp_buffer *buffer = pfile->buffer; - register const unsigned char *cur = buffer->cur; - - expanded: - name_limit = list->namebuf + list->name_cap; - namebuf = list->namebuf + list->name_used; + const U_CHAR *name = cur; + unsigned int len; - for (; cur < buffer->rlimit && namebuf < name_limit; ) + while (cur < rlimit) { - unsigned char c = *namebuf = *cur; /* Copy a single char. */ - - if (! is_idchar(c)) - goto out; - namebuf++; - cur++; + if (! is_idchar (*cur)) + break; /* $ is not a legal identifier character in the standard, but is commonly accepted as an extension. Don't warn about it in skipped conditional blocks. */ - if (c == '$' && CPP_PEDANTIC (pfile) && ! pfile->skipping) + if (*cur == '$' && CPP_PEDANTIC (pfile) && ! pfile->skipping) { - buffer->cur = cur; + CPP_BUFFER (pfile)->cur = cur; cpp_pedwarn (pfile, "'$' character in identifier"); } + cur++; } + len = cur - name; - /* Run out of name space? */ - if (cur < buffer->rlimit) + if (tok->val.node) { - list->name_used = namebuf - list->namebuf; - auto_expand_name_space (list); - goto expanded; + unsigned int oldlen = tok->val.node->length; + U_CHAR *newname = alloca (oldlen + len); + memcpy (newname, tok->val.node->name, oldlen); + memcpy (newname + oldlen, name, len); + len += oldlen; + name = newname; } - out: - buffer->cur = cur; - name->len = namebuf - name->text; - list->name_used = namebuf - list->namebuf; + tok->val.node = cpp_lookup (pfile, name, len); + return cur; } /* Parse (append) a number. */ @@ -1017,7 +1000,7 @@ static void parse_number (pfile, list, name) cpp_reader *pfile; cpp_toklist *list; - cpp_name *name; + cpp_string *name; { const unsigned char *name_limit; unsigned char *namebuf; @@ -1057,7 +1040,7 @@ parse_number (pfile, list, name) } /* Places a string terminated by an unescaped TERMINATOR into a - cpp_name, which should be expandable and thus at the top of the + cpp_string, which should be expandable and thus at the top of the list's stack. Handles embedded trigraphs, if necessary, and escaped newlines. @@ -1073,7 +1056,7 @@ parse_string (pfile, list, token, terminator) unsigned int terminator; { cpp_buffer *buffer = pfile->buffer; - cpp_name *name = &token->val.name; + cpp_string *name = &token->val.str; register const unsigned char *cur = buffer->cur; const unsigned char *name_limit; unsigned char *namebuf; @@ -1221,9 +1204,9 @@ save_comment (list, token, from, len, type) if (list->name_used + len > list->name_cap) _cpp_expand_name_space (list, len); - INIT_TOKEN_NAME (list, token); + INIT_TOKEN_STR (list, token); token->type = CPP_COMMENT; - token->val.name.len = len; + token->val.str.len = len; buffer = list->namebuf + list->name_used; list->name_used += len; @@ -1326,21 +1309,21 @@ lex_line (pfile, list) prev_dot = PREV_TOKEN_TYPE == CPP_DOT && IMMED_TOKEN (); if (prev_dot) cur_token--; - INIT_TOKEN_NAME (list, cur_token); + INIT_TOKEN_STR (list, cur_token); /* Prepend an immediately previous CPP_DOT token. */ if (prev_dot) { if (list->name_cap == list->name_used) auto_expand_name_space (list); - cur_token->val.name.len = 1; + cur_token->val.str.len = 1; list->namebuf[list->name_used++] = '.'; } continue_number: cur_token->type = CPP_NUMBER; /* Before parse_number. */ buffer->cur = cur; - parse_number (pfile, list, &cur_token->val.name); + parse_number (pfile, list, &cur_token->val.str); cur = buffer->cur; } /* Check for # 123 form of #line. */ @@ -1364,13 +1347,11 @@ lex_line (pfile, list) case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': cur--; /* Backup character. */ - INIT_TOKEN_NAME (list, cur_token); + cur_token->val.node = 0; cur_token->type = CPP_NAME; /* Identifier, macro etc. */ continue_name: - buffer->cur = cur; - parse_name (pfile, list, &cur_token->val.name); - cur = buffer->cur; + cur = parse_name (pfile, cur_token, cur, buffer->rlimit); if (MIGHT_BE_DIRECTIVE ()) list->directive = _cpp_check_directive (pfile, cur_token, @@ -1395,18 +1376,15 @@ lex_line (pfile, list) cur_token->type = c == '\'' ? CPP_CHAR : CPP_STRING; /* Do we have a wide string? */ if (cur_token[-1].type == CPP_NAME && IMMED_TOKEN () - && cur_token[-1].val.name.len == 1 - && cur_token[-1].val.name.text[0] == 'L' + && cur_token[-1].val.node == pfile->spec_nodes->n_L && !CPP_TRADITIONAL (pfile)) { - /* No need for 'L' any more. */ - list->name_used--; (--cur_token)->type = (c == '\'' ? CPP_WCHAR : CPP_WSTRING); } do_parse_string: /* Here c is one of ' " or >. */ - INIT_TOKEN_NAME (list, cur_token); + INIT_TOKEN_STR (list, cur_token); buffer->cur = cur; parse_string (pfile, list, cur_token, c); cur = buffer->cur; @@ -1797,7 +1775,7 @@ lex_line (pfile, list) { if (first[1].type == CPP_NAME) cpp_error (pfile, "invalid preprocessing directive #%.*s", - (int) first[1].val.name.len, first[1].val.name.text); + (int) first[1].val.node->length, first[1].val.node->name); else cpp_error (pfile, "invalid preprocessing directive"); } @@ -1900,23 +1878,27 @@ spell_token (pfile, token, buffer) break; case SPELL_IDENT: - memcpy (buffer, token->val.name.text, token->val.name.len); - buffer += token->val.name.len; + memcpy (buffer, token->val.node->name, token->val.node->length); + buffer += token->val.node->length; break; case SPELL_STRING: { - unsigned char c; - if (token->type == CPP_WSTRING || token->type == CPP_WCHAR) *buffer++ = 'L'; - c = '\''; + if (token->type == CPP_STRING || token->type == CPP_WSTRING) - c = '"'; - *buffer++ = c; - memcpy (buffer, token->val.name.text, token->val.name.len); - buffer += token->val.name.len; - *buffer++ = c; + *buffer++ = '"'; + if (token->type == CPP_CHAR || token->type == CPP_WCHAR) + *buffer++ = '\''; + + memcpy (buffer, token->val.str.text, token->val.str.len); + buffer += token->val.str.len; + + if (token->type == CPP_STRING || token->type == CPP_WSTRING) + *buffer++ = '"'; + if (token->type == CPP_CHAR || token->type == CPP_WCHAR) + *buffer++ = '\''; } break; @@ -2096,7 +2078,7 @@ is_macro_disabled (pfile, expansion, token) if (CPP_OPTION (pfile, warn_traditional)) cpp_warning (pfile, "function macro %.*s must be used with arguments in traditional C", - (int) token->val.name.len, token->val.name.text); + (int) token->val.node->length, token->val.node->name); return 1; } } @@ -2314,8 +2296,8 @@ make_string_token (token, text, len) buf = (U_CHAR *) xmalloc (len * 4); token->type = CPP_STRING; token->flags = 0; - token->val.name.text = buf; - token->val.name.len = quote_string (buf, text, len) - buf; + token->val.str.text = buf; + token->val.str.len = quote_string (buf, text, len) - buf; return token; } @@ -2335,8 +2317,8 @@ alloc_number_token (pfile, number) result->type = CPP_NUMBER; result->flags = 0; - result->val.name.text = (U_CHAR *) buf; - result->val.name.len = strlen (buf); + result->val.str.text = (U_CHAR *) buf; + result->val.str.len = strlen (buf); return result; } @@ -2369,10 +2351,10 @@ release_temp_tokens (pfile) { cpp_token *token = pfile->temp_tokens[--pfile->temp_used]; - if (token_spellings[token->type].type > SPELL_NONE) + if (token_spellings[token->type].type == SPELL_STRING) { - free ((char *) token->val.name.text); - token->val.name.text = 0; + free ((char *) token->val.str.text); + token->val.str.text = 0; } } } @@ -2394,9 +2376,9 @@ _cpp_free_temp_tokens (pfile) if (pfile->date) { - free ((char *) pfile->date->val.name.text); + free ((char *) pfile->date->val.str.text); free (pfile->date); - free ((char *) pfile->time->val.name.text); + free ((char *) pfile->time->val.str.text); free (pfile->time); } } @@ -2410,11 +2392,11 @@ duplicate_token (pfile, token) cpp_token *result = get_temp_token (pfile); *result = *token; - if (token_spellings[token->type].type > SPELL_NONE) + if (token_spellings[token->type].type == SPELL_STRING) { - U_CHAR *buff = (U_CHAR *) xmalloc (token->val.name.len); - memcpy (buff, token->val.name.text, token->val.name.len); - result->val.name.text = buff; + U_CHAR *buff = (U_CHAR *) xmalloc (token->val.str.len); + memcpy (buff, token->val.str.text, token->val.str.len); + result->val.str.text = buff; } return result; } @@ -2489,13 +2471,11 @@ can_paste (pfile, token1, token2, digraph) case CPP_NAME: if (b == CPP_NAME) return CPP_NAME; if (b == CPP_NUMBER - && is_numstart(token2->val.name.text[0])) return CPP_NAME; + && is_numstart(token2->val.str.text[0])) return CPP_NAME; if (b == CPP_CHAR - && token1->val.name.len == 1 - && token1->val.name.text[0] == 'L') return CPP_WCHAR; + && token1->val.node == pfile->spec_nodes->n_L) return CPP_WCHAR; if (b == CPP_STRING - && token1->val.name.len == 1 - && token1->val.name.text[0] == 'L') return CPP_WSTRING; + && token1->val.node == pfile->spec_nodes->n_L) return CPP_WSTRING; break; case CPP_NUMBER: @@ -2504,7 +2484,7 @@ can_paste (pfile, token1, token2, digraph) if (b == CPP_DOT) return CPP_NUMBER; /* Numbers cannot have length zero, so this is safe. */ if ((b == CPP_PLUS || b == CPP_MINUS) - && VALID_SIGN ('+', token1->val.name.text[token1->val.name.len - 1])) + && VALID_SIGN ('+', token1->val.str.text[token1->val.str.len - 1])) return CPP_NUMBER; break; @@ -2578,15 +2558,21 @@ maybe_paste_with_next (pfile, token) if (type == CPP_NAME || type == CPP_NUMBER) { /* Join spellings. */ - U_CHAR *buff, *buff2; + U_CHAR *buf, *end; pasted = get_temp_token (pfile); - buff = (U_CHAR *) xmalloc (TOKEN_LEN (token) + TOKEN_LEN (second)); - buff2 = spell_token (pfile, token, buff); - buff2 = spell_token (pfile, second, buff2); + buf = (U_CHAR *) alloca (TOKEN_LEN (token) + TOKEN_LEN (second)); + end = spell_token (pfile, token, buf); + end = spell_token (pfile, second, end); + *end = '\0'; - pasted->val.name.text = buff; - pasted->val.name.len = buff2 - buff; + if (type == CPP_NAME) + pasted->val.node = cpp_lookup (pfile, buf, end - buf); + else + { + pasted->val.str.text = uxstrdup (buf); + pasted->val.str.len = end - buf; + } } else if (type == CPP_WCHAR || type == CPP_WSTRING) pasted = duplicate_token (pfile, second); @@ -2597,7 +2583,7 @@ maybe_paste_with_next (pfile, token) } pasted->type = type; - pasted->flags = digraph ? DIGRAPH: 0; + pasted->flags = digraph ? DIGRAPH : 0; } /* The pasted token gets the whitespace flags and position of the @@ -2681,8 +2667,8 @@ stringify_arg (pfile, token) } result->type = CPP_STRING; - result->val.name.text = main_buf; - result->val.name.len = buf_used; + result->val.str.text = main_buf; + result->val.str.len = buf_used; restore_macro_expansion (pfile, prev_value); return result; } @@ -2907,7 +2893,7 @@ cpp_get_token (pfile) if (pfile->no_expand_level == pfile->cur_context || pfile->paste_level) return token; - node = cpp_lookup (pfile, token->val.name.text, token->val.name.len); + node = token->val.node; if (node->type == T_VOID) return token; @@ -3194,7 +3180,7 @@ special_symbol (pfile, node, token) #ifdef STDC_0_IN_SYSTEM_HEADERS if (CPP_IN_SYSTEM_HEADER (pfile) - && !cpp_defined (pfile, DSC("__STRICT_ANSI__"))) + && pfile->spec_nodes->n__STRICT_ANSI__->type == T_VOID) stdc = 0; #endif result = alloc_number_token (pfile, stdc); @@ -3217,16 +3203,16 @@ special_symbol (pfile, node, token) pfile->time = make_string_token ((cpp_token *) xmalloc (sizeof (cpp_token)), DSC("12:34:56")); - sprintf ((char *) pfile->date->val.name.text, "%s %2d %4d", + sprintf ((char *) pfile->date->val.str.text, "%s %2d %4d", monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900); - sprintf ((char *) pfile->time->val.name.text, "%02d:%02d:%02d", + sprintf ((char *) pfile->time->val.str.text, "%02d:%02d:%02d", tb->tm_hour, tb->tm_min, tb->tm_sec); } result = node->type == T_DATE ? pfile->date: pfile->time; break; case T_POISON: - cpp_error (pfile, "attempt to use poisoned \"%s\".", node->name); + cpp_error (pfile, "attempt to use poisoned \"%s\"", node->name); return token; default: |