* decl.c (lookup_namespace_name): Handle getting a
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 May 1999 00:20:07 +0000 (00:20 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 May 1999 00:20:07 +0000 (00:20 +0000)
TEMPLATE_ID_EXPR.
(expand_static_init): Don't call pushdecl for implicitly declared
`atexit' used to register destructors.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@27207 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/g++.old-deja/g++.ns/template10.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/debug3.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/static5.C [new file with mode: 0644]

index 32de5b1..301199a 100644 (file)
@@ -1,3 +1,10 @@
+1999-05-28  Mark Mitchell  <mark@codesourcery.com>
+
+       * decl.c (lookup_namespace_name): Handle getting a
+       TEMPLATE_ID_EXPR.
+       (expand_static_init): Don't call pushdecl for implicitly declared
+       `atexit' used to register destructors.
+
 1999-05-25  Mark Mitchell  <mark@codesourcery.com>
 
        * class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to
index d990a82..0b2d588 100644 (file)
@@ -5326,6 +5326,7 @@ lookup_namespace_name (namespace, name)
 {
   struct tree_binding _b;
   tree val;
+  tree template_id = NULL_TREE;
 
   my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
 
@@ -5342,6 +5343,16 @@ lookup_namespace_name (namespace, name)
 
   namespace = ORIGINAL_NAMESPACE (namespace);
 
+  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+    {
+      template_id = name;
+      name = TREE_OPERAND (name, 0);
+      if (TREE_CODE (name) == OVERLOAD)
+       name = DECL_NAME (OVL_CURRENT (name));
+      else if (TREE_CODE_CLASS (TREE_CODE (name)) == 'd')
+       name = DECL_NAME (name);
+    }
+
   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
   
   val = binding_init (&_b);
@@ -5352,6 +5363,26 @@ lookup_namespace_name (namespace, name)
     {
       val = BINDING_VALUE (val);
 
+      if (template_id)
+       {
+         if (DECL_CLASS_TEMPLATE_P (val))
+           val = lookup_template_class (val, 
+                                        TREE_OPERAND (template_id, 1),
+                                        /*in_decl=*/NULL_TREE,
+                                        /*context=*/NULL_TREE,
+                                        /*entering_scope=*/0);
+         else if (DECL_FUNCTION_TEMPLATE_P (val)
+                  || TREE_CODE (val) == OVERLOAD)
+           val = lookup_template_function (val, 
+                                           TREE_OPERAND (template_id, 1));
+         else
+           {
+             cp_error ("`%D::%D' is not a template",
+                       namespace, name);
+             return error_mark_node;
+           }
+       }
+
       /* If we have a single function from a using decl, pull it out.  */
       if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
        val = OVL_FUNCTION (val);
@@ -8479,11 +8510,16 @@ expand_static_init (decl, init)
              pfvlist = tree_cons (NULL_TREE, PFV, void_list_node);
 
              push_lang_context (lang_name_c);
+             /* Note that we do not call pushdecl for this function;
+                there's no reason that this declaration should be
+                accessible to anyone.  */
              atexit_fndecl
-               = builtin_function ("atexit",
-                                   build_function_type (void_type_node,
-                                                        pfvlist),
-                                   NOT_BUILT_IN, NULL_PTR);
+               = define_function ("atexit",
+                                  build_function_type (void_type_node,
+                                                       pfvlist),
+                                  NOT_BUILT_IN, 
+                                  /*pfn=*/0,
+                                  NULL_PTR);
              mark_used (atexit_fndecl);
              Atexit = default_conversion (atexit_fndecl);
              pop_lang_context ();
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/template10.C b/gcc/testsuite/g++.old-deja/g++.ns/template10.C
new file mode 100644 (file)
index 0000000..709844e
--- /dev/null
@@ -0,0 +1,7 @@
+// Build don't link:
+// Origin: Manuel Menezes de Sequeira <mms@torga.iscte.pt>
+
+namespace N {
+  template <class T> void g() {}
+}
+void (*pf)() = N::g<int>;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/debug3.C b/gcc/testsuite/g++.old-deja/g++.other/debug3.C
new file mode 100644 (file)
index 0000000..d1c8cf7
--- /dev/null
@@ -0,0 +1,22 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+// Special g++ Options: -O2
+
+struct S
+{
+  ~S();
+};
+
+inline void f()
+{
+  static S s;
+}
+
+typedef void (*fn_t)();
+
+fn_t g()
+{
+  return &f;
+}
+
+
diff --git a/gcc/testsuite/g++.old-deja/g++.other/static5.C b/gcc/testsuite/g++.old-deja/g++.other/static5.C
new file mode 100644 (file)
index 0000000..aedecf2
--- /dev/null
@@ -0,0 +1,16 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+struct S
+{
+  ~S();
+};
+
+inline void f()
+{
+  static S s;
+  atexit (0); // ERROR - implicit declaration
+}
+
+
+