/* CPP Library.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
+ 2009 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 it
under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+along with this program; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "localedir.h"
static void init_library (void);
-static void mark_named_operators (cpp_reader *);
+static void mark_named_operators (cpp_reader *, int);
static void read_original_filename (cpp_reader *);
static void read_original_directory (cpp_reader *);
static void post_options (cpp_reader *);
char std;
char cplusplus_comments;
char digraphs;
+ char uliterals;
};
static const struct lang_flags lang_defaults[] =
-{ /* c99 c++ xnum xid std // digr */
- /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1 },
- /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1 },
- /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0 },
- /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1 },
- /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1 },
- /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1 },
- /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1 },
- /* GNUCXX0X */ { 1, 1, 1, 0, 0, 1, 1 },
- /* CXX0X */ { 1, 1, 1, 0, 1, 1, 1 },
- /* ASM */ { 0, 0, 1, 0, 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
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. */
CPP_OPTION (pfile, warn_trigraphs) = 2;
CPP_OPTION (pfile, warn_endif_labels) = 1;
CPP_OPTION (pfile, warn_deprecated) = 1;
- CPP_OPTION (pfile, warn_long_long) = !CPP_OPTION (pfile, c99);
+ CPP_OPTION (pfile, 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, warn_builtin_macro_redefined) = 1;
CPP_OPTION (pfile, warn_normalize) = normalized_C;
/* Default CPP arithmetic to something sensible for the host for the
{
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);
}
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("__TIMESTAMP__", BT_TIMESTAMP),
- 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("__COUNTER__", BT_COUNTER),
+ 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),
/* Mark the C++ named operators in the hash table. */
static void
-mark_named_operators (cpp_reader *pfile)
+mark_named_operators (cpp_reader *pfile, int flags)
{
- const struct builtin *b;
+ const struct builtin_operator *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->flags |= flags;
hp->is_directive = 0;
hp->directive_index = b->value;
}
}
+/* Helper function of cpp_type2name. Return the string associated with
+ named operator TYPE. */
+const char *
+cpp_named_operator2name (enum cpp_ttype type)
+{
+ const struct builtin_operator *b;
+
+ for (b = operator_array;
+ b < (operator_array + ARRAY_SIZE (operator_array));
+ b++)
+ {
+ if (type == b->value)
+ return (const char *) b->name;
+ }
+
+ return NULL;
+}
+
void
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))
{
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
hp->type = NT_MACRO;
- hp->flags |= NODE_BUILTIN | NODE_WARN;
- hp->value.builtin = (enum builtin_type) 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 cpp_builtin_type) b->value;
}
}
void
cpp_post_options (cpp_reader *pfile)
{
+ int flags;
+
sanity_checks (pfile);
post_options (pfile);
/* Mark named operators before handling command line macros. */
+ flags = 0;
if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
- mark_named_operators (pfile);
+ flags |= NODE_OPERATOR;
+ if (CPP_OPTION (pfile, warn_cxx_operator_names))
+ flags |= NODE_DIAGNOSTIC | NODE_WARN_OPERATOR;
+ if (flags != 0)
+ mark_named_operators (pfile, flags);
}
/* Setup for processing input from the file named FNAME, or stdin if
}
/* This is called at the end of preprocessing. It pops the last
- buffer and writes dependency output, and returns the number of
- errors.
+ buffer and writes dependency output.
Maybe it should also reset state, such that you could call
cpp_start_read with a new filename to restart processing. */
-int
+void
cpp_finish (cpp_reader *pfile, FILE *deps_stream)
{
/* Warn about unused macros before popping the final buffer. */
while (pfile->buffer)
_cpp_pop_buffer (pfile);
- /* Don't write the deps file if there are errors. */
if (CPP_OPTION (pfile, deps.style) != DEPS_NONE
- && deps_stream && pfile->errors == 0)
+ && deps_stream)
{
deps_write (pfile->deps, deps_stream, 72);
/* Report on headers that could use multiple include guards. */
if (CPP_OPTION (pfile, print_include_names))
_cpp_report_missing_guards (pfile);
-
- return pfile->errors;
}
static void