Commit 4684cd27 by Mark Mitchell Committed by Mark Mitchell

c-common.h (lang_post_pch_load): New variable.

	* c-common.h (lang_post_pch_load): New variable.
	* c-pch.c (lang_post_pch_load): Define it.
	(c_common_read_pch): Use it.
	* cgraphunit.c (record_call_1): Give the front end a chance to
	record additional needed entities when a variable is marked as
	needed.
	* tlink.c (recompile_files): Robustify.
	(scan_linker_output): If a symbol is assigned to a file,
	but after recompilation is not present there, issue an error
	message.

	* cp-tree.h (IDENTIFIER_REPO_CHOSEN): Define.
	(lang_decl_flags): Narrow the width of "languages".  Add
	repo_available_p.
	(DECL_NEEDED_P): Remove.
	(FOR_EACH_CLONE): New macro.
	(DECL_REPO_AVAILABLE_P): Likewise.
	(DECL_TINFO_P): Likewise.
	(set_linkage_according_to_type): Declare.
	(import_export_vtable): Remove.
	(import_export_tinfo): Likewise.
	(mark_needed): New function.
	(decl_needed_p): Likewise.
	(note_vauge_linkage_fn): Likewise.
	(init_repo): Change prototype.
	(repo_template_used): Remove.
	(repo_template_instantiated): Likewise.
	(repo_emit_p): New function.
	(repo_export_class_p): Likewise.
	(no_linkage_check): Change prototype.
	* class.c (set_linkage_according_to_type): New function.
	(build_vtable): Use it.  Do not call import_export_vtable.  Set
	DECL_IGNORED_P if appropriate.
	* decl.c (duplicate_decls): Preserve DECL_REPO_AVAILABLE_P.
	(make_rtL_for_nonlocal_decls): Check for template instantiations
	explicitly.
	(grokfndecl): Adjust call to no_linkage_check.
	(set_linkage_for_static_data_member): New function.
	(grokvardecl): Use it.  Adjust call to no_linkage_check.
	(grokdeclarator): Use set_linkage_for_static_data_member.
	* decl2.c (note_vague_linkage_fn): New function.
	(note_vague_linkage_var): Likewise.
	(finish_static_data_member_decl): Use it.
	(import_export_vtable): Remove.
	(import_export_class): Use repo_export_class_p.
	(var_finalized_p): Simplify.
	(maybe_emit_vtables): Simplify.
	(mark_needed): New function.
	(decl_needed_p): Likewise.
	(import_export_decl): Add documentation and consistency checks.
	Use repo_emit_p.  Handle virtual tables and RTTI information
	here.
	(import_export_tinfo): Remove.
	(write_out_vars): Call import_export_decl.
	(cxx_callgraph_analyze_expr): Ensure that all vtables are emitted
	whenever one is.
	(finish_file): Use decl_needed_p.  Do not call import_export_decl
	for undefined static data members.  Do not warn about undefined
	inlines when using a repository.
	(mark_used): Use note_vague_linkage_fn.  Always defer template
	instantiations.
	* lex.c (cxx_init): Adjust call to init_repo.  Always set
	flag_unit_at_a-time.
	* method.c (synthesize_method): Remove unncessary
	import_export_decl call.
	(implicitly_declare_fn): Use set_linkage_according_to_type.
	* optimize.c (maybe_clone_body): Use FOR_EACH_CLONE.
	* pt.c (instantiate_class_template): Don't redundantly add classes
	to keyed_classes.  Don't call repo_template_used.
	(tsubst_decl): Set DECL_INTERFACE_KNOWN for instantiations of
	templates with internal linkage.
	(check_instantiated_args): Adjust call to no_linkage_check.
	(instantiate_template): Use FOR_EACH_CLONE.
	(mark_definable): New function.
	(mark_decl_instantiated): Use it.
	(do_decl_instantiation): Adjust tests for explicit instantiation
	after "extern template".
	(instantiate_class_member): Do not use repo_template_instantiated.
	(do_type_instantiation): Simplify.
	(instantiate_decl): Use mark_definable.  Check repo_emit_p.
	Simplify.
	* repo.c (repo_get_id): Remove.
	(original_repo): Remove.
	(IDENTIFIER_REPO_USED): Remove.
	(IDENTIFIER_REPO_CHOSEN): Remove.
	Remove all #if 0'd code.
	(repo_template_used): Remove.
	(repo_template_instantiated): Remove.
	(temporary_obstack_initialized_p): New variable.
	(init_repo): Register with lang_post_pch_load.  Avoid creating
	identifiers unnecessarily.  Don't use original_repo.  Close the
	file here.
	(reopen_repo_file_for_write): Not here.
	(finish_repo): Always write out a new repository file.
	(repo_emit_p): New function.
	(repo_export_class_p): Likewise.
	* rtti.c (get_tinfo_decl): Use set_linkage_according_to_type.
	(involves_incomplete_p): New function.
	(tinfo_base_init): Use it.
	(ptr_initializer): Remove non_public_ptr parameter.
	(ptm_initializer): Likewise.
	(get_pseudo_ti_init): Likewise.
	(unemitted_tinfo_decl_p): Remove.
	(emit_tinfo_decl): Use import_export_decl.
	* semantics.c (expand_body): Move updates of static_ctors and
	static_dtors to ...
	(expand_or_defer_fn): ... here.
	* tree.c (no_linkage_check): Add relaxed_p parameter.

	* g++.dg/abi/inline1.C: New test.
	* g++.dg/abi/local1-a.cc: Likewise.
	* g++.dg/abi/local1.C: Likewise.
	* g++.dg/abi/mangle11.C: Tweak location of warnings.
	* g++.dg/abi/mangle12.C: Likewise.
	* g++.dg/abi/mangle17.C: Likewise.
	* g++.dg/abi/mangle20-2.C: Likewise.
	* g++.dg/opt/interface1.C: Likewise.
	* g++.dg/opt/interface1.h: Likewise.
	* g++.dg/opt/interface1-a.cc: New test.
	* g++.dg/parse/repo1.C: New test.
	* g++.dg/template/repo1.C: Likewise.
	* g++.dg/warn/Winline-1.C: Likewise.
	* lib/gcc-dg.exp (gcc-dg-test-1): Fix -frepo handling.

