Commit c162c75e by Matt Austern Committed by Zack Weinberg

c-common.c (fix_string_type): Build the unqualified array type unconditionally...

2004-09-20  Matt Austern <austern@apple.com>
	    Zack Weinberg  <zack@codesourcery.com>

	* c-common.c (fix_string_type): Build the unqualified array
	type unconditionally, then use c_build_qualified_type to get
	the proper const-qualified variant, and set its
	TYPE_MAIN_VARIANT to refer to the unqualified type.
	* c-lex.c (c_lex_return_raw_string): New global.
	(c_lex_with_flags): Honor it.
	* c-pragma.h: Declare it.

cp:
	* decl.c (make_rtl_for_nonlocal_decl, start_preparsed_function):
	Apply lbasename to input_filename before passing to get_fileinfo.
	* semantics.c (begin_class_definition): Likewise.
	* lex.c (handle_pragma_interface): Apply get_fileinfo to the
	correct filename.  Rename variables to be less confusing.
	(handle_pragma_implementation): Likewise.  Disable "appears
	after file is included" diagnostic.

	* parser.c (struct cp_token): Add in_system_header fiag.
	(CP_TOKEN_BLOCK_NUM_TOKENS, struct cp_token_block)
	(CP_TOKEN_BUFFER_SIZE, cp_token_cache_push_token)
	(CPP_NONE, cp_lexer_read_token): Delete.
	(struct cp_lexer): Remove first_token, string_tokens,
	main_lexer_p fields.  Clarify comments.
	(struct cp_token_cache): Now just a pair of pointers.
	(CP_LEXER_BUFFER_SIZE): New #define.
	(CPP_PURGED): New fake token type.
	(cp_lexer_new_from_token_array, cp_lexer_destroy)
	(cp_lexer_peek_token_emit_debug_info, cp_lexer_skip_purged_tokens)
	(cp_lexer_handle_pragma, cp_token_cache_new, cp_parser_string_literal):
	New functions.
	(cp_lexer_new_from_tokens): Now a simple wrapper around
	cp_lexer_new_from_token_array.
	(cp_lexer_set_source_position_from_token): Also update
	in_system_header.
	(cp_lexer_next_token, cp_lexer_prev_token, cp_lexer_advance_token):
	Don't wrap round.
	(cp_lexer_token_difference): Dont handle wrapping round.
	(cp_lexer_new_main): Enable pragma deferral and raw strings,
	read the entire translation unit through c_lex_with_flags into
	this lexer's buffer, then turn raw strings back off again.
	(cp_lexer_grow_buffer): Adjust for buffer no longer being circular.
	(cp_lexer_get_preprocessor_token): No need to handle not being
	the main lexer.  Set token->in_system_header too.
	(cp_lexer_peek_token): Skip purged tokens.  Feed pragma tokens
	to cp_lexer_handle_pragma.  No need to call cp_lexer_read_token.
	(cp_lexer_peek_nth_token): Likewise.
	(cp_lexer_purge_token): Mark the token PURGED, don't shift all
	the other tokens down.
	(cp_lexer_purge_tokens_after): Likewise.
	(cp_lexer_save_tokens, cp_lexer_rollback_tokens): Don't worry
	about there being no tokens.
	(cp_lexer_print_token): Revise to give useful information on
	all tokens.
	(struct cp_parser): Add field translate_strings_p.
	(cp_parser_new): Initialize it.
	(cp_parser_translation_unit): Destroy the lexer when done.
	(cp_parser_parameter_declaration): Restructure saving of
	default arguments.
	(cp_parser_save_member_function_body): Likewise.
	(cp_parser_check_for_invalid_template_id)
	(cp_parser_nested_name_specifier_opt, cp_parser_template_id):
	Adjust calls to cp_lexer_advance_token.
	(cp_parser_skip_to_closing_parenthesis, cp_parser_declaration):
	No need to fiddle c_lex_string_translate.
	(cp_parser_primary_expression, cp_parser_linkage_specification)
	(cp_parser_asm_definition, cp_parser_asm_specification_opt)
	(cp_parser_asm_operand_list, cp_parser_asm_clobber_list)
	Use cp_parser_string_literal.
	(cp_parser_attribute_list): Save and restore
	parser->translate_strings_p, not c_lex_string_translate.
	(cp_parser_cache_group): Delete.
	(cp_parser_cache_group_1): Rename cp_parser_cache_group.  Do
	not take a cache argument.

