Mercurial > hg > CbC > CbC_gcc
diff libcpp/directives.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/libcpp/directives.c Sun Aug 21 07:07:55 2011 +0900 +++ b/libcpp/directives.c Fri Oct 27 22:46:09 2017 +0900 @@ -1,7 +1,5 @@ /* 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. + Copyright (C) 1986-2017 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 +30,7 @@ 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. */ @@ -118,10 +116,14 @@ static void do_pragma_poison (cpp_reader *); static void do_pragma_system_header (cpp_reader *); static void do_pragma_dependency (cpp_reader *); +static void do_pragma_warning_or_error (cpp_reader *, bool error); +static void do_pragma_warning (cpp_reader *); +static void do_pragma_error (cpp_reader *); static void do_linemarker (cpp_reader *); 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 void destringize_and_run (cpp_reader *, const cpp_string *, + source_location); 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 *); @@ -186,6 +188,16 @@ DIRECTIVE_TABLE }; #undef D + +/* A NULL-terminated array of directive names for use + when suggesting corrections for misspelled directives. */ +#define D(name, t, origin, flags) #name, +static const char * const directive_names[] = { +DIRECTIVE_TABLE + NULL +}; +#undef D + #undef DIRECTIVE_TABLE /* Wrapper struct directive for linemarkers. @@ -212,16 +224,33 @@ ; } -/* Ensure there are no stray tokens at the end of a directive. If - EXPAND is true, tokens macro-expanding to nothing are allowed. */ +/* Helper function for check_oel. */ + static void -check_eol (cpp_reader *pfile, bool expand) +check_eol_1 (cpp_reader *pfile, bool expand, int reason) { 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); + cpp_pedwarning (pfile, reason, "extra tokens at end of #%s directive", + pfile->directive->name); +} + +/* Variant of check_eol used for Wendif-labels warnings. */ + +static void +check_eol_endif_labels (cpp_reader *pfile) +{ + check_eol_1 (pfile, false, CPP_W_ENDIF_LABELS); +} + +/* 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, bool expand) +{ + check_eol_1 (pfile, expand, CPP_W_NONE); } /* Ensure there are no stray tokens other than comments at the end of @@ -328,7 +357,7 @@ if (no_expand) pfile->state.prevent_expansion++; - _cpp_scan_out_logical_line (pfile, NULL); + _cpp_scan_out_logical_line (pfile, NULL, false); if (no_expand) pfile->state.prevent_expansion--; @@ -446,7 +475,7 @@ We exclude the -fdirectives-only case because macro expansion has not been performed yet, and block comments can cause spaces - to preceed the directive. */ + to precede the directive. */ if (CPP_OPTION (pfile, preprocessed) && !CPP_OPTION (pfile, directives_only) && (indented || !(dir->flags & IN_I))) @@ -479,8 +508,35 @@ if (CPP_OPTION (pfile, lang) == CLK_ASM) skip = 0; else if (!pfile->state.skipping) - cpp_error (pfile, CPP_DL_ERROR, "invalid preprocessing directive #%s", - cpp_token_as_text (pfile, dname)); + { + const char *unrecognized + = (const char *)cpp_token_as_text (pfile, dname); + const char *hint = NULL; + + /* Call back into gcc to get a spelling suggestion. Ideally + we'd just use best_match from gcc/spellcheck.h (and filter + out the uncommon directives), but that requires moving it + to a support library. */ + if (pfile->cb.get_suggestion) + hint = pfile->cb.get_suggestion (pfile, unrecognized, + directive_names); + + if (hint) + { + rich_location richloc (pfile->line_table, dname->src_loc); + source_range misspelled_token_range + = get_range_from_loc (pfile->line_table, dname->src_loc); + richloc.add_fixit_replace (misspelled_token_range, hint); + cpp_error_at_richloc (pfile, CPP_DL_ERROR, &richloc, + "invalid preprocessing directive #%s;" + " did you mean #%s?", + unrecognized, hint); + } + else + cpp_error (pfile, CPP_DL_ERROR, + "invalid preprocessing directive #%s", + unrecognized); + } } pfile->directive = dir; @@ -548,6 +604,11 @@ if (is_def_or_undef && node == pfile->spec_nodes.n_defined) cpp_error (pfile, CPP_DL_ERROR, "\"defined\" cannot be used as a macro name"); + else if (is_def_or_undef + && (node == pfile->spec_nodes.n__has_include__ + || node == pfile->spec_nodes.n__has_include_next__)) + cpp_error (pfile, CPP_DL_ERROR, + "\"__has_include__\" cannot be used as a macro name"); else if (! (node->flags & NODE_POISONED)) return node; } @@ -609,6 +670,11 @@ if (node->flags & NODE_WARN) cpp_error (pfile, CPP_DL_WARNING, "undefining \"%s\"", NODE_NAME (node)); + else if ((node->flags & NODE_BUILTIN) + && CPP_OPTION (pfile, warn_builtin_macro_redefined)) + cpp_warning_with_line (pfile, CPP_W_BUILTIN_MACRO_REDEFINED, + pfile->directive_line, 0, + "undefining \"%s\"", NODE_NAME (node)); if (CPP_OPTION (pfile, warn_unused_macros)) _cpp_warn_if_unused_macro (pfile, node, NULL); @@ -789,7 +855,7 @@ pfile->directive->name, fname, angle_brackets, buf); - _cpp_stack_include (pfile, fname, angle_brackets, type); + _cpp_stack_include (pfile, fname, angle_brackets, type, location); } XDELETEVEC (fname); @@ -883,15 +949,15 @@ 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]; + struct line_maps *line_table = pfile->line_table; + const line_map_ordinary *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. */ @@ -937,6 +1003,7 @@ skip_rest_of_line (pfile); _cpp_do_file_change (pfile, LC_RENAME_VERBATIM, new_file, new_lineno, map_sysp); + line_table->seen_line_directive = true; } /* Interpret the # 44 "file" [flags] notation, which has slightly @@ -945,12 +1012,12 @@ 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]; + struct line_maps *line_table = pfile->line_table; + const line_map_ordinary *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; @@ -1016,6 +1083,23 @@ skip_rest_of_line (pfile); + if (reason == LC_LEAVE) + { + /* Reread map since cpp_get_token can invalidate it with a + reallocation. */ + map = LINEMAPS_LAST_ORDINARY_MAP (line_table); + const line_map_ordinary *from; + if (MAIN_FILE_P (map) + || (new_file + && (from = INCLUDED_FROM (pfile->line_table, map)) != NULL + && filename_cmp (ORDINARY_MAP_FILE_NAME (from), new_file) != 0)) + { + cpp_warning (pfile, CPP_W_NONE, + "file \"%s\" linemarker ignored due to " + "incorrect nesting", new_file); + return; + } + } /* 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 @@ -1024,6 +1108,7 @@ pfile->line_table->highest_location--; _cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp); + line_table->seen_line_directive = true; } /* Arrange the file_change callback. pfile->line has changed to @@ -1035,13 +1120,20 @@ const char *to_file, linenum_type file_line, unsigned int sysp) { + linemap_assert (reason != LC_ENTER_MACRO); const struct line_map *map = linemap_add (pfile->line_table, reason, sysp, to_file, file_line); + const line_map_ordinary *ord_map = NULL; if (map != NULL) - linemap_line_start (pfile->line_table, map->to_line, 127); + { + ord_map = linemap_check_ordinary (map); + linemap_line_start (pfile->line_table, + ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map), + 127); + } if (pfile->cb.file_change) - pfile->cb.file_change (pfile, map); + pfile->cb.file_change (pfile, ord_map); } /* Report a warning or error detected by the program we are @@ -1261,6 +1353,8 @@ register_pragma_internal (pfile, "GCC", "system_header", do_pragma_system_header); register_pragma_internal (pfile, "GCC", "dependency", do_pragma_dependency); + register_pragma_internal (pfile, "GCC", "warning", do_pragma_warning); + register_pragma_internal (pfile, "GCC", "error", do_pragma_error); } /* Return the number of registered pragmas in PE. */ @@ -1345,13 +1439,15 @@ do_pragma (cpp_reader *pfile) { const struct pragma_entry *p = NULL; - const cpp_token *token, *pragma_token = pfile->cur_token; + const cpp_token *token, *pragma_token; + source_location pragma_token_virt_loc = 0; cpp_token ns_token; unsigned int count = 1; pfile->state.prevent_expansion++; - token = cpp_get_token (pfile); + pragma_token = token = cpp_get_token_with_location (pfile, + &pragma_token_virt_loc); ns_token = *token; if (token->type == CPP_NAME) { @@ -1361,6 +1457,7 @@ bool allow_name_expansion = p->allow_expansion; if (allow_name_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.node); @@ -1376,7 +1473,7 @@ { if (p->is_deferred) { - pfile->directive_result.src_loc = pragma_token->src_loc; + pfile->directive_result.src_loc = pragma_token_virt_loc; pfile->directive_result.type = CPP_PRAGMA; pfile->directive_result.flags = pragma_token->flags; pfile->directive_result.val.pragma = p->u.ident; @@ -1629,6 +1726,42 @@ free ((void *) fname); } +/* Issue a diagnostic with the message taken from the pragma. If + ERROR is true, the diagnostic is a warning, otherwise, it is an + error. */ +static void +do_pragma_warning_or_error (cpp_reader *pfile, bool error) +{ + const cpp_token *tok = _cpp_lex_token (pfile); + cpp_string str; + if (tok->type != CPP_STRING + || !cpp_interpret_string_notranslate (pfile, &tok->val.str, 1, &str, + CPP_STRING) + || str.len == 0) + { + cpp_error (pfile, CPP_DL_ERROR, "invalid \"#pragma GCC %s\" directive", + error ? "error" : "warning"); + return; + } + cpp_error (pfile, error ? CPP_DL_ERROR : CPP_DL_WARNING, + "%s", str.text); + free ((void *)str.text); +} + +/* Issue a warning diagnostic. */ +static void +do_pragma_warning (cpp_reader *pfile) +{ + do_pragma_warning_or_error (pfile, false); +} + +/* Issue an error diagnostic. */ +static void +do_pragma_error (cpp_reader *pfile) +{ + do_pragma_warning_or_error (pfile, true); +} + /* Get a token but skip padding. */ static const cpp_token * get_token_no_padding (cpp_reader *pfile) @@ -1675,7 +1808,8 @@ /* Destringize IN into a temporary buffer, by removing the first \ of \" and \\ sequences, and process the result as a #pragma directive. */ static void -destringize_and_run (cpp_reader *pfile, const cpp_string *in) +destringize_and_run (cpp_reader *pfile, const cpp_string *in, + source_location expansion_loc) { const unsigned char *src, *limit; char *dest, *result; @@ -1710,10 +1844,7 @@ saved_cur_token = pfile->cur_token; saved_cur_run = pfile->cur_run; - pfile->context = XNEW (cpp_context); - pfile->context->macro = 0; - pfile->context->prev = 0; - pfile->context->next = 0; + pfile->context = XCNEW (cpp_context); /* Inline run_directive, since we need to delay the _cpp_pop_buffer until we've read all of the tokens that we want. */ @@ -1758,6 +1889,12 @@ toks = XRESIZEVEC (cpp_token, toks, maxcount); } toks[count] = *cpp_get_token (pfile); + /* _Pragma is a builtin, so we're not within a macro-map, and so + the token locations are set to bogus ordinary locations + near to, but after that of the "_Pragma". + Paper over this by setting them equal to the location of the + _Pragma itself (PR preprocessor/69126). */ + toks[count].src_loc = expansion_loc; /* Macros have been already expanded by cpp_get_token if the pragma allowed expansion. */ toks[count++].flags |= NO_EXPAND; @@ -1792,14 +1929,14 @@ /* Handle the _Pragma operator. Return 0 on error, 1 if ok. */ int -_cpp_do__Pragma (cpp_reader *pfile) +_cpp_do__Pragma (cpp_reader *pfile, source_location expansion_loc) { const cpp_token *string = get__Pragma_string (pfile); pfile->directive_result.type = CPP_PADDING; if (string) { - destringize_and_run (pfile, &string->val.str); + destringize_and_run (pfile, &string->val.str, expansion_loc); return 1; } cpp_error (pfile, CPP_DL_ERROR, @@ -1819,7 +1956,12 @@ 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)) { @@ -1860,7 +2002,12 @@ 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)) { @@ -1934,7 +2081,7 @@ /* Only check EOL if was not originally skipping. */ if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels)) - check_eol (pfile, false); + check_eol_endif_labels (pfile); } } @@ -1958,23 +2105,16 @@ } ifs->type = T_ELIF; - if (! ifs->was_skipping) + /* See DR#412: "Only the first group whose control condition + evaluates to true (nonzero) is processed; any following groups + are skipped and their controlling directives are processed as + if they were in a group that is skipped." */ + if (ifs->skip_elses) + pfile->state.skipping = 1; + else { - bool value; - /* The standard mandates that the expression be parsed even - if we are skipping elses at this point -- the lexical - restrictions on #elif only apply to skipped groups, but - this group is not being skipped. Temporarily set - skipping to false to get lexer warnings. */ - pfile->state.skipping = 0; - value = _cpp_parse_expr (pfile, false); - if (ifs->skip_elses) - pfile->state.skipping = 1; - else - { - pfile->state.skipping = ! value; - ifs->skip_elses = value; - } + pfile->state.skipping = ! _cpp_parse_expr (pfile, false); + ifs->skip_elses = ! pfile->state.skipping; } /* Invalidate any controlling macro. */ @@ -1995,7 +2135,7 @@ { /* Only check EOL if was not originally skipping. */ if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels)) - check_eol (pfile, false); + check_eol_endif_labels (pfile); /* If potential control macro, we go back outside again. */ if (ifs->next == 0 && ifs->mi_cmacro) @@ -2322,11 +2462,11 @@ void cpp_define_formatted (cpp_reader *pfile, const char *fmt, ...) { - char *ptr = NULL; + char *ptr; va_list ap; va_start (ap, fmt); - vasprintf (&ptr, fmt, ap); + ptr = xvasprintf (fmt, ap); va_end (ap); cpp_define (pfile, ptr); @@ -2507,6 +2647,7 @@ cpp_buffer *buffer = pfile->buffer; struct _cpp_file *inc = buffer->file; struct if_stack *ifs; + const unsigned char *to_free; /* Walk back up the conditional stack till we reach its level at entry to this file, issuing error messages. */ @@ -2520,6 +2661,7 @@ /* _cpp_do_file_change expects pfile->buffer to be the new one. */ pfile->buffer = buffer->prev; + to_free = buffer->to_free; free (buffer->notes); /* Free the buffer object now; we may want to push a new buffer @@ -2528,7 +2670,7 @@ if (inc) { - _cpp_pop_file_buffer (pfile, inc); + _cpp_pop_file_buffer (pfile, inc, to_free); _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0); } @@ -2548,3 +2690,12 @@ node->directive_index = i; } } + +/* Extract header file from a bracket include. Parsing starts after '<'. + The string is malloced and must be freed by the caller. */ +char * +_cpp_bracket_include(cpp_reader *pfile) +{ + return glue_header_name (pfile); +} +