From-SVN: r85309
parent b4042a03
2004-07-29 Mark Mitchell <mark@codesourcery.com>
* c-common.h (lang_post_pch_load): New variable.
* c-pch.c (lang_post_pch_load): Define it.
(c_common_read_pch): Use it.
* cgraphunit.c (record_call_1): Give the front end a chance to
record additional needed entities when a variable is marked as
needed.
* tlink.c (recompile_files): Robustify.
(scan_linker_output): If a symbol is assigned to a file,
but after recompilation is not present there, issue an error
message.
2004-07-29 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> 2004-07-29 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* tree-ssa-loop-im.c (force_move_till_expr, force_move_till): * tree-ssa-loop-im.c (force_move_till_expr, force_move_till):
......
...@@ -286,6 +286,10 @@ extern void (*lang_expand_function_end) (void); ...@@ -286,6 +286,10 @@ extern void (*lang_expand_function_end) (void);
noreturn attribute. */ noreturn attribute. */
extern int (*lang_missing_noreturn_ok_p) (tree); extern int (*lang_missing_noreturn_ok_p) (tree);
/* If non-NULL, this function is called after a precompile header file
is loaded. */
extern void (*lang_post_pch_load) (void);
extern void push_file_scope (void); extern void push_file_scope (void);
extern void pop_file_scope (void); extern void pop_file_scope (void);
extern int yyparse (void); extern int yyparse (void);
......
...@@ -384,6 +384,10 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd) ...@@ -384,6 +384,10 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
return result == 0; return result == 0;
} }
/* If non-NULL, this function is called after a precompile header file
is loaded. */
void (*lang_post_pch_load) (void);
/* Load in the PCH file NAME, open on FD. It was originally searched for /* Load in the PCH file NAME, open on FD. It was originally searched for
by ORIG_NAME. */ by ORIG_NAME. */
...@@ -443,6 +447,11 @@ c_common_read_pch (cpp_reader *pfile, const char *name, ...@@ -443,6 +447,11 @@ c_common_read_pch (cpp_reader *pfile, const char *name,
return; return;
fclose (f); fclose (f);
/* Give the front end a chance to take action after a PCH file has
been loadeded. */
if (lang_post_pch_load)
(*lang_post_pch_load) ();
} }
/* Indicate that no more PCH files should be read. */ /* Indicate that no more PCH files should be read. */
......
...@@ -400,7 +400,12 @@ record_call_1 (tree *tp, int *walk_subtrees, void *data) ...@@ -400,7 +400,12 @@ record_call_1 (tree *tp, int *walk_subtrees, void *data)
by this function and re-examine whether the decl is actually used by this function and re-examine whether the decl is actually used
after rtl has been generated. */ after rtl has been generated. */
if (TREE_STATIC (t)) if (TREE_STATIC (t))
cgraph_varpool_mark_needed_node (cgraph_varpool_node (t)); {
cgraph_varpool_mark_needed_node (cgraph_varpool_node (t));
if (lang_hooks.callgraph.analyze_expr)
return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees,
data);
}
break; break;
case ADDR_EXPR: case ADDR_EXPR:
......
2004-07-29 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (IDENTIFIER_REPO_CHOSEN): Define.
(lang_decl_flags): Narrow the width of "languages". Add
repo_available_p.
(DECL_NEEDED_P): Remove.
(FOR_EACH_CLONE): New macro.
(DECL_REPO_AVAILABLE_P): Likewise.
(DECL_TINFO_P): Likewise.
(set_linkage_according_to_type): Declare.
(import_export_vtable): Remove.
(import_export_tinfo): Likewise.
(mark_needed): New function.
(decl_needed_p): Likewise.
(note_vauge_linkage_fn): Likewise.
(init_repo): Change prototype.
(repo_template_used): Remove.
(repo_template_instantiated): Likewise.
(repo_emit_p): New function.
(repo_export_class_p): Likewise.
(no_linkage_check): Change prototype.
* class.c (set_linkage_according_to_type): New function.
(build_vtable): Use it. Do not call import_export_vtable. Set
DECL_IGNORED_P if appropriate.
* decl.c (duplicate_decls): Preserve DECL_REPO_AVAILABLE_P.
(make_rtL_for_nonlocal_decls): Check for template instantiations
explicitly.
(grokfndecl): Adjust call to no_linkage_check.
(set_linkage_for_static_data_member): New function.
(grokvardecl): Use it. Adjust call to no_linkage_check.
(grokdeclarator): Use set_linkage_for_static_data_member.
* decl2.c (note_vague_linkage_fn): New function.
(note_vague_linkage_var): Likewise.
(finish_static_data_member_decl): Use it.
(import_export_vtable): Remove.
(import_export_class): Use repo_export_class_p.
(var_finalized_p): Simplify.
(maybe_emit_vtables): Simplify.
(mark_needed): New function.
(decl_needed_p): Likewise.
(import_export_decl): Add documentation and consistency checks.
Use repo_emit_p. Handle virtual tables and RTTI information
here.
(import_export_tinfo): Remove.
(write_out_vars): Call import_export_decl.
(cxx_callgraph_analyze_expr): Ensure that all vtables are emitted
whenever one is.
(finish_file): Use decl_needed_p. Do not call import_export_decl
for undefined static data members. Do not warn about undefined
inlines when using a repository.
(mark_used): Use note_vague_linkage_fn. Always defer template
instantiations.
* lex.c (cxx_init): Adjust call to init_repo. Always set
flag_unit_at_a-time.
* method.c (synthesize_method): Remove unncessary
import_export_decl call.
(implicitly_declare_fn): Use set_linkage_according_to_type.
* optimize.c (maybe_clone_body): Use FOR_EACH_CLONE.
* pt.c (instantiate_class_template): Don't redundantly add classes
to keyed_classes. Don't call repo_template_used.
(tsubst_decl): Set DECL_INTERFACE_KNOWN for instantiations of
templates with internal linkage.
(check_instantiated_args): Adjust call to no_linkage_check.
(instantiate_template): Use FOR_EACH_CLONE.
(mark_definable): New function.
(mark_decl_instantiated): Use it.
(do_decl_instantiation): Adjust tests for explicit instantiation
after "extern template".
(instantiate_class_member): Do not use repo_template_instantiated.
(do_type_instantiation): Simplify.
(instantiate_decl): Use mark_definable. Check repo_emit_p.
Simplify.
* repo.c (repo_get_id): Remove.
(original_repo): Remove.
(IDENTIFIER_REPO_USED): Remove.
(IDENTIFIER_REPO_CHOSEN): Remove.
Remove all #if 0'd code.
(repo_template_used): Remove.
(repo_template_instantiated): Remove.
(temporary_obstack_initialized_p): New variable.
(init_repo): Register with lang_post_pch_load. Avoid creating
identifiers unnecessarily. Don't use original_repo. Close the
file here.
(reopen_repo_file_for_write): Not here.
(finish_repo): Always write out a new repository file.
(repo_emit_p): New function.
(repo_export_class_p): Likewise.
* rtti.c (get_tinfo_decl): Use set_linkage_according_to_type.
(involves_incomplete_p): New function.
(tinfo_base_init): Use it.
(ptr_initializer): Remove non_public_ptr parameter.
(ptm_initializer): Likewise.
(get_pseudo_ti_init): Likewise.
(unemitted_tinfo_decl_p): Remove.
(emit_tinfo_decl): Use import_export_decl.
* semantics.c (expand_body): Move updates of static_ctors and
static_dtors to ...
(expand_or_defer_fn): ... here.
* tree.c (no_linkage_check): Add relaxed_p parameter.
2004-07-28 Eric Christopher <echristo@redhat.com> 2004-07-28 Eric Christopher <echristo@redhat.com>
* cp-lang.c (LANG_HOOKS_UNSAFE_FOR_REEVAL): Delete. * cp-lang.c (LANG_HOOKS_UNSAFE_FOR_REEVAL): Delete.
......
...@@ -581,6 +581,32 @@ get_vtt_name (tree type) ...@@ -581,6 +581,32 @@ get_vtt_name (tree type)
return mangle_vtt_for_type (type); return mangle_vtt_for_type (type);
} }
/* DECL is an entity associated with TYPE, like a virtual table or an
implicitly generated constructor. Determine whether or not DECL
should have external or internal linkage at the object file
level. This routine does not deal with COMDAT linkage and other
similar complexities; it simply sets TREE_PUBLIC if it possible for
entities in other translation units to contain copies of DECL, in
the abstract. */
void
set_linkage_according_to_type (tree type, tree decl)
{
/* If TYPE involves a local class in a function with internal
linkage, then DECL should have internal linkage too. Other local
classes have no linkage -- but if their containing functions
have external linkage, it makes sense for DECL to have external
linkage too. That will allow template definitions to be merged,
for example. */
if (no_linkage_check (type, /*relaxed_p=*/true))
{
TREE_PUBLIC (decl) = 0;
DECL_INTERFACE_KNOWN (decl) = 1;
}
else
TREE_PUBLIC (decl) = 1;
}
/* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE. /* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE.
(For a secondary vtable for B-in-D, CLASS_TYPE should be D, not B.) (For a secondary vtable for B-in-D, CLASS_TYPE should be D, not B.)
Use NAME for the name of the vtable, and VTABLE_TYPE for its type. */ Use NAME for the name of the vtable, and VTABLE_TYPE for its type. */
...@@ -601,17 +627,42 @@ build_vtable (tree class_type, tree name, tree vtable_type) ...@@ -601,17 +627,42 @@ build_vtable (tree class_type, tree name, tree vtable_type)
DECL_VIRTUAL_P (decl) = 1; DECL_VIRTUAL_P (decl) = 1;
DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN; DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
DECL_VTABLE_OR_VTT_P (decl) = 1; DECL_VTABLE_OR_VTT_P (decl) = 1;
/* At one time the vtable info was grabbed 2 words at a time. This /* At one time the vtable info was grabbed 2 words at a time. This
fails on sparc unless you have 8-byte alignment. (tiemann) */ fails on sparc unless you have 8-byte alignment. (tiemann) */
DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
DECL_ALIGN (decl)); DECL_ALIGN (decl));
set_linkage_according_to_type (class_type, decl);
/* The vtable has not been defined -- yet. */
DECL_EXTERNAL (decl) = 1;
DECL_NOT_REALLY_EXTERN (decl) = 1;
if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG)
/* Mark the VAR_DECL node representing the vtable itself as a
"gratuitous" one, thereby forcing dwarfout.c to ignore it. It
is rather important that such things be ignored because any
effort to actually generate DWARF for them will run into
trouble when/if we encounter code like:
#pragma interface
struct S { virtual void member (); };
because the artificial declaration of the vtable itself (as
manufactured by the g++ front end) will say that the vtable is
a static member of `S' but only *after* the debug output for
the definition of `S' has already been output. This causes
grief because the DWARF entry for the definition of the vtable
will try to refer back to an earlier *declaration* of the
vtable as a static member of `S' and there won't be one. We
might be able to arrange to have the "vtable static member"
attached to the member list for `S' before the debug info for
`S' get written (which would solve the problem) but that would
require more intrusive changes to the g++ front end. */
DECL_IGNORED_P (decl) = 1;
/* The vtable's visibility is the class visibility. There is no way /* The vtable's visibility is the class visibility. There is no way
to override the visibility for just the vtable. */ to override the visibility for just the vtable. */
DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type); DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
DECL_VISIBILITY_SPECIFIED (decl) = CLASSTYPE_VISIBILITY_SPECIFIED (class_type); DECL_VISIBILITY_SPECIFIED (decl) = CLASSTYPE_VISIBILITY_SPECIFIED (class_type);
import_export_vtable (decl, class_type, 0);
return decl; return decl;
} }
......
...@@ -48,7 +48,7 @@ struct diagnostic_context; ...@@ -48,7 +48,7 @@ struct diagnostic_context;
STATEMENT_LIST_NO_SCOPE (in STATEMENT_LIST). STATEMENT_LIST_NO_SCOPE (in STATEMENT_LIST).
EXPR_STMT_STMT_EXPR_RESULT (in EXPR_STMT) EXPR_STMT_STMT_EXPR_RESULT (in EXPR_STMT)
BIND_EXPR_TRY_BLOCK (in BIND_EXPR) BIND_EXPR_TRY_BLOCK (in BIND_EXPR)
1: IDENTIFIER_VIRTUAL_P. 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG. TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE. TEMPLATE_PARMS_FOR_INLINE.
DELETE_EXPR_USE_VEC (in DELETE_EXPR). DELETE_EXPR_USE_VEC (in DELETE_EXPR).
...@@ -56,7 +56,7 @@ struct diagnostic_context; ...@@ -56,7 +56,7 @@ struct diagnostic_context;
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (in _TYPE). TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (in _TYPE).
ICS_ELLIPSIS_FLAG (in _CONV) ICS_ELLIPSIS_FLAG (in _CONV)
DECL_INITIALIZED_P (in VAR_DECL) DECL_INITIALIZED_P (in VAR_DECL)
2: IDENTIFIER_OPNAME_P. 2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE)
TYPE_POLYMORPHIC_P (in _TYPE) TYPE_POLYMORPHIC_P (in _TYPE)
ICS_THIS_FLAG (in _CONV) ICS_THIS_FLAG (in _CONV)
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL) DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
...@@ -70,9 +70,10 @@ struct diagnostic_context; ...@@ -70,9 +70,10 @@ struct diagnostic_context;
4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, 4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
or FIELD_DECL). or FIELD_DECL).
IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
DECL_TINFO_P (in VAR_DECL)
5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE) 5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE)
DECL_VTABLE_OR_VTT_P (in VAR_DECL) DECL_VTABLE_OR_VTT_P (in VAR_DECL)
6: For future expansion 6: IDENTIFIER_REPO_CHOSEN (in IDENTIFIER_NODE)
Usage of TYPE_LANG_FLAG_?: Usage of TYPE_LANG_FLAG_?:
0: TYPE_DEPENDENT_P 0: TYPE_DEPENDENT_P
...@@ -375,6 +376,12 @@ typedef enum cp_id_kind ...@@ -375,6 +376,12 @@ typedef enum cp_id_kind
#define IDENTIFIER_CTOR_OR_DTOR_P(NODE) \ #define IDENTIFIER_CTOR_OR_DTOR_P(NODE) \
TREE_LANG_FLAG_3 (NODE) TREE_LANG_FLAG_3 (NODE)
/* True iff NAME is the DECL_ASSEMBLER_NAME for an entity with vague
linkage which the prelinker has assigned to this translation
unit. */
#define IDENTIFIER_REPO_CHOSEN(NAME) \
(TREE_LANG_FLAG_6 (NAME))
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */ /* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
#define C_TYPE_FIELDS_READONLY(TYPE) \ #define C_TYPE_FIELDS_READONLY(TYPE) \
(LANG_TYPE_CLASS_CHECK (TYPE)->fields_readonly) (LANG_TYPE_CLASS_CHECK (TYPE)->fields_readonly)
...@@ -1515,7 +1522,11 @@ struct lang_type GTY(()) ...@@ -1515,7 +1522,11 @@ struct lang_type GTY(())
struct lang_decl_flags GTY(()) struct lang_decl_flags GTY(())
{ {
ENUM_BITFIELD(languages) language : 8; ENUM_BITFIELD(languages) language : 4;
unsigned global_ctor_p : 1;
unsigned global_dtor_p : 1;
unsigned anticipated_p : 1;
unsigned template_conv_p : 1;
unsigned operator_attr : 1; unsigned operator_attr : 1;
unsigned constructor_attr : 1; unsigned constructor_attr : 1;
...@@ -1534,14 +1545,12 @@ struct lang_decl_flags GTY(()) ...@@ -1534,14 +1545,12 @@ struct lang_decl_flags GTY(())
unsigned initialized_in_class : 1; unsigned initialized_in_class : 1;
unsigned assignment_operator_p : 1; unsigned assignment_operator_p : 1;
unsigned global_ctor_p : 1;
unsigned global_dtor_p : 1;
unsigned anticipated_p : 1;
unsigned template_conv_p : 1;
unsigned u1sel : 1; unsigned u1sel : 1;
unsigned u2sel : 1; unsigned u2sel : 1;
unsigned can_be_full : 1; unsigned can_be_full : 1;
unsigned this_thunk_p : 1; unsigned this_thunk_p : 1;
unsigned repo_available_p : 1;
unsigned dummy : 3;
union lang_decl_u { union lang_decl_u {
/* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
...@@ -1631,19 +1640,6 @@ struct lang_decl GTY(()) ...@@ -1631,19 +1640,6 @@ struct lang_decl GTY(())
#endif /* ENABLE_TREE_CHECKING */ #endif /* ENABLE_TREE_CHECKING */
/* DECL_NEEDED_P holds of a declaration when we need to emit its
definition. This is true when the back-end tells us that
the symbol has been referenced in the generated code. If, however,
we are not generating code, then it is also true when a symbol has
just been used somewhere, even if it's not really needed. We need
anything that isn't comdat, but we don't know for sure whether or
not something is comdat until end-of-file. */
#define DECL_NEEDED_P(DECL) \
((at_eof && TREE_PUBLIC (DECL) && !DECL_COMDAT (DECL)) \
|| (DECL_ASSEMBLER_NAME_SET_P (DECL) \
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL))) \
|| (((flag_syntax_only || flag_unit_at_a_time) && TREE_USED (DECL))))
/* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the /* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
declaration. Some entities (like a member function in a local declaration. Some entities (like a member function in a local
class, or a local variable) do not have linkage at all, and this class, or a local variable) do not have linkage at all, and this
...@@ -1730,6 +1726,21 @@ struct lang_decl GTY(()) ...@@ -1730,6 +1726,21 @@ struct lang_decl GTY(())
#define DECL_CLONED_FUNCTION(NODE) \ #define DECL_CLONED_FUNCTION(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u.f.cloned_function) (DECL_LANG_SPECIFIC (NODE)->u.f.cloned_function)
/* Perform an action for each clone of FN, if FN is a function with
clones. This macro should be used like:
FOR_EACH_CLONE (clone, fn)
{ ... }
*/
#define FOR_EACH_CLONE(CLONE, FN) \
if (TREE_CODE (FN) == FUNCTION_DECL \
&& (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (FN) \
|| DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (FN))) \
for (CLONE = TREE_CHAIN (FN); \
CLONE && DECL_CLONED_FUNCTION_P (CLONE); \
CLONE = TREE_CHAIN (CLONE))
/* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS. */ /* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS. */
#define DECL_DISCRIMINATOR_P(NODE) \ #define DECL_DISCRIMINATOR_P(NODE) \
(TREE_CODE (NODE) == VAR_DECL \ (TREE_CODE (NODE) == VAR_DECL \
...@@ -1921,6 +1932,11 @@ struct lang_decl GTY(()) ...@@ -1921,6 +1932,11 @@ struct lang_decl GTY(())
DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1, \ DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1, \
DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p = (THIS_ADJUSTING)) DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p = (THIS_ADJUSTING))
/* True iff DECL is an entity with vague linkage whose definition is
available in this translation unit. */
#define DECL_REPO_AVAILABLE_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.repo_available_p)
/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
template function. */ template function. */
#define DECL_PRETTY_FUNCTION_P(NODE) \ #define DECL_PRETTY_FUNCTION_P(NODE) \
...@@ -1965,6 +1981,10 @@ struct lang_decl GTY(()) ...@@ -1965,6 +1981,10 @@ struct lang_decl GTY(())
(DECL_CONTEXT (NODE) \ (DECL_CONTEXT (NODE) \
&& TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL) && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL)
/* 1 iff VAR_DECL node NODE is a type-info decl. This flag is set for
both the primary typeinfo object and the associated NTBS name. */
#define DECL_TINFO_P(NODE) TREE_LANG_FLAG_4 (VAR_DECL_CHECK (NODE))
/* 1 iff VAR_DECL node NODE is virtual table or VTT. */ /* 1 iff VAR_DECL node NODE is virtual table or VTT. */
#define DECL_VTABLE_OR_VTT_P(NODE) TREE_LANG_FLAG_5 (VAR_DECL_CHECK (NODE)) #define DECL_VTABLE_OR_VTT_P(NODE) TREE_LANG_FLAG_5 (VAR_DECL_CHECK (NODE))
...@@ -3643,6 +3663,7 @@ extern tree get_primary_binfo (tree); ...@@ -3643,6 +3663,7 @@ extern tree get_primary_binfo (tree);
extern void debug_class (tree); extern void debug_class (tree);
extern void debug_thunks (tree); extern void debug_thunks (tree);
extern tree cp_fold_obj_type_ref (tree, tree); extern tree cp_fold_obj_type_ref (tree, tree);
extern void set_linkage_according_to_type (tree, tree);
/* in cvt.c */ /* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree); extern tree convert_to_reference (tree, tree, int, int, tree);
...@@ -3787,9 +3808,7 @@ extern tree finish_table (tree, tree, tree, int); ...@@ -3787,9 +3808,7 @@ extern tree finish_table (tree, tree, tree, int);
extern tree coerce_new_type (tree); extern tree coerce_new_type (tree);
extern tree coerce_delete_type (tree); extern tree coerce_delete_type (tree);
extern void comdat_linkage (tree); extern void comdat_linkage (tree);
extern void import_export_vtable (tree, tree, int);
extern void import_export_decl (tree); extern void import_export_decl (tree);
extern void import_export_tinfo (tree, tree, bool);
extern tree build_cleanup (tree); extern tree build_cleanup (tree);
extern tree build_offset_ref_call_from_tree (tree, tree); extern tree build_offset_ref_call_from_tree (tree, tree);
extern void check_default_args (tree); extern void check_default_args (tree);
...@@ -3801,6 +3820,9 @@ extern tree get_guard (tree); ...@@ -3801,6 +3820,9 @@ extern tree get_guard (tree);
extern tree get_guard_cond (tree); extern tree get_guard_cond (tree);
extern tree set_guard (tree); extern tree set_guard (tree);
extern tree cxx_callgraph_analyze_expr (tree *, int *, tree); extern tree cxx_callgraph_analyze_expr (tree *, int *, tree);
extern void mark_needed (tree);
extern bool decl_needed_p (tree);
extern void note_vague_linkage_fn (tree);
/* XXX Not i18n clean. */ /* XXX Not i18n clean. */
#define cp_deprecated(STR) \ #define cp_deprecated(STR) \
...@@ -3973,9 +3995,9 @@ extern bool reregister_specialization (tree, tree, tree); ...@@ -3973,9 +3995,9 @@ extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree); extern tree fold_non_dependent_expr (tree);
/* in repo.c */ /* in repo.c */
extern void repo_template_used (tree); extern void init_repo (void);
extern void repo_template_instantiated (tree, bool); extern int repo_emit_p (tree);
extern void init_repo (const char *); extern bool repo_export_class_p (tree);
extern void finish_repo (void); extern void finish_repo (void);
/* in rtti.c */ /* in rtti.c */
...@@ -4192,7 +4214,7 @@ extern tree error_type (tree); ...@@ -4192,7 +4214,7 @@ extern tree error_type (tree);
extern int varargs_function_p (tree); extern int varargs_function_p (tree);
extern int really_overloaded_fn (tree); extern int really_overloaded_fn (tree);
extern bool cp_tree_equal (tree, tree); extern bool cp_tree_equal (tree, tree);
extern tree no_linkage_check (tree); extern tree no_linkage_check (tree, bool);
extern void debug_binfo (tree); extern void debug_binfo (tree);
extern tree build_dummy_object (tree); extern tree build_dummy_object (tree);
extern tree maybe_dummy_object (tree, tree *); extern tree maybe_dummy_object (tree, tree *);
......
...@@ -1753,6 +1753,7 @@ duplicate_decls (tree newdecl, tree olddecl) ...@@ -1753,6 +1753,7 @@ duplicate_decls (tree newdecl, tree olddecl)
DECL_LANG_SPECIFIC (newdecl)->decl_flags.u2 = DECL_LANG_SPECIFIC (newdecl)->decl_flags.u2 =
DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2; DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2;
DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl); DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl);
DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
DECL_INITIALIZED_IN_CLASS_P (newdecl) DECL_INITIALIZED_IN_CLASS_P (newdecl)
|= DECL_INITIALIZED_IN_CLASS_P (olddecl); |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
...@@ -4571,7 +4572,8 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) ...@@ -4571,7 +4572,8 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
defer_p = 1; defer_p = 1;
} }
/* Likewise for template instantiations. */ /* Likewise for template instantiations. */
else if (DECL_COMDAT (decl)) else if (DECL_LANG_SPECIFIC (decl)
&& DECL_IMPLICIT_INSTANTIATION (decl))
defer_p = 1; defer_p = 1;
/* If we're deferring the variable, we only need to make RTL if /* If we're deferring the variable, we only need to make RTL if
...@@ -5513,7 +5515,8 @@ grokfndecl (tree ctype, ...@@ -5513,7 +5515,8 @@ grokfndecl (tree ctype,
declare an entity with linkage. declare an entity with linkage.
Only check this for public decls for now. See core 319, 389. */ Only check this for public decls for now. See core 319, 389. */
t = no_linkage_check (TREE_TYPE (decl)); t = no_linkage_check (TREE_TYPE (decl),
/*relaxed_p=*/false);
if (t) if (t)
{ {
if (TYPE_ANONYMOUS_P (t)) if (TYPE_ANONYMOUS_P (t))
...@@ -5723,6 +5726,25 @@ grokfndecl (tree ctype, ...@@ -5723,6 +5726,25 @@ grokfndecl (tree ctype,
return decl; return decl;
} }
/* DECL is a VAR_DECL for a static data member. Set flags to reflect
the linkage that DECL will receive in the object file. */
static void
set_linkage_for_static_data_member (tree decl)
{
/* A static data member always has static storage duration and
external linkage. Note that static data members are forbidden in
local classes -- the only situation in which a class has
non-external linkage. */
TREE_PUBLIC (decl) = 1;
TREE_STATIC (decl) = 1;
/* For non-template classes, static data members are always put
out in exactly those files where they are defined, just as
with ordinarly namespace-scope variables. */
if (!processing_template_decl)
DECL_INTERFACE_KNOWN (decl) = 1;
}
/* Create a VAR_DECL named NAME with the indicated TYPE. /* Create a VAR_DECL named NAME with the indicated TYPE.
If SCOPE is non-NULL, it is the class type or namespace containing If SCOPE is non-NULL, it is the class type or namespace containing
...@@ -5782,12 +5804,10 @@ grokvardecl (tree type, ...@@ -5782,12 +5804,10 @@ grokvardecl (tree type,
DECL_EXTERNAL (decl) = !initialized; DECL_EXTERNAL (decl) = !initialized;
} }
/* In class context, static means one per class,
public access, and static storage. */
if (DECL_CLASS_SCOPE_P (decl)) if (DECL_CLASS_SCOPE_P (decl))
{ {
TREE_PUBLIC (decl) = 1; set_linkage_for_static_data_member (decl);
TREE_STATIC (decl) = 1; /* This function is only called with out-of-class definitions. */
DECL_EXTERNAL (decl) = 0; DECL_EXTERNAL (decl) = 0;
} }
/* At top level, either `static' or no s.c. makes a definition /* At top level, either `static' or no s.c. makes a definition
...@@ -5822,7 +5842,8 @@ grokvardecl (tree type, ...@@ -5822,7 +5842,8 @@ grokvardecl (tree type,
declare an entity with linkage. declare an entity with linkage.
Only check this for public decls for now. */ Only check this for public decls for now. */
tree t = no_linkage_check (TREE_TYPE (decl)); tree t = no_linkage_check (TREE_TYPE (decl),
/*relaxed_p=*/false);
if (t) if (t)
{ {
if (TYPE_ANONYMOUS_P (t)) if (TYPE_ANONYMOUS_P (t))
...@@ -7859,9 +7880,11 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -7859,9 +7880,11 @@ grokdeclarator (const cp_declarator *declarator,
/* C++ allows static class members. All other work /* C++ allows static class members. All other work
for this is done by grokfield. */ for this is done by grokfield. */
decl = build_lang_decl (VAR_DECL, unqualified_id, type); decl = build_lang_decl (VAR_DECL, unqualified_id, type);
TREE_STATIC (decl) = 1; set_linkage_for_static_data_member (decl);
/* In class context, 'static' means public access. */ /* Even if there is an in-class initialization, DECL
TREE_PUBLIC (decl) = DECL_EXTERNAL (decl) = 1; is considered undefined until an out-of-class
definition is provided. */
DECL_EXTERNAL (decl) = 1;
} }
else else
{ {
...@@ -9842,6 +9865,11 @@ start_preparsed_function (tree decl1, tree attrs, int flags) ...@@ -9842,6 +9865,11 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
DECL_EXTERNAL (decl1) = 0; DECL_EXTERNAL (decl1) = 0;
DECL_NOT_REALLY_EXTERN (decl1) = 0; DECL_NOT_REALLY_EXTERN (decl1) = 0;
DECL_INTERFACE_KNOWN (decl1) = 1; DECL_INTERFACE_KNOWN (decl1) = 1;
/* If this function is in an interface implemented in this file,
make sure that the backend knows to emit this function
here. */
if (!DECL_EXTERNAL (decl1))
mark_needed (decl1);
} }
else if (interface_unknown && interface_only else if (interface_unknown && interface_only
&& ! DECL_TEMPLATE_INSTANTIATION (decl1)) && ! DECL_TEMPLATE_INSTANTIATION (decl1))
......
...@@ -361,6 +361,17 @@ cxx_init (void) ...@@ -361,6 +361,17 @@ cxx_init (void)
interface_unknown = 1; interface_unknown = 1;
/* The fact that G++ uses COMDAT for many entities (inline
functions, template instantiations, virtual tables, etc.) mean
that it is fundamentally unreliable to try to make decisions
about whether or not to output a particular entity until the end
of the compilation. However, the inliner requires that functions
be provided to the back end if they are to be inlined.
Therefore, we always use unit-at-a-time mode; in that mode, we
can provide entities to the back end and it will decide what to
emit based on what is actually needed. */
flag_unit_at_a_time = 1;
if (c_common_init () == false) if (c_common_init () == false)
{ {
pop_srcloc(); pop_srcloc();
...@@ -369,7 +380,7 @@ cxx_init (void) ...@@ -369,7 +380,7 @@ cxx_init (void)
init_cp_pragma (); init_cp_pragma ();
init_repo (main_input_filename); init_repo ();
pop_srcloc(); pop_srcloc();
return true; return true;
......
...@@ -700,9 +700,6 @@ synthesize_method (tree fndecl) ...@@ -700,9 +700,6 @@ synthesize_method (tree fndecl)
bool need_body = true; bool need_body = true;
tree stmt; tree stmt;
if (at_eof)
import_export_decl (fndecl);
/* If we've been asked to synthesize a clone, just synthesize the /* If we've been asked to synthesize a clone, just synthesize the
cloned function instead. Doing so will automatically fill in the cloned function instead. Doing so will automatically fill in the
body for the clone. */ body for the clone. */
...@@ -1014,7 +1011,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) ...@@ -1014,7 +1011,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL, grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL,
TYPE_UNQUALIFIED); TYPE_UNQUALIFIED);
grok_special_member_properties (fn); grok_special_member_properties (fn);
TREE_PUBLIC (fn) = !decl_function_context (TYPE_MAIN_DECL (type)); set_linkage_according_to_type (type, fn);
rest_of_decl_compilation (fn, /*asmspec=*/NULL, rest_of_decl_compilation (fn, /*asmspec=*/NULL,
toplevel_bindings_p (), at_eof); toplevel_bindings_p (), at_eof);
DECL_IN_AGGR_P (fn) = 1; DECL_IN_AGGR_P (fn) = 1;
......
...@@ -89,9 +89,7 @@ maybe_clone_body (tree fn) ...@@ -89,9 +89,7 @@ maybe_clone_body (tree fn)
/* We know that any clones immediately follow FN in the TYPE_METHODS /* We know that any clones immediately follow FN in the TYPE_METHODS
list. */ list. */
push_to_top_level (); push_to_top_level ();
for (clone = TREE_CHAIN (fn); FOR_EACH_CLONE (clone, fn)
clone && DECL_CLONED_FUNCTION_P (clone);
clone = TREE_CHAIN (clone))
{ {
tree parm; tree parm;
tree clone_parm; tree clone_parm;
......
...@@ -2892,18 +2892,6 @@ expand_body (tree fn) ...@@ -2892,18 +2892,6 @@ expand_body (tree fn)
extract_interface_info (); extract_interface_info ();
/* If this function is marked with the constructor attribute, add it
to the list of functions to be called along with constructors
from static duration objects. */
if (DECL_STATIC_CONSTRUCTOR (fn))
static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
/* If this function is marked with the destructor attribute, add it
to the list of functions to be called along with destructors from
static duration objects. */
if (DECL_STATIC_DESTRUCTOR (fn))
static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
if (DECL_CLONED_FUNCTION_P (fn)) if (DECL_CLONED_FUNCTION_P (fn))
{ {
/* If this is a clone, go through the other clones now and mark /* If this is a clone, go through the other clones now and mark
...@@ -2957,15 +2945,39 @@ expand_or_defer_fn (tree fn) ...@@ -2957,15 +2945,39 @@ expand_or_defer_fn (tree fn)
return; return;
} }
/* If this function is marked with the constructor attribute, add it
to the list of functions to be called along with constructors
from static duration objects. */
if (DECL_STATIC_CONSTRUCTOR (fn))
static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
/* If this function is marked with the destructor attribute, add it
to the list of functions to be called along with destructors from
static duration objects. */
if (DECL_STATIC_DESTRUCTOR (fn))
static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
/* We make a decision about linkage for these functions at the end
of the compilation. Until that point, we do not want the back
end to output them -- but we do want it to see the bodies of
these fucntions so that it can inline them as appropriate. */
if (DECL_DECLARED_INLINE_P (fn) || DECL_IMPLICIT_INSTANTIATION (fn))
{
if (!at_eof)
{
DECL_EXTERNAL (fn) = 1;
DECL_NOT_REALLY_EXTERN (fn) = 1;
note_vague_linkage_fn (fn);
}
else
import_export_decl (fn);
}
/* There's no reason to do any of the work here if we're only doing /* There's no reason to do any of the work here if we're only doing
semantic analysis; this code just generates RTL. */ semantic analysis; this code just generates RTL. */
if (flag_syntax_only) if (flag_syntax_only)
return; return;
/* Compute the appropriate object-file linkage for inline functions. */
if (DECL_DECLARED_INLINE_P (fn))
import_export_decl (fn);
function_depth++; function_depth++;
/* Expand or defer, at the whim of the compilation unit manager. */ /* Expand or defer, at the whim of the compilation unit manager. */
......
...@@ -1062,10 +1062,11 @@ find_tree (tree t, tree x) ...@@ -1062,10 +1062,11 @@ find_tree (tree t, tree x)
} }
/* Check if the type T depends on a type with no linkage and if so, return /* Check if the type T depends on a type with no linkage and if so, return
it. */ it. If RELAXED_P then do not consider a class type declared within
a TREE_PUBLIC function to have no linkage. */
tree tree
no_linkage_check (tree t) no_linkage_check (tree t, bool relaxed_p)
{ {
tree r; tree r;
...@@ -1076,6 +1077,8 @@ no_linkage_check (tree t) ...@@ -1076,6 +1077,8 @@ no_linkage_check (tree t)
switch (TREE_CODE (t)) switch (TREE_CODE (t))
{ {
tree fn;
case RECORD_TYPE: case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t)) if (TYPE_PTRMEMFUNC_P (t))
goto ptrmem; goto ptrmem;
...@@ -1085,25 +1088,28 @@ no_linkage_check (tree t) ...@@ -1085,25 +1088,28 @@ no_linkage_check (tree t)
return NULL_TREE; return NULL_TREE;
/* Fall through. */ /* Fall through. */
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
if (decl_function_context (TYPE_MAIN_DECL (t)) if (TYPE_ANONYMOUS_P (t))
|| TYPE_ANONYMOUS_P (t)) return t;
fn = decl_function_context (TYPE_MAIN_DECL (t));
if (fn && (!relaxed_p || !TREE_PUBLIC (fn)))
return t; return t;
return NULL_TREE; return NULL_TREE;
case ARRAY_TYPE: case ARRAY_TYPE:
case POINTER_TYPE: case POINTER_TYPE:
case REFERENCE_TYPE: case REFERENCE_TYPE:
return no_linkage_check (TREE_TYPE (t)); return no_linkage_check (TREE_TYPE (t), relaxed_p);
case OFFSET_TYPE: case OFFSET_TYPE:
ptrmem: ptrmem:
r = no_linkage_check (TYPE_PTRMEM_POINTED_TO_TYPE (t)); r = no_linkage_check (TYPE_PTRMEM_POINTED_TO_TYPE (t),
relaxed_p);
if (r) if (r)
return r; return r;
return no_linkage_check (TYPE_PTRMEM_CLASS_TYPE (t)); return no_linkage_check (TYPE_PTRMEM_CLASS_TYPE (t), relaxed_p);
case METHOD_TYPE: case METHOD_TYPE:
r = no_linkage_check (TYPE_METHOD_BASETYPE (t)); r = no_linkage_check (TYPE_METHOD_BASETYPE (t), relaxed_p);
if (r) if (r)
return r; return r;
/* Fall through. */ /* Fall through. */
...@@ -1114,11 +1120,11 @@ no_linkage_check (tree t) ...@@ -1114,11 +1120,11 @@ no_linkage_check (tree t)
parm && parm != void_list_node; parm && parm != void_list_node;
parm = TREE_CHAIN (parm)) parm = TREE_CHAIN (parm))
{ {
r = no_linkage_check (TREE_VALUE (parm)); r = no_linkage_check (TREE_VALUE (parm), relaxed_p);
if (r) if (r)
return r; return r;
} }
return no_linkage_check (TREE_TYPE (t)); return no_linkage_check (TREE_TYPE (t), relaxed_p);
} }
default: default:
......
2004-07-29 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/inline1.C: New test.
* g++.dg/abi/local1-a.cc: Likewise.
* g++.dg/abi/local1.C: Likewise.
* g++.dg/abi/mangle11.C: Tweak location of warnings.
* g++.dg/abi/mangle12.C: Likewise.
* g++.dg/abi/mangle17.C: Likewise.
* g++.dg/abi/mangle20-2.C: Likewise.
* g++.dg/opt/interface1.C: Likewise.
* g++.dg/opt/interface1.h: Likewise.
* g++.dg/opt/interface1-a.cc: New test.
* g++.dg/parse/repo1.C: New test.
* g++.dg/template/repo1.C: Likewise.
* g++.dg/warn/Winline-1.C: Likewise.
* lib/gcc-dg.exp (gcc-dg-test-1): Fix -frepo handling.
2004-07-29 Diego Novillo <dnovillo@redhat.com> 2004-07-29 Diego Novillo <dnovillo@redhat.com>
* gcc.dg/tree-ssa/20040729-1.c: New test. * gcc.dg/tree-ssa/20040729-1.c: New test.
......
struct S {
S() {}
virtual void g() {}
};
// { dg-final { scan-assembler-not "_ZTV1S" } }
struct B {
virtual void b() {}
};
static B* f() {
struct D : public B {
};
return new D;
}
B* g() {
return f();
}
// { dg-do run }
// { dg-additional-sources "local1-a.cc" }
#include <typeinfo>
struct B {
virtual void b() {}
};
static B* f() {
struct D : public B {
};
return new D;
}
extern B* g();
int main () {
if (typeid (*f()) == typeid (*g()))
return 1;
}
// { dg-options "-Wabi -fabi-version=1" } // { dg-options "-Wabi -fabi-version=1" }
template <typename Q> template <typename Q>
void f (typename Q::X) {} void f (typename Q::X) {} // { dg-warning "mangle" }
struct S { struct S {
typedef int X; typedef int X;
}; };
template void f<S> (int); // { dg-warning "mangle" } template void f<S> (int);
// { dg-options "-Wabi -fabi-version=1" } // { dg-options "-Wabi -fabi-version=1" }
template <template <typename> class Q> template <template <typename> class Q>
void f (typename Q<int>::X) {} void f (typename Q<int>::X) {} // { dg-warning "mangle" }
template <typename Q> template <typename Q>
struct S { struct S {
typedef int X; typedef int X;
}; };
template void f<S> (int); // { dg-warning "mangle" } template void f<S> (int);
...@@ -4,8 +4,8 @@ enum E { e = 3 }; ...@@ -4,8 +4,8 @@ enum E { e = 3 };
template <int I> struct S {}; template <int I> struct S {};
template <int I> void f (S<I + e + int (3.7)>) {} template <int I> void f (S<I + e + int (3.7)>) {} // { dg-warning "mangle" }
template void f<7>(S<7 + e + int (3.7)>); // { dg-warning "mangle" } template void f<7>(S<7 + e + int (3.7)>);
template <int I> void g (S<I + e + int (3.7)>) {} template <int I> void g (S<I + e + int (3.7)>) {} // { dg-warning "mangle" }
template void g<7>(S<7 + e + int (3.7)>); // { dg-warning "mangle" } template void g<7>(S<7 + e + int (3.7)>);
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
// PR 9043 // PR 9043
// mangled array types in templates // mangled array types in templates
template <int I> void f(int (*)[2]) {} template <int I> void f(int (*)[2]) {} // { dg-warning "mangled name" }
template <int I> void g(int (*)[I+2]) {} template <int I> void g(int (*)[I+2]) {}
template void f<1>(int (*)[2]); // { dg-warning "mangled name" } template void f<1>(int (*)[2]);
// { dg-final { scan-assembler "\n_?_Z1fILi1EEvPALi2E_i\[: \t\n\]" } } // { dg-final { scan-assembler "\n_?_Z1fILi1EEvPALi2E_i\[: \t\n\]" } }
template void g<1>(int (*)[3]); template void g<1>(int (*)[3]);
// { dg-final { scan-assembler "\n_?_Z1gILi1EEvPAplT_Li2E_i\[: \t\n\]" } } // { dg-final { scan-assembler "\n_?_Z1gILi1EEvPAplT_Li2E_i\[: \t\n\]" } }
struct Test {
void f();
};
Test t;
void g() {
t.f();
}
// { dg-do run }
// { dg-options "-O2" }
// { dg-additional-sources "interface1-a.cc" }
#pragma implementation "interface1.h"
#include "interface1.h"
extern void g();
int main () {
g();
}
#pragma interface "interface1.h"
struct Test {
void f();
};
inline void Test::f() {
}
// { dg-options "-frepo" }
extern "C" inline void f() {}
int main () {
f();
}
// { dg-options "-frepo" }
struct A {
A();
};
A::A() {}
template <typename T>
struct B : public A {
B() {} // { dg-bogus "" }
};
B<int> b;
int main () {}
// { dg-options "-Winline -O2 -fno-unit-at-a-time" } // { dg-options "-Winline -O2" }
static inline int foo(int x); // { dg-warning "" } static inline int foo(int x);
int main() int main()
{ {
return(foo(17)); // { dg-warning "" } return(foo(17));
} }
inline int foo(int x) { return(x); } inline int foo(int x) { return(x); }
...@@ -119,8 +119,10 @@ proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } { ...@@ -119,8 +119,10 @@ proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } {
if { $do_what == "repo" } { if { $do_what == "repo" } {
set object_file "$output_file" set object_file "$output_file"
set output_file "[file rootname [file tail $prog]].exe" set output_file "[file rootname [file tail $prog]].exe"
concat comp_output \ set comp_output \
[$target_compile "$object_file" "$output_file" "executable" $options] [ concat $comp_output \
[$target_compile "$object_file" "$output_file" \
"executable" $options] ]
} }
return [list $comp_output $output_file] return [list $comp_output $output_file]
......
...@@ -470,6 +470,12 @@ recompile_files (void) ...@@ -470,6 +470,12 @@ recompile_files (void)
obstack_grow (&temporary_obstack, "; ", 2); obstack_grow (&temporary_obstack, "; ", 2);
obstack_grow (&temporary_obstack, c_file_name, strlen (c_file_name)); obstack_grow (&temporary_obstack, c_file_name, strlen (c_file_name));
obstack_1grow (&temporary_obstack, ' '); obstack_1grow (&temporary_obstack, ' ');
if (!f->args)
{
error ("repository file `%s' does not contain command-line "
"arguments", f->key);
return 0;
}
obstack_grow (&temporary_obstack, f->args, strlen (f->args)); obstack_grow (&temporary_obstack, f->args, strlen (f->args));
obstack_1grow (&temporary_obstack, ' '); obstack_1grow (&temporary_obstack, ' ');
command = obstack_copy0 (&temporary_obstack, f->main, strlen (f->main)); command = obstack_copy0 (&temporary_obstack, f->main, strlen (f->main));
...@@ -645,6 +651,9 @@ scan_linker_output (const char *fname) ...@@ -645,6 +651,9 @@ scan_linker_output (const char *fname)
if (sym && sym->tweaked) if (sym && sym->tweaked)
{ {
error ("`%s' was assigned to `%s', but was not defined "
"during recompilation, or vice versa",
sym->key, sym->file->key);
fclose (stream); fclose (stream);
return 0; return 0;
} }
......
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