From-SVN: r87786
parent 5cfa8766
2004-09-20 Matt Austern <austern@apple.com>
Zack Weinberg <zack@codesourcery.com>
* c-common.c (fix_string_type): Build the unqualified array
type unconditionally, then use c_build_qualified_type to get
the proper const-qualified variant, and set its
TYPE_MAIN_VARIANT to refer to the unqualified type.
* c-lex.c (c_lex_return_raw_string): New global.
(c_lex_with_flags): Honor it.
* c-pragma.h: Declare it.
2004-09-20 Daniel Berlin <dberlin@dberlin.org> 2004-09-20 Daniel Berlin <dberlin@dberlin.org>
* Makefile.in: Fix flags.h dependencies to be $(FLAGS_H). * Makefile.in: Fix flags.h dependencies to be $(FLAGS_H).
...@@ -79,7 +90,7 @@ ...@@ -79,7 +90,7 @@
2004-09-20 Daniel Berlin <dberlin@dberlin.org> 2004-09-20 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-pre.c (compute_antic_aux): Use malloc'd worklist, to avoid * tree-ssa-pre.c (compute_antic_aux): Use malloc'd worklist, to avoid
generating useless garbage. generating useless garbage.
2004-09-20 Paolo Bonzini <bonzini@gnu.org> 2004-09-20 Paolo Bonzini <bonzini@gnu.org>
......
...@@ -843,8 +843,8 @@ fix_string_type (tree value) ...@@ -843,8 +843,8 @@ fix_string_type (tree value)
const int nchars_max = flag_isoc99 ? 4095 : 509; const int nchars_max = flag_isoc99 ? 4095 : 509;
int length = TREE_STRING_LENGTH (value); int length = TREE_STRING_LENGTH (value);
int nchars; int nchars;
tree e_type, i_type; tree e_type, i_type, a_type;
/* Compute the number of elements, for the array type. */ /* Compute the number of elements, for the array type. */
nchars = wide_flag ? length / wchar_bytes : length; nchars = wide_flag ? length / wchar_bytes : length;
...@@ -853,15 +853,28 @@ fix_string_type (tree value) ...@@ -853,15 +853,28 @@ fix_string_type (tree value)
nchars - 1, nchars_max, flag_isoc99 ? 99 : 89); nchars - 1, nchars_max, flag_isoc99 ? 99 : 89);
e_type = wide_flag ? wchar_type_node : char_type_node; e_type = wide_flag ? wchar_type_node : char_type_node;
/* Create the array type for the string constant. /* Create the array type for the string constant. flag_const_strings
-Wwrite-strings says make the string constant an array of const char says make the string constant an array of const char so that
so that copying it to a non-const pointer will get a warning. copying it to a non-const pointer will get a warning. For C++,
For C++, this is the standard behavior. */ this is the standard behavior.
if (flag_const_strings)
e_type = build_type_variant (e_type, 1, 0); The C++ front end relies on TYPE_MAIN_VARIANT of a cv-qualified
array type being the unqualified version of that type.
Therefore, if we are constructing an array of const char, we must
construct the matching unqualified array type first. The C front
end does not require this, but it does no harm, so we do it
unconditionally. */
i_type = build_index_type (build_int_cst (NULL_TREE, nchars - 1)); i_type = build_index_type (build_int_cst (NULL_TREE, nchars - 1));
TREE_TYPE (value) = build_array_type (e_type, i_type); a_type = build_array_type (e_type, i_type);
if (flag_const_strings)
{
/* bleah, c_build_qualified_type should set TYPE_MAIN_VARIANT. */
tree qa_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST);
TYPE_MAIN_VARIANT (qa_type) = a_type;
a_type = qa_type;
}
TREE_TYPE (value) = a_type;
TREE_CONSTANT (value) = 1; TREE_CONSTANT (value) = 1;
TREE_INVARIANT (value) = 1; TREE_INVARIANT (value) = 1;
TREE_READONLY (value) = 1; TREE_READONLY (value) = 1;
......
...@@ -60,6 +60,10 @@ int c_header_level; /* depth in C headers - C++ only */ ...@@ -60,6 +60,10 @@ int c_header_level; /* depth in C headers - C++ only */
to the untranslated one. */ to the untranslated one. */
int c_lex_string_translate = 1; int c_lex_string_translate = 1;
/* True if strings should be passed to the caller of c_lex completely
unmolested (no concatenation, no translation). */
bool c_lex_return_raw_strings = false;
static tree interpret_integer (const cpp_token *, unsigned int); static tree interpret_integer (const cpp_token *, unsigned int);
static tree interpret_float (const cpp_token *, unsigned int); static tree interpret_float (const cpp_token *, unsigned int);
static enum integer_type_kind narrowest_unsigned_type static enum integer_type_kind narrowest_unsigned_type
...@@ -428,7 +432,12 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags) ...@@ -428,7 +432,12 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
case CPP_STRING: case CPP_STRING:
case CPP_WSTRING: case CPP_WSTRING:
return lex_string (tok, value, false); if (!c_lex_return_raw_strings)
return lex_string (tok, value, false);
/* else fall through */
case CPP_PRAGMA:
*value = build_string (tok->val.str.len, (char *)tok->val.str.text);
break; break;
/* These tokens should not be visible outside cpplib. */ /* These tokens should not be visible outside cpplib. */
......
...@@ -70,4 +70,8 @@ extern enum cpp_ttype c_lex_with_flags (tree *, unsigned char *); ...@@ -70,4 +70,8 @@ extern enum cpp_ttype c_lex_with_flags (tree *, unsigned char *);
is the TREE_CHAIN of the latter. */ is the TREE_CHAIN of the latter. */
extern int c_lex_string_translate; extern int c_lex_string_translate;
/* If true, strings should be passed to the caller of c_lex completely
unmolested (no concatenation, no translation). */
extern bool c_lex_return_raw_strings;
#endif /* GCC_C_PRAGMA_H */ #endif /* GCC_C_PRAGMA_H */
2004-09-20 Matt Austern <austern@apple.com>
Zack Weinberg <zack@codesourcery.com>
* decl.c (make_rtl_for_nonlocal_decl, start_preparsed_function):
Apply lbasename to input_filename before passing to get_fileinfo.
* semantics.c (begin_class_definition): Likewise.
* lex.c (handle_pragma_interface): Apply get_fileinfo to the
correct filename. Rename variables to be less confusing.
(handle_pragma_implementation): Likewise. Disable "appears
after file is included" diagnostic.
* parser.c (struct cp_token): Add in_system_header fiag.
(CP_TOKEN_BLOCK_NUM_TOKENS, struct cp_token_block)
(CP_TOKEN_BUFFER_SIZE, cp_token_cache_push_token)
(CPP_NONE, cp_lexer_read_token): Delete.
(struct cp_lexer): Remove first_token, string_tokens,
main_lexer_p fields. Clarify comments.
(struct cp_token_cache): Now just a pair of pointers.
(CP_LEXER_BUFFER_SIZE): New #define.
(CPP_PURGED): New fake token type.
(cp_lexer_new_from_token_array, cp_lexer_destroy)
(cp_lexer_peek_token_emit_debug_info, cp_lexer_skip_purged_tokens)
(cp_lexer_handle_pragma, cp_token_cache_new, cp_parser_string_literal):
New functions.
(cp_lexer_new_from_tokens): Now a simple wrapper around
cp_lexer_new_from_token_array.
(cp_lexer_set_source_position_from_token): Also update
in_system_header.
(cp_lexer_next_token, cp_lexer_prev_token, cp_lexer_advance_token):
Don't wrap round.
(cp_lexer_token_difference): Dont handle wrapping round.
(cp_lexer_new_main): Enable pragma deferral and raw strings,
read the entire translation unit through c_lex_with_flags into
this lexer's buffer, then turn raw strings back off again.
(cp_lexer_grow_buffer): Adjust for buffer no longer being circular.
(cp_lexer_get_preprocessor_token): No need to handle not being
the main lexer. Set token->in_system_header too.
(cp_lexer_peek_token): Skip purged tokens. Feed pragma tokens
to cp_lexer_handle_pragma. No need to call cp_lexer_read_token.
(cp_lexer_peek_nth_token): Likewise.
(cp_lexer_purge_token): Mark the token PURGED, don't shift all
the other tokens down.
(cp_lexer_purge_tokens_after): Likewise.
(cp_lexer_save_tokens, cp_lexer_rollback_tokens): Don't worry
about there being no tokens.
(cp_lexer_print_token): Revise to give useful information on
all tokens.
(struct cp_parser): Add field translate_strings_p.
(cp_parser_new): Initialize it.
(cp_parser_translation_unit): Destroy the lexer when done.
(cp_parser_parameter_declaration): Restructure saving of
default arguments.
(cp_parser_save_member_function_body): Likewise.
(cp_parser_check_for_invalid_template_id)
(cp_parser_nested_name_specifier_opt, cp_parser_template_id):
Adjust calls to cp_lexer_advance_token.
(cp_parser_skip_to_closing_parenthesis, cp_parser_declaration):
No need to fiddle c_lex_string_translate.
(cp_parser_primary_expression, cp_parser_linkage_specification)
(cp_parser_asm_definition, cp_parser_asm_specification_opt)
(cp_parser_asm_operand_list, cp_parser_asm_clobber_list)
Use cp_parser_string_literal.
(cp_parser_attribute_list): Save and restore
parser->translate_strings_p, not c_lex_string_translate.
(cp_parser_cache_group): Delete.
(cp_parser_cache_group_1): Rename cp_parser_cache_group. Do
not take a cache argument.
2004-09-20 Giovanni Bajo <giovannibajo@gcc.gnu.org> 2004-09-20 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/14179 PR c++/14179
......
...@@ -4637,7 +4637,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) ...@@ -4637,7 +4637,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
{ {
/* Fool with the linkage of static consts according to #pragma /* Fool with the linkage of static consts according to #pragma
interface. */ interface. */
struct c_fileinfo *finfo = get_fileinfo (input_filename); struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
if (!finfo->interface_unknown && !TREE_PUBLIC (decl)) if (!finfo->interface_unknown && !TREE_PUBLIC (decl))
{ {
TREE_PUBLIC (decl) = 1; TREE_PUBLIC (decl) = 1;
...@@ -9729,7 +9729,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) ...@@ -9729,7 +9729,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
int doing_friend = 0; int doing_friend = 0;
struct cp_binding_level *bl; struct cp_binding_level *bl;
tree current_function_parms; tree current_function_parms;
struct c_fileinfo *finfo = get_fileinfo (input_filename); struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
/* Sanity check. */ /* Sanity check. */
gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE); gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE);
......
...@@ -463,16 +463,16 @@ handle_pragma_interface (cpp_reader* dfile ATTRIBUTE_UNUSED ) ...@@ -463,16 +463,16 @@ handle_pragma_interface (cpp_reader* dfile ATTRIBUTE_UNUSED )
{ {
tree fname = parse_strconst_pragma ("interface", 1); tree fname = parse_strconst_pragma ("interface", 1);
struct c_fileinfo *finfo; struct c_fileinfo *finfo;
const char *main_filename; const char *filename;
if (fname == (tree)-1) if (fname == (tree)-1)
return; return;
else if (fname == 0) else if (fname == 0)
main_filename = lbasename (input_filename); filename = lbasename (input_filename);
else else
main_filename = ggc_strdup (TREE_STRING_POINTER (fname)); filename = ggc_strdup (TREE_STRING_POINTER (fname));
finfo = get_fileinfo (input_filename); finfo = get_fileinfo (filename);
if (impl_file_chain == 0) if (impl_file_chain == 0)
{ {
...@@ -482,7 +482,7 @@ handle_pragma_interface (cpp_reader* dfile ATTRIBUTE_UNUSED ) ...@@ -482,7 +482,7 @@ handle_pragma_interface (cpp_reader* dfile ATTRIBUTE_UNUSED )
main_input_filename = input_filename; main_input_filename = input_filename;
} }
finfo->interface_only = interface_strcmp (main_filename); finfo->interface_only = interface_strcmp (filename);
/* If MULTIPLE_SYMBOL_SPACES is set, we cannot assume that we can see /* If MULTIPLE_SYMBOL_SPACES is set, we cannot assume that we can see
a definition in another file. */ a definition in another file. */
if (!MULTIPLE_SYMBOL_SPACES || !finfo->interface_only) if (!MULTIPLE_SYMBOL_SPACES || !finfo->interface_only)
...@@ -502,7 +502,7 @@ static void ...@@ -502,7 +502,7 @@ static void
handle_pragma_implementation (cpp_reader* dfile ATTRIBUTE_UNUSED ) handle_pragma_implementation (cpp_reader* dfile ATTRIBUTE_UNUSED )
{ {
tree fname = parse_strconst_pragma ("implementation", 1); tree fname = parse_strconst_pragma ("implementation", 1);
const char *main_filename; const char *filename;
struct impl_files *ifiles = impl_file_chain; struct impl_files *ifiles = impl_file_chain;
if (fname == (tree)-1) if (fname == (tree)-1)
...@@ -511,28 +511,36 @@ handle_pragma_implementation (cpp_reader* dfile ATTRIBUTE_UNUSED ) ...@@ -511,28 +511,36 @@ handle_pragma_implementation (cpp_reader* dfile ATTRIBUTE_UNUSED )
if (fname == 0) if (fname == 0)
{ {
if (main_input_filename) if (main_input_filename)
main_filename = main_input_filename; filename = main_input_filename;
else else
main_filename = input_filename; filename = input_filename;
main_filename = lbasename (main_filename); filename = lbasename (filename);
} }
else else
{ {
main_filename = ggc_strdup (TREE_STRING_POINTER (fname)); filename = ggc_strdup (TREE_STRING_POINTER (fname));
if (cpp_included (parse_in, main_filename)) #if 0
warning ("#pragma implementation for %s appears after file is included", /* We currently cannot give this diagnostic, as we reach this point
main_filename); only after cpplib has scanned the entire translation unit, so
cpp_included always returns true. A plausible fix is to compare
the current source-location cookie with the first source-location
cookie (if any) of the filename, but this requires completing the
--enable-mapped-location project first. See PR 17577. */
if (cpp_included (parse_in, filename))
warning ("#pragma implementation for %qs appears after "
"file is included", filename);
#endif
} }
for (; ifiles; ifiles = ifiles->next) for (; ifiles; ifiles = ifiles->next)
{ {
if (! strcmp (ifiles->filename, main_filename)) if (! strcmp (ifiles->filename, filename))
break; break;
} }
if (ifiles == 0) if (ifiles == 0)
{ {
ifiles = xmalloc (sizeof (struct impl_files)); ifiles = xmalloc (sizeof (struct impl_files));
ifiles->filename = main_filename; ifiles->filename = filename;
ifiles->next = impl_file_chain; ifiles->next = impl_file_chain;
impl_file_chain = ifiles; impl_file_chain = ifiles;
} }
...@@ -770,7 +778,7 @@ cxx_make_type (enum tree_code code) ...@@ -770,7 +778,7 @@ cxx_make_type (enum tree_code code)
/* Set up some flags that give proper default behavior. */ /* Set up some flags that give proper default behavior. */
if (IS_AGGR_TYPE_CODE (code)) if (IS_AGGR_TYPE_CODE (code))
{ {
struct c_fileinfo *finfo = get_fileinfo (input_filename); struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown); SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only; CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
} }
......
...@@ -2106,7 +2106,7 @@ begin_class_definition (tree t) ...@@ -2106,7 +2106,7 @@ begin_class_definition (tree t)
before. */ before. */
if (! TYPE_ANONYMOUS_P (t)) if (! TYPE_ANONYMOUS_P (t))
{ {
struct c_fileinfo *finfo = get_fileinfo (input_filename); struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only; CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X SET_CLASSTYPE_INTERFACE_UNKNOWN_X
(t, finfo->interface_unknown); (t, finfo->interface_unknown);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment