#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"
/* 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 */
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,
a multibyte sequence, or as a single byte. */
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;
- }
-
- /* 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.
+ result = cpp_interpret_charconst (parse_in, token,
+ &chars_seen, &unsignedp);
- 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;
}