/* Process declarations and variables for C++ compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
#include "tree-mudflap.h"
#include "cgraph.h"
#include "tree-inline.h"
+#include "c-pragma.h"
extern cpp_reader *parse_in;
} *priority_info;
static void mark_vtable_entries (tree);
-static void grok_function_init (tree, tree);
static bool maybe_emit_vtables (tree);
-static tree build_anon_union_vars (tree);
static bool acceptable_java_type (tree);
static tree start_objects (int, int);
static void finish_objects (int, int, tree);
/* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
indicated NAME. */
-tree
+static tree
build_artificial_parm (tree name, tree type)
{
tree parm = cp_build_parm_decl (name, type);
/* We don't need an in-charge parameter for constructors that don't
have virtual bases. */
if (DECL_CONSTRUCTOR_P (fn)
- && !TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
+ && !CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
return;
arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
/* If this is a subobject constructor or destructor, our caller will
pass us a pointer to our VTT. */
- if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
+ if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
{
parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type);
this_quals |= TYPE_QUAL_CONST;
qual_type = cp_build_qualified_type (type, this_quals);
parm = build_artificial_parm (this_identifier, qual_type);
- c_apply_type_quals_to_decl (this_quals, parm);
+ cp_apply_type_quals_to_decl (this_quals, parm);
TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
DECL_ARGUMENTS (function) = parm;
}
}
type = TREE_TYPE (array_expr);
- my_friendly_assert (type, 20030626);
+ gcc_assert (type);
type = non_reference (type);
/* If they have an `operator[]', use that. */
array_expr = p2, index_exp = i1;
else
{
- error ("invalid types `%T[%T]' for array subscript",
- type, TREE_TYPE (index_exp));
+ error ("invalid types %<%T[%T]%> for array subscript",
+ type, TREE_TYPE (index_exp));
return error_mark_node;
}
return t;
}
- exp = convert_from_reference (exp);
-
/* An array can't have been allocated by new, so complain. */
if (TREE_CODE (exp) == VAR_DECL
&& TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
- warning ("deleting array `%#D'", exp);
+ warning ("deleting array %q#D", exp);
t = build_expr_type_conversion (WANT_POINTER, exp, true);
if (t == NULL_TREE || t == error_mark_node)
{
- error ("type `%#T' argument given to `delete', expected pointer",
- TREE_TYPE (exp));
+ error ("type %q#T argument given to %<delete%>, expected pointer",
+ TREE_TYPE (exp));
return error_mark_node;
}
/* You can't delete functions. */
if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
{
- error ("cannot delete a function. Only pointer-to-objects are valid arguments to `delete'");
+ error ("cannot delete a function. Only pointer-to-objects are "
+ "valid arguments to %<delete%>");
return error_mark_node;
}
/* Deleting ptr to void is undefined behavior [expr.delete/3]. */
if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
{
- warning ("deleting `%T' is undefined", type);
+ warning ("deleting %qT is undefined", type);
doing_vec = 0;
}
{
tree decl;
- my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
decl = DECL_TEMPLATE_RESULT (tmpl);
if (TREE_CODE (decl) == FUNCTION_DECL
/* 14.5.2.2 [temp.mem]
A local class shall not have member templates. */
- error ("invalid declaration of member template `%#D' in local class",
- decl);
+ error ("invalid declaration of member template %q#D in local class",
+ decl);
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
{
A member function template shall not be virtual. */
error
- ("invalid use of `virtual' in template declaration of `%#D'",
+ ("invalid use of %<virtual%> in template declaration of %q#D",
decl);
DECL_VIRTUAL_P (decl) = 0;
}
DECL_IGNORED_P (tmpl) = 1;
}
else
- error ("template declaration of `%#D'", decl);
+ error ("template declaration of %q#D", decl);
}
/* Return true iff TYPE is a valid Java parameter or return type. */
if (!acceptable_java_type (ret_type))
{
- error ("Java method '%D' has non-Java return type `%T'",
- method, ret_type);
+ error ("Java method %qD has non-Java return type %qT",
+ method, ret_type);
jerr = true;
}
tree type = TREE_VALUE (arg_types);
if (!acceptable_java_type (type))
{
- error ("Java method '%D' has non-Java parameter type `%T'",
- method, type);
+ error ("Java method %qD has non-Java parameter type %qT",
+ method, type);
jerr = true;
}
}
/* Sanity check: report error if this function FUNCTION is not
really a member of the class (CTYPE) it is supposed to belong to.
- TEMPLATE_PARMS is used to specifiy the template parameters of a member
+ TEMPLATE_PARMS is used to specify the template parameters of a member
template passed as FUNCTION_DECL. If the member template is passed as a
TEMPLATE_DECL, it can be NULL since the parameters can be extracted
from the declaration. If the function is not a function template, it
if (DECL_USE_TEMPLATE (function)
&& !(TREE_CODE (function) == TEMPLATE_DECL
&& DECL_TEMPLATE_SPECIALIZATION (function))
- && is_member_template (DECL_TI_TEMPLATE (function)))
+ && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (function)))
/* Since this is a specialization of a member template,
we're not going to find the declaration in the class.
For example, in:
either were not passed, or they are the same of DECL_TEMPLATE_PARMS. */
if (TREE_CODE (function) == TEMPLATE_DECL)
{
- my_friendly_assert (!template_parms
- || comp_template_parms
- (template_parms,
- DECL_TEMPLATE_PARMS (function)),
- 20040303);
+ gcc_assert (!template_parms
+ || comp_template_parms (template_parms,
+ DECL_TEMPLATE_PARMS (function)));
template_parms = DECL_TEMPLATE_PARMS (function);
}
/* OK, is this a definition of a member template? */
is_template = (template_parms != NULL_TREE);
- ix = lookup_fnfields_1 (complete_type (ctype),
- DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
- DECL_DESTRUCTOR_P (function) ? dtor_identifier :
- DECL_NAME (function));
-
+ ix = class_method_index_for_fn (complete_type (ctype), function);
if (ix >= 0)
{
VEC(tree) *methods = CLASSTYPE_METHOD_VEC (ctype);
tree fndecls, fndecl = 0;
bool is_conv_op;
- bool pop_p;
+ tree pushed_scope;
const char *format = NULL;
- pop_p = push_scope (ctype);
+ pushed_scope = push_scope (ctype);
for (fndecls = VEC_index (tree, methods, ix);
fndecls; fndecls = OVL_NEXT (fndecls))
{
== DECL_TI_TEMPLATE (fndecl))))
break;
}
- if (pop_p)
- pop_scope (ctype);
+ if (pushed_scope)
+ pop_scope (pushed_scope);
if (fndecls)
return OVL_CURRENT (fndecls);
- error ("prototype for `%#D' does not match any in class `%T'",
+ error ("prototype for %q#D does not match any in class %qT",
function, ctype);
is_conv_op = DECL_CONV_FN_P (fndecl);
else if (!COMPLETE_TYPE_P (ctype))
cxx_incomplete_type_error (function, ctype);
else
- error ("no `%#D' member function declared in class `%T'",
+ error ("no %q#D member function declared in class %qT",
function, ctype);
/* If we did not find the method in the class, add it to avoid
finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
int flags)
{
- my_friendly_assert (TREE_PUBLIC (decl), 0);
+ gcc_assert (TREE_PUBLIC (decl));
DECL_CONTEXT (decl) = current_class_type;
note_vague_linkage_var (decl);
if (LOCAL_CLASS_P (current_class_type))
- pedwarn ("local class `%#T' shall not have static data member `%#D'",
+ pedwarn ("local class %q#T shall not have static data member %q#D",
current_class_type, decl);
/* Static consts need not be initialized in the class definition. */
if (!declspecs->any_specifiers_p
&& declarator->kind == cdk_id
- && TREE_CODE (declarator->u.id.name) == SCOPE_REF
- && (TREE_CODE (TREE_OPERAND (declarator->u.id.name, 1))
- == IDENTIFIER_NODE))
+ && declarator->u.id.qualifying_scope
+ && TREE_CODE (declarator->u.id.unqualified_name) == IDENTIFIER_NODE)
/* Access declaration */
- return do_class_using_decl (declarator->u.id.name);
+ return do_class_using_decl (declarator->u.id.qualifying_scope,
+ declarator->u.id.unqualified_name);
if (init
&& TREE_CODE (init) == TREE_LIST
if (TREE_CODE (value) == TYPE_DECL && init)
{
- error ("typedef `%D' is initialized (use __typeof__ instead)", value);
+ error ("typedef %qD is initialized (use __typeof__ instead)", value);
init = NULL_TREE;
}
if (DECL_NAME (value) != NULL_TREE
&& IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'
&& ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr"))
- error ("member `%D' conflicts with virtual function table field name",
- value);
+ error ("member %qD conflicts with virtual function table field name",
+ value);
/* Stash away type declarations. */
if (TREE_CODE (value) == TYPE_DECL)
if (processing_template_decl)
value = push_template_decl (value);
+ if (attrlist)
+ {
+ /* Avoid storing attributes in template parameters:
+ tsubst is not ready to handle them. */
+ tree type = TREE_TYPE (value);
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ sorry ("applying attributes to template parameters is not implemented");
+ else
+ cplus_decl_attributes (&value, attrlist, 0);
+ }
+
return value;
}
if (DECL_IN_AGGR_P (value))
{
- error ("`%D' is already defined in `%T'", value,
- DECL_CONTEXT (value));
+ error ("%qD is already defined in %qT", value, DECL_CONTEXT (value));
return void_type_node;
}
{
if (TREE_CODE (value) == FUNCTION_DECL)
{
- grok_function_init (value, init);
- init = NULL_TREE;
+ /* Initializers for functions are rejected early in the parser.
+ If we get here, it must be a pure specifier for a method. */
+ gcc_assert (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE);
+ gcc_assert (error_operand_p (init) || integer_zerop (init));
+ DECL_PURE_VIRTUAL_P (value) = 1;
}
else if (pedantic && TREE_CODE (value) != VAR_DECL)
/* Already complained in grokdeclarator. */
if (!processing_template_decl)
{
- if (TREE_CODE (init) == CONST_DECL)
- init = DECL_INITIAL (init);
- else if (TREE_READONLY_DECL_P (init))
- init = decl_constant_value (init);
- else if (TREE_CODE (init) == CONSTRUCTOR)
+ if (TREE_CODE (init) == CONSTRUCTOR)
init = digest_init (TREE_TYPE (value), init, (tree *)0);
+ else
+ init = integral_constant_value (init);
+
if (init != error_mark_node && ! TREE_CONSTANT (init))
{
/* We can allow references to things that are effectively
if (attrlist)
cplus_decl_attributes (&value, attrlist, 0);
- if (TREE_CODE (value) == VAR_DECL)
+ switch (TREE_CODE (value))
{
+ case VAR_DECL:
finish_static_data_member_decl (value, init, asmspec_tree,
flags);
return value;
- }
- if (TREE_CODE (value) == FIELD_DECL)
- {
+
+ case FIELD_DECL:
if (asmspec)
- error ("`asm' specifiers are not permitted on non-static data members");
+ error ("%<asm%> specifiers are not permitted on non-static data members");
if (DECL_INITIAL (value) == error_mark_node)
init = error_mark_node;
cp_finish_decl (value, init, NULL_TREE, flags);
DECL_INITIAL (value) = init;
DECL_IN_AGGR_P (value) = 1;
return value;
- }
- if (TREE_CODE (value) == FUNCTION_DECL)
- {
+
+ case FUNCTION_DECL:
if (asmspec)
set_user_assembler_name (value, asmspec);
if (!DECL_FRIEND_P (value))
DECL_IN_AGGR_P (value) = 1;
return value;
+
+ default:
+ gcc_unreachable ();
}
- abort ();
- /* NOTREACHED */
return NULL_TREE;
}
if (TREE_CODE (value) == TYPE_DECL)
{
- error ("cannot declare `%D' to be a bit-field type", value);
+ error ("cannot declare %qD to be a bit-field type", value);
return NULL_TREE;
}
check here. */
if (TREE_CODE (value) == FUNCTION_DECL)
{
- error ("cannot declare bit-field `%D' with function type",
+ error ("cannot declare bit-field %qD with function type",
DECL_NAME (value));
return NULL_TREE;
}
if (DECL_IN_AGGR_P (value))
{
- error ("`%D' is already defined in the class %T", value,
- DECL_CONTEXT (value));
+ error ("%qD is already defined in the class %qT", value,
+ DECL_CONTEXT (value));
return void_type_node;
}
if (TREE_STATIC (value))
{
- error ("static member `%D' cannot be a bit-field", value);
+ error ("static member %qD cannot be a bit-field", value);
return NULL_TREE;
}
cp_finish_decl (value, NULL_TREE, NULL_TREE, 0);
return value;
}
-/* When a function is declared with an initializer,
- do the right thing. Currently, there are two possibilities:
-
- class B
- {
- public:
- // initialization possibility #1.
- virtual void f () = 0;
- int g ();
- };
-
- class D1 : B
- {
- public:
- int d1;
- // error, no f ();
- };
-
- class D2 : B
- {
- public:
- int d2;
- void f ();
- };
-
- class D3 : B
- {
- public:
- int d3;
- // initialization possibility #2
- void f () = B::f;
- };
-
-*/
-
-static void
-grok_function_init (tree decl, tree init)
-{
- /* An initializer for a function tells how this function should
- be inherited. */
- tree type = TREE_TYPE (decl);
-
- if (TREE_CODE (type) == FUNCTION_TYPE)
- error ("initializer specified for non-member function `%D'", decl);
- else if (integer_zerop (init))
- DECL_PURE_VIRTUAL_P (decl) = 1;
- else
- error ("invalid initializer for virtual method `%D'", decl);
-}
\f
void
cplus_decl_attributes (tree *decl, tree attributes, int flags)
SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
}
\f
-/* Walks through the namespace- or function-scope anonymous union OBJECT,
- building appropriate ALIAS_DECLs. Returns one of the fields for use in
- the mangled name. */
+/* Walks through the namespace- or function-scope anonymous union
+ OBJECT, with the indicated TYPE, building appropriate ALIAS_DECLs.
+ Returns one of the fields for use in the mangled name. */
static tree
-build_anon_union_vars (tree object)
+build_anon_union_vars (tree type, tree object)
{
- tree type = TREE_TYPE (object);
tree main_decl = NULL_TREE;
tree field;
continue;
if (TREE_CODE (field) != FIELD_DECL)
{
- cp_pedwarn_at ("\
-`%#D' invalid; an anonymous union can only have non-static data members",
+ cp_pedwarn_at ("%q#D invalid; an anonymous union can only "
+ "have non-static data members",
field);
continue;
}
if (TREE_PRIVATE (field))
- cp_pedwarn_at ("private member `%#D' in anonymous union", field);
+ cp_pedwarn_at ("private member %q#D in anonymous union", field);
else if (TREE_PROTECTED (field))
- cp_pedwarn_at ("protected member `%#D' in anonymous union", field);
+ cp_pedwarn_at ("protected member %q#D in anonymous union", field);
if (processing_template_decl)
ref = build_min_nt (COMPONENT_REF, object,
decl = pushdecl (decl);
}
else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
- decl = build_anon_union_vars (ref);
+ decl = build_anon_union_vars (TREE_TYPE (field), ref);
else
decl = 0;
void
finish_anon_union (tree anon_union_decl)
{
- tree type = TREE_TYPE (anon_union_decl);
+ tree type;
tree main_decl;
- bool public_p = TREE_PUBLIC (anon_union_decl);
+ bool public_p;
+
+ if (anon_union_decl == error_mark_node)
+ return;
+
+ type = TREE_TYPE (anon_union_decl);
+ public_p = TREE_PUBLIC (anon_union_decl);
/* The VAR_DECL's context is the same as the TYPE's context. */
DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type));
return;
}
- main_decl = build_anon_union_vars (anon_union_decl);
+ main_decl = build_anon_union_vars (type, anon_union_decl);
if (main_decl == NULL_TREE)
{
warning ("anonymous union with no members");
int e = 0;
tree args = TYPE_ARG_TYPES (type);
- my_friendly_assert (TREE_CODE (type) == FUNCTION_TYPE, 20001107);
+ gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
if (!same_type_p (TREE_TYPE (type), ptr_type_node))
- e = 1, error ("`operator new' must return type `%T'", ptr_type_node);
+ {
+ e = 1;
+ error ("%<operator new%> must return type %qT", ptr_type_node);
+ }
if (!args || args == void_list_node
|| !same_type_p (TREE_VALUE (args), size_type_node))
e = 2;
if (args && args != void_list_node)
args = TREE_CHAIN (args);
- pedwarn ("`operator new' takes type `size_t' (`%T') as first parameter", size_type_node);
+ pedwarn ("%<operator new%> takes type %<size_t%> (%qT) "
+ "as first parameter", size_type_node);
}
switch (e)
{
int e = 0;
tree args = TYPE_ARG_TYPES (type);
- my_friendly_assert (TREE_CODE (type) == FUNCTION_TYPE, 20001107);
+ gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
if (!same_type_p (TREE_TYPE (type), void_type_node))
- e = 1, error ("`operator delete' must return type `%T'", void_type_node);
+ {
+ e = 1;
+ error ("%<operator delete%> must return type %qT", void_type_node);
+ }
if (!args || args == void_list_node
|| !same_type_p (TREE_VALUE (args), ptr_type_node))
e = 2;
if (args && args != void_list_node)
args = TREE_CHAIN (args);
- error ("`operator delete' takes type `%T' as first parameter", ptr_type_node);
+ error ("%<operator delete%> takes type %qT as first parameter",
+ ptr_type_node);
}
switch (e)
{
if (! flag_weak)
return;
- /* We can't set DECL_COMDAT on functions, or finish_file will think
+ /* We can't set DECL_COMDAT on functions, or cp_finish_file will think
we can get away with not emitting them if they aren't used. We need
to for variables so that cp_finish_decl will update their linkage,
because their DECL_INITIAL may not have been set properly yet. */
non-abstract virtual member function has been defined in this
translation unit. But, we can't possibly know that until we've
seen the entire translation unit. */
- my_friendly_assert (at_eof, 20000226);
+ gcc_assert (at_eof);
if (CLASSTYPE_INTERFACE_KNOWN (ctype))
return;
- /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma interface,
+ /* If MULTIPLE_SYMBOL_SPACES is set and we saw a #pragma interface,
we will have CLASSTYPE_INTERFACE_ONLY set but not
CLASSTYPE_INTERFACE_KNOWN. In that case, we don't want to use this
heuristic because someone will supply a #pragma implementation
import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1);
}
-#ifdef MULTIPLE_SYMBOL_SPACES
- if (import_export == -1)
+ /* When MULTIPLE_SYMBOL_SPACES is set, we cannot count on seeing
+ a definition anywhere else. */
+ if (MULTIPLE_SYMBOL_SPACES && import_export == -1)
import_export = 0;
-#endif
/* Allow backends the chance to overrule the decision. */
if (targetm.cxx.import_export_class)
bool
decl_needed_p (tree decl)
{
- my_friendly_assert (TREE_CODE (decl) == VAR_DECL
- || TREE_CODE (decl) == FUNCTION_DECL,
- 20040726);
+ gcc_assert (TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == FUNCTION_DECL);
/* This function should only be called at the end of the translation
unit. We cannot be sure of whether or not something will be
COMDAT until that point. */
- my_friendly_assert (at_eof, 20040726);
+ gcc_assert (at_eof);
/* All entities with external linkage that are not COMDAT should be
emitted; they may be referred to from other object files. */
if (TREE_TYPE (primary_vtbl) == void_type_node)
return false;
+ /* On some targets, we cannot determine the key method until the end
+ of the translation unit -- which is when this function is
+ called. */
+ if (!targetm.cxx.key_method_may_be_inline ())
+ determine_key_method (ctype);
+
/* See if any of the vtables are needed. */
for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl))
{
if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
{
+ tree expr = store_init_value (vtbl, DECL_INITIAL (vtbl));
+
/* It had better be all done at compile-time. */
- if (store_init_value (vtbl, DECL_INITIAL (vtbl)))
- abort ();
+ gcc_assert (!expr);
}
/* Write it out. */
/* Cloned constructors and destructors get the same visibility as
the underlying function. That should be set up in
maybe_clone_body. */
- my_friendly_assert (!DECL_CLONED_FUNCTION_P (decl), 20040804);
+ gcc_assert (!DECL_CLONED_FUNCTION_P (decl));
/* Give the common code a chance to make a determination. */
if (c_determine_visibility (decl))
{
/* Virtual tables have DECL_CONTEXT set to their associated class,
so they are automatically handled above. */
- my_friendly_assert (!(TREE_CODE (decl) == VAR_DECL
- && DECL_VTABLE_OR_VTT_P (decl)), 20040803);
+ gcc_assert (TREE_CODE (decl) != VAR_DECL
+ || !DECL_VTABLE_OR_VTT_P (decl));
/* Entities not associated with any class just get the
visibility specified by their attributes. */
return;
{
DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
DECL_VISIBILITY_SPECIFIED (decl) = 1;
- return;
}
-
- if (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_DECLARED_INLINE_P (decl)
- && visibility_options.inlines_hidden)
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl)
+ && visibility_options.inlines_hidden)
{
DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (decl) = 1;
}
+ else if (CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
+ {
+ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ }
+ /* If no explicit visibility information has been provided for
+ this class, some targets require that class data be
+ exported. */
+ else if (TREE_CODE (decl) == VAR_DECL
+ && targetm.cxx.export_class_data ()
+ && (DECL_TINFO_P (decl)
+ || (DECL_VTABLE_OR_VTT_P (decl)
+ /* Construction virtual tables are not emitted
+ because they cannot be referred to from other
+ object files; their name is not standardized by
+ the ABI. */
+ && !DECL_CONSTRUCTION_VTABLE_P (decl))))
+ DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
else
{
DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
- DECL_VISIBILITY_SPECIFIED (decl)
- = CLASSTYPE_VISIBILITY_SPECIFIED (class_type);
+ DECL_VISIBILITY_SPECIFIED (decl) = 0;
}
}
}
"-frepo" it would be incorrect to make decisions about what
entities to emit when building the PCH; those decisions must be
delayed until the repository information has been processed. */
- my_friendly_assert (at_eof, 20040727);
+ gcc_assert (at_eof);
/* Object file linkage for explicit instantiations is handled in
mark_decl_instantiated. For static variables in functions with
vague linkage, maybe_commonize_var is used.
Therefore, the only declarations that should be provided to this
- function are those with external linkage that:
+ function are those with external linkage that are:
* implicit instantiations of function templates
definition available in this translation unit.
The following assertions check these conditions. */
- my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL
- || TREE_CODE (decl) == VAR_DECL,
- 2004725);
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == VAR_DECL);
/* Any code that creates entities with TREE_PUBLIC cleared should
also set DECL_INTERFACE_KNOWN. */
- my_friendly_assert (TREE_PUBLIC (decl), 20040725);
+ gcc_assert (TREE_PUBLIC (decl));
if (TREE_CODE (decl) == FUNCTION_DECL)
- my_friendly_assert (DECL_IMPLICIT_INSTANTIATION (decl)
- || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
- || DECL_DECLARED_INLINE_P (decl),
- 20040725);
+ gcc_assert (DECL_IMPLICIT_INSTANTIATION (decl)
+ || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
+ || DECL_DECLARED_INLINE_P (decl));
else
- my_friendly_assert (DECL_IMPLICIT_INSTANTIATION (decl)
- || DECL_VTABLE_OR_VTT_P (decl)
- || DECL_TINFO_P (decl),
- 20040725);
+ gcc_assert (DECL_IMPLICIT_INSTANTIATION (decl)
+ || DECL_VTABLE_OR_VTT_P (decl)
+ || DECL_TINFO_P (decl));
/* Check that a definition of DECL is available in this translation
unit. */
- my_friendly_assert (!DECL_REALLY_EXTERN (decl), 20040725);
+ gcc_assert (!DECL_REALLY_EXTERN (decl));
/* Assume that DECL will not have COMDAT linkage. */
comdat_p = false;
/* This function should only be called for declarations that really
require cleanups. */
- my_friendly_assert (!TYPE_HAS_TRIVIAL_DESTRUCTOR (type), 20030106);
+ gcc_assert (!TYPE_HAS_TRIVIAL_DESTRUCTOR (type));
/* Treat all objects with destructors as used; the destructor may do
something substantive. */
DECL_WEAK (guard) = DECL_WEAK (decl);
DECL_ARTIFICIAL (guard) = 1;
+ DECL_IGNORED_P (guard) = 1;
TREE_USED (guard) = 1;
pushdecl_top_level_and_finish (guard, NULL_TREE);
}
guard_if_stmt = begin_if_stmt ();
cond = cp_build_binary_op (EQ_EXPR,
priority_decl,
- build_int_2 (priority, 0));
+ build_int_cst (NULL_TREE, priority));
init_cond = initp ? integer_one_node : integer_zero_node;
init_cond = cp_build_binary_op (EQ_EXPR,
initialize_p_decl,
{
/* When using __cxa_atexit, we never try to destroy
anything from a static destructor. */
- my_friendly_assert (initp, 20000629);
+ gcc_assert (initp);
guard_cond = get_guard_cond (guard);
}
/* If we don't have __cxa_atexit, then we will be running
/* If we're using __cxa_atexit, register a a function that calls the
destructor for the object. */
if (flag_use_cxa_atexit)
- register_dtor_fn (decl);
+ finish_expr_stmt (register_dtor_fn (decl));
/* Finish up. */
finish_static_initialization_or_destruction (guard_if_stmt);
/* If we're using __cxa_atexit, then destructors are registered
immediately after objects are initialized. */
- my_friendly_assert (!flag_use_cxa_atexit, 20000121);
+ gcc_assert (!flag_use_cxa_atexit);
/* If we don't need a destructor, there's nothing to do. */
if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
}
/* The only things that can be initialized are variables. */
- my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 19990420);
+ gcc_assert (TREE_CODE (decl) == VAR_DECL);
/* If this object is not defined, we don't need to do anything
here. */
if (! body)
body = start_objects (function_key, priority);
- arguments = tree_cons (NULL_TREE, build_int_2 (priority, 0),
+ arguments = tree_cons (NULL_TREE,
+ build_int_cst (NULL_TREE, priority),
NULL_TREE);
- arguments = tree_cons (NULL_TREE, build_int_2 (constructor_p, 0),
+ arguments = tree_cons (NULL_TREE,
+ build_int_cst (NULL_TREE, constructor_p),
arguments);
finish_expr_stmt (build_function_call (fndecl, arguments));
}
first, since that way we only need to reverse the decls once. */
void
-finish_file (void)
+cp_finish_file (void)
{
tree vars;
bool reconsider;
size_t i;
location_t locus;
unsigned ssdf_count = 0;
+ int retries = 0;
locus = input_location;
at_eof = 1;
input_line -= 1;
#endif
- interface_unknown = 1;
- interface_only = 0;
-
/* We now have to write out all the stuff we put off writing out.
These include:
do
{
tree t;
- size_t n_old, n_new;
reconsider = false;
/* If there are templates that we've put off instantiating, do
them now. */
- instantiate_pending_templates ();
+ instantiate_pending_templates (retries);
ggc_collect ();
/* Write out virtual tables as required. Note that writing out
instantiation of members of that class. If we write out
vtables then we remove the class from our list so we don't
have to look at it again. */
-
+
while (keyed_classes != NULL_TREE
&& maybe_emit_vtables (TREE_VALUE (keyed_classes)))
{
next = TREE_CHAIN (t);
}
}
-
+
/* Write out needed type info variables. We have to be careful
looping through unemitted decls, because emit_tinfo_decl may
- cause other variables to be needed. We stick new elements
- (and old elements that we may need to reconsider) at the end
- of the array, then shift them back to the beginning once we're
- done. */
-
- n_old = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls);
- for (i = 0; i < n_old; ++i)
- {
- tree tinfo_decl = VARRAY_TREE (unemitted_tinfo_decls, i);
- if (emit_tinfo_decl (tinfo_decl))
- reconsider = true;
- else
- VARRAY_PUSH_TREE (unemitted_tinfo_decls, tinfo_decl);
- }
-
- /* The only elements we want to keep are the new ones. Copy
- them to the beginning of the array, then get rid of the
- leftovers. */
- n_new = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls) - n_old;
- if (n_new)
- memmove (&VARRAY_TREE (unemitted_tinfo_decls, 0),
- &VARRAY_TREE (unemitted_tinfo_decls, n_old),
- n_new * sizeof (tree));
- memset (&VARRAY_TREE (unemitted_tinfo_decls, n_new),
- 0, n_old * sizeof (tree));
- VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls) = n_new;
+ cause other variables to be needed. New elements will be
+ appended, and we remove from the vector those that actually
+ get emitted. */
+ for (i = VEC_length (tree, unemitted_tinfo_decls);
+ VEC_iterate (tree, unemitted_tinfo_decls, --i, t);)
+ if (emit_tinfo_decl (t))
+ {
+ reconsider = true;
+ VEC_unordered_remove (tree, unemitted_tinfo_decls, i);
+ }
/* The list of objects with static storage duration is built up
in reverse order. We clear STATIC_AGGREGATES so that any new
reconsider = true;
/* Ask the back end to emit functions and variables that are
- enqued. These emissions may result in marking more entities
+ enqueued. These emissions may result in marking more entities
as needed. */
if (cgraph_assemble_pending_functions ())
reconsider = true;
if (cgraph_varpool_assemble_pending_decls ())
reconsider = true;
+
+ retries++;
}
while (reconsider);
already verified there was a definition. */
&& !DECL_EXPLICIT_INSTANTIATION (decl))
{
- cp_warning_at ("inline function `%D' used but never defined", decl);
+ cp_warning_at ("inline function %qD used but never defined", decl);
/* This symbol is effectively an "extern" declaration now.
This is not strictly necessary, but removes a duplicate
warning. */
if (priority_info_map)
splay_tree_delete (priority_info_map);
+ /* Generate any missing aliases. */
+ maybe_apply_pending_pragma_weaks ();
+
/* We're done with static constructors, so we can go back to "C++"
linkage now. */
pop_lang_context ();
cgraph_finalize_compilation_unit ();
cgraph_optimize ();
- /* Emit mudflap static registration function. This must be done
- after all the user functions have been expanded. */
- if (flag_mudflap)
- mudflap_finish_file ();
-
/* Now, issue warnings about static, but not defined, functions,
etc., and emit debugging information. */
walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider);
if (processing_template_decl)
{
- my_friendly_assert (TREE_CODE (fn) == DOTSTAR_EXPR
- || TREE_CODE (fn) == MEMBER_REF,
- 20030708);
+ gcc_assert (TREE_CODE (fn) == DOTSTAR_EXPR
+ || TREE_CODE (fn) == MEMBER_REF);
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
return build_min_nt (CALL_EXPR, fn, args, NULL_TREE);
saw_def = true;
else if (saw_def)
{
- cp_error_at ("default argument missing for parameter %P of `%+#D'",
+ cp_error_at ("default argument missing for parameter %P of %q+#D",
i, x);
break;
}
&& DECL_ARTIFICIAL (decl)
&& !DECL_THUNK_P (decl)
&& ! DECL_INITIAL (decl)
- /* Kludge: don't synthesize for default args. */
+ /* Kludge: don't synthesize for default args. Unfortunately this
+ rules out initializers of namespace-scoped objects too, but
+ it's sort-of ok if the implicit ctor or dtor decl keeps
+ pointing to the class location. */
&& current_function_decl)
{
+ /* Put the function definition at the position where it is needed,
+ rather than within the body of the class. That way, an error
+ during the generation of the implicit body points at the place
+ where the attempt to generate the function occurs, giving the
+ user a hint as to why we are attempting to generate the
+ function. */
+ DECL_SOURCE_LOCATION (decl) = input_location;
+
synthesize_method (decl);
/* If we've already synthesized the method we don't need to
instantiate it, so we can return right away. */