aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-04-26 01:27:09 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-04-26 01:27:09 +0000
commitea56c40c484e89e5a67f71a2c90a1ad645c89540 (patch)
treef5a8e8bd5875fafd17ed7be1c1529abe30e283e6
parentab409f1be9b3b60c3cc8ffed32e4201f50019a28 (diff)
downloadgcc-ea56c40c484e89e5a67f71a2c90a1ad645c89540.zip
gcc-ea56c40c484e89e5a67f71a2c90a1ad645c89540.tar.gz
gcc-ea56c40c484e89e5a67f71a2c90a1ad645c89540.tar.bz2
decl2.c (finish_file): Don't call import_export_decl for functions that are not defined.
* decl2.c (finish_file): Don't call import_export_decl for functions that are not defined. (handle_class_head): Robustify. * pt.c (instantiate_decl): Do not call cp_finish_decl for variables that are not defined. * g++.old-deja/g++.pt/instantiate12.C: Explicit instantiate initialized static data members. From-SVN: r66095
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/decl2.c18
-rw-r--r--gcc/cp/pt.c43
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C10
5 files changed, 71 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f246bee..e4b5602 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2003-04-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_file): Don't call import_export_decl for
+ functions that are not defined.
+ (handle_class_head): Robustify.
+ * pt.c (instantiate_decl): Do not call cp_finish_decl for
+ variables that are not defined.
+
2003-04-24 Sylvain Pion <Sylvain.Pion@mpi-sb.mpg.de>
* call.c (print_z_candidates): Fix off by one error.
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 3f9c66f..a52bdaa 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2730,9 +2730,7 @@ finish_file ()
for (i = 0; i < deferred_fns_used; ++i)
{
tree decl = VARRAY_TREE (deferred_fns, i);
-
- import_export_decl (decl);
-
+
/* Does it need synthesizing? */
if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
&& TREE_USED (decl)
@@ -2749,6 +2747,15 @@ finish_file ()
reconsider = true;
}
+ /* If the function has no body, avoid calling
+ import_export_decl. On a system without weak symbols,
+ calling import_export_decl will make an inline template
+ instantiation "static", which will result in errors about
+ the use of undefined functions if there is no body for
+ the function. */
+ if (!DECL_SAVED_TREE (decl))
+ continue;
+
/* We lie to the back-end, pretending that some functions
are not defined when they really are. This keeps these
functions from being put out unnecessarily. But, we must
@@ -4668,7 +4675,10 @@ handle_class_head (enum tag_types tag_kind, tree scope, tree id,
if (!decl)
{
- decl = TYPE_MAIN_DECL (xref_tag (tag_kind, id, attributes, false));
+ decl = xref_tag (tag_kind, id, attributes, false);
+ if (decl == error_mark_node)
+ return error_mark_node;
+ decl = TYPE_MAIN_DECL (decl);
xrefd_p = true;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 74f497e..9faf035 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10927,11 +10927,6 @@ instantiate_decl (d, defer_ok)
if (need_push)
push_to_top_level ();
- /* We're now committed to instantiating this template. Mark it as
- instantiated so that recursive calls to instantiate_decl do not
- try to instantiate it again. */
- DECL_TEMPLATE_INSTANTIATED (d) = 1;
-
/* Regenerate the declaration in case the template has been modified
by a subsequent redeclaration. */
regenerate_decl_from_template (d, td);
@@ -10950,10 +10945,36 @@ instantiate_decl (d, defer_ok)
DECL_IN_AGGR_P (d) = 0;
import_export_decl (d);
DECL_EXTERNAL (d) = ! DECL_NOT_REALLY_EXTERN (d);
- cp_finish_decl (d,
- (!DECL_INITIALIZED_IN_CLASS_P (d)
- ? DECL_INITIAL (d) : NULL_TREE),
- NULL_TREE, 0);
+
+ if (DECL_EXTERNAL (d))
+ {
+ /* The fact that this code is executing indicates that:
+
+ (1) D is a template static data member, for which a
+ definition is available.
+
+ (2) An implicit or explicit instantiation has occured.
+
+ (3) We are not going to emit a definition of the static
+ data member at this time.
+
+ This situation is peculiar, but it occurs on platforms
+ without weak symbols when performing an implicit
+ instantiation. There, we cannot implicitly instantiate a
+ defined static data member in more than one translation
+ unit, so import_export_decl marks the declaration as
+ external; we must rely on explicit instantiation. */
+ }
+ else
+ {
+ /* Mark D as instantiated so that recursive calls to
+ instantiate_decl do not try to instantiate it again. */
+ DECL_TEMPLATE_INSTANTIATED (d) = 1;
+ cp_finish_decl (d,
+ (!DECL_INITIALIZED_IN_CLASS_P (d)
+ ? DECL_INITIAL (d) : NULL_TREE),
+ NULL_TREE, 0);
+ }
}
else if (TREE_CODE (d) == FUNCTION_DECL)
{
@@ -10962,6 +10983,10 @@ instantiate_decl (d, defer_ok)
tree tmpl_parm;
tree spec_parm;
+ /* Mark D as instantiated so that recursive calls to
+ instantiate_decl do not try to instantiate it again. */
+ DECL_TEMPLATE_INSTANTIATED (d) = 1;
+
/* Save away the current list, in case we are instantiating one
template from within the body of another. */
saved_local_specializations = local_specializations;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bfc4ff2..2590adf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-04-25 Mark Mitchell <mark@codesourcery.com>
+
+ * g++.old-deja/g++.pt/instantiate12.C: Explicit instantiate
+ initialized static data members.
+
2003-04-25 H.J. Lu <hjl@gnu.org>
* gcc.dg/ia64-sync-4.c: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C b/gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C
index e1cc853..ce1efe0 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C
@@ -48,3 +48,13 @@ int main ()
return 9;
return 0;
}
+
+// On platforms that do not have weak symbols, these static data
+// members must be explicitly instantiated. The iflag and jflag data
+// members should not have to be explicitly instantiated because their
+// const-ness should allow the compiler to elide references to the
+// actual variables.
+template const bool X<int>::cflag;
+template const bool X<int>::flag;
+template const bool X<float>::cflag;
+template const bool X<float>::flag;