Wolfgang Thallergcc16 merge934c3885 months agoHistory
1012 lines · 33.9 KB · C++
RawDownload
/* CPP Library.   Copyright (C) 1986-2026 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 itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 3, or (at your option) anylater version. This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details. You should have received a copy of the GNU General Public Licensealong with this program; see the file COPYING3.  If not see<http://www.gnu.org/licenses/>.  */ #include "config.h"#include "system.h"#include "cpplib.h"#include "internal.h"#include "mkdeps.h"#include "localedir.h"#include "filenames.h" #ifndef ENABLE_CANONICAL_SYSTEM_HEADERS#ifdef HAVE_DOS_BASED_FILE_SYSTEM#define ENABLE_CANONICAL_SYSTEM_HEADERS 1#else#define ENABLE_CANONICAL_SYSTEM_HEADERS 0#endif#endif static void init_library (void);static void mark_named_operators (cpp_reader *, int);static bool read_original_filename (cpp_reader *);static void read_original_directory (cpp_reader *);static void post_options (cpp_reader *); /* If we have designated initializers (GCC >2.7) these tables can be   initialized, constant data.  Similarly for C++14 and later.   Otherwise, they have to be filled in at runtime.  */#if HAVE_DESIGNATED_INITIALIZERS #define init_trigraph_map()  /* Nothing.  */#define TRIGRAPH_MAP \__extension__ const uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { #define END };#define s(p, v) [p] = v, #elif __cpp_constexpr >= 201304L #define init_trigraph_map()  /* Nothing.  */#define TRIGRAPH_MAP \constexpr _cpp_trigraph_map_s::_cpp_trigraph_map_s () : map {} {#define END } \constexpr _cpp_trigraph_map_s _cpp_trigraph_map_d;#define s(p, v) map[p] = v; #else #define TRIGRAPH_MAP uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { 0 }; \ static void init_trigraph_map (void) { \ unsigned char *x = _cpp_trigraph_map; #define END }#define s(p, v) x[p] = v; #endif TRIGRAPH_MAP  s('=', '#')	s(')', ']')	s('!', '|')  s('(', '[')	s('\'', '^')	s('>', '}')  s('/', '\\')	s('<', '{')	s('-', '~')END #undef s#undef END#undef TRIGRAPH_MAP /* A set of booleans indicating what CPP features each source language   requires.  */struct lang_flags{  unsigned int c99 : 1;  unsigned int cplusplus : 1;  unsigned int extended_numbers : 1;  unsigned int extended_identifiers : 1;  unsigned int c11_identifiers : 1;  unsigned int xid_identifiers : 1;  unsigned int std : 1;  unsigned int digraphs : 1;  unsigned int uliterals : 1;  unsigned int rliterals : 1;  unsigned int user_literals : 1;  unsigned int binary_constants : 1;  unsigned int digit_separators : 1;  unsigned int trigraphs : 1;  unsigned int utf8_char_literals : 1;  unsigned int va_opt : 1;  unsigned int scope : 1;  unsigned int dfp_constants : 1;  unsigned int size_t_literals : 1;  unsigned int elifdef : 1;  unsigned int warning_directive : 1;  unsigned int delimited_escape_seqs : 1;  unsigned int named_uc_escape_seqs : 1;  unsigned int octal_constants : 1;  unsigned int true_false : 1;  unsigned int embed : 1;  unsigned int imaginary_constants : 1;  unsigned int low_ucns : 1;}; static const struct lang_flags lang_defaults[] = {  /*					       u         e w   n					 b d   8         l a   a   t     l			     x         u i i   c v s   s i r d m o r e   o		       x     i   d u r d n g t h a c   z f n e e c u m i w		   c c n x c d s i l l l c s r l o o d l d d l d t f b m u		   9 + u i 1 i t g i i i s e i i p p f i e i i u a a e a c		   9 + m d 1 d d r t t t t p g t t e p t f r m c l l d g n */  /* GNUC89   */ { 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },  /* GNUC99   */ { 1,0,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },  /* GNUC11   */ { 1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },  /* GNUC17   */ { 1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },  /* GNUC23   */ { 1,0,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0,1,1,0,0,0,1,1,0,1 },  /* GNUC2Y   */ { 1,0,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,1 },  /* STDC89   */ { 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },  /* STDC94   */ { 0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },  /* STDC99   */ { 1,0,1,1,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },  /* STDC11   */ { 1,0,1,1,1,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },  /* STDC17   */ { 1,0,1,1,1,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },  /* STDC23   */ { 1,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,0,1,1,0,1 },  /* STDC2Y   */ { 1,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,1 },  /* GNUCXX   */ { 0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1 },  /* CXX98    */ { 0,1,0,1,0,1,1,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1 },  /* GNUCXX11 */ { 1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1 },  /* CXX11    */ { 1,1,0,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1 },  /* GNUCXX14 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1 },  /* CXX14    */ { 1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1 },  /* GNUCXX17 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,1,0,0,1 },  /* CXX17    */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,0,0,0,0,0,1,0,0,1 },  /* GNUCXX20 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,1,0,0,1 },  /* CXX20    */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,1,0,0,1 },  /* GNUCXX23 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,0,1 },  /* CXX23    */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,0,1 },  /* GNUCXX26 */ { 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,1,0,1 },  /* CXX26    */ { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,1,0,1 },  /* ASM      */ { 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}; /* Sets internal flags correctly for a given language.  */voidcpp_set_lang (cpp_reader *pfile, enum c_lang lang){  const struct lang_flags *l = &lang_defaults[(int) lang];   CPP_OPTION (pfile, lang) = lang;   CPP_OPTION (pfile, c99)			 = l->c99;  CPP_OPTION (pfile, cplusplus)			 = l->cplusplus;  CPP_OPTION (pfile, extended_numbers)		 = l->extended_numbers;  CPP_OPTION (pfile, extended_identifiers)	 = l->extended_identifiers;  CPP_OPTION (pfile, c11_identifiers)		 = l->c11_identifiers;  CPP_OPTION (pfile, xid_identifiers)		 = l->xid_identifiers;  CPP_OPTION (pfile, std)			 = l->std;  CPP_OPTION (pfile, digraphs)			 = l->digraphs;  CPP_OPTION (pfile, uliterals)			 = l->uliterals;  CPP_OPTION (pfile, rliterals)			 = l->rliterals;  CPP_OPTION (pfile, user_literals)		 = l->user_literals;  CPP_OPTION (pfile, binary_constants)		 = l->binary_constants;  CPP_OPTION (pfile, digit_separators)		 = l->digit_separators;  CPP_OPTION (pfile, trigraphs)			 = l->trigraphs;  CPP_OPTION (pfile, utf8_char_literals)	 = l->utf8_char_literals;  CPP_OPTION (pfile, va_opt)			 = l->va_opt;  CPP_OPTION (pfile, scope)			 = l->scope;  CPP_OPTION (pfile, dfp_constants)		 = l->dfp_constants;  CPP_OPTION (pfile, size_t_literals)		 = l->size_t_literals;  CPP_OPTION (pfile, elifdef)			 = l->elifdef;  CPP_OPTION (pfile, warning_directive)		 = l->warning_directive;  CPP_OPTION (pfile, delimited_escape_seqs)	 = l->delimited_escape_seqs;  CPP_OPTION (pfile, named_uc_escape_seqs)	 = l->named_uc_escape_seqs;  CPP_OPTION (pfile, octal_constants)		 = l->octal_constants;  CPP_OPTION (pfile, true_false)		 = l->true_false;  CPP_OPTION (pfile, embed)			 = l->embed;  CPP_OPTION (pfile, imaginary_constants)	 = l->imaginary_constants;  CPP_OPTION (pfile, low_ucns)			 = l->low_ucns;} /* Initialize library global state.  */static voidinit_library (void){  static int initialized = 0;   if (! initialized)    {      initialized = 1;       _cpp_init_lexer ();       /* Set up the trigraph map.  This doesn't need to do anything if	 we were compiled with a compiler that supports C99 designated	 initializers.  */      init_trigraph_map (); #ifdef ENABLE_NLS       (void) bindtextdomain (PACKAGE, LOCALEDIR);#endif    }} /* Initialize a cpp_reader structure.  */cpp_reader *cpp_create_reader (enum c_lang lang, cpp_hash_table *table,		   class line_maps *line_table, cpp_hash_table *extra_table){  cpp_reader *pfile;   /* Initialize this instance of the library if it hasn't been already.  */  init_library ();   pfile = XCNEW (cpp_reader);  memset (&pfile->base_context, 0, sizeof (pfile->base_context));   cpp_set_lang (pfile, lang);  CPP_OPTION (pfile, warn_multichar) = 1;  CPP_OPTION (pfile, discard_comments) = 1;  CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1;  CPP_OPTION (pfile, max_include_depth) = 200;  CPP_OPTION (pfile, operator_names) = 1;  CPP_OPTION (pfile, warn_trigraphs) = 2;  CPP_OPTION (pfile, warn_endif_labels) = 1;  CPP_OPTION (pfile, cpp_warn_c90_c99_compat) = -1;  CPP_OPTION (pfile, cpp_warn_c11_c23_compat) = -1;  CPP_OPTION (pfile, cpp_warn_c23_c2y_compat) = -1;  CPP_OPTION (pfile, cpp_warn_cxx11_compat) = 0;  CPP_OPTION (pfile, cpp_warn_cxx20_compat) = 0;  CPP_OPTION (pfile, cpp_warn_deprecated) = 1;  CPP_OPTION (pfile, cpp_warn_long_long) = 0;  CPP_OPTION (pfile, dollars_in_ident) = 1;  CPP_OPTION (pfile, warn_dollars) = 1;  CPP_OPTION (pfile, warn_variadic_macros) = 1;  CPP_OPTION (pfile, suppress_builtin_macro_warnings) = 0;  CPP_OPTION (pfile, warn_builtin_macro_redefined) = 1;  CPP_OPTION (pfile, cpp_warn_implicit_fallthrough) = 0;  CPP_OPTION (pfile, warn_header_guard) = 0;  /* By default, track locations of tokens resulting from macro     expansion.  The '2' means, track the locations with the highest     accuracy.  Read the comments for struct     cpp_options::track_macro_expansion to learn about the other     values.  */  CPP_OPTION (pfile, track_macro_expansion) = 2;  CPP_OPTION (pfile, warn_normalize) = normalized_C;  CPP_OPTION (pfile, warn_literal_suffix) = 1;  CPP_OPTION (pfile, canonical_system_headers)      = ENABLE_CANONICAL_SYSTEM_HEADERS;  CPP_OPTION (pfile, ext_numeric_literals) = 1;  CPP_OPTION (pfile, warn_date_time) = 0;  CPP_OPTION (pfile, cpp_warn_bidirectional) = bidirectional_unpaired;  CPP_OPTION (pfile, cpp_warn_invalid_utf8) = 0;  CPP_OPTION (pfile, cpp_warn_unicode) = 1;  CPP_OPTION (pfile, cpp_input_charset_explicit) = 0;  CPP_OPTION (pfile, cpp_tabstop) = 8;   /* Default CPP arithmetic to something sensible for the host for the     benefit of dumb users like fix-header.  */  CPP_OPTION (pfile, precision) = CHAR_BIT * sizeof (long);  CPP_OPTION (pfile, char_precision) = CHAR_BIT;  CPP_OPTION (pfile, wchar_precision) = CHAR_BIT * sizeof (int);  CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int);  CPP_OPTION (pfile, unsigned_char) = 0;  CPP_OPTION (pfile, unsigned_wchar) = 1;  CPP_OPTION (pfile, unsigned_utf8char) = 1;  CPP_OPTION (pfile, bytes_big_endian) = 1;  /* does not matter */   /* Default to no charset conversion.  */  CPP_OPTION (pfile, narrow_charset) = _cpp_default_encoding ();  CPP_OPTION (pfile, wide_charset) = 0;   /* Default the input character set to UTF-8.  */  CPP_OPTION (pfile, input_charset) = _cpp_default_encoding ();   /* A fake empty "directory" used as the starting point for files     looked up without a search path.  Name cannot be '/' because we     don't want to prepend anything at all to filenames using it.  All     other entries are correct zero-initialized.  */  pfile->no_search_path.name = (char *) "";   /* Initialize the line map.  */  pfile->line_table = line_table;   /* Initialize lexer state.  */  pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);   /* Set up static tokens.  */  pfile->avoid_paste.type = CPP_PADDING;  pfile->avoid_paste.val.source = NULL;  pfile->avoid_paste.src_loc = 0;  pfile->endarg.type = CPP_EOF;  pfile->endarg.flags = 0;  pfile->endarg.src_loc = 0;   /* Create a token buffer for the lexer.  */  _cpp_init_tokenrun (&pfile->base_run, 250);  pfile->cur_run = &pfile->base_run;  pfile->cur_token = pfile->base_run.base;   /* Initialize the base context.  */  pfile->context = &pfile->base_context;  pfile->base_context.c.macro = 0;  pfile->base_context.prev = pfile->base_context.next = 0;   /* Aligned and unaligned storage.  */  pfile->a_buff = _cpp_get_buff (pfile, 0);  pfile->u_buff = _cpp_get_buff (pfile, 0);   /* Initialize table for push_macro/pop_macro.  */  pfile->pushed_macros = 0;   /* Do not force token locations by default.  */  pfile->forced_token_location = 0;   /* Note the timestamp is unset.  */  pfile->time_stamp = time_t (-1);  pfile->time_stamp_kind = 0;   /* The expression parser stack.  */  _cpp_expand_op_stack (pfile);   /* Initialize the buffer obstack.  */  obstack_specify_allocation (&pfile->buffer_ob, 0, 0, xmalloc, free);   _cpp_init_files (pfile);   _cpp_init_hashtable (pfile, table, extra_table);   return pfile;} /* Set the line_table entry in PFILE.  This is called after reading a   PCH file, as the old line_table will be incorrect.  */voidcpp_set_line_map (cpp_reader *pfile, class line_maps *line_table){  pfile->line_table = line_table;} /* Free resources used by PFILE.  Accessing PFILE after this function   returns leads to undefined behavior.  Returns the error count.  */voidcpp_destroy (cpp_reader *pfile){  cpp_context *context, *contextn;  struct def_pragma_macro *pmacro;  tokenrun *run, *runn;  int i;   free (pfile->op_stack);   while (CPP_BUFFER (pfile) != NULL)    _cpp_pop_buffer (pfile);   free (pfile->out.base);   if (pfile->macro_buffer)    {      free (pfile->macro_buffer);      pfile->macro_buffer = NULL;      pfile->macro_buffer_len = 0;    }   if (pfile->deps)    deps_free (pfile->deps);  obstack_free (&pfile->buffer_ob, 0);   _cpp_destroy_hashtable (pfile);  _cpp_cleanup_files (pfile);  _cpp_destroy_iconv (pfile);   _cpp_free_buff (pfile->a_buff);  _cpp_free_buff (pfile->u_buff);  _cpp_free_buff (pfile->free_buffs);   for (run = &pfile->base_run; run; run = runn)    {      runn = run->next;      free (run->base);      if (run != &pfile->base_run)	free (run);    }   for (context = pfile->base_context.next; context; context = contextn)    {      contextn = context->next;      free (context);    }   if (pfile->comments.entries)    {      for (i = 0; i < pfile->comments.count; i++)	free (pfile->comments.entries[i].comment);       free (pfile->comments.entries);    }  if (pfile->pushed_macros)    {      do	{	  pmacro = pfile->pushed_macros;	  pfile->pushed_macros = pmacro->next;	  free (pmacro->name);	  free (pmacro);	}      while (pfile->pushed_macros);    }   free (pfile);} /* This structure defines one built-in identifier.  A node will be   entered in the hash table under the name NAME, with value VALUE.    There are two tables of these.  builtin_array holds all the   "builtin" macros: these are handled by builtin_macro() in   macro.cc.  Builtin is somewhat of a misnomer -- the property of   interest is that these macros require special code to compute their   expansions.  The value is a "cpp_builtin_type" enumerator.    operator_array holds the C++ named operators.  These are keywords   which act as aliases for punctuators.  In C++, they cannot be   altered through #define, and #if recognizes them as operators.  In   C, these are not entered into the hash table at all (but see   <iso646.h>).  The value is a token-type enumerator.  */struct builtin_macro{  const uchar *const name;  const unsigned short len;  const unsigned short value;  const bool always_warn_if_redefined;}; #define B(n, t, f)    { DSC(n), t, f }static const struct builtin_macro builtin_array[] ={  B("__TIMESTAMP__",	 BT_TIMESTAMP,     false),  B("__TIME__",		 BT_TIME,          false),  B("__DATE__",		 BT_DATE,          false),  B("__FILE__",		 BT_FILE,          false),  B("__FILE_NAME__",	 BT_FILE_NAME,     false),  B("__BASE_FILE__",	 BT_BASE_FILE,     false),  B("__LINE__",		 BT_SPECLINE,      true),  B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL, true),  B("__COUNTER__",	 BT_COUNTER,       true),  /* Make sure to update the list of built-in     function-like macros in traditional.cc:     fun_like_macro() when adding more following */  B("__has_attribute",	 BT_HAS_ATTRIBUTE, true),  B("__has_c_attribute", BT_HAS_STD_ATTRIBUTE, true),  B("__has_cpp_attribute", BT_HAS_ATTRIBUTE, true),  B("__has_builtin",	 BT_HAS_BUILTIN,   true),  B("__has_include",	 BT_HAS_INCLUDE,   true),  B("__has_include_next",BT_HAS_INCLUDE_NEXT,   true),  B("__has_embed",	 BT_HAS_EMBED, true),  B("__has_feature",	 BT_HAS_FEATURE, true),  B("__has_extension",	 BT_HAS_EXTENSION, true),  /* Keep builtins not used for -traditional-cpp at the end, and     update init_builtins() if any more are added.  */  B("_Pragma",		 BT_PRAGMA,        true),  B("__STDC__",		 BT_STDC,          true),};#undef B struct builtin_operator{  const uchar *const name;  const unsigned short len;  const unsigned short value;}; #define B(n, t)    { DSC(n), t }static const struct builtin_operator operator_array[] ={  B("and",	CPP_AND_AND),  B("and_eq",	CPP_AND_EQ),  B("bitand",	CPP_AND),  B("bitor",	CPP_OR),  B("compl",	CPP_COMPL),  B("not",	CPP_NOT),  B("not_eq",	CPP_NOT_EQ),  B("or",	CPP_OR_OR),  B("or_eq",	CPP_OR_EQ),  B("xor",	CPP_XOR),  B("xor_eq",	CPP_XOR_EQ)};

Lines 1–500 of 1012.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t