/* CPP Library.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 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
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
#include "cpplib.h"
#include "internal.h"
#include "mkdeps.h"
+#include "localedir.h"
static void init_library (void);
static void mark_named_operators (cpp_reader *);
char c99;
char cplusplus;
char extended_numbers;
+ char extended_identifiers;
char std;
char cplusplus_comments;
char digraphs;
+ char uliterals;
};
static const struct lang_flags lang_defaults[] =
-{ /* c99 c++ xnum std // digr */
- /* GNUC89 */ { 0, 0, 1, 0, 1, 1 },
- /* GNUC99 */ { 1, 0, 1, 0, 1, 1 },
- /* STDC89 */ { 0, 0, 0, 1, 0, 0 },
- /* STDC94 */ { 0, 0, 0, 1, 0, 1 },
- /* STDC99 */ { 1, 0, 1, 1, 1, 1 },
- /* GNUCXX */ { 0, 1, 1, 0, 1, 1 },
- /* CXX98 */ { 0, 1, 1, 1, 1, 1 },
- /* ASM */ { 0, 0, 1, 0, 1, 0 }
+{ /* c99 c++ xnum xid std // digr ulit */
+ /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1, 0 },
+ /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1, 1 },
+ /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0 },
+ /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1, 0 },
+ /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1, 0 },
+ /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1, 0 },
+ /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1, 0 },
+ /* GNUCXX0X */ { 1, 1, 1, 0, 0, 1, 1, 1 },
+ /* CXX0X */ { 1, 1, 1, 0, 1, 1, 1, 1 },
+ /* ASM */ { 0, 0, 1, 0, 0, 1, 0, 0 }
+ /* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX0X, and
+ CXX0X when no longer experimental (when all uses of identifiers
+ in the compiler have been audited for correct handling of
+ extended identifiers). */
};
/* Sets internal flags correctly for a given language. */
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, std) = l->std;
- CPP_OPTION (pfile, trigraphs) = l->std;
- CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments;
- CPP_OPTION (pfile, digraphs) = l->digraphs;
+ 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, std) = l->std;
+ CPP_OPTION (pfile, trigraphs) = l->std;
+ CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments;
+ CPP_OPTION (pfile, digraphs) = l->digraphs;
+ CPP_OPTION (pfile, uliterals) = l->uliterals;
}
/* Initialize library global state. */
init_trigraph_map ();
#ifdef ENABLE_NLS
- (void) bindtextdomain ("gcc", LOCALEDIR);
+ (void) bindtextdomain (PACKAGE, LOCALEDIR);
#endif
}
}
/* Initialize this instance of the library if it hasn't been already. */
init_library ();
- pfile = xcalloc (1, sizeof (cpp_reader));
+ pfile = XCNEW (cpp_reader);
cpp_set_lang (pfile, lang);
CPP_OPTION (pfile, warn_multichar) = 1;
CPP_OPTION (pfile, dollars_in_ident) = 1;
CPP_OPTION (pfile, warn_dollars) = 1;
CPP_OPTION (pfile, warn_variadic_macros) = 1;
+ CPP_OPTION (pfile, warn_builtin_macro_redefined) = 1;
+ CPP_OPTION (pfile, warn_normalize) = normalized_C;
/* Default CPP arithmetic to something sensible for the host for the
benefit of dumb users like fix-header. */
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. */
+void
+cpp_set_line_map (cpp_reader *pfile, struct 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. */
void
{
cpp_context *context, *contextn;
tokenrun *run, *runn;
+ int i;
free (pfile->op_stack);
free (context);
}
+ if (pfile->comments.entries)
+ {
+ for (i = 0; i < pfile->comments.count; i++)
+ free (pfile->comments.entries[i].comment);
+
+ free (pfile->comments.entries);
+ }
+
free (pfile);
}
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
+ macro.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.
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
+struct builtin_macro
{
- const uchar *name;
- unsigned short len;
- unsigned short value;
+ const uchar *const name;
+ const unsigned short len;
+ const unsigned short value;
+ const bool always_warn_if_redefined;
};
-#define B(n, t) { DSC(n), t }
-static const struct builtin builtin_array[] =
+#define B(n, t, f) { DSC(n), t, f }
+static const struct builtin_macro builtin_array[] =
{
- B("__TIME__", BT_TIME),
- B("__DATE__", BT_DATE),
- B("__FILE__", BT_FILE),
- B("__BASE_FILE__", BT_BASE_FILE),
- B("__LINE__", BT_SPECLINE),
- B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL),
+ B("__TIMESTAMP__", BT_TIMESTAMP, false),
+ B("__TIME__", BT_TIME, false),
+ B("__DATE__", BT_DATE, false),
+ B("__FILE__", BT_FILE, 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),
/* Keep builtins not used for -traditional-cpp at the end, and
update init_builtins() if any more are added. */
- B("_Pragma", BT_PRAGMA),
- B("__STDC__", BT_STDC),
+ 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;
};
-static const struct builtin operator_array[] =
+#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),
static void
mark_named_operators (cpp_reader *pfile)
{
- const struct builtin *b;
+ const struct builtin_operator *b;
for (b = operator_array;
b < (operator_array + ARRAY_SIZE (operator_array));
}
}
-/* Read the builtins table above and enter them, and language-specific
- macros, into the hash table. HOSTED is true if this is a hosted
- environment. */
void
-cpp_init_builtins (cpp_reader *pfile, int hosted)
+cpp_init_special_builtins (cpp_reader *pfile)
{
- const struct builtin *b;
+ const struct builtin_macro *b;
size_t n = ARRAY_SIZE (builtin_array);
if (CPP_OPTION (pfile, traditional))
n -= 2;
+ else if (! CPP_OPTION (pfile, stdc_0_in_system_headers)
+ || CPP_OPTION (pfile, std))
+ n--;
- for(b = builtin_array; b < builtin_array + n; b++)
+ for (b = builtin_array; b < builtin_array + n; b++)
{
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;
+ hp->flags |= NODE_BUILTIN;
+ if (b->always_warn_if_redefined
+ || CPP_OPTION (pfile, warn_builtin_macro_redefined))
+ hp->flags |= NODE_WARN;
+ hp->value.builtin = (enum builtin_type) b->value;
}
+}
+
+/* Read the builtins table above and enter them, and language-specific
+ macros, into the hash table. HOSTED is true if this is a hosted
+ environment. */
+void
+cpp_init_builtins (cpp_reader *pfile, int hosted)
+{
+ cpp_init_special_builtins (pfile);
+
+ if (!CPP_OPTION (pfile, traditional)
+ && (! CPP_OPTION (pfile, stdc_0_in_system_headers)
+ || CPP_OPTION (pfile, std)))
+ _cpp_define_builtin (pfile, "__STDC__ 1");
if (CPP_OPTION (pfile, cplusplus))
_cpp_define_builtin (pfile, "__cplusplus 1");
# define sanity_checks(PFILE)
#endif
-/* Add a dependency target. Can be called any number of times before
- cpp_read_main_file(). If no targets have been added before
- cpp_read_main_file(), then the default target is used. */
-void
-cpp_add_dependency_target (cpp_reader *pfile, const char *target, int quote)
-{
- if (!pfile->deps)
- pfile->deps = deps_init ();
-
- deps_add_target (pfile->deps, target, quote);
-}
-
/* This is called after options have been parsed, and partially
processed. */
void
}
pfile->main_file
- = _cpp_find_file (pfile, fname, &pfile->no_search_path, false);
+ = _cpp_find_file (pfile, fname, &pfile->no_search_path, false, 0);
if (_cpp_find_failed (pfile->main_file))
return NULL;
token = _cpp_lex_direct (pfile);
if (token->type == CPP_HASH)
{
+ pfile->state.in_directive = 1;
token1 = _cpp_lex_direct (pfile);
_cpp_backup_tokens (pfile, 1);
+ pfile->state.in_directive = 0;
/* If it's a #line directive, handle it. */
if (token1->type == CPP_NUMBER)
if (pfile->cb.dir_change)
{
- char *debugdir = alloca (token->val.str.len - 3);
+ char *debugdir = (char *) alloca (token->val.str.len - 3);
memcpy (debugdir, (const char *) token->val.str.text + 1,
token->val.str.len - 4);
if (CPP_OPTION (pfile, warn_unused_macros))
cpp_forall_identifiers (pfile, _cpp_warn_if_unused_macro, NULL);
- /* cpplex.c leaves the final buffer on the stack. This it so that
+ /* lex.c leaves the final buffer on the stack. This it so that
it returns an unending stream of CPP_EOFs to the client. If we
popped the buffer, we'd dereference a NULL buffer pointer and
segfault. It's nice to allow the client to do worry-free excess
preprocessed text. Read preprocesed source in ISO mode. */
if (CPP_OPTION (pfile, preprocessed))
{
- pfile->state.prevent_expansion = 1;
+ if (!CPP_OPTION (pfile, directives_only))
+ pfile->state.prevent_expansion = 1;
CPP_OPTION (pfile, traditional) = 0;
}
if (CPP_OPTION (pfile, traditional))
{
+ CPP_OPTION (pfile, cplusplus_comments) = 0;
+
/* Traditional CPP does not accurately track column information. */
CPP_OPTION (pfile, show_column) = 0;
CPP_OPTION (pfile, trigraphs) = 0;