static void initialize_dependency_output PARAMS ((cpp_reader *));
static void initialize_standard_includes PARAMS ((cpp_reader *));
-static void new_pending_directive PARAMS ((struct cpp_pending *,
+static void new_pending_directive PARAMS ((struct cpp_pending *,
const char *,
cl_directive_handler));
#ifdef HOST_EBCDIC
static int opt_comp PARAMS ((const void *, const void *));
+static void sort_options PARAMS ((void));
#endif
static int parse_option PARAMS ((const char *));
-static int handle_option PARAMS ((cpp_reader *, int, char **));
+static int dump_macros_helper PARAMS ((cpp_reader *, cpp_hashnode *));
/* Fourth argument to append_include_chain: chain to use */
enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
#define A(x) s(x, ISidnum|ISidstart)
#define N(x) s(x, ISidnum|ISnumstart)
#define H(x) s(x, IShspace|ISspace)
+#define V(x) s(x, ISvspace|ISspace)
#define S(x) s(x, ISspace)
ISTABLE
N('1') N('2') N('3') N('4') N('5') N('6') N('7') N('8') N('9') N('0')
- H('\0') H(' ') H('\t') H('\v') H('\f')
+ H(' ') H('\t')
- S('\n')
+ V('\n') V('\r')
+
+ S('\0') S('\v') S('\f')
END
#undef A
#undef N
#undef H
+#undef V
#undef S
#undef s
#undef ISTABLE
cpp_reader_init (pfile)
cpp_reader *pfile;
{
+#ifdef HOST_EBCDIC
+ sort_options ();
+#endif
+
memset ((char *) pfile, 0, sizeof (cpp_reader));
pfile->token_buffer_size = 200;
CPP_OPTION (pfile, cplusplus_comments) = 1;
CPP_OPTION (pfile, warn_import) = 1;
CPP_OPTION (pfile, warn_paste) = 1;
+ CPP_OPTION (pfile, digraphs) = 1;
CPP_OPTION (pfile, discard_comments) = 1;
CPP_OPTION (pfile, show_column) = 1;
CPP_OPTION (pfile, tabstop) = 8;
CPP_OPTION (pfile, pending) =
(struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
- _cpp_init_stacks (pfile);
_cpp_init_macros (pfile);
+ _cpp_init_stacks (pfile);
_cpp_init_includes (pfile);
}
if (pfile->deps)
deps_free (pfile->deps);
+ if (pfile->spec_nodes)
+ free (pfile->spec_nodes);
+
+ _cpp_free_temp_tokens (pfile);
+ _cpp_cleanup_includes (pfile);
_cpp_cleanup_stacks (pfile);
_cpp_cleanup_macros (pfile);
- _cpp_cleanup_includes (pfile);
- _cpp_free_temp_tokens (pfile);
}
/* This structure defines one built-in macro. A node of type TYPE will
be entered in the macro hash table under the name NAME, with value
- VALUE (if any). Two values are not compile time constants, so we tag
+ VALUE (if any). If TYPE is T_OPERATOR, the CODE field is used instead.
+
+ Two values are not compile time constants, so we tag
them in the FLAGS field instead:
VERS value is the global version_string, quoted
ULP value is the global user_label_prefix
+
+ Also, macros with CPLUS set in the flags field are entered only for C++.
*/
struct builtin
{
const U_CHAR *name;
const char *value;
- unsigned short type;
+ unsigned char code;
+ unsigned char type;
unsigned short flags;
unsigned int len;
};
-#define VERS 0x01
-#define ULP 0x02
-
-#define B(n, t) { U n, 0, t, 0, sizeof n - 1 }
-#define C(n, v) { U n, v, T_MACRO, 0, sizeof n - 1 }
-#define X(n, f) { U n, 0, T_MACRO, f, sizeof n - 1 }
+#define VERS 0x01
+#define ULP 0x02
+#define CPLUS 0x04
+
+#define B(n, t) { U n, 0, 0, t, 0, sizeof n - 1 }
+#define C(n, v) { U n, v, 0, T_MACRO, 0, sizeof n - 1 }
+#define X(n, f) { U n, 0, 0, T_MACRO, f, sizeof n - 1 }
+#define O(n, c, f) { U n, 0, c, T_OPERATOR, f, sizeof n - 1 }
static const struct builtin builtin_array[] =
{
B("__TIME__", T_TIME),
#ifndef NO_BUILTIN_WCHAR_TYPE
C("__WCHAR_TYPE__", WCHAR_TYPE),
#endif
+
+ /* Named operators known to the preprocessor. These cannot be #defined
+ and always have their stated meaning. They are treated like normal
+ string tokens except for the type code and the meaning. Most of them
+ are only for C++ (but see iso646.h). */
+ O("defined", CPP_DEFINED, 0),
+ 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),
};
#undef B
#undef C
const struct builtin *b;
for(b = builtin_array; b < builtin_array_end; b++)
{
+ if (b->flags & CPLUS && ! CPP_OPTION (pfile, cplusplus))
+ continue;
+
if (b->type == T_MACRO)
{
const char *val;
}
else
{
- cpp_hashnode *hp;
-
- if (b->type == T_STDC && CPP_TRADITIONAL (pfile))
- continue;
-
- hp = cpp_lookup (pfile, b->name, b->len);
+ cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
hp->type = b->type;
+ if (b->type == T_OPERATOR)
+ hp->value.code = b->code;
}
}
}
return 0;
}
- /* Chill should not be used with -trigraphs. */
- if (CPP_OPTION (pfile, chill) && CPP_OPTION (pfile, trigraphs))
- {
- cpp_warning (pfile, "-lang-chill and -trigraphs are mutually exclusive");
- CPP_OPTION (pfile, trigraphs) = 0;
- }
-
/* -Wtraditional is not useful in C++ mode. */
if (CPP_OPTION (pfile, cplusplus))
CPP_OPTION (pfile, warn_traditional) = 0;
- /* Do not warn about illegal token pasting if -traditional,
- -lang-fortran, or -lang-asm. */
- if (CPP_OPTION (pfile, traditional)
- || CPP_OPTION (pfile, lang_fortran)
- || CPP_OPTION (pfile, lang_asm))
+ /* Do not warn about illegal token pasting if -lang-asm. */
+ if (CPP_OPTION (pfile, lang_asm))
CPP_OPTION (pfile, warn_paste) = 0;
/* Set this if it hasn't been set already. */
return 1;
}
+
+/* Dump out the hash table. */
+static int
+dump_macros_helper (pfile, hp)
+ cpp_reader *pfile;
+ cpp_hashnode *hp;
+{
+ if (hp->type == T_MACRO)
+ _cpp_dump_definition (pfile, hp);
+ return 1;
+}
+
/* This is called at the end of preprocessing. It pops the
last buffer and writes dependency output. It should also
clear macro definitions, such that you could call cpp_start_read
}
if (CPP_OPTION (pfile, dump_macros) == dump_only)
- _cpp_dump_macro_hash (pfile);
+ cpp_forall_identifiers (pfile, dump_macros_helper);
/* Flush any pending output. */
if (print)
DEF_OPT("lang-c", 0, OPT_lang_c) \
DEF_OPT("lang-c++", 0, OPT_lang_cplusplus) \
DEF_OPT("lang-c89", 0, OPT_lang_c89) \
- DEF_OPT("lang-chill", 0, OPT_lang_chill) \
- DEF_OPT("lang-fortran", 0, OPT_lang_fortran) \
DEF_OPT("lang-objc", 0, OPT_lang_objc) \
DEF_OPT("lang-objc++", 0, OPT_lang_objcplusplus) \
DEF_OPT("nostdinc", 0, OPT_nostdinc) \
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", 0, OPT_traditional) \
DEF_OPT("trigraphs", 0, OPT_trigraphs) \
DEF_OPT("v", 0, OPT_v) \
DEF_OPT("w", 0, OPT_w)
#undef DEF_OPT
#undef COMMAND_LINE_OPTIONS
+#ifdef HOST_EBCDIC
+static void
+sort_options (void)
+{
+ static int opts_sorted = 0;
+
+ if (!opts_sorted)
+ {
+ opts_sorted = 1;
+ /* For non-ASCII hosts, the array needs to be sorted at runtime */
+ qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp);
+ }
+}
+#endif
+
+
/* Perform a binary search to find which, if any, option the given
command-line matches. Returns its index in the option array,
negative on failure. Complications arise since some options can be
Can be called multiple times, to handle multiple sets of options.
Returns number of strings consumed. */
-static int
-handle_option (pfile, argc, argv)
+int
+cpp_handle_option (pfile, argc, argv)
cpp_reader *pfile;
int argc;
char **argv;
case OPT_pedantic:
CPP_OPTION (pfile, pedantic) = 1;
break;
- case OPT_traditional:
- CPP_OPTION (pfile, traditional) = 1;
- CPP_OPTION (pfile, cplusplus_comments) = 0;
- CPP_OPTION (pfile, trigraphs) = 0;
- CPP_OPTION (pfile, warn_trigraphs) = 0;
- break;
case OPT_trigraphs:
CPP_OPTION (pfile, trigraphs) = 1;
break;
CPP_OPTION (pfile, cplusplus_comments) = 1;
CPP_OPTION (pfile, c89) = 0;
CPP_OPTION (pfile, c99) = 1;
+ CPP_OPTION (pfile, digraphs) = 1;
CPP_OPTION (pfile, objc) = 0;
break;
- case OPT_lang_c89:
- CPP_OPTION (pfile, cplusplus) = 0;
- CPP_OPTION (pfile, cplusplus_comments) = 0;
- CPP_OPTION (pfile, c89) = 1;
- CPP_OPTION (pfile, c99) = 0;
- CPP_OPTION (pfile, objc) = 0;
- CPP_OPTION (pfile, trigraphs) = 1;
- new_pending_directive (pend, "__STRICT_ANSI__", cpp_define);
- break;
case OPT_lang_cplusplus:
CPP_OPTION (pfile, cplusplus) = 1;
CPP_OPTION (pfile, cplusplus_comments) = 1;
CPP_OPTION (pfile, c89) = 0;
CPP_OPTION (pfile, c99) = 0;
CPP_OPTION (pfile, objc) = 0;
+ CPP_OPTION (pfile, digraphs) = 1;
new_pending_directive (pend, "__cplusplus", cpp_define);
break;
case OPT_lang_objcplusplus:
CPP_OPTION (pfile, dollars_in_ident) = 0;
new_pending_directive (pend, "__ASSEMBLER__", cpp_define);
break;
- case OPT_lang_fortran:
- CPP_OPTION (pfile, lang_fortran) = 1;
- CPP_OPTION (pfile, traditional) = 1;
- CPP_OPTION (pfile, cplusplus_comments) = 0;
- new_pending_directive (pend, "_LANGUAGE_FORTRAN", cpp_define);
- break;
- case OPT_lang_chill:
- CPP_OPTION (pfile, objc) = 0;
- CPP_OPTION (pfile, cplusplus) = 0;
- CPP_OPTION (pfile, chill) = 1;
- CPP_OPTION (pfile, traditional) = 1;
- break;
case OPT_nostdinc:
/* -nostdinc causes no default include directories.
You must specify all include-file directories with -I. */
CPP_OPTION (pfile, c89) = 1;
CPP_OPTION (pfile, c99) = 0;
CPP_OPTION (pfile, objc) = 0;
+ CPP_OPTION (pfile, digraphs) = 1;
break;
case OPT_std_gnu9x:
case OPT_std_gnu99:
CPP_OPTION (pfile, cplusplus_comments) = 1;
CPP_OPTION (pfile, c89) = 0;
CPP_OPTION (pfile, c99) = 1;
+ CPP_OPTION (pfile, digraphs) = 1;
CPP_OPTION (pfile, objc) = 0;
new_pending_directive (CPP_OPTION (pfile, pending),
"__STDC_VERSION__=199901L", cpp_define);
/* Fall through */
case OPT_std_iso9899_1990:
case OPT_std_c89:
+ case OPT_lang_c89:
CPP_OPTION (pfile, cplusplus) = 0;
CPP_OPTION (pfile, cplusplus_comments) = 0;
CPP_OPTION (pfile, c89) = 1;
CPP_OPTION (pfile, c99) = 0;
CPP_OPTION (pfile, objc) = 0;
+ CPP_OPTION (pfile, digraphs) = opt_code == OPT_std_iso9899_199409;
CPP_OPTION (pfile, trigraphs) = 1;
- new_pending_directive (CPP_OPTION (pfile, pending),
- "__STRICT_ANSI__", cpp_define);
+ new_pending_directive (pend, "__STRICT_ANSI__", cpp_define);
break;
case OPT_std_iso9899_199x:
case OPT_std_iso9899_1999:
CPP_OPTION (pfile, c89) = 0;
CPP_OPTION (pfile, c99) = 1;
CPP_OPTION (pfile, objc) = 0;
+ CPP_OPTION (pfile, digraphs) = 1;
CPP_OPTION (pfile, trigraphs) = 1;
new_pending_directive (CPP_OPTION (pfile, pending),
"__STRICT_ANSI__", cpp_define);
int i;
int strings_processed;
-#ifdef HOST_EBCDIC
- static int opts_sorted = 0;
-
- if (!opts_sorted)
- {
- opts_sorted = 1;
- /* For non-ASCII hosts, the array needs to be sorted at runtime */
- qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp);
- }
-#endif
-
for (i = 0; i < argc; i += strings_processed)
{
- strings_processed = handle_option (pfile, argc - i, argv + i);
+ strings_processed = cpp_handle_option (pfile, argc - i, argv + i);
if (strings_processed == 0)
break;
}
fputs (_("\
-pedantic Issue all warnings demanded by strict ISO C\n\
-pedantic-errors Issue -pedantic warnings as errors instead\n\
- -traditional Follow K&R pre-processor behaviour\n\
-trigraphs Support ISO C trigraphs\n\
-lang-c Assume that the input sources are in C\n\
-lang-c89 Assume that the input sources are in C89\n\
- -lang-c++ Assume that the input sources are in C++\n\
"), stdout);
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\
- -lang-fortran Assume that the input sources are in Fortran\n\
- -lang-chill Assume that the input sources are in Chill\n\
"), stdout);
fputs (_("\
-std=<std name> Specify the conformance standard; one of:\n\
"), stdout);
fputs (_("\
-Wno-comment{s} Do not warn about comments\n\
- -Wtraditional Warn if a macro argument is/would be turned into\n\
- a string if -traditional is specified\n\
- -Wno-traditional Do not warn about stringification\n\
+ -Wtraditional Warn about features not present in traditional C\n\
+ -Wno-traditional Do not warn about traditional C\n\
-Wundef Warn if an undefined macro is used by #if\n\
-Wno-undef Do not warn about testing undefined macros\n\
-Wimport Warn about the use of the #import directive\n\