c-lex.c (get_nonpadding_token): Remove.
* c-lex.c (get_nonpadding_token): Remove. (c_lex_with_flags): Push timevar and eat padding here. Improve stray token diagnostic. (lex_string): Replace logic with switch statement, eat padding token here. * cp/parser.c (cp_lexer_get_preprocessor_token): Remove unneeded padding token checking. testsuite: * gcc.dg/cpp/direct2.c: Adjust expected errors, robustify parser resyncing. * gcc.dg/cpp/direct2s.c: Likewise. From-SVN: r89577
This commit is contained in:
parent
bbdb90f76b
commit
51e63e60b3
|
@ -1,3 +1,11 @@
|
|||
2004-10-26 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* c-lex.c (get_nonpadding_token): Remove.
|
||||
(c_lex_with_flags): Push timevar and eat padding here. Improve
|
||||
stray token diagnostic.
|
||||
(lex_string): Replace logic with switch statement, eat padding
|
||||
token here.
|
||||
|
||||
2004-10-26 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
PR 18149
|
||||
|
|
173
gcc/c-lex.c
173
gcc/c-lex.c
|
@ -327,32 +327,28 @@ cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc,
|
|||
(const char *) NODE_NAME (node));
|
||||
}
|
||||
|
||||
static inline const cpp_token *
|
||||
get_nonpadding_token (void)
|
||||
{
|
||||
const cpp_token *tok;
|
||||
timevar_push (TV_CPP);
|
||||
do
|
||||
tok = cpp_get_token (parse_in);
|
||||
while (tok->type == CPP_PADDING);
|
||||
timevar_pop (TV_CPP);
|
||||
|
||||
return tok;
|
||||
}
|
||||
/* Read a token and return its type. Fill *VALUE with its value, if
|
||||
applicable. Fill *CPP_FLAGS with the token's flags, if it is
|
||||
non-NULL. */
|
||||
|
||||
enum cpp_ttype
|
||||
c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
||||
{
|
||||
const cpp_token *tok;
|
||||
location_t atloc;
|
||||
static bool no_more_pch;
|
||||
const cpp_token *tok;
|
||||
enum cpp_ttype type;
|
||||
|
||||
timevar_push (TV_CPP);
|
||||
retry:
|
||||
tok = get_nonpadding_token ();
|
||||
|
||||
tok = cpp_get_token (parse_in);
|
||||
type = tok->type;
|
||||
|
||||
retry_after_at:
|
||||
switch (tok->type)
|
||||
switch (type)
|
||||
{
|
||||
case CPP_PADDING:
|
||||
goto retry;
|
||||
|
||||
case CPP_NAME:
|
||||
*value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
|
||||
break;
|
||||
|
@ -384,33 +380,52 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
|||
|
||||
case CPP_ATSIGN:
|
||||
/* An @ may give the next token special significance in Objective-C. */
|
||||
atloc = input_location;
|
||||
tok = get_nonpadding_token ();
|
||||
if (c_dialect_objc ())
|
||||
{
|
||||
tree val;
|
||||
switch (tok->type)
|
||||
location_t atloc = input_location;
|
||||
|
||||
retry_at:
|
||||
tok = cpp_get_token (parse_in);
|
||||
type = tok->type;
|
||||
switch (type)
|
||||
{
|
||||
case CPP_NAME:
|
||||
val = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
|
||||
if (objc_is_reserved_word (val))
|
||||
{
|
||||
*value = val;
|
||||
return CPP_AT_NAME;
|
||||
}
|
||||
break;
|
||||
|
||||
case CPP_PADDING:
|
||||
goto retry_at;
|
||||
|
||||
case CPP_STRING:
|
||||
case CPP_WSTRING:
|
||||
return lex_string (tok, value, true);
|
||||
type = lex_string (tok, value, true);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
case CPP_NAME:
|
||||
*value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
|
||||
if (objc_is_reserved_word (*value))
|
||||
{
|
||||
type = CPP_AT_NAME;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
/* ... or not. */
|
||||
error ("%Hstray %<@%> in program", &atloc);
|
||||
goto retry_after_at;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* ... or not. */
|
||||
error ("%Hstray '@' in program", &atloc);
|
||||
goto retry_after_at;
|
||||
/* FALLTHROUGH */
|
||||
case CPP_HASH:
|
||||
case CPP_PASTE:
|
||||
{
|
||||
unsigned char name[4];
|
||||
|
||||
*cpp_spell_token (parse_in, tok, name) = 0;
|
||||
|
||||
error ("stray %qs in program", name);
|
||||
}
|
||||
|
||||
goto retry;
|
||||
|
||||
case CPP_OTHER:
|
||||
{
|
||||
|
@ -419,9 +434,9 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
|||
if (c == '"' || c == '\'')
|
||||
error ("missing terminating %c character", (int) c);
|
||||
else if (ISGRAPH (c))
|
||||
error ("stray '%c' in program", (int) c);
|
||||
error ("stray %qc in program", (int) c);
|
||||
else
|
||||
error ("stray '\\%o' in program", (int) c);
|
||||
error ("stray %<\\%o%> in program", (int) c);
|
||||
}
|
||||
goto retry;
|
||||
|
||||
|
@ -433,8 +448,12 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
|||
case CPP_STRING:
|
||||
case CPP_WSTRING:
|
||||
if (!c_lex_return_raw_strings)
|
||||
return lex_string (tok, value, false);
|
||||
/* else fall through */
|
||||
{
|
||||
type = lex_string (tok, value, false);
|
||||
break;
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case CPP_PRAGMA:
|
||||
*value = build_string (tok->val.str.len, (char *) tok->val.str.text);
|
||||
|
@ -451,15 +470,18 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
|||
break;
|
||||
}
|
||||
|
||||
if (cpp_flags)
|
||||
*cpp_flags = tok->flags;
|
||||
|
||||
if (!no_more_pch)
|
||||
{
|
||||
no_more_pch = true;
|
||||
c_common_no_more_pch ();
|
||||
}
|
||||
|
||||
if (cpp_flags)
|
||||
*cpp_flags = tok->flags;
|
||||
return tok->type;
|
||||
|
||||
timevar_pop (TV_CPP);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
enum cpp_ttype
|
||||
|
@ -690,7 +712,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
|
|||
{
|
||||
tree value;
|
||||
bool wide = false;
|
||||
size_t count = 1;
|
||||
size_t concats = 0;
|
||||
struct obstack str_ob;
|
||||
cpp_string istr;
|
||||
|
||||
|
@ -702,51 +724,58 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
|
|||
if (tok->type == CPP_WSTRING)
|
||||
wide = true;
|
||||
|
||||
tok = get_nonpadding_token ();
|
||||
if (c_dialect_objc () && tok->type == CPP_ATSIGN)
|
||||
retry:
|
||||
tok = cpp_get_token (parse_in);
|
||||
switch (tok->type)
|
||||
{
|
||||
objc_string = true;
|
||||
tok = get_nonpadding_token ();
|
||||
}
|
||||
if (tok->type == CPP_STRING || tok->type == CPP_WSTRING)
|
||||
{
|
||||
gcc_obstack_init (&str_ob);
|
||||
obstack_grow (&str_ob, &str, sizeof (cpp_string));
|
||||
|
||||
do
|
||||
case CPP_PADDING:
|
||||
goto retry;
|
||||
case CPP_ATSIGN:
|
||||
if (c_dialect_objc ())
|
||||
{
|
||||
count++;
|
||||
if (tok->type == CPP_WSTRING)
|
||||
wide = true;
|
||||
obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
|
||||
|
||||
tok = get_nonpadding_token ();
|
||||
if (c_dialect_objc () && tok->type == CPP_ATSIGN)
|
||||
{
|
||||
objc_string = true;
|
||||
tok = get_nonpadding_token ();
|
||||
}
|
||||
objc_string = true;
|
||||
goto retry;
|
||||
}
|
||||
while (tok->type == CPP_STRING || tok->type == CPP_WSTRING);
|
||||
strs = (cpp_string *) obstack_finish (&str_ob);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
case CPP_WSTRING:
|
||||
wide = true;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case CPP_STRING:
|
||||
if (!concats)
|
||||
{
|
||||
gcc_obstack_init (&str_ob);
|
||||
obstack_grow (&str_ob, &str, sizeof (cpp_string));
|
||||
}
|
||||
|
||||
concats++;
|
||||
obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* We have read one more token than we want. */
|
||||
_cpp_backup_tokens (parse_in, 1);
|
||||
if (concats)
|
||||
strs = (cpp_string *) obstack_finish (&str_ob);
|
||||
|
||||
if (count > 1 && !objc_string && warn_traditional && !in_system_header)
|
||||
if (concats && !objc_string && warn_traditional && !in_system_header)
|
||||
warning ("traditional C rejects string constant concatenation");
|
||||
|
||||
if ((c_lex_string_translate
|
||||
? cpp_interpret_string : cpp_interpret_string_notranslate)
|
||||
(parse_in, strs, count, &istr, wide))
|
||||
(parse_in, strs, concats + 1, &istr, wide))
|
||||
{
|
||||
value = build_string (istr.len, (char *) istr.text);
|
||||
free ((void *) istr.text);
|
||||
|
||||
if (c_lex_string_translate == -1)
|
||||
{
|
||||
int xlated = cpp_interpret_string_notranslate (parse_in, strs, count,
|
||||
int xlated = cpp_interpret_string_notranslate (parse_in, strs,
|
||||
concats + 1,
|
||||
&istr, wide);
|
||||
/* Assume that, if we managed to translate the string above,
|
||||
then the untranslated parsing will always succeed. */
|
||||
|
@ -782,7 +811,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
|
|||
TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
|
||||
*valp = fix_string_type (value);
|
||||
|
||||
if (strs != &str)
|
||||
if (concats)
|
||||
obstack_free (&str_ob, 0);
|
||||
|
||||
return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2004-10-26 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* parser.c (cp_lexer_get_preprocessor_token): Remove unneeded
|
||||
padding token checking.
|
||||
|
||||
2004-10-25 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR c++/18121
|
||||
|
|
|
@ -374,30 +374,9 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
|
|||
cp_token *token)
|
||||
{
|
||||
static int is_extern_c = 0;
|
||||
bool done;
|
||||
|
||||
done = false;
|
||||
/* Keep going until we get a token we like. */
|
||||
while (!done)
|
||||
{
|
||||
/* Get a new token from the preprocessor. */
|
||||
token->type = c_lex_with_flags (&token->value, &token->flags);
|
||||
/* Issue messages about tokens we cannot process. */
|
||||
switch (token->type)
|
||||
{
|
||||
case CPP_ATSIGN:
|
||||
case CPP_HASH:
|
||||
case CPP_PASTE:
|
||||
error ("invalid token");
|
||||
break;
|
||||
|
||||
default:
|
||||
/* This is a good token, so we exit the loop. */
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Now we've got our token. */
|
||||
/* Get a new token from the preprocessor. */
|
||||
token->type = c_lex_with_flags (&token->value, &token->flags);
|
||||
token->location = input_location;
|
||||
token->in_system_header = in_system_header;
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2004-10-26 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* gcc.dg/cpp/direct2.c: Adjust expected errors, robustify parser
|
||||
resyncing.
|
||||
* gcc.dg/cpp/direct2s.c: Likewise.
|
||||
|
||||
2004-10-25 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* objc.dg/image-info.m: Update for changes to section selection.
|
||||
|
|
|
@ -10,15 +10,24 @@
|
|||
#define HASHDEFINE #define
|
||||
#define HASHINCLUDE #include
|
||||
|
||||
HASH include "somerandomfile" /*{ dg-error "syntax|parse" "non-include" }*/
|
||||
HASH include "somerandomfile" /*{ dg-error "stray" "non-include" }*/
|
||||
/*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 13 }*/
|
||||
HASHINCLUDE <somerandomfile> /*{ dg-error "syntax|parse" "non-include 2" }*/
|
||||
/*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 15 }*/
|
||||
int resync_parser_1; /*{ dg-error "parse" "" }*/
|
||||
|
||||
void g ()
|
||||
HASHINCLUDE <somerandomfile> /*{ dg-error "stray" "non-include 2" }*/
|
||||
/*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 17 }*/
|
||||
int resync_parser_2;
|
||||
|
||||
void g1 ()
|
||||
{
|
||||
HASH define X 1 /* { dg-error "syntax error" "# from macro" } */
|
||||
HASHDEFINE Y 1 /* { dg-error "syntax error" "#define from macro" } */
|
||||
HASH define X 1 /* { dg-error "stray|undeclared|parse|for each" "# from macro" } */
|
||||
int resync_parser_3;
|
||||
}
|
||||
|
||||
void g2 ()
|
||||
{
|
||||
HASHDEFINE Y 1 /* { dg-error "stray|undeclared|parse|for each" "#define from macro" } */
|
||||
int resync_parser_4;
|
||||
}
|
||||
|
||||
#pragma GCC dependency "direct2.c"
|
||||
|
@ -34,4 +43,4 @@ void f ()
|
|||
#define starslash *##/
|
||||
|
||||
slashstar starslash /* { dg-error "(parse|syntax) error" "not a comment" } */
|
||||
/* { dg-warning "does not give" "paste warning(s)" { target *-*-* } 36 } */
|
||||
/* { dg-warning "does not give" "paste warning(s)" { target *-*-* } 45 } */
|
||||
|
|
|
@ -12,18 +12,27 @@
|
|||
#define HASHDEFINE #define
|
||||
#define HASHINCLUDE #include
|
||||
|
||||
HASH include "somerandomfile" /*{ dg-error "syntax|parse" "non-include" }*/
|
||||
HASH include "somerandomfile" /*{ dg-error "stray" "non-include" }*/
|
||||
/*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 15 }*/
|
||||
HASHINCLUDE <somerandomfile> /*{ dg-error "syntax|parse" "non-include 2" }*/
|
||||
/*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 17 }*/
|
||||
int resync_parser_1; /*{ dg-error "parse" "" }*/
|
||||
|
||||
void g ()
|
||||
HASHINCLUDE <somerandomfile> /*{ dg-error "stray" "non-include 2" }*/
|
||||
/*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 18 }*/
|
||||
int resync_parser_2;
|
||||
|
||||
void g1 ()
|
||||
{
|
||||
HASH define X 1 /* { dg-error "syntax error" "# from macro" } */
|
||||
HASHDEFINE Y 1 /* { dg-error "syntax error" "#define from macro" } */
|
||||
HASH define X 1 /* { dg-error "stray|undeclared|parse|for each" "# from macro" } */
|
||||
int resync_parser_3;
|
||||
}
|
||||
|
||||
#pragma GCC dependency "direct2s.c"
|
||||
void g2 ()
|
||||
{
|
||||
HASHDEFINE Y 1 /* { dg-error "stray|undeclared|parse|for each" "#define from macro" } */
|
||||
int resync_parser_4;
|
||||
}
|
||||
|
||||
#pragma GCC dependency "direct2.c"
|
||||
#
|
||||
|
||||
void f ()
|
||||
|
|
Loading…
Reference in New Issue