/* CPP Library. (Directive handling.)
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2007, 2008 Free Software Foundation, Inc.
+ 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+along with this program; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
/* Forward declarations. */
static void skip_rest_of_line (cpp_reader *);
-static void check_eol (cpp_reader *);
+static void check_eol (cpp_reader *, bool);
static void start_directive (cpp_reader *);
static void prepare_directive_trad (cpp_reader *);
static void end_directive (cpp_reader *, int);
static void directive_diagnostics (cpp_reader *, const directive *, int);
static void run_directive (cpp_reader *, int, const char *, size_t);
static char *glue_header_name (cpp_reader *);
-static const char *parse_include (cpp_reader *, int *, const cpp_token ***);
+static const char *parse_include (cpp_reader *, int *, const cpp_token ***,
+ source_location *);
static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
static unsigned int read_flag (cpp_reader *, unsigned int);
-static int strtolinenum (const uchar *, unsigned int, linenum_type *);
+static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *);
static void do_diagnostic (cpp_reader *, int, int);
static cpp_hashnode *lex_macro_node (cpp_reader *, bool);
static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
static const cpp_token *get_token_no_padding (cpp_reader *);
static const cpp_token *get__Pragma_string (cpp_reader *);
static void destringize_and_run (cpp_reader *, const cpp_string *);
-static int parse_answer (cpp_reader *, struct answer **, int);
+static int parse_answer (cpp_reader *, struct answer **, int, source_location);
static cpp_hashnode *parse_assertion (cpp_reader *, struct answer **, int);
static struct answer ** find_answer (cpp_hashnode *, const struct answer *);
static void handle_assertion (cpp_reader *, const char *, int);
;
}
-/* Ensure there are no stray tokens at the end of a directive. */
+/* Ensure there are no stray tokens at the end of a directive. If
+ EXPAND is true, tokens macro-expanding to nothing are allowed. */
static void
-check_eol (cpp_reader *pfile)
+check_eol (cpp_reader *pfile, bool expand)
{
- if (! SEEN_EOL () && _cpp_lex_token (pfile)->type != CPP_EOF)
+ if (! SEEN_EOL () && (expand
+ ? cpp_get_token (pfile)
+ : _cpp_lex_token (pfile))->type != CPP_EOF)
cpp_error (pfile, CPP_DL_PEDWARN, "extra tokens at end of #%s directive",
pfile->directive->name);
}
if (dname->type == CPP_NAME)
{
- if (dname->val.node->is_directive)
- dir = &dtable[dname->val.node->directive_index];
+ if (dname->val.node.node->is_directive)
+ dir = &dtable[dname->val.node.node->directive_index];
}
/* We do not recognize the # followed by a number extension in
assembler code. */
if (token->type == CPP_NAME)
{
- cpp_hashnode *node = token->val.node;
+ cpp_hashnode *node = token->val.node.node;
if (is_def_or_undef && node == pfile->spec_nodes.n_defined)
cpp_error (pfile, CPP_DL_ERROR,
else if (token->flags & NAMED_OP)
cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" cannot be used as a macro name as it is an operator in C++",
- NODE_NAME (token->val.node));
+ NODE_NAME (token->val.node.node));
else if (token->type == CPP_EOF)
cpp_error (pfile, CPP_DL_ERROR, "no macro name given in #%s directive",
pfile->directive->name);
}
}
- check_eol (pfile);
+ check_eol (pfile, false);
}
/* Undefine a single macro/assertion/whatever. */
/* Returns the file name of #include, #include_next, #import and
#pragma dependency. The string is malloced and the caller should
- free it. Returns NULL on error. */
+ free it. Returns NULL on error. LOCATION is the source location
+ of the file name. */
+
static const char *
parse_include (cpp_reader *pfile, int *pangle_brackets,
- const cpp_token ***buf)
+ const cpp_token ***buf, source_location *location)
{
char *fname;
const cpp_token *header;
/* Allow macro expansion. */
header = get_token_no_padding (pfile);
+ *location = header->src_loc;
if (header->type == CPP_STRING || header->type == CPP_HEADER_NAME)
{
fname = XNEWVEC (char, header->val.str.len - 1);
/* This pragma allows extra tokens after the file name. */
}
else if (buf == NULL || CPP_OPTION (pfile, discard_comments))
- check_eol (pfile);
+ check_eol (pfile, true);
else
{
/* If we are not discarding comments, then gather them while
const char *fname;
int angle_brackets;
const cpp_token **buf = NULL;
+ source_location location;
/* Re-enable saving of comments if requested, so that the include
callback can dump comments which follow #include. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
- fname = parse_include (pfile, &angle_brackets, &buf);
+ fname = parse_include (pfile, &angle_brackets, &buf, &location);
if (!fname)
{
if (buf)
if (!*fname)
{
- cpp_error (pfile, CPP_DL_ERROR, "empty filename in #%s",
- pfile->directive->name);
+ cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0,
+ "empty filename in #%s",
+ pfile->directive->name);
XDELETEVEC (fname);
if (buf)
XDELETEVEC (buf);
}
/* Subroutine of do_line and do_linemarker. Convert a number in STR,
- of length LEN, to binary; store it in NUMP, and return 0 if the
- number was well-formed, 1 if not. Temporary, hopefully. */
-static int
-strtolinenum (const uchar *str, unsigned int len, linenum_type *nump)
+ of length LEN, to binary; store it in NUMP, and return false if the
+ number was well-formed, true if not. WRAPPED is set to true if the
+ number did not fit into 'unsigned long'. */
+static bool
+strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped)
{
linenum_type reg = 0;
+ linenum_type reg_prev = 0;
+
uchar c;
+ *wrapped = false;
while (len--)
{
c = *str++;
if (!ISDIGIT (c))
- return 1;
+ return true;
reg *= 10;
reg += c - '0';
+ if (reg < reg_prev)
+ *wrapped = true;
+ reg_prev = reg;
}
*nump = reg;
- return 0;
+ return false;
}
/* Interpret #line command.
/* C99 raised the minimum limit on #line numbers. */
linenum_type cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
+ bool wrapped;
/* #line commands expand macros. */
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
|| strtolinenum (token->val.str.text, token->val.str.len,
- &new_lineno))
+ &new_lineno, &wrapped))
{
if (token->type == CPP_EOF)
cpp_error (pfile, CPP_DL_ERROR, "unexpected end of file after #line");
return;
}
- if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap))
+ if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap || wrapped))
cpp_error (pfile, CPP_DL_PEDWARN, "line number out of range");
+ else if (wrapped)
+ cpp_error (pfile, CPP_DL_WARNING, "line number out of range");
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
{
cpp_string s = { 0, 0 };
if (cpp_interpret_string_notranslate (pfile, &token->val.str, 1,
- &s, false))
+ &s, CPP_STRING))
new_file = (const char *)s.text;
- check_eol (pfile);
+ check_eol (pfile, true);
}
else if (token->type != CPP_EOF)
{
}
skip_rest_of_line (pfile);
- _cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno,
+ _cpp_do_file_change (pfile, LC_RENAME_VERBATIM, new_file, new_lineno,
map_sysp);
}
const char *new_file = map->to_file;
linenum_type new_lineno;
unsigned int new_sysp = map->sysp;
- enum lc_reason reason = LC_RENAME;
+ enum lc_reason reason = LC_RENAME_VERBATIM;
int flag;
+ bool wrapped;
/* Back up so we can get the number again. Putting this in
_cpp_handle_directive risks two calls to _cpp_backup_tokens in
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
|| strtolinenum (token->val.str.text, token->val.str.len,
- &new_lineno))
+ &new_lineno, &wrapped))
{
/* Unlike #line, there does not seem to be a way to get an EOF
here. So, it should be safe to always spell the token. */
{
cpp_string s = { 0, 0 };
if (cpp_interpret_string_notranslate (pfile, &token->val.str,
- 1, &s, false))
+ 1, &s, CPP_STRING))
new_file = (const char *)s.text;
new_sysp = 0;
}
pfile->buffer->sysp = new_sysp;
- check_eol (pfile);
+ check_eol (pfile, false);
}
else if (token->type != CPP_EOF)
{
}
skip_rest_of_line (pfile);
+
+ /* Compensate for the increment in linemap_add that occurs in
+ _cpp_do_file_change. We're currently at the start of the line
+ *following* the #line directive. A separate source_location for this
+ location makes no sense (until we do the LC_LEAVE), and
+ complicates LAST_SOURCE_LINE_LOCATION. */
+ pfile->line_table->highest_location--;
+
_cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp);
}
else if (pfile->cb.ident)
pfile->cb.ident (pfile, pfile->directive_line, &str->val.str);
- check_eol (pfile);
+ check_eol (pfile, false);
}
/* Lookup a PRAGMA name in a singly-linked CHAIN. Returns the
ns_token = *token;
if (token->type == CPP_NAME)
{
- p = lookup_pragma_entry (pfile->pragmas, token->val.node);
+ p = lookup_pragma_entry (pfile->pragmas, token->val.node.node);
if (p && p->is_nspace)
{
bool allow_name_expansion = p->allow_expansion;
pfile->state.prevent_expansion--;
token = cpp_get_token (pfile);
if (token->type == CPP_NAME)
- p = lookup_pragma_entry (p->u.space, token->val.node);
+ p = lookup_pragma_entry (p->u.space, token->val.node.node);
else
p = NULL;
if (allow_name_expansion)
if (cpp_in_primary_file (pfile))
cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file");
- check_eol (pfile);
+ check_eol (pfile, false);
_cpp_mark_file_once_only (pfile, pfile->buffer->file);
}
break;
}
- hp = tok->val.node;
+ hp = tok->val.node.node;
if (hp->flags & NODE_POISONED)
continue;
"#pragma system_header ignored outside include file");
else
{
- check_eol (pfile);
+ check_eol (pfile, false);
skip_rest_of_line (pfile);
cpp_make_system_header (pfile, 1, 0);
}
{
const char *fname;
int angle_brackets, ordering;
+ source_location location;
- fname = parse_include (pfile, &angle_brackets, NULL);
+ fname = parse_include (pfile, &angle_brackets, NULL, &location);
if (!fname)
return;
pfile->cb.used_undef (pfile, pfile->directive_line, node);
}
}
- check_eol (pfile);
+ check_eol (pfile, false);
}
}
pfile->cb.used_undef (pfile, pfile->directive_line, node);
}
}
- check_eol (pfile);
+ check_eol (pfile, false);
}
}
/* Only check EOL if was not originally skipping. */
if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
- check_eol (pfile);
+ check_eol (pfile, false);
}
}
{
/* Only check EOL if was not originally skipping. */
if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
- check_eol (pfile);
+ check_eol (pfile, false);
/* If potential control macro, we go back outside again. */
if (ifs->next == 0 && ifs->mi_cmacro)
/* Read the tokens of the answer into the macro pool, in a directive
of type TYPE. Only commit the memory if we intend it as permanent
storage, i.e. the #assert case. Returns 0 on success, and sets
- ANSWERP to point to the answer. */
+ ANSWERP to point to the answer. PRED_LOC is the location of the
+ predicate. */
static int
-parse_answer (cpp_reader *pfile, struct answer **answerp, int type)
+parse_answer (cpp_reader *pfile, struct answer **answerp, int type,
+ source_location pred_loc)
{
const cpp_token *paren;
struct answer *answer;
if (type == T_UNASSERT && paren->type == CPP_EOF)
return 0;
- cpp_error (pfile, CPP_DL_ERROR, "missing '(' after predicate");
+ cpp_error_with_line (pfile, CPP_DL_ERROR, pred_loc, 0,
+ "missing '(' after predicate");
return 1;
}
if (predicate->type == CPP_EOF)
cpp_error (pfile, CPP_DL_ERROR, "assertion without predicate");
else if (predicate->type != CPP_NAME)
- cpp_error (pfile, CPP_DL_ERROR, "predicate must be an identifier");
- else if (parse_answer (pfile, answerp, type) == 0)
+ cpp_error_with_line (pfile, CPP_DL_ERROR, predicate->src_loc, 0,
+ "predicate must be an identifier");
+ else if (parse_answer (pfile, answerp, type, predicate->src_loc) == 0)
{
- unsigned int len = NODE_LEN (predicate->val.node);
+ unsigned int len = NODE_LEN (predicate->val.node.node);
unsigned char *sym = (unsigned char *) alloca (len + 1);
/* Prefix '#' to get it out of macro namespace. */
sym[0] = '#';
- memcpy (sym + 1, NODE_NAME (predicate->val.node), len);
+ memcpy (sym + 1, NODE_NAME (predicate->val.node.node), len);
result = cpp_lookup (pfile, sym, len + 1);
}
node->type = NT_ASSERTION;
node->value.answers = new_answer;
- check_eol (pfile);
+ check_eol (pfile, false);
}
}
if (node->value.answers == 0)
node->type = NT_VOID;
- check_eol (pfile);
+ check_eol (pfile, false);
}
else
_cpp_free_definition (node);
run_directive (pfile, type, str, count);
}
-/* The number of errors for a given reader. */
-unsigned int
-cpp_errors (cpp_reader *pfile)
-{
- return pfile->errors;
-}
-
/* The options structure. */
cpp_options *
cpp_get_options (cpp_reader *pfile)