@@ -8915,7 +8915,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
break;
case RID_COMPLEX:
dupe = specs->complex_p;
- if (!flag_isoc99 && !in_system_header)
+ if (!flag_isoc99 && !in_system_header_at (loc))
pedwarn (loc, OPT_pedantic,
"ISO C90 does not support complex types");
if (specs->typespec_word == cts_void)
@@ -9443,7 +9443,8 @@ declspecs_add_attrs (struct c_declspecs *specs, tree attrs)
double". */
struct c_declspecs *
-finish_declspecs (struct c_declspecs *specs)
+finish_declspecs (struct c_declspecs *specs,
+ location_t where)
{
/* If a type was specified as a whole, we have no modifiers and are
done. */
@@ -9464,9 +9465,9 @@ finish_declspecs (struct c_declspecs *specs)
{
if (specs->saturating_p)
{
- error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
+ error_at (where, "%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
if (!targetm.fixed_point_supported_p ())
- error ("fixed-point types not supported for this target");
+ error_at (where, "fixed-point types not supported for this target");
specs->typespec_word = cts_fract;
}
else if (specs->long_p || specs->short_p
@@ -9477,7 +9478,7 @@ finish_declspecs (struct c_declspecs *specs)
else if (specs->complex_p)
{
specs->typespec_word = cts_double;
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (where, OPT_pedantic,
"ISO C does not support plain %<complex%> meaning "
"%<double complex%>");
}
@@ -9522,7 +9523,7 @@ finish_declspecs (struct c_declspecs *specs)
specs->type = char_type_node;
if (specs->complex_p)
{
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (where, OPT_pedantic,
"ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
@@ -9535,7 +9536,7 @@ finish_declspecs (struct c_declspecs *specs)
: int128_integer_type_node);
if (specs->complex_p)
{
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (where, OPT_pedantic,
"ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
@@ -9561,7 +9562,7 @@ finish_declspecs (struct c_declspecs *specs)
: integer_type_node);
if (specs->complex_p)
{
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (where, OPT_pedantic,
"ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
@@ -314,7 +314,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
case CPP_NUMBER:
{
- unsigned int flags = cpp_classify_number (parse_in, tok);
+ unsigned int flags = cpp_classify_number (parse_in, tok, *loc);
switch (flags & CPP_N_CATEGORY)
{
@@ -397,7 +397,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
*cpp_spell_token (parse_in, tok, name, true) = 0;
- error ("stray %qs in program", name);
+ error_at (*loc, "stray %qs in program", name);
}
goto retry;
@@ -1437,7 +1437,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
c_parser_skip_to_end_of_block_or_statement (parser);
return;
}
- finish_declspecs (specs);
+ finish_declspecs (specs, here);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
if (empty_ok)
@@ -2506,7 +2506,7 @@ c_parser_struct_declaration (c_parser *parser)
c_parser_error (parser, "expected specifier-qualifier-list");
return NULL_TREE;
}
- finish_declspecs (specs);
+ finish_declspecs (specs, decl_loc);
if (c_parser_next_token_is (parser, CPP_SEMICOLON)
|| c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
{
@@ -3172,6 +3172,8 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs)
tree prefix_attrs;
tree postfix_attrs = NULL_TREE;
bool dummy = false;
+ location_t here = c_parser_peek_token (parser)->location;
+
if (!c_parser_next_token_starts_declspecs (parser))
{
c_token *token = c_parser_peek_token (parser);
@@ -3200,7 +3202,7 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs)
attrs = NULL_TREE;
}
c_parser_declspecs (parser, specs, true, true, true);
- finish_declspecs (specs);
+ finish_declspecs (specs, here);
pending_xref_error ();
prefix_attrs = specs->attrs;
specs->attrs = NULL_TREE;
@@ -3489,6 +3491,8 @@ c_parser_type_name (c_parser *parser)
struct c_declarator *declarator;
struct c_type_name *ret;
bool dummy = false;
+ location_t here = c_parser_peek_token (parser)->location;
+
c_parser_declspecs (parser, specs, false, true, true);
if (!specs->declspecs_seen_p)
{
@@ -3496,7 +3500,7 @@ c_parser_type_name (c_parser *parser)
return NULL;
}
pending_xref_error ();
- finish_declspecs (specs);
+ finish_declspecs (specs, here);
declarator = c_parser_declarator (parser,
specs->typespec_kind != ctsk_none,
C_DTR_ABSTRACT, &dummy);
@@ -491,7 +491,7 @@ extern struct c_declspecs *declspecs_add_scspec (struct c_declspecs *, tree);
extern struct c_declspecs *declspecs_add_attrs (struct c_declspecs *, tree);
extern struct c_declspecs *declspecs_add_addrspace (struct c_declspecs *,
addr_space_t);
-extern struct c_declspecs *finish_declspecs (struct c_declspecs *);
+extern struct c_declspecs *finish_declspecs (struct c_declspecs *, location_t);
/* in c-objc-common.c */
extern bool c_objc_common_init (void);
new file mode 100644
@@ -0,0 +1,16 @@
+/* Contributed by Dodji Seketeli <dodji@redhat.com> */
+/* Origin: PR preprocessor/7263 */
+/* { dg-options "-pedantic -std=c89 -ftrack-macro-expansion=1" } */
+/* { dg-do compile } */
+
+/* This tests the proprer suppression of warning coming from macro
+ defined in system headers and expanded in a non-system header
+ location. */
+#include "syshdr3.h"
+
+_Complex c = _Complex_I + _Complex_I; /* These macros are defined in
+ system header so we should
+ have no warning here. */
+U_LL u = ONE_ULL; /* Likewise here. */
+
+unsigned long long v = 1ULL; /* { dg-warning "long long" } */
new file mode 100644
@@ -0,0 +1,7 @@
+#pragma GCC system_header
+
+#define _Complex __complex__
+#define _Complex_I 1.0iF
+
+#define U_LL unsigned long long
+#define ONE_ULL 1ULL
@@ -20,10 +20,10 @@ f3 (void)
return 0k; /* { dg-error "not supported" "reject fixed-point" } */
}
-_Sat
-f4 (void) /* { dg-error "not supported" "reject fixed-point" } */
+_Sat /* { dg-error "not supported" "reject fixed-point" } */
+f4 (void)
{
return 0k; /* { dg-error "not supported" "reject fixed-point" } */
}
-/* { dg-error "is used without" "" { target *-*-* } 24 } */
+/* { dg-error "is used without" "" { target *-*-* } 23 } */
@@ -38,26 +38,7 @@ cpp_diagnostic (cpp_reader * pfile, int level, int reason,
source_location src_loc;
bool ret;
- if (CPP_OPTION (pfile, traditional))
- {
- if (pfile->state.in_directive)
- src_loc = pfile->directive_line;
- else
- src_loc = LINEMAPS_ORDINARY_HIGHEST_LINE (pfile->line_table);
- }
- /* We don't want to refer to a token before the beginning of the
- current run -- that is invalid. */
- else if (pfile->cur_token == pfile->cur_run->base)
- {
- if (pfile->cur_run->prev != NULL)
- src_loc = pfile->cur_run->prev->limit->src_loc;
- else
- src_loc = 0;
- }
- else
- {
- src_loc = pfile->cur_token[-1].src_loc;
- }
+ src_loc = _cpp_get_prev_token_spelling_loc (pfile);
if (!pfile->cb.error)
abort ();
@@ -59,7 +59,7 @@ static cpp_num num_rshift (cpp_num, size_t, size_t);
static cpp_num append_digit (cpp_num, int, int, size_t);
static cpp_num parse_defined (cpp_reader *);
-static cpp_num eval_token (cpp_reader *, const cpp_token *);
+static cpp_num eval_token (cpp_reader *, const cpp_token *, source_location);
static struct op *reduce (cpp_reader *, struct op *, enum cpp_ttype);
static unsigned int interpret_float_suffix (const uchar *, size_t);
static unsigned int interpret_int_suffix (const uchar *, size_t);
@@ -76,6 +76,12 @@ static void check_promotion (cpp_reader *, const struct op *);
#define SYNTAX_ERROR2(msgid, arg) \
do { cpp_error (pfile, CPP_DL_ERROR, msgid, arg); goto syntax_error; } \
while(0)
+#define SYNTAX_ERROR_AT(loc, msgid) \
+ do { cpp_error_with_line (pfile, CPP_DL_ERROR, (loc), 0, msgid); goto syntax_error; } \
+ while(0)
+#define SYNTAX_ERROR2_AT(loc, msgid, arg) \
+ do { cpp_error_with_line (pfile, CPP_DL_ERROR, (loc), 0, msgid, arg); goto syntax_error; } \
+ while(0)
/* Subroutine of cpp_classify_number. S points to a float suffix of
length LEN, possibly zero. Returns 0 for an invalid suffix, or a
@@ -223,7 +229,8 @@ interpret_int_suffix (const uchar *s, size_t len)
floating point, or invalid), radix (decimal, octal, hexadecimal),
and type suffixes. */
unsigned int
-cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
+cpp_classify_number (cpp_reader *pfile, const cpp_token *token,
+ source_location virtual_location)
{
const uchar *str = token->val.str.text;
const uchar *limit;
@@ -279,7 +286,8 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
if (float_flag == NOT_FLOAT)
float_flag = AFTER_POINT;
else
- SYNTAX_ERROR ("too many decimal points in number");
+ SYNTAX_ERROR_AT (virtual_location,
+ "too many decimal points in number");
}
else if ((radix <= 10 && (c == 'e' || c == 'E'))
|| (radix == 16 && (c == 'p' || c == 'P')))
@@ -307,8 +315,8 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
radix = 10;
if (CPP_PEDANTIC (pfile))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "fixed-point constants are a GCC extension");
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
+ "fixed-point constants are a GCC extension");
goto syntax_ok;
}
else
@@ -321,26 +329,29 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
if (max_digit >= radix)
{
if (radix == 2)
- SYNTAX_ERROR2 ("invalid digit \"%c\" in binary constant", '0' + max_digit);
+ SYNTAX_ERROR2_AT (virtual_location,
+ "invalid digit \"%c\" in binary constant", '0' + max_digit);
else
- SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
+ SYNTAX_ERROR2_AT (virtual_location,
+ "invalid digit \"%c\" in octal constant", '0' + max_digit);
}
if (float_flag != NOT_FLOAT)
{
if (radix == 2)
{
- cpp_error (pfile, CPP_DL_ERROR,
- "invalid prefix \"0b\" for floating constant");
+ cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
+ "invalid prefix \"0b\" for floating constant");
return CPP_N_INVALID;
}
if (radix == 16 && !seen_digit)
- SYNTAX_ERROR ("no digits in hexadecimal floating constant");
+ SYNTAX_ERROR_AT (virtual_location,
+ "no digits in hexadecimal floating constant");
if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "use of C99 hexadecimal floating constant");
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
+ "use of C99 hexadecimal floating constant");
if (float_flag == AFTER_EXPON)
{
@@ -349,21 +360,22 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
/* Exponent is decimal, even if string is a hex float. */
if (!ISDIGIT (*str))
- SYNTAX_ERROR ("exponent has no digits");
+ SYNTAX_ERROR_AT (virtual_location, "exponent has no digits");
do
str++;
while (ISDIGIT (*str));
}
else if (radix == 16)
- SYNTAX_ERROR ("hexadecimal floating constants require an exponent");
+ SYNTAX_ERROR_AT (virtual_location,
+ "hexadecimal floating constants require an exponent");
result = interpret_float_suffix (str, limit - str);
if (result == 0)
{
- cpp_error (pfile, CPP_DL_ERROR,
- "invalid suffix \"%.*s\" on floating constant",
- (int) (limit - str), str);
+ cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
+ "invalid suffix \"%.*s\" on floating constant",
+ (int) (limit - str), str);
return CPP_N_INVALID;
}
@@ -371,33 +383,33 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
if (limit != str
&& CPP_WTRADITIONAL (pfile)
&& ! cpp_sys_macro_p (pfile))
- cpp_warning (pfile, CPP_W_TRADITIONAL,
- "traditional C rejects the \"%.*s\" suffix",
- (int) (limit - str), str);
+ cpp_warning_with_line (pfile, CPP_W_TRADITIONAL, virtual_location, 0,
+ "traditional C rejects the \"%.*s\" suffix",
+ (int) (limit - str), str);
/* A suffix for double is a GCC extension via decimal float support.
If the suffix also specifies an imaginary value we'll catch that
later. */
if ((result == CPP_N_MEDIUM) && CPP_PEDANTIC (pfile))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "suffix for double constant is a GCC extension");
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
+ "suffix for double constant is a GCC extension");
/* Radix must be 10 for decimal floats. */
if ((result & CPP_N_DFLOAT) && radix != 10)
{
- cpp_error (pfile, CPP_DL_ERROR,
- "invalid suffix \"%.*s\" with hexadecimal floating constant",
- (int) (limit - str), str);
+ cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
+ "invalid suffix \"%.*s\" with hexadecimal floating constant",
+ (int) (limit - str), str);
return CPP_N_INVALID;
}
if ((result & (CPP_N_FRACT | CPP_N_ACCUM)) && CPP_PEDANTIC (pfile))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "fixed-point constants are a GCC extension");
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
+ "fixed-point constants are a GCC extension");
if ((result & CPP_N_DFLOAT) && CPP_PEDANTIC (pfile))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "decimal float constants are a GCC extension");
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
+ "decimal float constants are a GCC extension");
result |= CPP_N_FLOATING;
}
@@ -406,9 +418,9 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
result = interpret_int_suffix (str, limit - str);
if (result == 0)
{
- cpp_error (pfile, CPP_DL_ERROR,
- "invalid suffix \"%.*s\" on integer constant",
- (int) (limit - str), str);
+ cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
+ "invalid suffix \"%.*s\" on integer constant",
+ (int) (limit - str), str);
return CPP_N_INVALID;
}
@@ -421,9 +433,10 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
&& CPP_OPTION (pfile, cpp_warn_long_long);
if (u_or_i || large)
- cpp_warning (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL,
- "traditional C rejects the \"%.*s\" suffix",
- (int) (limit - str), str);
+ cpp_warning_with_line (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL,
+ virtual_location, 0,
+ "traditional C rejects the \"%.*s\" suffix",
+ (int) (limit - str), str);
}
if ((result & CPP_N_WIDTH) == CPP_N_LARGE
@@ -434,9 +447,11 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
: N_("use of C99 long long integer constant");
if (CPP_OPTION (pfile, c99))
- cpp_warning (pfile, CPP_W_LONG_LONG, message);
+ cpp_warning_with_line (pfile, CPP_W_LONG_LONG, virtual_location,
+ 0, message);
else
- cpp_pedwarning (pfile, CPP_W_LONG_LONG, message);
+ cpp_pedwarning_with_line (pfile, CPP_W_LONG_LONG,
+ virtual_location, 0, message);
}
result |= CPP_N_INTEGER;
@@ -444,11 +459,11 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
syntax_ok:
if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "imaginary constants are a GCC extension");
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
+ "imaginary constants are a GCC extension");
if (radix == 2 && CPP_PEDANTIC (pfile))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "binary constants are a GCC extension");
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
+ "binary constants are a GCC extension");
if (radix == 10)
result |= CPP_N_DECIMAL;
@@ -731,7 +746,8 @@ parse_defined (cpp_reader *pfile)
number or character constant, or the result of the "defined" or "#"
operators). */
static cpp_num
-eval_token (cpp_reader *pfile, const cpp_token *token)
+eval_token (cpp_reader *pfile, const cpp_token *token,
+ source_location virtual_location)
{
cpp_num result;
unsigned int temp;
@@ -743,18 +759,18 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
switch (token->type)
{
case CPP_NUMBER:
- temp = cpp_classify_number (pfile, token);
+ temp = cpp_classify_number (pfile, token, virtual_location);
switch (temp & CPP_N_CATEGORY)
{
case CPP_N_FLOATING:
- cpp_error (pfile, CPP_DL_ERROR,
- "floating constant in preprocessor expression");
+ cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
+ "floating constant in preprocessor expression");
break;
case CPP_N_INTEGER:
if (!(temp & CPP_N_IMAGINARY))
return cpp_interpret_integer (pfile, token, temp);
- cpp_error (pfile, CPP_DL_ERROR,
- "imaginary number in preprocessor expression");
+ cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
+ "imaginary number in preprocessor expression");
break;
case CPP_N_INVALID:
@@ -801,8 +817,9 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
result.high = 0;
result.low = 0;
if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval)
- cpp_warning (pfile, CPP_W_UNDEF, "\"%s\" is not defined",
- NODE_NAME (token->val.node.node));
+ cpp_warning_with_line (pfile, CPP_W_UNDEF, virtual_location, 0,
+ "\"%s\" is not defined",
+ NODE_NAME (token->val.node.node));
}
break;
@@ -812,11 +829,12 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
/* A pedantic warning takes precedence over a deprecated
warning here. */
if (CPP_PEDANTIC (pfile))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "assertions are a GCC extension");
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN,
+ virtual_location, 0,
+ "assertions are a GCC extension");
else if (CPP_OPTION (pfile, cpp_warn_deprecated))
- cpp_warning (pfile, CPP_W_DEPRECATED,
- "assertions are a deprecated extension");
+ cpp_warning_with_line (pfile, CPP_W_DEPRECATED, virtual_location, 0,
+ "assertions are a deprecated extension");
}
_cpp_test_assertion (pfile, &temp);
result.high = 0;
@@ -918,6 +936,8 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if)
struct op *top = pfile->op_stack;
unsigned int lex_count;
bool saw_leading_not, want_value = true;
+ source_location virtual_location = 0,
+ prev_virtual_location = _cpp_get_prev_token_spelling_loc (pfile);
pfile->state.skip_eval = 0;
@@ -934,9 +954,12 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if)
struct op op;
lex_count++;
- op.token = cpp_get_token (pfile);
+
+ if (virtual_location)
+ prev_virtual_location = virtual_location;
+ op.token = cpp_get_token_with_location (pfile, &virtual_location);
op.op = op.token->type;
- op.loc = op.token->src_loc;
+ op.loc = virtual_location;
switch (op.op)
{
@@ -949,10 +972,11 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if)
case CPP_NAME:
case CPP_HASH:
if (!want_value)
- SYNTAX_ERROR2 ("missing binary operator before token \"%s\"",
- cpp_token_as_text (pfile, op.token));
+ SYNTAX_ERROR2_AT (prev_virtual_location,
+ "missing binary operator before token \"%s\"",
+ cpp_token_as_text (pfile, op.token));
want_value = false;
- top->value = eval_token (pfile, op.token);
+ top->value = eval_token (pfile, op.token, virtual_location);
continue;
case CPP_NOT:
@@ -969,8 +993,9 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if)
default:
if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ)
- SYNTAX_ERROR2 ("token \"%s\" is not valid in preprocessor expressions",
- cpp_token_as_text (pfile, op.token));
+ SYNTAX_ERROR2_AT (op.loc,
+ "token \"%s\" is not valid in preprocessor expressions",
+ cpp_token_as_text (pfile, op.token));
break;
}
@@ -978,27 +1003,32 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if)
if (optab[op.op].flags & NO_L_OPERAND)
{
if (!want_value)
- SYNTAX_ERROR2 ("missing binary operator before token \"%s\"",
- cpp_token_as_text (pfile, op.token));
+ SYNTAX_ERROR2_AT (prev_virtual_location,
+ "missing binary operator before token \"%s\"",
+ cpp_token_as_text (pfile, op.token));
}
else if (want_value)
{
/* We want a number (or expression) and haven't got one.
Try to emit a specific diagnostic. */
if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN)
- SYNTAX_ERROR ("missing expression between '(' and ')'");
+ SYNTAX_ERROR_AT (op.loc,
+ "missing expression between '(' and ')'");
if (op.op == CPP_EOF && top->op == CPP_EOF)
- SYNTAX_ERROR2 ("%s with no expression", is_if ? "#if" : "#elif");
+ SYNTAX_ERROR2_AT (op.loc,
+ "%s with no expression", is_if ? "#if" : "#elif");
if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
- SYNTAX_ERROR2 ("operator '%s' has no right operand",
- cpp_token_as_text (pfile, top->token));
+ SYNTAX_ERROR2_AT (op.loc,
+ "operator '%s' has no right operand",
+ cpp_token_as_text (pfile, top->token));
else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF)
/* Complain about missing paren during reduction. */;
else
- SYNTAX_ERROR2 ("operator '%s' has no left operand",
- cpp_token_as_text (pfile, op.token));
+ SYNTAX_ERROR2_AT (op.loc,
+ "operator '%s' has no left operand",
+ cpp_token_as_text (pfile, op.token));
}
top = reduce (pfile, top, op.op);
@@ -1023,7 +1053,8 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if)
break;
case CPP_COLON:
if (top->op != CPP_QUERY)
- SYNTAX_ERROR (" ':' without preceding '?'");
+ SYNTAX_ERROR_AT (op.loc,
+ " ':' without preceding '?'");
if (!num_zerop (top[-1].value)) /* Was '?' condition true? */
pfile->state.skip_eval++;
else
@@ -1040,7 +1071,7 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if)
top->op = op.op;
top->token = op.token;
- top->loc = op.token->src_loc;
+ top->loc = op.loc;
}
/* The controlling macro expression is only valid if we called lex 3
@@ -1051,8 +1082,9 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if)
if (top != pfile->op_stack)
{
- cpp_error (pfile, CPP_DL_ICE, "unbalanced stack in %s",
- is_if ? "#if" : "#elif");
+ cpp_error_with_line (pfile, CPP_DL_ICE, top->loc, 0,
+ "unbalanced stack in %s",
+ is_if ? "#if" : "#elif");
syntax_error:
return false; /* Return false on syntax error. */
}
@@ -827,7 +827,8 @@ struct cpp_num
/* Classify a CPP_NUMBER token. The return value is a combination of
the flags from the above sets. */
-extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *);
+extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *,
+ source_location);
/* Evaluate a token classified as category CPP_N_INTEGER. */
extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *,
@@ -640,6 +640,7 @@ extern int _cpp_equiv_tokens (const cpp_token *, const cpp_token *);
extern void _cpp_init_tokenrun (tokenrun *, unsigned int);
extern cpp_hashnode *_cpp_lex_identifier (cpp_reader *, const char *);
extern int _cpp_remaining_tokens_num_in_context (cpp_reader *);
+extern source_location _cpp_get_prev_token_spelling_loc (cpp_reader *);
/* In init.c. */
extern void _cpp_maybe_push_include_file (cpp_reader *);
@@ -2885,3 +2885,34 @@ cpp_token_val_index (cpp_token *tok)
return CPP_TOKEN_FLD_NONE;
}
}
+
+/* Return the location of the previous token in the token stream. */
+
+source_location
+_cpp_get_prev_token_spelling_loc (cpp_reader *pfile)
+{
+ source_location spelling_loc;
+
+ if (CPP_OPTION (pfile, traditional))
+ {
+ if (pfile->state.in_directive)
+ spelling_loc = pfile->directive_line;
+ else
+ spelling_loc = LINEMAPS_ORDINARY_HIGHEST_LINE (pfile->line_table);
+ }
+ /* We don't want to refer to a token before the beginning of the
+ current run -- that is invalid. */
+ else if (pfile->cur_token == pfile->cur_run->base)
+ {
+ if (pfile->cur_run->prev != NULL)
+ spelling_loc = pfile->cur_run->prev->limit->src_loc;
+ else
+ spelling_loc = 0;
+ }
+ else
+ {
+ spelling_loc = pfile->cur_token[-1].src_loc;
+ }
+
+ return spelling_loc;
+}