/* 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 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
#include "real.h"
#include "rtl.h"
#include "tree.h"
-#include "expr.h"
#include "input.h"
#include "output.h"
#include "c-tree.h"
#include "splay-tree.h"
#include "debug.h"
-/* The current line map. */
-static const struct line_map *map;
-
-/* The line used to refresh the lineno global variable after each token. */
-static unsigned int src_lineno;
-
/* We may keep statistics about how long which files took to compile. */
static int header_time, body_time;
static splay_tree file_info_tree;
int pending_lang_change; /* If we need to switch languages - C++ only */
int c_header_level; /* depth in C headers - C++ only */
+/* If we need to translate characters received. This is tri-state:
+ 0 means use only the untranslated string; 1 means use only
+ the translated string; -1 means chain the translated string
+ to the untranslated one. */
+int c_lex_string_translate = 1;
+
static tree interpret_integer (const cpp_token *, unsigned int);
static tree interpret_float (const cpp_token *, unsigned int);
static enum integer_type_kind
if (n)
return (struct c_fileinfo *) n->value;
- fi = (struct c_fileinfo *) xmalloc (sizeof (struct c_fileinfo));
+ fi = xmalloc (sizeof (struct c_fileinfo));
fi->time = 0;
fi->interface_only = 0;
fi->interface_unknown = 1;
lexed token on the line. Used for diagnostic line numbers. */
static void
cb_line_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const cpp_token *token,
- int parsing_args ATTRIBUTE_UNUSED)
+ int parsing_args)
{
- src_lineno = SOURCE_LINE (map, token->line);
+ if (token->type != CPP_EOF && !parsing_args)
+#ifdef USE_MAPPED_LOCATION
+ input_location = token->src_loc;
+#else
+ {
+ source_location loc = token->src_loc;
+ const struct line_map *map = linemap_lookup (&line_table, loc);
+ input_line = SOURCE_LINE (map, loc);
+ }
+#endif
}
void
fe_file_change (const struct line_map *new_map)
{
- unsigned int to_line = SOURCE_LINE (new_map, new_map->to_line);
+ if (new_map == NULL)
+ return;
if (new_map->reason == LC_ENTER)
{
/* Don't stack the main buffer on the input stack;
we already did in compile_file. */
- if (map == NULL)
- main_input_filename = new_map->to_file;
- else
+ if (! MAIN_FILE_P (new_map))
{
- int included_at = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
+#ifdef USE_MAPPED_LOCATION
+ 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);
input_line = included_at;
push_srcloc (new_map->to_file, 1);
+#endif
(*debug_hooks->start_source_file) (included_at, new_map->to_file);
#ifndef NO_IMPLICIT_EXTERN_C
if (c_header_level)
#endif
pop_srcloc ();
- (*debug_hooks->end_source_file) (to_line);
+ (*debug_hooks->end_source_file) (new_map->to_line);
}
update_header_times (new_map->to_file);
in_system_header = new_map->sysp != 0;
+#ifdef USE_MAPPED_LOCATION
+ input_location = new_map->start_location;
+#else
input_filename = new_map->to_file;
- input_line = to_line;
- map = new_map;
+ input_line = new_map->to_line;
+#endif
/* Hook for C++. */
extract_interface_info ();
}
static void
-cb_def_pragma (cpp_reader *pfile, unsigned int line)
+cb_def_pragma (cpp_reader *pfile, source_location loc)
{
/* Issue a warning message if we have been asked to do so. Ignore
unknown pragmas in system headers unless an explicit
-Wunknown-pragmas has been given. */
if (warn_unknown_pragmas > in_system_header)
{
+#ifndef USE_MAPPED_LOCATION
+ const struct line_map *map = linemap_lookup (&line_table, loc);
+#endif
const unsigned char *space, *name;
const cpp_token *s;
name = cpp_token_as_text (pfile, s);
}
- input_line = SOURCE_LINE (map, line);
+#ifdef USE_MAPPED_LOCATION
+ input_location = loc;
+#else
+ input_line = SOURCE_LINE (map, loc);
+#endif
warning ("ignoring #pragma %s %s", space, name);
}
}
/* #define callback for DWARF and DWARF2 debug info. */
static void
-cb_define (cpp_reader *pfile, unsigned int line, cpp_hashnode *node)
+cb_define (cpp_reader *pfile, source_location loc, cpp_hashnode *node)
{
- (*debug_hooks->define) (SOURCE_LINE (map, line),
+ const struct line_map *map = linemap_lookup (&line_table, loc);
+ (*debug_hooks->define) (SOURCE_LINE (map, loc),
(const char *) cpp_macro_definition (pfile, node));
}
/* #undef callback for DWARF and DWARF2 debug info. */
static void
-cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, unsigned int line,
+cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location loc,
cpp_hashnode *node)
{
- (*debug_hooks->undef) (SOURCE_LINE (map, line),
+ const struct line_map *map = linemap_lookup (&line_table, loc);
+ (*debug_hooks->undef) (SOURCE_LINE (map, loc),
(const char *) NODE_NAME (node));
}
\f
while (tok->type == CPP_PADDING);
timevar_pop (TV_CPP);
- /* The C++ front end does horrible things with the current line
- number. To ensure an accurate line number, we must reset it
- every time we advance a token. */
- input_line = src_lineno;
-
return tok;
-}
+}
int
-c_lex (tree *value)
+c_lex_with_flags (tree *value, unsigned char *cpp_flags)
{
const cpp_token *tok;
location_t atloc;
+ static bool no_more_pch;
retry:
tok = get_nonpadding_token ();
break;
}
+ if (! no_more_pch)
+ {
+ no_more_pch = true;
+ c_common_no_more_pch ();
+ }
+
+ if (cpp_flags)
+ *cpp_flags = tok->flags;
return tok->type;
}
+int
+c_lex (tree *value)
+{
+ return c_lex_with_flags (value, NULL);
+}
+
/* Returns the narrowest C-visible unsigned type, starting with the
minimum specified by FLAGS, that can fit VALUE, or itk_none if
there isn't one. */
if (tok->type == CPP_WSTRING)
wide = true;
obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
-
+
tok = get_nonpadding_token ();
if (c_dialect_objc () && tok->type == CPP_ATSIGN)
{
if (count > 1 && !objc_string && warn_traditional && !in_system_header)
warning ("traditional C rejects string constant concatenation");
- if (cpp_interpret_string (parse_in, strs, count, &istr, wide))
+ if ((c_lex_string_translate
+ ? cpp_interpret_string : cpp_interpret_string_notranslate)
+ (parse_in, strs, count, &istr, wide))
{
value = build_string (istr.len, (char *)istr.text);
free ((void *)istr.text);
+
+ if (c_lex_string_translate == -1)
+ {
+ if (!cpp_interpret_string_notranslate (parse_in, strs, count,
+ &istr, wide))
+ /* Assume that, if we managed to translate the string
+ above, then the untranslated parsing will always
+ succeed. */
+ abort ();
+
+ if (TREE_STRING_LENGTH (value) != (int)istr.len
+ || 0 != strncmp (TREE_STRING_POINTER (value), (char *)istr.text,
+ istr.len))
+ {
+ /* Arrange for us to return the untranslated string in
+ *valp, but to set up the C type of the translated
+ one. */
+ *valp = build_string (istr.len, (char *)istr.text);
+ valp = &TREE_CHAIN (*valp);
+ }
+ free ((void *)istr.text);
+ }
}
else
{