X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl2.c;h=97b3ee0f3f25adf6e607c04ba35d402b49f258d1;hb=1e307880e3f8c596704fae458a8378068b807d5c;hp=a1664b81bcd94a44d62d625a7f4aed1b29f30ecc;hpb=2970ab3d17c41b33da12f9d80a5f83990d475645;p=pf3gnuchains%2Fgcc-fork.git
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a1664b81bcd..97b3ee0f3f2 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1,13 +1,13 @@
/* Process declarations and variables for C++ compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
@@ -16,9 +16,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+. */
/* Process declarations and symbol lookup for C++ front end.
@@ -136,6 +135,12 @@ cp_build_parm_decl (tree name, tree type)
sees templates. */
if (!processing_template_decl)
DECL_ARG_TYPE (parm) = type_passed_as (type);
+
+ /* If the type is a pack expansion, then we have a function
+ parameter pack. */
+ if (type && TREE_CODE (type) == TYPE_PACK_EXPANSION)
+ FUNCTION_PARAMETER_PACK_P (parm) = 1;
+
return parm;
}
@@ -535,8 +540,8 @@ check_java_method (tree method)
TEMPLATE_DECL, it can be NULL since the parameters can be extracted
from the declaration. If the function is not a function template, it
must be NULL.
- It returns the original declaration for the function, or NULL_TREE
- if no declaration was found (and an error was emitted). */
+ It returns the original declaration for the function, NULL_TREE if
+ no declaration was found, error_mark_node if an error was emitted. */
tree
check_classfn (tree ctype, tree function, tree template_parms)
@@ -672,16 +677,9 @@ check_classfn (tree ctype, tree function, tree template_parms)
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
- spurious errors (unless the CTYPE is not yet defined, in which
- case we'll only confuse ourselves when the function is declared
- properly within the class. */
- if (COMPLETE_TYPE_P (ctype))
- add_method (ctype, function, NULL_TREE);
-
if (pushed_scope)
pop_scope (pushed_scope);
- return NULL_TREE;
+ return error_mark_node;
}
/* DECL is a function with vague linkage. Remember it so that at the
@@ -802,16 +800,7 @@ grokfield (const cp_declarator *declarator,
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);
- }
+ cplus_decl_attributes (&value, attrlist, 0);
return value;
}
@@ -987,13 +976,127 @@ grokbitfield (const cp_declarator *declarator,
}
+/* Returns true iff ATTR is an attribute which needs to be applied at
+ instantiation time rather than template definition time. */
+
+static bool
+is_late_template_attribute (tree attr, tree decl)
+{
+ tree name = TREE_PURPOSE (attr);
+ tree args = TREE_VALUE (attr);
+ const struct attribute_spec *spec = lookup_attribute_spec (name);
+
+ if (!spec)
+ /* Unknown attribute. */
+ return false;
+
+ if (is_attribute_p ("aligned", name)
+ && args
+ && value_dependent_expression_p (TREE_VALUE (args)))
+ /* Can't apply this until we know the desired alignment. */
+ return true;
+ else if (TREE_CODE (decl) == TYPE_DECL || spec->type_required)
+ {
+ tree type = TYPE_P (decl) ? decl : TREE_TYPE (decl);
+
+ /* We can't apply any attributes to a completely unknown type until
+ instantiation time. */
+ enum tree_code code = TREE_CODE (type);
+ if (code == TEMPLATE_TYPE_PARM
+ || code == BOUND_TEMPLATE_TEMPLATE_PARM
+ || code == TYPENAME_TYPE)
+ return true;
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
+/* ATTR_P is a list of attributes. Remove any attributes which need to be
+ applied at instantiation time and return them. If IS_DEPENDENT is true,
+ the declaration itself is dependent, so all attributes should be applied
+ at instantiation time. */
+
+static tree
+splice_template_attributes (tree *attr_p, tree decl)
+{
+ tree *p = attr_p;
+ tree late_attrs = NULL_TREE;
+ tree *q = &late_attrs;
+
+ if (!p)
+ return NULL_TREE;
+
+ for (; *p; )
+ {
+ if (is_late_template_attribute (*p, decl))
+ {
+ ATTR_IS_DEPENDENT (*p) = 1;
+ *q = *p;
+ *p = TREE_CHAIN (*p);
+ q = &TREE_CHAIN (*q);
+ *q = NULL_TREE;
+ }
+ else
+ p = &TREE_CHAIN (*p);
+ }
+
+ return late_attrs;
+}
+
+/* Remove any late attributes from the list in ATTR_P and attach them to
+ DECL_P. */
+
+static void
+save_template_attributes (tree *attr_p, tree *decl_p)
+{
+ tree late_attrs = splice_template_attributes (attr_p, *decl_p);
+ tree *q;
+
+ if (!late_attrs)
+ return;
+
+ /* Give this type a name so we know to look it up again at instantiation
+ time. */
+ if (TREE_CODE (*decl_p) == TYPE_DECL
+ && DECL_ORIGINAL_TYPE (*decl_p) == NULL_TREE)
+ {
+ tree oldt = TREE_TYPE (*decl_p);
+ tree newt = build_variant_type_copy (oldt);
+ DECL_ORIGINAL_TYPE (*decl_p) = oldt;
+ TREE_TYPE (*decl_p) = newt;
+ TYPE_NAME (newt) = *decl_p;
+ TREE_USED (newt) = TREE_USED (*decl_p);
+ }
+
+ if (DECL_P (*decl_p))
+ q = &DECL_ATTRIBUTES (*decl_p);
+ else
+ q = &TYPE_ATTRIBUTES (*decl_p);
+
+ if (*q)
+ q = &TREE_CHAIN (tree_last (*q));
+ *q = late_attrs;
+}
+
+/* Like decl_attributes, but handle C++ complexity. */
+
void
cplus_decl_attributes (tree *decl, tree attributes, int flags)
{
if (*decl == NULL_TREE || *decl == void_type_node
- || *decl == error_mark_node)
+ || *decl == error_mark_node
+ || attributes == NULL_TREE)
return;
+ if (processing_template_decl)
+ {
+ save_template_attributes (&attributes, decl);
+ if (attributes == NULL_TREE)
+ return;
+ }
+
if (TREE_CODE (*decl) == TEMPLATE_DECL)
decl = &DECL_TEMPLATE_RESULT (*decl);
@@ -1051,6 +1154,7 @@ build_anon_union_vars (tree type, tree object)
tree base;
decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
+ DECL_ANON_UNION_VAR_P (decl) = 1;
base = get_base_address (object);
TREE_PUBLIC (decl) = TREE_PUBLIC (base);
@@ -1147,15 +1251,33 @@ coerce_new_type (tree type)
error ("% must return type %qT", ptr_type_node);
}
- if (!args || args == void_list_node
- || !same_type_p (TREE_VALUE (args), size_type_node))
+ if (args && args != void_list_node)
{
- e = 2;
- if (args && args != void_list_node)
- args = TREE_CHAIN (args);
- pedwarn ("% takes type % (%qT) "
- "as first parameter", size_type_node);
+ if (TREE_PURPOSE (args))
+ {
+ /* [basic.stc.dynamic.allocation]
+
+ The first parameter shall not have an associated default
+ argument. */
+ error ("the first parameter of % cannot "
+ "have a default argument");
+ /* Throw away the default argument. */
+ TREE_PURPOSE (args) = NULL_TREE;
+ }
+
+ if (!same_type_p (TREE_VALUE (args), size_type_node))
+ {
+ e = 2;
+ args = TREE_CHAIN (args);
+ }
}
+ else
+ e = 2;
+
+ if (e == 2)
+ pedwarn ("% takes type % (%qT) "
+ "as first parameter", size_type_node);
+
switch (e)
{
case 2:
@@ -1210,6 +1332,9 @@ coerce_delete_type (tree type)
return type;
}
+/* DECL is a VAR_DECL for a vtable: walk through the entries in the vtable
+ and mark them as needed. */
+
static void
mark_vtable_entries (tree decl)
{
@@ -1562,7 +1687,7 @@ static int
type_visibility (tree type)
{
int vis = VISIBILITY_DEFAULT;
- walk_tree_without_duplicates (&type, min_vis_r, &vis);
+ cp_walk_tree_without_duplicates (&type, min_vis_r, &vis);
return vis;
}
@@ -1579,6 +1704,7 @@ constrain_visibility (tree decl, int visibility)
if (!DECL_EXTERN_C_P (decl))
{
TREE_PUBLIC (decl) = 0;
+ DECL_ONE_ONLY (decl) = 0;
DECL_INTERFACE_KNOWN (decl) = 1;
if (DECL_LANG_SPECIFIC (decl))
DECL_NOT_REALLY_EXTERN (decl) = 1;
@@ -1677,25 +1803,10 @@ determine_visibility (tree decl)
else
use_template = 0;
- /* Anything that is exported must have default visibility. */
- if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
- && lookup_attribute ("dllexport",
- TREE_CODE (decl) == TYPE_DECL
- ? TYPE_ATTRIBUTES (TREE_TYPE (decl))
- : DECL_ATTRIBUTES (decl)))
- {
- DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
- DECL_VISIBILITY_SPECIFIED (decl) = 1;
- }
-
/* If DECL is a member of a class, visibility specifiers on the
class can influence the visibility of the DECL. */
if (DECL_CLASS_SCOPE_P (decl))
class_type = DECL_CONTEXT (decl);
- else if (TREE_CODE (decl) == VAR_DECL
- && DECL_TINFO_P (decl)
- && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl))))
- class_type = TREE_TYPE (DECL_NAME (decl));
else
{
/* Not a class member. */
@@ -1724,6 +1835,19 @@ determine_visibility (tree decl)
but have no TEMPLATE_INFO, so don't try to check it. */
use_template = 0;
}
+ else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl)
+ && flag_visibility_ms_compat)
+ {
+ /* Under -fvisibility-ms-compat, types are visible by default,
+ even though their contents aren't. */
+ tree underlying_type = TREE_TYPE (DECL_NAME (decl));
+ int underlying_vis = type_visibility (underlying_type);
+ if (underlying_vis == VISIBILITY_ANON
+ || CLASSTYPE_VISIBILITY_SPECIFIED (underlying_type))
+ constrain_visibility (decl, underlying_vis);
+ else
+ DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ }
else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl))
{
/* tinfo visibility is based on the type it's for. */
@@ -1781,7 +1905,8 @@ determine_visibility (tree decl)
{
/* Propagate anonymity from type to decl. */
int tvis = type_visibility (TREE_TYPE (decl));
- if (tvis == VISIBILITY_ANON)
+ if (tvis == VISIBILITY_ANON
+ || ! DECL_VISIBILITY_SPECIFIED (decl))
constrain_visibility (decl, tvis);
}
}
@@ -1792,18 +1917,20 @@ determine_visibility (tree decl)
static void
determine_visibility_from_class (tree decl, tree class_type)
{
+ if (DECL_VISIBILITY_SPECIFIED (decl))
+ return;
+
if (visibility_options.inlines_hidden
/* Don't do this for inline templates; specializations might not be
inline, and we don't want them to inherit the hidden
visibility. We'll set it here for all inline instantiations. */
&& !processing_template_decl
- && ! DECL_VISIBILITY_SPECIFIED (decl)
&& TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)
&& (! DECL_LANG_SPECIFIC (decl)
|| ! DECL_EXPLICIT_INSTANTIATION (decl)))
DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
- else if (!DECL_VISIBILITY_SPECIFIED (decl))
+ else
{
/* Default to the class visibility. */
DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
@@ -1822,7 +1949,6 @@ determine_visibility_from_class (tree decl, tree class_type)
&& !DECL_CONSTRUCTION_VTABLE_P (decl)))
&& TREE_PUBLIC (decl)
&& !DECL_REALLY_EXTERN (decl)
- && !DECL_VISIBILITY_SPECIFIED (decl)
&& !CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
targetm.cxx.determine_class_data_visibility (decl);
}
@@ -1850,13 +1976,16 @@ constrain_class_visibility (tree type)
for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
if (TREE_CODE (t) == FIELD_DECL && TREE_TYPE (t) != error_mark_node)
{
- tree ftype = strip_array_types (TREE_TYPE (t));
+ tree ftype = strip_pointer_or_array_types (TREE_TYPE (t));
int subvis = type_visibility (ftype);
if (subvis == VISIBILITY_ANON)
- warning (0, "\
+ {
+ if (!in_main_input_context ())
+ warning (0, "\
%qT has a field %qD whose type uses the anonymous namespace",
- type, t);
+ type, t);
+ }
else if (IS_AGGR_TYPE (ftype)
&& vis < VISIBILITY_HIDDEN
&& subvis >= VISIBILITY_HIDDEN)
@@ -1871,9 +2000,12 @@ constrain_class_visibility (tree type)
int subvis = type_visibility (TREE_TYPE (t));
if (subvis == VISIBILITY_ANON)
- warning (0, "\
+ {
+ if (!in_main_input_context())
+ warning (0, "\
%qT has a base %qT whose type uses the anonymous namespace",
- type, TREE_TYPE (t));
+ type, TREE_TYPE (t));
+ }
else if (vis < VISIBILITY_HIDDEN
&& subvis >= VISIBILITY_HIDDEN)
warning (OPT_Wattributes, "\
@@ -2098,7 +2230,8 @@ import_export_decl (tree decl)
{
/* DECL is an implicit instantiation of a function or static
data member. */
- if (flag_implicit_templates
+ if ((flag_implicit_templates
+ && !flag_use_repository)
|| (flag_implicit_inline_templates
&& TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)))
@@ -2176,10 +2309,7 @@ build_cleanup (tree decl)
if (TREE_CODE (type) == ARRAY_TYPE)
temp = decl;
else
- {
- cxx_mark_addressable (decl);
- temp = build1 (ADDR_EXPR, build_pointer_type (type), decl);
- }
+ temp = build_address (decl);
temp = build_delete (TREE_TYPE (temp), temp,
sfk_complete_destructor,
LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
@@ -2213,6 +2343,8 @@ get_guard (tree decl)
DECL_ONE_ONLY (guard) = DECL_ONE_ONLY (decl);
if (TREE_PUBLIC (decl))
DECL_WEAK (guard) = DECL_WEAK (decl);
+ DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
+ DECL_VISIBILITY_SPECIFIED (guard) = DECL_VISIBILITY_SPECIFIED (decl);
DECL_ARTIFICIAL (guard) = 1;
DECL_IGNORED_P (guard) = 1;
@@ -2319,9 +2451,11 @@ start_objects (int method_type, int initp)
void_list_node));
start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED);
- /* It can be a static function as long as collect2 does not have
- to scan the object file to find its ctor/dtor routine. */
- TREE_PUBLIC (current_function_decl) = ! targetm.have_ctors_dtors;
+ TREE_PUBLIC (current_function_decl) = 0;
+
+ /* Mark as artificial because it's not explicitly in the user's
+ source code. */
+ DECL_ARTIFICIAL (current_function_decl) = 1;
/* Mark this declaration as used to avoid spurious warnings. */
TREE_USED (current_function_decl) = 1;
@@ -2349,23 +2483,19 @@ finish_objects (int method_type, int initp, tree body)
/* Finish up. */
finish_compound_stmt (body);
fn = finish_function (0);
- expand_or_defer_fn (fn);
- /* When only doing semantic analysis, and no RTL generation, we
- can't call functions that directly emit assembly code; there is
- no assembly file in which to put the code. */
- if (flag_syntax_only)
- return;
-
- if (targetm.have_ctors_dtors)
+ if (method_type == 'I')
{
- rtx fnsym = XEXP (DECL_RTL (fn), 0);
- cgraph_mark_needed_node (cgraph_node (fn));
- if (method_type == 'I')
- (* targetm.asm_out.constructor) (fnsym, initp);
- else
- (* targetm.asm_out.destructor) (fnsym, initp);
+ DECL_STATIC_CONSTRUCTOR (fn) = 1;
+ decl_init_priority_insert (fn, initp);
+ }
+ else
+ {
+ DECL_STATIC_DESTRUCTOR (fn) = 1;
+ decl_fini_priority_insert (fn, initp);
}
+
+ expand_or_defer_fn (fn);
}
/* The names of the parameters to the function created to handle
@@ -2898,8 +3028,7 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
Here we must deal with member pointers. */
tree
-cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
- tree from ATTRIBUTE_UNUSED)
+cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED)
{
tree t = *tp;
@@ -3289,8 +3418,6 @@ cp_write_global_declarations (void)
if (priority_info_map)
splay_tree_delete (priority_info_map);
- c_build_cdtor_fns ();
-
/* Generate any missing aliases. */
maybe_apply_pending_pragma_weaks ();
@@ -3373,9 +3500,9 @@ build_offset_ref_call_from_tree (tree fn, tree args)
parameter. That must be done before the FN is transformed
because we depend on the form of FN. */
args = build_non_dependent_args (args);
+ object = build_non_dependent_expr (object);
if (TREE_CODE (fn) == DOTSTAR_EXPR)
object = build_unary_op (ADDR_EXPR, object, 0);
- object = build_non_dependent_expr (object);
args = tree_cons (NULL_TREE, object, args);
/* Now that the arguments are done, transform FN. */
fn = build_non_dependent_expr (fn);