X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libcpp%2Fdirectives.c;h=0510c6e3a8ef1480b03c5e51f8b4d4fe7f8e9a09;hb=1d7a003c97f78641f79c6fdb926e4dca6663c06e;hp=9c988dfa1365ea8c6617f7fbc80c3ae2c6029cc7;hpb=723ebaea39cb2d29bd1895b74c328b2117f85dda;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libcpp/directives.c b/libcpp/directives.c index 9c988dfa136..0510c6e3a8e 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -1,7 +1,7 @@ /* 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 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 @@ -32,7 +32,7 @@ along with this program; see the file COPYING3. If not see 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. */ @@ -104,7 +104,7 @@ static const char *parse_include (cpp_reader *, int *, const cpp_token ***, static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *); static unsigned int read_flag (cpp_reader *, unsigned int); static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *); -static void do_diagnostic (cpp_reader *, int, int); +static void do_diagnostic (cpp_reader *, int, int, int); static cpp_hashnode *lex_macro_node (cpp_reader *, bool); static int undefine_macros (cpp_reader *, cpp_hashnode *, void *); static void do_include_common (cpp_reader *, enum include_type); @@ -126,6 +126,9 @@ 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); +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 @@ -151,11 +154,11 @@ D(error, T_ERROR, STDC89, 0) /* 475 */ \ D(pragma, T_PRAGMA, STDC89, IN_I) /* 195 */ \ D(warning, T_WARNING, EXTENSION, 0) /* 22 */ \ D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL | EXPAND) /* 19 */ \ -D(ident, T_IDENT, EXTENSION, IN_I | DEPRECATED) /* 11 */ \ +D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \ D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* 0 ObjC */ \ D(assert, T_ASSERT, EXTENSION, DEPRECATED) /* 0 SVR4 */ \ D(unassert, T_UNASSERT, EXTENSION, DEPRECATED) /* 0 SVR4 */ \ -D(sccs, T_SCCS, EXTENSION, IN_I | DEPRECATED) /* 0 SVR4? */ +D(sccs, T_SCCS, EXTENSION, IN_I) /* 0 SVR4? */ /* #sccs is synonymous with #ident. */ #define do_sccs do_ident @@ -278,16 +281,17 @@ start_directive (cpp_reader *pfile) 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) { @@ -352,9 +356,9 @@ directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented) 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_error (pfile, CPP_DL_WARNING, "#%s is a deprecated GCC extension", - dir->name); + && CPP_OPTION (pfile, cpp_warn_deprecated)) + cpp_warning (pfile, CPP_W_DEPRECATED, + "#%s is a deprecated GCC extension", dir->name); } /* Traditionally, a directive is ignored unless its # is in @@ -366,16 +370,16 @@ directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented) if (CPP_WTRADITIONAL (pfile)) { if (dir == &dtable[T_ELIF]) - cpp_error (pfile, CPP_DL_WARNING, - "suggest not using #elif in traditional C"); + cpp_warning (pfile, CPP_W_TRADITIONAL, + "suggest not using #elif in traditional C"); else if (indented && dir->origin == KANDR) - cpp_error (pfile, CPP_DL_WARNING, - "traditional C ignores #%s with the # indented", - dir->name); + cpp_warning (pfile, CPP_W_TRADITIONAL, + "traditional C ignores #%s with the # indented", + dir->name); else if (!indented && dir->origin != KANDR) - cpp_error (pfile, CPP_DL_WARNING, - "suggest hiding #%s from traditional C with an indented #", - dir->name); + cpp_warning (pfile, CPP_W_TRADITIONAL, + "suggest hiding #%s from traditional C with an indented #", + dir->name); } } @@ -398,7 +402,7 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) 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; @@ -697,7 +701,8 @@ parse_include (cpp_reader *pfile, int *pangle_brackets, /* Allow macro expansion. */ header = get_token_no_padding (pfile); *location = header->src_loc; - if (header->type == CPP_STRING || header->type == CPP_HEADER_NAME) + if ((header->type == CPP_STRING && header->val.str.text[0] != 'R') + || header->type == CPP_HEADER_NAME) { fname = XNEWVEC (char, header->val.str.len - 1); memcpy (fname, header->val.str.text + 1, header->val.str.len - 2); @@ -879,14 +884,14 @@ static void 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. */ @@ -941,11 +946,11 @@ static void 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; @@ -1033,7 +1038,9 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, 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); @@ -1042,7 +1049,7 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, /* Report a warning or error detected by the program we are processing. Use the directive's tokens in the error message. */ static void -do_diagnostic (cpp_reader *pfile, int code, int print_dir) +do_diagnostic (cpp_reader *pfile, int code, int reason, int print_dir) { const unsigned char *dir_name; unsigned char *line; @@ -1056,21 +1063,26 @@ do_diagnostic (cpp_reader *pfile, int code, int print_dir) line = cpp_output_line_to_string (pfile, dir_name); pfile->state.prevent_expansion--; - cpp_error_with_line (pfile, code, src_loc, 0, "%s", line); + if (code == CPP_DL_WARNING_SYSHDR && reason) + cpp_warning_with_line_syshdr (pfile, reason, src_loc, 0, "%s", line); + else if (code == CPP_DL_WARNING && reason) + cpp_warning_with_line (pfile, reason, src_loc, 0, "%s", line); + else + cpp_error_with_line (pfile, code, src_loc, 0, "%s", line); free (line); } static void do_error (cpp_reader *pfile) { - do_diagnostic (pfile, CPP_DL_ERROR, 1); + do_diagnostic (pfile, CPP_DL_ERROR, 0, 1); } static void do_warning (cpp_reader *pfile) { /* We want #warning diagnostics to be emitted in system headers too. */ - do_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, 1); + do_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, CPP_W_WARNING_DIRECTIVE, 1); } /* Report program identification. */ @@ -1243,6 +1255,8 @@ _cpp_init_internal_pragmas (cpp_reader *pfile) { /* Pragmas in the global namespace. */ register_pragma_internal (pfile, 0, "once", do_pragma_once); + register_pragma_internal (pfile, 0, "push_macro", do_pragma_push_macro); + register_pragma_internal (pfile, 0, "pop_macro", do_pragma_pop_macro); /* New GCC-specific pragmas should be put in the GCC namespace. */ register_pragma_internal (pfile, "GCC", "poison", do_pragma_poison); @@ -1348,7 +1362,36 @@ do_pragma (cpp_reader *pfile) { 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); @@ -1422,6 +1465,116 @@ do_pragma_once (cpp_reader *pfile) _cpp_mark_file_once_only (pfile, pfile->buffer->file); } +/* Handle #pragma push_macro(STRING). */ +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; + struct def_pragma_macro *c; + + txt = get__Pragma_string (pfile); + if (!txt) + { + source_location src_loc = pfile->cur_token[-1].src_loc; + cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, + "invalid #pragma push_macro directive"); + check_eol (pfile, false); + skip_rest_of_line (pfile); + return; + } + dest = macroname = (char *) alloca (txt->val.str.len + 2); + src = (const char *) (txt->val.str.text + 1 + (txt->val.str.text[0] == 'L')); + limit = (const char *) (txt->val.str.text + txt->val.str.len - 1); + while (src < limit) + { + /* We know there is a character following the backslash. */ + if (*src == '\\' && (src[1] == '\\' || src[1] == '"')) + src++; + *dest++ = *src++; + } + *dest = 0; + 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; + 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; +} + +/* Handle #pragma pop_macro(STRING). */ +static void +do_pragma_pop_macro (cpp_reader *pfile) +{ + char *macroname, *dest; + const char *limit, *src; + const cpp_token *txt; + struct def_pragma_macro *l = NULL, *c = pfile->pushed_macros; + txt = get__Pragma_string (pfile); + if (!txt) + { + source_location src_loc = pfile->cur_token[-1].src_loc; + cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, + "invalid #pragma pop_macro directive"); + check_eol (pfile, false); + skip_rest_of_line (pfile); + return; + } + dest = macroname = (char *) alloca (txt->val.str.len + 2); + src = (const char *) (txt->val.str.text + 1 + (txt->val.str.text[0] == 'L')); + limit = (const char *) (txt->val.str.text + txt->val.str.len - 1); + while (src < limit) + { + /* We know there is a character following the backslash. */ + if (*src == '\\' && (src[1] == '\\' || src[1] == '"')) + src++; + *dest++ = *src++; + } + *dest = 0; + check_eol (pfile, false); + skip_rest_of_line (pfile); + + while (c != NULL) + { + if (!strcmp (c->name, macroname)) + { + if (!l) + pfile->pushed_macros = c->next; + else + l->next = c->next; + cpp_pop_definition (pfile, c); + free (c->definition); + free (c->name); + free (c); + break; + } + l = c; + c = c->next; + } +} + /* Handle #pragma GCC poison, to poison one or more identifiers so that the lexer produces a hard error for each subsequent usage. */ static void @@ -1500,7 +1653,7 @@ do_pragma_dependency (cpp_reader *pfile) if (cpp_get_token (pfile)->type != CPP_EOF) { _cpp_backup_tokens (pfile, 1); - do_diagnostic (pfile, CPP_DL_WARNING, 0); + do_diagnostic (pfile, CPP_DL_WARNING, 0, 0); } } @@ -1537,7 +1690,8 @@ get__Pragma_string (cpp_reader *pfile) if (string->type == CPP_EOF) _cpp_backup_tokens (pfile, 1); if (string->type != CPP_STRING && string->type != CPP_WSTRING - && string->type != CPP_STRING32 && string->type != CPP_STRING16) + && string->type != CPP_STRING32 && string->type != CPP_STRING16 + && string->type != CPP_UTF8STRING) return NULL; paren = get_token_no_padding (pfile); @@ -1588,7 +1742,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) 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; @@ -1696,13 +1850,21 @@ do_ifdef (cpp_reader *pfile) 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)) { node->flags |= NODE_USED; if (node->type == NT_MACRO) { + if ((node->flags & NODE_BUILTIN) + && pfile->cb.user_builtin_macro) + pfile->cb.user_builtin_macro (pfile, node); if (pfile->cb.used_define) pfile->cb.used_define (pfile, pfile->directive_line, node); } @@ -1712,6 +1874,8 @@ do_ifdef (cpp_reader *pfile) pfile->cb.used_undef (pfile, pfile->directive_line, node); } } + if (pfile->cb.used) + pfile->cb.used (pfile, pfile->directive_line, node); check_eol (pfile, false); } } @@ -1732,13 +1896,21 @@ do_ifndef (cpp_reader *pfile) 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)) { node->flags |= NODE_USED; if (node->type == NT_MACRO) { + if ((node->flags & NODE_BUILTIN) + && pfile->cb.user_builtin_macro) + pfile->cb.user_builtin_macro (pfile, node); if (pfile->cb.used_define) pfile->cb.used_define (pfile, pfile->directive_line, node); } @@ -1748,6 +1920,8 @@ do_ifndef (cpp_reader *pfile) pfile->cb.used_undef (pfile, pfile->directive_line, node); } } + if (pfile->cb.used) + pfile->cb.used (pfile, pfile->directive_line, node); check_eol (pfile, false); } } @@ -2156,7 +2330,8 @@ do_unassert (cpp_reader *pfile) void cpp_define (cpp_reader *pfile, const char *str) { - char *buf, *p; + char *buf; + const char *p; size_t count; /* Copy the entire option so we can modify it. @@ -2222,40 +2397,12 @@ cpp_undef (cpp_reader *pfile, const char *macro) run_directive (pfile, T_UNDEF, buf, len); } -/* Like lex_macro_node, but read the input from STR. */ -static cpp_hashnode * -lex_macro_node_from_str (cpp_reader *pfile, const char *str) -{ - size_t len = strlen (str); - uchar *buf = (uchar *) alloca (len + 1); - cpp_hashnode *node; - - memcpy (buf, str, len); - buf[len] = '\n'; - cpp_push_buffer (pfile, buf, len, true); - node = lex_macro_node (pfile, true); - _cpp_pop_buffer (pfile); - - return node; -} - -/* 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 = lex_macro_node_from_str (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 = lex_macro_node_from_str (pfile, str); + cpp_hashnode *node = _cpp_lex_identifier (pfile, c->name); if (node == NULL) return; @@ -2272,16 +2419,35 @@ cpp_pop_definition (cpp_reader *pfile, const char *str, cpp_macro *dfn) 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. */