/* 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, 2009, 2010 Free Software Foundation, Inc.
+ 2007, 2008, 2009, 2010, 2011 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
struct if_stack
{
struct if_stack *next;
- linenum_type line; /* Line where condition started. */
+ source_location line; /* Line where condition started. */
const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */
bool skip_elses; /* Can future #else / #elif be skipped? */
bool was_skipping; /* If were skipping on entry. */
static void handle_assertion (cpp_reader *, const char *, int);
static void do_pragma_push_macro (cpp_reader *);
static void do_pragma_pop_macro (cpp_reader *);
+static void cpp_pop_definition (cpp_reader *, struct def_pragma_macro *);
/* This is the table of directive handlers. It is ordered by
frequency of occurrence; the numbers at the end are directive
static void
end_directive (cpp_reader *pfile, int skip_line)
{
- if (pfile->state.in_deferred_pragma)
- ;
- else if (CPP_OPTION (pfile, traditional))
+ if (CPP_OPTION (pfile, traditional))
{
/* Revert change of prepare_directive_trad. */
- pfile->state.prevent_expansion--;
+ if (!pfile->state.in_deferred_pragma)
+ pfile->state.prevent_expansion--;
if (pfile->directive != &dtable[T_DEFINE])
_cpp_remove_overlay (pfile);
}
+ else if (pfile->state.in_deferred_pragma)
+ ;
/* We don't skip for an assembler #. */
else if (skip_line)
{
cpp_error (pfile, CPP_DL_PEDWARN, "#%s is a GCC extension", dir->name);
else if (((dir->flags & DEPRECATED) != 0
|| (dir == &dtable[T_IMPORT] && !CPP_OPTION (pfile, objc)))
- && CPP_OPTION (pfile, warn_deprecated))
+ && CPP_OPTION (pfile, cpp_warn_deprecated))
cpp_warning (pfile, CPP_W_DEPRECATED,
"#%s is a deprecated GCC extension", dir->name);
}
if (was_parsing_args)
{
- if (CPP_OPTION (pfile, pedantic))
+ if (CPP_OPTION (pfile, cpp_pedantic))
cpp_error (pfile, CPP_DL_PEDWARN,
"embedding a directive within macro arguments is not portable");
pfile->state.parsing_args = 0;
do_line (cpp_reader *pfile)
{
const struct line_maps *line_table = pfile->line_table;
- const struct line_map *map = &line_table->maps[line_table->used - 1];
+ const struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
/* skip_rest_of_line() may cause line table to be realloc()ed so note down
sysp right now. */
- unsigned char map_sysp = map->sysp;
+ unsigned char map_sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (map);
const cpp_token *token;
- const char *new_file = map->to_file;
+ const char *new_file = ORDINARY_MAP_FILE_NAME (map);
linenum_type new_lineno;
/* C99 raised the minimum limit on #line numbers. */
do_linemarker (cpp_reader *pfile)
{
const struct line_maps *line_table = pfile->line_table;
- const struct line_map *map = &line_table->maps[line_table->used - 1];
+ const struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
const cpp_token *token;
- const char *new_file = map->to_file;
+ const char *new_file = ORDINARY_MAP_FILE_NAME (map);
linenum_type new_lineno;
- unsigned int new_sysp = map->sysp;
+ unsigned int new_sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (map);
enum lc_reason reason = LC_RENAME_VERBATIM;
int flag;
bool wrapped;
const struct line_map *map = linemap_add (pfile->line_table, reason, sysp,
to_file, file_line);
if (map != NULL)
- linemap_line_start (pfile->line_table, map->to_line, 127);
+ linemap_line_start (pfile->line_table,
+ ORDINARY_MAP_STARTING_LINE_NUMBER (map),
+ 127);
if (pfile->cb.file_change)
pfile->cb.file_change (pfile, map);
{
bool allow_name_expansion = p->allow_expansion;
if (allow_name_expansion)
- pfile->state.prevent_expansion--;
+ {
+ pfile->state.prevent_expansion--;
+ /*
+ Kludge ahead.
+
+ Consider this code snippet:
+
+ #define P parallel
+ #pragma omp P for
+ ... a for loop ...
+
+ Once we parsed the 'omp' namespace of the #pragma
+ directive, we then parse the 'P' token that represents the
+ pragma name. P being a macro, it is expanded into the
+ resulting 'parallel' token.
+
+ At this point the 'p' variable contains the 'parallel'
+ pragma name. And pfile->context->macro is non-null
+ because we are still right at the end of the macro
+ context of 'P'. The problem is, if we are being
+ (indirectly) called by cpp_get_token_with_location,
+ that function might test pfile->context->macro to see
+ if we are in the context of a macro expansion, (and we
+ are) and then use pfile->invocation_location as the
+ location of the macro invocation. So we must instruct
+ cpp_get_token below to set
+ pfile->invocation_location. */
+ pfile->set_invocation_location = true;
+ }
+
token = cpp_get_token (pfile);
if (token->type == CPP_NAME)
p = lookup_pragma_entry (p->u.space, token->val.node.node);
static void
do_pragma_push_macro (cpp_reader *pfile)
{
+ cpp_hashnode *node;
+ size_t defnlen;
+ const uchar *defn = NULL;
char *macroname, *dest;
const char *limit, *src;
const cpp_token *txt;
check_eol (pfile, false);
skip_rest_of_line (pfile);
c = XNEW (struct def_pragma_macro);
+ memset (c, 0, sizeof (struct def_pragma_macro));
c->name = XNEWVAR (char, strlen (macroname) + 1);
strcpy (c->name, macroname);
c->next = pfile->pushed_macros;
- c->value = cpp_push_definition (pfile, c->name);
+ node = _cpp_lex_identifier (pfile, c->name);
+ if (node->type == NT_VOID)
+ c->is_undef = 1;
+ else
+ {
+ defn = cpp_macro_definition (pfile, node);
+ defnlen = ustrlen (defn);
+ c->definition = XNEWVEC (uchar, defnlen + 2);
+ c->definition[defnlen] = '\n';
+ c->definition[defnlen + 1] = 0;
+ c->line = node->value.macro->line;
+ c->syshdr = node->value.macro->syshdr;
+ c->used = node->value.macro->used;
+ memcpy (c->definition, defn, defnlen);
+ }
+
pfile->pushed_macros = c;
}
pfile->pushed_macros = c->next;
else
l->next = c->next;
- cpp_pop_definition (pfile, c->name, c->value);
+ cpp_pop_definition (pfile, c);
+ free (c->definition);
free (c->name);
free (c);
break;
saved_cur_run = pfile->cur_run;
pfile->context = XNEW (cpp_context);
- pfile->context->macro = 0;
+ pfile->context->c.macro = 0;
pfile->context->prev = 0;
pfile->context->next = 0;
if (node)
{
- skip = node->type != NT_MACRO;
+ /* Do not treat conditional macros as being defined. This is due to
+ the powerpc and spu ports using conditional macros for 'vector',
+ 'bool', and 'pixel' to act as conditional keywords. This messes
+ up tests like #ifndef bool. */
+ skip = (node->type != NT_MACRO
+ || ((node->flags & NODE_CONDITIONAL) != 0));
_cpp_mark_macro_used (node);
if (!(node->flags & NODE_USED))
{
if (node)
{
- skip = node->type == NT_MACRO;
+ /* Do not treat conditional macros as being defined. This is due to
+ the powerpc and spu ports using conditional macros for 'vector',
+ 'bool', and 'pixel' to act as conditional keywords. This messes
+ up tests like #ifndef bool. */
+ skip = (node->type == NT_MACRO
+ && ((node->flags & NODE_CONDITIONAL) == 0));
_cpp_mark_macro_used (node);
if (!(node->flags & NODE_USED))
{
run_directive (pfile, T_UNDEF, buf, len);
}
-/* If STR is a defined macro, return its definition node, else return NULL. */
-cpp_macro *
-cpp_push_definition (cpp_reader *pfile, const char *str)
-{
- cpp_hashnode *node = _cpp_lex_identifier (pfile, str);
- if (node && node->type == NT_MACRO)
- return node->value.macro;
- else
- return NULL;
-}
-
-/* Replace a previous definition DFN of the macro STR. If DFN is NULL,
- then the macro should be undefined. */
-void
-cpp_pop_definition (cpp_reader *pfile, const char *str, cpp_macro *dfn)
+/* Replace a previous definition DEF of the macro STR. If DEF is NULL,
+ or first element is zero, then the macro should be undefined. */
+static void
+cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c)
{
- cpp_hashnode *node = _cpp_lex_identifier (pfile, str);
+ cpp_hashnode *node = _cpp_lex_identifier (pfile, c->name);
if (node == NULL)
return;
if (node->type != NT_VOID)
_cpp_free_definition (node);
- if (dfn)
- {
- node->type = NT_MACRO;
- node->value.macro = dfn;
- if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")))
- node->flags |= NODE_WARN;
-
- if (pfile->cb.define)
- pfile->cb.define (pfile, pfile->directive_line, node);
- }
+ if (c->is_undef)
+ return;
+ {
+ size_t namelen;
+ const uchar *dn;
+ cpp_hashnode *h = NULL;
+ cpp_buffer *nbuf;
+
+ namelen = ustrcspn (c->definition, "( \n");
+ h = cpp_lookup (pfile, c->definition, namelen);
+ dn = c->definition + namelen;
+
+ h->type = NT_VOID;
+ h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
+ nbuf = cpp_push_buffer (pfile, dn, ustrchr (dn, '\n') - dn, true);
+ if (nbuf != NULL)
+ {
+ _cpp_clean_line (pfile);
+ nbuf->sysp = 1;
+ if (!_cpp_create_definition (pfile, h))
+ abort ();
+ _cpp_pop_buffer (pfile);
+ }
+ else
+ abort ();
+ h->value.macro->line = c->line;
+ h->value.macro->syshdr = c->syshdr;
+ h->value.macro->used = c->used;
+ }
}
/* Process the string STR as if it appeared as the body of a #assert. */