#include "config.h"
#include "system.h"
+#include "real.h"
#include "rtl.h"
#include "tree.h"
#include "expr.h"
#include "input.h"
#include "output.h"
-#include "c-lex.h"
#include "c-tree.h"
#include "c-common.h"
#include "flags.h"
#include "splay-tree.h"
#include "debug.h"
-/* MULTIBYTE_CHARS support only works for native compilers.
- ??? Ideally what we want is to model widechar support after
- the current floating point support. */
-#ifdef CROSS_COMPILE
-#undef MULTIBYTE_CHARS
-#endif
-
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
#include <locale.h>
static int header_time, body_time;
static splay_tree file_info_tree;
-/* Cause the `yydebug' variable to be defined. */
-#define YYDEBUG 1
-
/* File used for outputting assembler code. */
extern FILE *asm_out_file;
/* Number of bytes in a wide character. */
#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
-int indent_level; /* Number of { minus number of }. */
int pending_lang_change; /* If we need to switch languages - C++ only */
int c_header_level; /* depth in C headers - C++ only */
the primary source file. */
void
-c_common_parse_file ()
+c_common_parse_file (set_yydebug)
+ int set_yydebug ATTRIBUTE_UNUSED;
{
+#if YYDEBUG != 0
+ yydebug = set_yydebug;
+#else
+ warning ("YYDEBUG not defined");
+#endif
+
(*debug_hooks->start_source_file) (lineno, input_filename);
cpp_finish_options (parse_in);
yyparse ();
+ free_parser_stacks ();
}
struct c_fileinfo *
splay_tree_foreach (file_info_tree, dump_one_header, 0);
}
-/* Not yet handled: #pragma, #define, #undef.
- No need to deal with linemarkers under normal conditions. */
-
static void
cb_ident (pfile, line, str)
cpp_reader *pfile ATTRIBUTE_UNUSED;
lineno = included_at;
push_srcloc (new_map->to_file, 1);
- input_file_stack->indent_level = indent_level;
(*debug_hooks->start_source_file) (included_at, new_map->to_file);
#ifndef NO_IMPLICIT_EXTERN_C
if (c_header_level)
--pending_lang_change;
}
#endif
-#if 0
- if (indent_level != input_file_stack->indent_level)
- {
- warning_with_file_and_line
- (input_filename, lineno,
- "this file contains more '%c's than '%c's",
- indent_level > input_file_stack->indent_level ? '{' : '}',
- indent_level > input_file_stack->indent_level ? '}' : '{');
- }
-#endif
pop_srcloc ();
(*debug_hooks->end_source_file) (to_line);
*value = NULL_TREE;
switch (tok->type)
{
- case CPP_OPEN_BRACE: indent_level++; break;
- case CPP_CLOSE_BRACE: indent_level--; break;
-
/* Issue this error here, where we can get at tok->val.c. */
case CPP_OTHER:
if (ISGRAPH (tok->val.c))
char *buf = alloca ((len + 1) * (wide ? WCHAR_BYTES : 1));
char *q = buf;
const unsigned char *p = str, *limit = str + len;
- unsigned int c;
- unsigned width = wide ? WCHAR_TYPE_SIZE
- : TYPE_PRECISION (char_type_node);
+ cppchar_t c;
#ifdef MULTIBYTE_CHARS
/* Reset multibyte conversion state. */
#endif
if (c == '\\' && !ignore_escape_flag)
- {
- unsigned int mask;
-
- if (width < HOST_BITS_PER_INT)
- mask = ((unsigned int) 1 << width) - 1;
- else
- mask = ~0;
- c = cpp_parse_escape (parse_in, &p, limit, mask);
- }
+ c = cpp_parse_escape (parse_in, &p, limit, wide);
- /* Add this single character into the buffer either as a wchar_t
- or as a single byte. */
+ /* Add this single character into the buffer either as a wchar_t,
+ a multibyte sequence, or as a single byte. */
if (wide)
{
unsigned charwidth = TYPE_PRECISION (char_type_node);
}
q += WCHAR_BYTES;
}
+#ifdef MULTIBYTE_CHARS
+ else if (char_len > 1)
+ {
+ /* We're dealing with a multibyte character. */
+ for ( ; char_len >0; --char_len)
+ {
+ *q++ = *(p - char_len);
+ }
+ }
+#endif
else
{
*q++ = c;
lex_charconst (token)
const cpp_token *token;
{
- HOST_WIDE_INT result;
+ cppchar_t result;
tree type, value;
unsigned int chars_seen;
+ int unsignedp;
- result = cpp_interpret_charconst (parse_in, token, warn_multichar,
- &chars_seen);
- if (token->type == CPP_WCHAR)
- {
- value = build_int_2 (result, 0);
- type = wchar_type_node;
- }
- else
- {
- if (result < 0)
- value = build_int_2 (result, -1);
- else
- value = build_int_2 (result, 0);
-
- /* In C, a character constant has type 'int'.
- In C++ 'char', but multi-char charconsts have type 'int'. */
- if (c_language == clk_cplusplus && chars_seen <= 1)
- type = char_type_node;
- else
- type = integer_type_node;
- }
+ result = cpp_interpret_charconst (parse_in, token,
+ &chars_seen, &unsignedp);
- /* cpp_interpret_charconst issues a warning if the constant
- overflows, but if the number fits in HOST_WIDE_INT anyway, it
- will return it un-truncated, which may cause problems down the
- line. So set the type to widest_integer_literal_type, call
- convert to truncate it to the proper type, then clear
- TREE_OVERFLOW so we don't get a second warning.
-
- FIXME: cpplib's assessment of overflow may not be accurate on a
- platform where the final type can change at (compiler's) runtime. */
+ /* Cast to cppchar_signed_t to get correct sign-extension of RESULT
+ before possibly widening to HOST_WIDE_INT for build_int_2. */
+ if (unsignedp || (cppchar_signed_t) result >= 0)
+ value = build_int_2 (result, 0);
+ else
+ value = build_int_2 ((cppchar_signed_t) result, -1);
- TREE_TYPE (value) = widest_integer_literal_type_node;
- value = convert (type, value);
- TREE_OVERFLOW (value) = 0;
+ if (token->type == CPP_WCHAR)
+ type = wchar_type_node;
+ /* In C, a character constant has type 'int'.
+ In C++ 'char', but multi-char charconsts have type 'int'. */
+ else if ((c_language == clk_c || c_language == clk_objective_c)
+ || chars_seen > 1)
+ type = integer_type_node;
+ else
+ type = char_type_node;
+ TREE_TYPE (value) = type;
return value;
}