Commit 51e63e60 by Nathan Sidwell Committed by Nathan Sidwell

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
parent bbdb90f7
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> 2004-10-26 Geoffrey Keating <geoffk@apple.com>
PR 18149 PR 18149
......
...@@ -327,32 +327,28 @@ cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc, ...@@ -327,32 +327,28 @@ cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc,
(const char *) NODE_NAME (node)); (const char *) NODE_NAME (node));
} }
static inline const cpp_token * /* Read a token and return its type. Fill *VALUE with its value, if
get_nonpadding_token (void) applicable. Fill *CPP_FLAGS with the token's flags, if it is
{ non-NULL. */
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;
}
enum cpp_ttype enum cpp_ttype
c_lex_with_flags (tree *value, unsigned char *cpp_flags) c_lex_with_flags (tree *value, unsigned char *cpp_flags)
{ {
const cpp_token *tok;
location_t atloc;
static bool no_more_pch; static bool no_more_pch;
const cpp_token *tok;
enum cpp_ttype type;
timevar_push (TV_CPP);
retry: retry:
tok = get_nonpadding_token (); tok = cpp_get_token (parse_in);
type = tok->type;
retry_after_at: retry_after_at:
switch (tok->type) switch (type)
{ {
case CPP_PADDING:
goto retry;
case CPP_NAME: case CPP_NAME:
*value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node)); *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
break; break;
...@@ -384,33 +380,52 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags) ...@@ -384,33 +380,52 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
case CPP_ATSIGN: case CPP_ATSIGN:
/* An @ may give the next token special significance in Objective-C. */ /* An @ may give the next token special significance in Objective-C. */
atloc = input_location;
tok = get_nonpadding_token ();
if (c_dialect_objc ()) if (c_dialect_objc ())
{ {
tree val; location_t atloc = input_location;
switch (tok->type)
retry_at:
tok = cpp_get_token (parse_in);
type = tok->type;
switch (type)
{ {
case CPP_PADDING:
goto retry_at;
case CPP_STRING:
case CPP_WSTRING:
type = lex_string (tok, value, true);
break;
case CPP_NAME: case CPP_NAME:
val = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node)); *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
if (objc_is_reserved_word (val)) if (objc_is_reserved_word (*value))
{ {
*value = val; type = CPP_AT_NAME;
return CPP_AT_NAME; break;
} }
break; /* FALLTHROUGH */
case CPP_STRING:
case CPP_WSTRING:
return lex_string (tok, value, true);
default: break; default:
/* ... or not. */
error ("%Hstray %<@%> in program", &atloc);
goto retry_after_at;
} }
break;
} }
/* ... or not. */ /* FALLTHROUGH */
error ("%Hstray '@' in program", &atloc); case CPP_HASH:
goto retry_after_at; 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: case CPP_OTHER:
{ {
...@@ -419,9 +434,9 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags) ...@@ -419,9 +434,9 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
if (c == '"' || c == '\'') if (c == '"' || c == '\'')
error ("missing terminating %c character", (int) c); error ("missing terminating %c character", (int) c);
else if (ISGRAPH (c)) else if (ISGRAPH (c))
error ("stray '%c' in program", (int) c); error ("stray %qc in program", (int) c);
else else
error ("stray '\\%o' in program", (int) c); error ("stray %<\\%o%> in program", (int) c);
} }
goto retry; goto retry;
...@@ -433,8 +448,12 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags) ...@@ -433,8 +448,12 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
case CPP_STRING: case CPP_STRING:
case CPP_WSTRING: case CPP_WSTRING:
if (!c_lex_return_raw_strings) 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: case CPP_PRAGMA:
*value = build_string (tok->val.str.len, (char *) tok->val.str.text); *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) ...@@ -451,15 +470,18 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
break; break;
} }
if (cpp_flags)
*cpp_flags = tok->flags;
if (!no_more_pch) if (!no_more_pch)
{ {
no_more_pch = true; no_more_pch = true;
c_common_no_more_pch (); c_common_no_more_pch ();
} }
if (cpp_flags) timevar_pop (TV_CPP);
*cpp_flags = tok->flags;
return tok->type; return type;
} }
enum cpp_ttype enum cpp_ttype
...@@ -690,7 +712,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string) ...@@ -690,7 +712,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
{ {
tree value; tree value;
bool wide = false; bool wide = false;
size_t count = 1; size_t concats = 0;
struct obstack str_ob; struct obstack str_ob;
cpp_string istr; cpp_string istr;
...@@ -702,51 +724,58 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string) ...@@ -702,51 +724,58 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
if (tok->type == CPP_WSTRING) if (tok->type == CPP_WSTRING)
wide = true; wide = true;
tok = get_nonpadding_token (); retry:
if (c_dialect_objc () && tok->type == CPP_ATSIGN) 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); case CPP_PADDING:
obstack_grow (&str_ob, &str, sizeof (cpp_string)); goto retry;
case CPP_ATSIGN:
do if (c_dialect_objc ())
{ {
count++; objc_string = true;
if (tok->type == CPP_WSTRING) goto retry;
wide = true; }
obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string)); /* FALLTHROUGH */
tok = get_nonpadding_token (); default:
if (c_dialect_objc () && tok->type == CPP_ATSIGN) break;
{
objc_string = true; case CPP_WSTRING:
tok = get_nonpadding_token (); wide = true;
} /* FALLTHROUGH */
case CPP_STRING:
if (!concats)
{
gcc_obstack_init (&str_ob);
obstack_grow (&str_ob, &str, sizeof (cpp_string));
} }
while (tok->type == CPP_STRING || tok->type == CPP_WSTRING);
strs = (cpp_string *) obstack_finish (&str_ob); concats++;
obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
goto retry;
} }
/* We have read one more token than we want. */ /* We have read one more token than we want. */
_cpp_backup_tokens (parse_in, 1); _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"); warning ("traditional C rejects string constant concatenation");
if ((c_lex_string_translate if ((c_lex_string_translate
? cpp_interpret_string : cpp_interpret_string_notranslate) ? 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); value = build_string (istr.len, (char *) istr.text);
free ((void *) istr.text); free ((void *) istr.text);
if (c_lex_string_translate == -1) 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); &istr, wide);
/* Assume that, if we managed to translate the string above, /* Assume that, if we managed to translate the string above,
then the untranslated parsing will always succeed. */ then the untranslated parsing will always succeed. */
...@@ -782,7 +811,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string) ...@@ -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; TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
*valp = fix_string_type (value); *valp = fix_string_type (value);
if (strs != &str) if (concats)
obstack_free (&str_ob, 0); obstack_free (&str_ob, 0);
return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING; return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING;
......
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> 2004-10-25 Andrew Pinski <pinskia@physics.uc.edu>
PR c++/18121 PR c++/18121
......
...@@ -374,30 +374,9 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED , ...@@ -374,30 +374,9 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
cp_token *token) cp_token *token)
{ {
static int is_extern_c = 0; static int is_extern_c = 0;
bool done;
done = false; /* Get a new token from the preprocessor. */
/* Keep going until we get a token we like. */ token->type = c_lex_with_flags (&token->value, &token->flags);
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. */
token->location = input_location; token->location = input_location;
token->in_system_header = in_system_header; token->in_system_header = in_system_header;
......
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> 2004-10-25 Geoffrey Keating <geoffk@apple.com>
* objc.dg/image-info.m: Update for changes to section selection. * objc.dg/image-info.m: Update for changes to section selection.
......
...@@ -10,15 +10,24 @@ ...@@ -10,15 +10,24 @@
#define HASHDEFINE #define #define HASHDEFINE #define
#define HASHINCLUDE #include #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 }*/ /*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 13 }*/
HASHINCLUDE <somerandomfile> /*{ dg-error "syntax|parse" "non-include 2" }*/ int resync_parser_1; /*{ dg-error "parse" "" }*/
/*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 15 }*/
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 "stray|undeclared|parse|for each" "# from macro" } */
int resync_parser_3;
}
void g2 ()
{ {
HASH define X 1 /* { dg-error "syntax error" "# from macro" } */ HASHDEFINE Y 1 /* { dg-error "stray|undeclared|parse|for each" "#define from macro" } */
HASHDEFINE Y 1 /* { dg-error "syntax error" "#define from macro" } */ int resync_parser_4;
} }
#pragma GCC dependency "direct2.c" #pragma GCC dependency "direct2.c"
...@@ -34,4 +43,4 @@ void f () ...@@ -34,4 +43,4 @@ void f ()
#define starslash *##/ #define starslash *##/
slashstar starslash /* { dg-error "(parse|syntax) error" "not a comment" } */ 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 @@ ...@@ -12,18 +12,27 @@
#define HASHDEFINE #define #define HASHDEFINE #define
#define HASHINCLUDE #include #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 }*/ /*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 15 }*/
HASHINCLUDE <somerandomfile> /*{ dg-error "syntax|parse" "non-include 2" }*/ int resync_parser_1; /*{ dg-error "parse" "" }*/
/*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 17 }*/
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 "stray|undeclared|parse|for each" "# from macro" } */
int resync_parser_3;
}
void g2 ()
{ {
HASH define X 1 /* { dg-error "syntax error" "# from macro" } */ HASHDEFINE Y 1 /* { dg-error "stray|undeclared|parse|for each" "#define from macro" } */
HASHDEFINE Y 1 /* { dg-error "syntax error" "#define from macro" } */ int resync_parser_4;
} }
#pragma GCC dependency "direct2s.c" #pragma GCC dependency "direct2.c"
# #
void f () void f ()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment