/* Mainly the interface between cpplib and the C front ends.
Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997
- 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
This file is part of GCC.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
#include "config.h"
#include "system.h"
static int header_time, body_time;
static splay_tree file_info_tree;
-#undef WCHAR_TYPE_SIZE
-#define WCHAR_TYPE_SIZE TYPE_PRECISION (wchar_type_node)
-
-/* Number of bytes in a wide character. */
-#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
-
int pending_lang_change; /* If we need to switch languages - C++ only */
int c_header_level; /* depth in C headers - C++ only */
/* Set the debug callbacks if we can use them. */
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& (write_symbols == DWARF2_DEBUG
- || write_symbols == VMS_AND_DWARF2_DEBUG))
+ || write_symbols == VMS_AND_DWARF2_DEBUG))
{
cb->define = cb_define;
cb->undef = cb_undef;
if (!MAIN_FILE_P (new_map))
{
#ifdef USE_MAPPED_LOCATION
- int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
+ int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
input_location = included_at;
push_srcloc (new_map->start_location);
#else
- int included_at = LAST_SOURCE_LINE (new_map - 1);
+ int included_at = LAST_SOURCE_LINE (new_map - 1);
input_line = included_at;
push_srcloc (new_map->to_file, 1);
if (c_header_level && --c_header_level == 0)
{
if (new_map->sysp == 2)
- warning ("badly nested C headers from preprocessor");
+ warning (0, "badly nested C headers from preprocessor");
--pending_lang_change;
}
#endif
name = cpp_token_as_text (pfile, s);
}
- warning ("%Hignoring #pragma %s %s", &fe_loc, space, name);
+ warning (OPT_Wunknown_pragmas, "%Hignoring #pragma %s %s",
+ &fe_loc, space, name);
}
}
static bool no_more_pch;
const cpp_token *tok;
enum cpp_ttype type;
+ unsigned char add_flags = 0;
timevar_push (TV_CPP);
retry:
tok = cpp_get_token (parse_in);
type = tok->type;
-
+
retry_after_at:
#ifdef USE_MAPPED_LOCATION
*loc = tok->src_loc;
{
case CPP_PADDING:
goto retry;
-
+
case CPP_NAME:
*value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
break;
break;
case CPP_N_INTEGER:
+ /* C++ uses '0' to mark virtual functions as pure.
+ Set PURE_ZERO to pass this information to the C++ parser. */
+ if (tok->val.str.len == 1 && *tok->val.str.text == '0')
+ add_flags = PURE_ZERO;
*value = interpret_integer (tok, flags);
break;
if (c_dialect_objc ())
{
location_t atloc = input_location;
-
+
retry_at:
tok = cpp_get_token (parse_in);
type = tok->type;
{
case CPP_PADDING:
goto retry_at;
-
+
case CPP_STRING:
case CPP_WSTRING:
type = lex_string (tok, value, true);
case CPP_PASTE:
{
unsigned char name[4];
-
+
*cpp_spell_token (parse_in, tok, name, true) = 0;
-
+
error ("stray %qs in program", name);
}
-
+
goto retry;
case CPP_OTHER:
type = lex_string (tok, value, false);
break;
}
+ *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
+ break;
- /* FALLTHROUGH */
-
case CPP_PRAGMA:
- *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
+ *value = build_int_cst (NULL, tok->val.pragma);
break;
/* These tokens should not be visible outside cpplib. */
}
if (cpp_flags)
- *cpp_flags = tok->flags;
+ *cpp_flags = tok->flags | add_flags;
if (!no_more_pch)
{
no_more_pch = true;
c_common_no_more_pch ();
}
-
+
timevar_pop (TV_CPP);
-
- return type;
-}
-enum cpp_ttype
-c_lex (tree *value)
-{
- location_t loc;
- return c_lex_with_flags (value, &loc, NULL);
+ return type;
}
/* Returns the narrowest C-visible unsigned type, starting with the
for (; itk < itk_none; itk += 2 /* skip signed types */)
{
tree upper = TYPE_MAX_VALUE (integer_types[itk]);
-
+
if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
|| ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
&& TREE_INT_CST_LOW (upper) >= low))
if (itk_u < itk_unsigned_long)
itk_u = itk_unsigned_long;
itk = itk_u;
- warning ("this decimal constant is unsigned only in ISO C90");
+ warning (0, "this decimal constant is unsigned only in ISO C90");
}
- else if (warn_traditional)
- warning ("this decimal constant would be unsigned in ISO C90");
+ else
+ warning (OPT_Wtraditional,
+ "this decimal constant would be unsigned in ISO C90");
}
}
}
REAL_VALUE_TYPE real;
char *copy;
size_t copylen;
- const char *type_name;
- /* FIXME: make %T work in error/warning, then we don't need type_name. */
- if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
- {
+ /* Decode type based on width and properties. */
+ if (flags & CPP_N_DFLOAT)
+ if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
+ type = dfloat128_type_node;
+ else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
+ type = dfloat32_type_node;
+ else
+ type = dfloat64_type_node;
+ else
+ if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
type = long_double_type_node;
- type_name = "long double";
- }
- else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL
- || flag_single_precision_constant)
- {
+ else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL
+ || flag_single_precision_constant)
type = float_type_node;
- type_name = "float";
- }
- else
- {
+ else
type = double_type_node;
- type_name = "double";
- }
/* Copy the constant to a nul-terminated buffer. If the constant
has any suffixes, cut them off; REAL_VALUE_ATOF/ REAL_VALUE_HTOF
can't handle them. */
copylen = token->val.str.len;
- if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM)
- /* Must be an F or L suffix. */
- copylen--;
- if (flags & CPP_N_IMAGINARY)
- /* I or J suffix. */
- copylen--;
+ if (flags & CPP_N_DFLOAT)
+ copylen -= 2;
+ else
+ {
+ if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM)
+ /* Must be an F or L suffix. */
+ copylen--;
+ if (flags & CPP_N_IMAGINARY)
+ /* I or J suffix. */
+ copylen--;
+ }
copy = (char *) alloca (copylen + 1);
memcpy (copy, token->val.str.text, copylen);
copy[copylen] = '\0';
- real_from_string (&real, copy);
- real_convert (&real, TYPE_MODE (type), &real);
+ real_from_string3 (&real, copy, TYPE_MODE (type));
/* Both C and C++ require a diagnostic for a floating constant
outside the range of representable values of its type. Since we
appropriate for this to be a mandatory pedwarn rather than
conditioned on -pedantic. */
if (REAL_VALUE_ISINF (real) && pedantic)
- pedwarn ("floating constant exceeds range of %<%s%>", type_name);
+ pedwarn ("floating constant exceeds range of %qT", type);
/* Create a node with determined type and value. */
value = build_real (type, real);
goto retry;
}
/* FALLTHROUGH */
-
+
default:
break;
-
+
case CPP_WSTRING:
wide = true;
/* FALLTHROUGH */
-
+
case CPP_STRING:
if (!concats)
{
gcc_obstack_init (&str_ob);
obstack_grow (&str_ob, &str, sizeof (cpp_string));
}
-
+
concats++;
obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
goto retry;
/* We have read one more token than we want. */
_cpp_backup_tokens (parse_in, 1);
if (concats)
- strs = (cpp_string *) obstack_finish (&str_ob);
+ strs = XOBFINISH (&str_ob, cpp_string *);
- if (concats && !objc_string && warn_traditional && !in_system_header)
- warning ("traditional C rejects string constant concatenation");
+ if (concats && !objc_string && !in_system_header)
+ warning (OPT_Wtraditional,
+ "traditional C rejects string constant concatenation");
if ((c_lex_string_translate
? cpp_interpret_string : cpp_interpret_string_notranslate)
/* Assume that, if we managed to translate the string above,
then the untranslated parsing will always succeed. */
gcc_assert (xlated);
-
+
if (TREE_STRING_LENGTH (value) != (int) istr.len
|| 0 != strncmp (TREE_STRING_POINTER (value), (char *) istr.text,
istr.len))