char *, int));
static void init_library PARAMS ((void));
static void init_builtins PARAMS ((cpp_reader *));
+static void mark_named_operators PARAMS ((cpp_reader *));
static void append_include_chain PARAMS ((cpp_reader *,
char *, int, int));
static struct search_path * remove_dup_dir PARAMS ((cpp_reader *,
cpp_reader *pfile;
char *dir;
int path;
- int cxx_aware ATTRIBUTE_UNUSED;
+ int cxx_aware;
{
struct cpp_pending *pend = CPP_OPTION (pfile, pending);
struct search_path *new;
include files since these two lists are really just a concatenation
of one "system" list. */
if (path == SYSTEM || path == AFTER)
-#ifdef NO_IMPLICIT_EXTERN_C
- new->sysp = 1;
-#else
new->sysp = cxx_aware ? 1 : 2;
-#endif
else
new->sysp = 0;
new->name_map = NULL;
for (cur = head; cur; cur = cur->next)
{
for (other = head; other != cur; other = other->next)
- if (INO_T_EQ (cur->ino, other->ino) && cur->dev == other->dev)
+ if (INO_T_EQ (cur->ino, other->ino) && cur->dev == other->dev)
{
if (cur->sysp && !other->sysp)
{
struct lang_flags
{
char c99;
- char objc;
char cplusplus;
char extended_numbers;
char trigraphs;
/* ??? Enable $ in identifiers in assembly? */
static const struct lang_flags lang_defaults[] =
-{ /* c99 objc c++ xnum trig dollar c++comm digr */
- /* GNUC89 */ { 0, 0, 0, 1, 0, 1, 1, 1 },
- /* GNUC99 */ { 1, 0, 0, 1, 0, 1, 1, 1 },
- /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0 },
- /* STDC94 */ { 0, 0, 0, 0, 1, 0, 0, 1 },
- /* STDC99 */ { 1, 0, 0, 1, 1, 0, 1, 1 },
- /* GNUCXX */ { 0, 0, 1, 1, 0, 1, 1, 1 },
- /* CXX98 */ { 0, 0, 1, 1, 1, 0, 1, 1 },
- /* OBJC */ { 0, 1, 0, 1, 0, 1, 1, 1 },
- /* OBJCXX */ { 0, 1, 1, 1, 0, 1, 1, 1 },
- /* ASM */ { 0, 0, 0, 1, 0, 0, 1, 0 }
+{ /* c99 c++ xnum trig dollar c++comm digr */
+ /* GNUC89 */ { 0, 0, 1, 0, 1, 1, 1 },
+ /* GNUC99 */ { 1, 0, 1, 0, 1, 1, 1 },
+ /* STDC89 */ { 0, 0, 0, 1, 0, 0, 0 },
+ /* STDC94 */ { 0, 0, 0, 1, 0, 0, 1 },
+ /* STDC99 */ { 1, 0, 1, 1, 0, 1, 1 },
+ /* GNUCXX */ { 0, 1, 1, 0, 1, 1, 1 },
+ /* CXX98 */ { 0, 1, 1, 1, 0, 1, 1 },
+ /* ASM */ { 0, 0, 1, 0, 0, 1, 0 }
};
/* Sets internal flags correctly for a given language. */
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, objc) = l->objc;
CPP_OPTION (pfile, cplusplus) = l->cplusplus;
CPP_OPTION (pfile, extended_numbers) = l->extended_numbers;
CPP_OPTION (pfile, trigraphs) = l->trigraphs;
/* Default CPP arithmetic to something sensible for the host for the
benefit of dumb users like fix-header. */
-#define BITS_PER_HOST_WIDEST_INT (CHAR_BIT * sizeof (HOST_WIDEST_INT))
- CPP_OPTION (pfile, precision) = BITS_PER_HOST_WIDEST_INT;
+ 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) = !DEFAULT_SIGNED_CHAR;
+ CPP_OPTION (pfile, unsigned_char) = 0;
CPP_OPTION (pfile, unsigned_wchar) = 1;
/* It's simplest to just create this struct whether or not it will
/* Initialise the line map. Start at logical line 1, so we can use
a line number of zero for special states. */
init_line_maps (&pfile->line_maps);
- pfile->line = 1;
+ pfile->trad_line = pfile->line = 1;
/* Initialize lexer state. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
while (CPP_BUFFER (pfile) != NULL)
_cpp_pop_buffer (pfile);
+ if (pfile->trad_out_base)
+ free (pfile->trad_out_base);
+
if (pfile->macro_buffer)
{
free ((PTR) pfile->macro_buffer);
return result;
}
-
/* This structure defines one built-in identifier. A node will be
- entered in the hash table under the name NAME, with value VALUE (if
- any). If flags has OPERATOR, the node's operator field is used; if
- flags has BUILTIN the node's builtin field is used. Macros that are
- known at build time should not be flagged BUILTIN, as then they do
- not appear in macro dumps with e.g. -dM or -dD.
-
- Also, macros with CPLUS set in the flags field are entered only for C++. */
+ 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
+ cppmacro.c. 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 "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
{
const uchar *name;
- const char *value;
- unsigned char builtin;
- unsigned char operator;
- unsigned short flags;
unsigned short len;
+ unsigned short value;
};
-#define CPLUS 0x04
-#define BUILTIN 0x08
-#define OPERATOR 0x10
-#define B(n, t) { U n, 0, t, 0, BUILTIN, sizeof n - 1 }
-#define O(n, c, f) { U n, 0, 0, c, OPERATOR | f, sizeof n - 1 }
+#define B(n, t) { DSC(n), t }
static const struct builtin builtin_array[] =
{
B("__TIME__", BT_TIME),
B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL),
B("_Pragma", BT_PRAGMA),
B("__STDC__", BT_STDC),
+};
- /* Named operators known to the preprocessor. These cannot be #defined
- and always have their stated meaning. They are treated like normal
- identifiers except for the type code and the meaning. Most of them
- are only for C++ (but see iso646.h). */
- O("and", CPP_AND_AND, CPLUS),
- O("and_eq", CPP_AND_EQ, CPLUS),
- O("bitand", CPP_AND, CPLUS),
- O("bitor", CPP_OR, CPLUS),
- O("compl", CPP_COMPL, CPLUS),
- O("not", CPP_NOT, CPLUS),
- O("not_eq", CPP_NOT_EQ, CPLUS),
- O("or", CPP_OR_OR, CPLUS),
- O("or_eq", CPP_OR_EQ, CPLUS),
- O("xor", CPP_XOR, CPLUS),
- O("xor_eq", CPP_XOR_EQ, CPLUS)
+static const struct builtin 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)
};
#undef B
-#undef O
-#define builtin_array_end (builtin_array + ARRAY_SIZE (builtin_array))
+
+/* Mark the C++ named operators in the hash table. */
+static void
+mark_named_operators (pfile)
+ cpp_reader *pfile;
+{
+ const struct builtin *b;
+
+ for (b = operator_array;
+ b < (operator_array + ARRAY_SIZE (operator_array));
+ b++)
+ {
+ cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
+ hp->flags |= NODE_OPERATOR;
+ hp->value.operator = b->value;
+ }
+}
/* Subroutine of cpp_read_main_file; reads the builtins table above and
enters them, and language-specific macros, into the hash table. */
{
const struct builtin *b;
- for(b = builtin_array; b < builtin_array_end; b++)
+ for(b = builtin_array;
+ b < (builtin_array + ARRAY_SIZE (builtin_array));
+ b++)
{
- cpp_hashnode *hp;
- if ((b->flags & CPLUS) && ! CPP_OPTION (pfile, cplusplus))
- continue;
-
- if ((b->flags & OPERATOR) && ! CPP_OPTION (pfile, operator_names))
- continue;
-
- hp = cpp_lookup (pfile, b->name, b->len);
- if (b->flags & OPERATOR)
- {
- hp->flags |= NODE_OPERATOR;
- hp->value.operator = b->operator;
- }
- else
- {
- hp->type = NT_MACRO;
- hp->flags |= NODE_BUILTIN | NODE_WARN;
- hp->value.builtin = b->builtin;
- }
+ cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
+ hp->type = NT_MACRO;
+ hp->flags |= NODE_BUILTIN | NODE_WARN;
+ hp->value.builtin = b->value;
}
if (CPP_OPTION (pfile, cplusplus))
_cpp_define_builtin (pfile, "__cplusplus 1");
-
- if (CPP_OPTION (pfile, objc))
+ else if (CPP_OPTION (pfile, objc))
_cpp_define_builtin (pfile, "__OBJC__ 1");
+ else if (CPP_OPTION (pfile, lang) == CLK_ASM)
+ _cpp_define_builtin (pfile, "__ASSEMBLER__ 1");
if (CPP_OPTION (pfile, lang) == CLK_STDC94)
_cpp_define_builtin (pfile, "__STDC_VERSION__ 199409L");
else if (CPP_OPTION (pfile, c99))
_cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L");
- if (CPP_OPTION (pfile, unsigned_char))
- _cpp_define_builtin (pfile, "__CHAR_UNSIGNED__ 1");
-
- if (CPP_OPTION (pfile, lang) == CLK_STDC89
- || CPP_OPTION (pfile, lang) == CLK_STDC94
- || CPP_OPTION (pfile, lang) == CLK_STDC99)
- _cpp_define_builtin (pfile, "__STRICT_ANSI__ 1");
- else if (CPP_OPTION (pfile, lang) == CLK_ASM)
- _cpp_define_builtin (pfile, "__ASSEMBLER__ 1");
-
if (pfile->cb.register_builtins)
(*pfile->cb.register_builtins) (pfile);
}
-#undef BUILTIN
-#undef OPERATOR
-#undef VERS
-#undef ULP
-#undef CPLUS
-#undef builtin_array_end
/* And another subroutine. This one sets up the standard include path. */
static void
cpp_reader *pfile;
{
cppchar_t test = 0;
+ size_t max_precision = 2 * CHAR_BIT * sizeof (cpp_num_part);
/* Sanity checks for assumptions about CPP arithmetic and target
type precisions made by cpplib. */
test--;
if (test < 1)
- cpp_error (pfile, DL_FATAL, "cppchar_t must be an unsigned type");
+ cpp_error (pfile, DL_ICE, "cppchar_t must be an unsigned type");
- if (CPP_OPTION (pfile, precision) > BITS_PER_HOST_WIDEST_INT)
- cpp_error (pfile, DL_FATAL,
- "preprocessor arithmetic has maximum precision of %u bits; target requires %u bits",
- BITS_PER_HOST_WIDEST_INT, CPP_OPTION (pfile, precision));
+ if (CPP_OPTION (pfile, precision) > max_precision)
+ cpp_error (pfile, DL_ICE,
+ "preprocessor arithmetic has maximum precision of %lu bits; target requires %lu bits",
+ (unsigned long) max_precision,
+ (unsigned long) CPP_OPTION (pfile, precision));
if (CPP_OPTION (pfile, precision) < CPP_OPTION (pfile, int_precision))
- cpp_error (pfile, DL_FATAL,
+ cpp_error (pfile, DL_ICE,
"CPP arithmetic must be at least as precise as a target int");
if (CPP_OPTION (pfile, char_precision) < 8)
- cpp_error (pfile, DL_FATAL, "target char is less than 8 bits wide");
+ cpp_error (pfile, DL_ICE, "target char is less than 8 bits wide");
if (CPP_OPTION (pfile, wchar_precision) < CPP_OPTION (pfile, char_precision))
- cpp_error (pfile, DL_FATAL,
+ cpp_error (pfile, DL_ICE,
"target wchar_t is narrower than target char");
if (CPP_OPTION (pfile, int_precision) < CPP_OPTION (pfile, char_precision))
- cpp_error (pfile, DL_FATAL,
+ cpp_error (pfile, DL_ICE,
"target int is narrower than target char");
+ /* This is assumed in eval_token() and could be fixed if necessary. */
+ if (sizeof (cppchar_t) > sizeof (cpp_num_part))
+ cpp_error (pfile, DL_ICE, "CPP half-integer narrower than CPP character");
+
if (CPP_OPTION (pfile, wchar_precision) > BITS_PER_CPPCHAR_T)
- cpp_error (pfile, DL_FATAL,
- "CPP on this host cannot handle wide character constants over %u bits, but the target requires %u bits",
- BITS_PER_CPPCHAR_T, CPP_OPTION (pfile, wchar_precision));
+ cpp_error (pfile, DL_ICE,
+ "CPP on this host cannot handle wide character constants over %lu bits, but the target requires %lu bits",
+ (unsigned long) BITS_PER_CPPCHAR_T,
+ (unsigned long) CPP_OPTION (pfile, wchar_precision));
}
#else
# define sanity_checks(PFILE)
of the front ends. */
if (CPP_OPTION (pfile, preprocessed))
read_original_filename (pfile);
+ /* Overlay an empty buffer to seed traditional preprocessing. */
+ else if (CPP_OPTION (pfile, traditional))
+ _cpp_overlay_buffer (pfile, U"", 0);
return pfile->map->to_file;
}
cpp_finish_options (pfile)
cpp_reader *pfile;
{
+ /* Mark named operators before handling command line macros. */
+ if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
+ mark_named_operators (pfile);
+
/* Install builtins and process command line macros etc. in the order
they appeared, but only if not already preprocessed. */
if (! CPP_OPTION (pfile, preprocessed))
struct pending_option *p;
_cpp_do_file_change (pfile, LC_RENAME, _("<built-in>"), 1, 0);
- init_builtins (pfile);
+ if (!CPP_OPTION (pfile, traditional) /* REMOVEME */)
+ init_builtins (pfile);
_cpp_do_file_change (pfile, LC_RENAME, _("<command line>"), 1, 0);
- for (p = CPP_OPTION (pfile, pending)->directive_head; p; p = p->next)
- (*p->handler) (pfile, p->arg);
+ if (!CPP_OPTION (pfile, traditional) /* REMOVEME */)
+ for (p = CPP_OPTION (pfile, pending)->directive_head; p; p = p->next)
+ (*p->handler) (pfile, p->arg);
/* Scan -imacros files after -D, -U, but before -include.
pfile->next_include_file is NULL, so _cpp_pop_buffer does not
if (pfile->next_include_file)
{
struct pending_option *head = *pfile->next_include_file;
-
+
while (head && !push_include (pfile, head))
head = head->next;
if (deps_stream != stdout)
{
if (ferror (deps_stream) || fclose (deps_stream) != 0)
- cpp_error (pfile, DL_FATAL, "I/O error on output");
+ cpp_error (pfile, DL_ERROR, "I/O error on output");
}
}
"-" removed. It must be sorted in ASCII collating order. */
#define COMMAND_LINE_OPTIONS \
DEF_OPT("$", 0, OPT_dollar) \
- DEF_OPT("+", 0, OPT_plus) \
DEF_OPT("-help", 0, OPT__help) \
DEF_OPT("-target-help", 0, OPT_target__help) \
DEF_OPT("-version", 0, OPT__version) \
DEF_OPT("fno-show-column", 0, OPT_fno_show_column) \
DEF_OPT("fpreprocessed", 0, OPT_fpreprocessed) \
DEF_OPT("fshow-column", 0, OPT_fshow_column) \
- DEF_OPT("fsigned-char", 0, OPT_fsigned_char) \
DEF_OPT("ftabstop=", no_num, OPT_ftabstop) \
- DEF_OPT("funsigned-char", 0, OPT_funsigned_char) \
DEF_OPT("h", 0, OPT_h) \
DEF_OPT("idirafter", no_dir, OPT_idirafter) \
DEF_OPT("imacros", no_fil, OPT_imacros) \
DEF_OPT("lang-c++", 0, OPT_lang_cplusplus) \
DEF_OPT("lang-c89", 0, OPT_lang_c89) \
DEF_OPT("lang-objc", 0, OPT_lang_objc) \
- DEF_OPT("lang-objc++", 0, OPT_lang_objcplusplus) \
DEF_OPT("nostdinc", 0, OPT_nostdinc) \
DEF_OPT("nostdinc++", 0, OPT_nostdincplusplus) \
DEF_OPT("o", no_fil, OPT_o) \
DEF_OPT("std=iso9899:199409", 0, OPT_std_iso9899_199409) \
DEF_OPT("std=iso9899:1999", 0, OPT_std_iso9899_1999) \
DEF_OPT("std=iso9899:199x", 0, OPT_std_iso9899_199x) \
+ DEF_OPT("traditional-cpp", 0, OPT_traditional_cpp) \
DEF_OPT("trigraphs", 0, OPT_trigraphs) \
DEF_OPT("v", 0, OPT_v) \
DEF_OPT("version", 0, OPT_version) \
else if (CPP_OPTION (pfile, out_fname) == NULL)
CPP_OPTION (pfile, out_fname) = argv[i];
else
- cpp_error (pfile, DL_FATAL,
+ cpp_error (pfile, DL_ERROR,
"too many filenames. Type %s --help for usage info",
progname);
}
arg = argv[++i];
if (!arg)
{
- cpp_error (pfile, DL_FATAL,
+ cpp_error (pfile, DL_ERROR,
cl_options[opt_index].msg, argv[i - 1]);
return argc;
}
case OPT_fno_show_column:
CPP_OPTION (pfile, show_column) = 0;
break;
- case OPT_fsigned_char:
- CPP_OPTION (pfile, unsigned_char) = 0;
- break;
- case OPT_funsigned_char:
- CPP_OPTION (pfile, unsigned_char) = 1;
- break;
case OPT_ftabstop:
/* Silently ignore empty string, non-longs and silly values. */
if (arg[0] != '\0')
CPP_OPTION (pfile, help_only) = 1;
break;
case OPT_target__help:
- /* Print if any target specific options. cpplib has none, but
+ /* Print if any target specific options. cpplib has none, but
make sure help_only gets set. */
CPP_OPTION (pfile, help_only) = 1;
- break;
+ break;
/* --version inhibits compilation, -version doesn't. -v means
verbose and -version. Historical reasons, don't ask. */
CPP_OPTION (pfile, pedantic_errors) = 1;
/* fall through */
case OPT_pedantic:
- CPP_OPTION (pfile, pedantic) = 1;
+ CPP_OPTION (pfile, pedantic) = 1;
CPP_OPTION (pfile, warn_endif_labels) = 1;
break;
case OPT_trigraphs:
- CPP_OPTION (pfile, trigraphs) = 1;
- break;
- case OPT_plus:
- CPP_OPTION (pfile, cplusplus) = 1;
- CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, trigraphs) = 1;
break;
case OPT_remap:
CPP_OPTION (pfile, remap) = 1;
break;
+ case OPT_traditional_cpp:
+ CPP_OPTION (pfile, traditional) = 1;
+ break;
case OPT_iprefix:
CPP_OPTION (pfile, include_prefix) = arg;
CPP_OPTION (pfile, include_prefix_len) = strlen (arg);
set_lang (pfile, CLK_GNUCXX);
break;
case OPT_lang_objc:
- set_lang (pfile, CLK_OBJC);
- break;
- case OPT_lang_objcplusplus:
- set_lang (pfile, CLK_OBJCXX);
+ CPP_OPTION (pfile, objc) = 1;
break;
case OPT_lang_asm:
set_lang (pfile, CLK_ASM);
CPP_OPTION (pfile, out_fname) = arg;
else
{
- cpp_error (pfile, DL_FATAL, "output filename specified twice");
+ cpp_error (pfile, DL_ERROR, "output filename specified twice");
return argc;
}
break;
/* Args to -d specify what parts of macros to dump.
Silently ignore unrecognised options; they may
be aimed at the compiler proper. */
- {
+ {
char c;
while ((c = *arg++) != '\0')
- switch (c)
- {
- case 'M':
+ switch (c)
+ {
+ case 'M':
CPP_OPTION (pfile, dump_macros) = dump_only;
break;
case 'N':
case OPT_MF:
CPP_OPTION (pfile, deps_file) = arg;
break;
- case OPT_MP:
+ case OPT_MP:
CPP_OPTION (pfile, deps_phony_targets) = 1;
break;
case OPT_MQ:
break;
case OPT_I: /* Add directory to path for includes. */
if (!strcmp (arg, "-"))
- {
+ {
/* -I- means:
Use the preceding -I directories for #include "..."
but not #include <...>.
}
else
{
- cpp_error (pfile, DL_FATAL, "-I- specified twice");
+ cpp_error (pfile, DL_ERROR, "-I- specified twice");
return argc;
}
- }
- else
+ }
+ else
append_include_chain (pfile, xstrdup (arg), BRACKET, 0);
break;
case OPT_isystem:
else if (! ignore)
return i;
break;
- }
+ }
}
return i + 1;
}
if (CPP_OPTION (pfile, cplusplus))
CPP_OPTION (pfile, warn_traditional) = 0;
+ /* The compiler front ends override this, but I think this is the
+ appropriate setting for the library. */
+ CPP_OPTION (pfile, warn_long_long) = (CPP_OPTION (pfile, pedantic)
+ && !CPP_OPTION (pfile, c99));
+
/* Permanently disable macro expansion if we are rescanning
- preprocessed text. */
+ preprocessed text. Read preprocesed source in ISO mode. */
if (CPP_OPTION (pfile, preprocessed))
- pfile->state.prevent_expansion = 1;
+ {
+ pfile->state.prevent_expansion = 1;
+ CPP_OPTION (pfile, traditional) = 0;
+ }
+
+ /* Traditional CPP does not accurately track column information. */
+ if (CPP_OPTION (pfile, traditional))
+ CPP_OPTION (pfile, show_column) = 0;
/* -dM makes no normal output. This is set here so that -dM -dD
works as expected. */
(CPP_OPTION (pfile, print_deps_missing_files)
|| CPP_OPTION (pfile, deps_file)
|| CPP_OPTION (pfile, deps_phony_targets)))
- cpp_error (pfile, DL_FATAL,
+ cpp_error (pfile, DL_ERROR,
"you must additionally specify either -M or -MM");
}
fputs (_("\
-lang-c++ Assume that the input sources are in C++\n\
-lang-objc Assume that the input sources are in ObjectiveC\n\
- -lang-objc++ Assume that the input sources are in ObjectiveC++\n\
-lang-asm Assume that the input sources are in assembler\n\
"), stdout);
fputs (_("\
-std=<std name> Specify the conformance standard; one of:\n\
gnu89, gnu99, c89, c99, iso9899:1990,\n\
iso9899:199409, iso9899:1999\n\
- -+ Allow parsing of C++ style features\n\
-w Inhibit warning messages\n\
-Wtrigraphs Warn if trigraphs are encountered\n\
-Wno-trigraphs Do not warn about trigraphs\n\