OSDN Git Service

d
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Apr 1998 20:36:47 +0000 (20:36 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Apr 1998 20:36:47 +0000 (20:36 +0000)
Thu Apr  9 22:16:57 1998  Per Bothner  <bothner@cygnus.com>
        * cp-tree.h (start_decl):  Update prototype.
        * decl.c (start_decl):  Like the C version, new parameters
        for the attributes.  Call cplus_decl_attributes here,
        (pushdecl):  Like C version, do build_type_copy if TYPE_DECL,
        (grokdeclarator):  Pass NULL for new start_decl arguments.
        * pt.c (tsubst_expr):  Likewise.
        * parse.y:  Merge cplus_decl_attribute calls into start_decl calls.
* typeck.c (common_type): Check TYPE_MAIN_VARIANT.
* lex.c (build_lang_decl): Add lang_name_java.
* class.c (push_lang_context): Add lang_name_java.
* method.c (build_mangled_name): Check for is_java_type.
Thu Apr  9 22:16:57 1998  Benjamin Kosnik  <bkoz@loony.cygnus.com>
* decl.c (grokdeclarator): Check TYPE_MAIN_VARIANT.
* call.c (build_scoped_method_call): Check for TREE_CODE for
VOID_TYPE instead of type ==  void_type_node.
(build_method_call): Ditto.
* decl.c (lookup_name_real): Ditto.
(grokdeclarator): Ditto.
(start_decl): Ditto.
(grokparms): Ditto.
(start_function): Ditto.
(finish_function): Ditto.
(start_method): Ditto.
also fixes g++/15415

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

gcc/cp/call.c
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c

index d001331..1c50b7e 100644 (file)
@@ -382,11 +382,12 @@ build_scoped_method_call (exp, basetype, name, parms)
      and template parms.  */
   if (TREE_CODE (name) == BIT_NOT_EXPR && ! IS_AGGR_TYPE (basetype))
     {
-      if (type != basetype)
+      if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype))
        cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
                  exp, basetype, type);
       name = TREE_OPERAND (name, 0);
-      if (basetype != name && basetype != get_type_value (name))
+      if (TYPE_MAIN_VARIANT (basetype) != name 
+         && basetype != get_type_value (name))
        cp_error ("qualified type `%T' does not match destructor name `~%T'",
                  basetype, name);
       return cp_convert (void_type_node, exp);
@@ -630,7 +631,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
       basetype = TREE_TYPE (instance);
       if (TREE_CODE (basetype) == REFERENCE_TYPE)
        basetype = TREE_TYPE (basetype);
-      if (! (name == basetype
+      if (! (name == TYPE_MAIN_VARIANT (basetype)
             || (IS_AGGR_TYPE (basetype)
                 && name == constructor_name (basetype))
             || basetype == get_type_value (name)))
index c2d6b05..5c4be24 100644 (file)
@@ -131,7 +131,7 @@ tree *current_lang_base, *current_lang_stack;
 int current_lang_stacksize;
 
 /* Names of languages we recognize.  */
-tree lang_name_c, lang_name_cplusplus;
+tree lang_name_c, lang_name_cplusplus, lang_name_java;
 tree current_lang_name;
 
 /* When layout out an aggregate type, the size of the
@@ -4886,7 +4886,7 @@ push_lang_context (name)
       current_lang_stacksize += 10;
     }
 
-  if (name == lang_name_cplusplus)
+  if (name == lang_name_cplusplus || name == lang_name_java)
     {
       strict_prototype = strict_prototypes_lang_cplusplus;
       current_lang_name = name;
index 32009a9..a71a768 100644 (file)
@@ -3286,22 +3286,25 @@ pushdecl (x)
       else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_CONTEXT (x) == NULL_TREE)
        return push_overloaded_decl (x, 0);
 
-      /* If declaring a type as a typedef, and the type has no known
-        typedef name, install this TYPE_DECL as its typedef name.  */
+      /* If declaring a type as a typedef, copy the type (unless we're
+        at line 0), and install this TYPE_DECL as the new type's typedef
+        name.  See the extensive comment in ../c-decl.c (pushdecl). */
       if (TREE_CODE (x) == TYPE_DECL)
        {
          tree type = TREE_TYPE (x);
-         tree name = (type != error_mark_node) ? TYPE_NAME (type) : x;
-
-         if (name == NULL_TREE || TREE_CODE (name) != TYPE_DECL)
-           {
-             /* If these are different names, and we're at the global
-                binding level, make two equivalent definitions.  */
-              name = x;
-              if (global_bindings_p ())
-                TYPE_NAME (type) = x;
-           }
-         my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140);
+          if (DECL_SOURCE_LINE (x) == 0)
+            {
+             if (TYPE_NAME (type) == 0)
+               TYPE_NAME (type) = x;
+            }
+          else if (type != error_mark_node && TYPE_NAME (type) != x)
+            {
+             DECL_ORIGINAL_TYPE (x) = type;
+              type = build_type_copy (type);
+             TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
+              TYPE_NAME (type) = x;
+              TREE_TYPE (x) = type;
+            }
 
          if (type != error_mark_node
              && TYPE_NAME (type)
@@ -4615,7 +4618,7 @@ lookup_name_real (name, prefer_type, nonclass)
 
          type = complete_type (type);
 
-         if (type == void_type_node)
+         if (TREE_CODE (type) == VOID_TYPE)
            val = IDENTIFIER_GLOBAL_VALUE (name);
          else if (TREE_CODE (type) == NAMESPACE_DECL)
            {
@@ -4954,6 +4957,7 @@ init_decl_processing ()
   /* Have to make these distinct before we try using them.  */
   lang_name_cplusplus = get_identifier ("C++");
   lang_name_c = get_identifier ("C");
+  lang_name_java = get_identifier ("Java");
 
   /* enter the global namespace */
   my_friendly_assert (global_namespace == NULL_TREE, 375);
@@ -5862,9 +5866,10 @@ groktypename (typename)
 int debug_temp_inits = 1;
 
 tree
-start_decl (declarator, declspecs, initialized)
+start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
      tree declarator, declspecs;
      int initialized;
+     tree attributes, prefix_attributes;
 {
   register tree decl;
   register tree type, tem;
@@ -5887,7 +5892,7 @@ start_decl (declarator, declspecs, initialized)
 
   decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
                         NULL_TREE);
-  if (decl == NULL_TREE || decl == void_type_node)
+  if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
     return NULL_TREE;
 
   type = TREE_TYPE (decl);
@@ -6029,6 +6034,9 @@ start_decl (declarator, declspecs, initialized)
       pushclass (context, 2);
     }
 
+  /* Set attributes here so if duplicate decl, will have proper attributes.  */
+  cplus_decl_attributes (decl, attributes, prefix_attributes);
+
   /* Add this decl to the current binding level, but not if it
      comes from another scope, e.g. a static member variable.
      TEM may equal DECL or it may be a previous decl of the same name.  */
@@ -7825,7 +7833,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                *next = TREE_OPERAND (decl, 0);
                init = TREE_OPERAND (decl, 1);
 
-               decl = start_decl (declarator, declspecs, 1);
+               decl = start_decl (declarator, declspecs, 1, NULL_TREE, NULL_TREE);
                /* Look for __unused__ attribute */
                if (TREE_USED (TREE_TYPE (decl)))
                  TREE_USED (decl) = 1;
@@ -8387,7 +8395,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
   constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type);
   volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type);
-  type = TYPE_MAIN_VARIANT (type);
+  type = build_type_variant (type, 0, 0);
   staticp = 0;
   inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);
   virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
@@ -8642,7 +8650,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
            /* Check for some types that there cannot be arrays of.  */
 
-           if (TYPE_MAIN_VARIANT (type) == void_type_node)
+           if (TREE_CODE (type) == VOID_TYPE)
              {
                cp_error ("declaration of `%D' as array of voids", dname);
                type = error_mark_node;
@@ -9081,7 +9089,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                }
              else
                {
-                 if (TYPE_MAIN_VARIANT (type) == void_type_node)
+                 if (TREE_CODE (type) == VOID_TYPE)
                    error ("invalid type: `void &'");
                  else
                    type = build_reference_type (type);
@@ -9354,6 +9362,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          if (IS_SIGNATURE (current_class_type) && opaque_typedef)
            SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1;
        }
+      else if (current_lang_name == lang_name_java)
+       decl = build_lang_decl (TYPE_DECL, declarator, type);
       else
        decl = build_decl (TYPE_DECL, declarator, type);
 
@@ -9495,7 +9505,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
      We don't complain about parms either, but that is because
      a better error message can be made later.  */
 
-  if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM)
+  if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM)
     {
       if (! declarator)
        error ("unnamed variable or field declared void");
@@ -9537,7 +9547,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          type = build_pointer_type (type);
        else if (TREE_CODE (type) == OFFSET_TYPE)
          type = build_pointer_type (type);
-       else if (type == void_type_node && declarator)
+       else if (TREE_CODE (type) == VOID_TYPE && declarator)
          {
            error ("declaration of `%s' as void", name);
            return NULL_TREE;
@@ -10116,7 +10126,7 @@ grokparms (first_parm, funcdef_flag)
     }
   else if (first_parm != NULL_TREE
           && TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST
-          && TREE_VALUE (first_parm) != void_type_node)
+          && TREE_CODE (TREE_VALUE (first_parm)) != VOID_TYPE)
     my_friendly_abort (145);
   else
     {
@@ -10138,7 +10148,8 @@ grokparms (first_parm, funcdef_flag)
 
              chain = TREE_CHAIN (parm);
              /* @@ weak defense against parse errors.  */
-             if (decl != void_type_node && TREE_CODE (decl) != TREE_LIST)
+             if (TREE_CODE (decl) != VOID_TYPE 
+                 && TREE_CODE (decl) != TREE_LIST)
                {
                  /* Give various messages as the need arises.  */
                  if (TREE_CODE (decl) == STRING_CST)
@@ -10148,7 +10159,7 @@ grokparms (first_parm, funcdef_flag)
                  continue;
                }
 
-             if (decl != void_type_node)
+             if (TREE_CODE (decl) != VOID_TYPE)
                {
                  decl = grokdeclarator (TREE_VALUE (decl),
                                         TREE_PURPOSE (decl),
@@ -10157,7 +10168,7 @@ grokparms (first_parm, funcdef_flag)
                  if (! decl)
                    continue;
                  type = TREE_TYPE (decl);
-                 if (TYPE_MAIN_VARIANT (type) == void_type_node)
+                 if (TREE_CODE (type) == VOID_TYPE)
                    decl = void_type_node;
                  else if (TREE_CODE (type) == METHOD_TYPE)
                    {
@@ -10197,7 +10208,7 @@ grokparms (first_parm, funcdef_flag)
                     }
                }
 
-             if (decl == void_type_node)
+             if (TREE_CODE (decl) == VOID_TYPE)
                {
                  if (result == NULL_TREE)
                    {
@@ -10516,7 +10527,7 @@ grok_op_properties (decl, virtualp, friendp)
                cp_error ("`%D' must be either a non-static member function or a non-member function", decl);
 
              if (p)
-               for (; TREE_VALUE (p) != void_type_node ; p = TREE_CHAIN (p))
+               for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p))
                  {
                    tree arg = TREE_VALUE (p);
                    if (TREE_CODE (arg) == REFERENCE_TYPE)
@@ -11364,7 +11375,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
   int doing_friend = 0;
 
   /* Sanity check.  */
-  my_friendly_assert (TREE_VALUE (void_list_node) == void_type_node, 160);
+  my_friendly_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160);
   my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161);
 
   /* Assume, until we see it does.  */
@@ -11539,7 +11550,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
   /* Effective C++ rule 15.  See also c_expand_return.  */
   if (warn_ecpp
       && DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
-      && TREE_TYPE (fntype) == void_type_node)
+      && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
     cp_warning ("`operator=' should return a reference to `*this'");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
@@ -11797,7 +11808,7 @@ store_parm_decls ()
                {
                  pushdecl (parm);
                }
-             else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
+             else if (TREE_CODE (TREE_TYPE (parm)) == VOID_TYPE)
                cp_error ("parameter `%D' declared void", parm);
              else
                {
@@ -12250,8 +12261,7 @@ finish_function (lineno, call_poplevel, nested)
                }
              c_expand_return (current_class_ptr);
            }
-         else if (TYPE_MAIN_VARIANT (TREE_TYPE (
-                                                DECL_RESULT (current_function_decl))) != void_type_node
+         else if (TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) != VOID_TYPE
                   && return_label != NULL_RTX)
            no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
 
@@ -12490,7 +12500,7 @@ finish_function (lineno, call_poplevel, nested)
        cp_warning ("`noreturn' function `%D' does return", fndecl);
       else if ((warn_return_type || pedantic)
               && current_function_returns_null
-              && TYPE_MAIN_VARIANT (TREE_TYPE (fntype)) != void_type_node)
+              && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE)
        {
          /* If this function returns non-void and control can drop through,
             complain.  */
@@ -12582,7 +12592,7 @@ start_method (declspecs, declarator)
     return NULL_TREE;
 
   /* Pass friends other than inline friend functions back.  */
-  if (TYPE_MAIN_VARIANT (fndecl) == void_type_node)
+  if (fndecl == void_type_node)
     return fndecl;
 
   if (TREE_CODE (fndecl) != FUNCTION_DECL)
@@ -12673,7 +12683,7 @@ finish_method (decl)
 
   register tree link;
 
-  if (TYPE_MAIN_VARIANT (decl) == void_type_node)
+  if (decl == void_type_node)
     return decl;
 
   old_initial = DECL_INITIAL (fndecl);
index 6033300..74f0519 100644 (file)
@@ -4373,6 +4373,8 @@ build_lang_decl (code, name, type)
     DECL_LANGUAGE (t) = lang_cplusplus;
   else if (current_lang_name == lang_name_c)
     DECL_LANGUAGE (t) = lang_c;
+  else if (current_lang_name == lang_name_java)
+    DECL_LANGUAGE (t) = lang_java;
   else my_friendly_abort (64);
 
   SET_DECL_NAMESPACE (t, current_namespace);
index e8ed718..6e20848 100644 (file)
@@ -1044,7 +1044,8 @@ build_mangled_name (parmtypes, begin, end)
               /* Every argument gets counted.  */
               typevec[maxtype++] = parmtype;
 
-              if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2])
+              if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2]
+                 && ! is_java_type (parmtype))
                 {
                   Nrepeats++;
                   continue;
@@ -1067,9 +1068,10 @@ build_mangled_name (parmtypes, begin, end)
                 }
 
               /* Only cache types which take more than one character.  */
-              if (parmtype != TYPE_MAIN_VARIANT (parmtype)
-                  || (TREE_CODE (parmtype) != INTEGER_TYPE
-                      && TREE_CODE (parmtype) != REAL_TYPE))
+              if ((parmtype != TYPE_MAIN_VARIANT (parmtype)
+                  || (TREE_CODE (parmtype) != INTEGER_TYPE
+                      && TREE_CODE (parmtype) != REAL_TYPE))
+                 && ! is_java_type (parmtype))
                 TREE_USED (parmtype) = 1;
             }
         if (TYPE_PTRMEMFUNC_P (parmtype))
@@ -1113,14 +1115,34 @@ process_modifiers (parmtype)
 
   if (TREE_READONLY (parmtype))
     OB_PUTC ('C');
-  if (TREE_CODE (parmtype) == INTEGER_TYPE && 
-             TYPE_MAIN_VARIANT (parmtype) == 
-                            unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
-    OB_PUTC ('U');
+  if (TREE_CODE (parmtype) == INTEGER_TYPE
+      && (TYPE_MAIN_VARIANT (parmtype)
+         == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
+      && ! is_java_type (parmtype))
+    {
+      OB_PUTC ('U');
+    }
   if (TYPE_VOLATILE (parmtype))
     OB_PUTC ('V');
 }
 
+/* True iff TYPE was declared as a "Java" type (inside extern "Java"). */
+
+int
+is_java_type (type)
+     tree type;
+{
+  if (TYPE_NAME (type) != NULL_TREE)
+    {
+      tree decl = TYPE_NAME (type);
+      if (TREE_CODE (decl) == TYPE_DECL
+         && DECL_LANG_SPECIFIC (decl) != NULL
+         && DECL_LANGUAGE (decl) == lang_java)
+       return 1;
+    }
+  return 0;
+}
+
 /* Check to see if a tree node has been entered into the Bcode typelist 
    if not, add it. Otherwise emit the code and return TRUE */
 static int 
@@ -1292,6 +1314,30 @@ process_overload_item (parmtype, extra_Gcode)
       }
 
     case INTEGER_TYPE:
+      /* "Java" integer types should mangle the same on all platforms,
+        and only depend on precision, not target 'int' size. */
+      if (is_java_type (parmtype))
+       {
+         if (TREE_UNSIGNED (parmtype))
+           {
+             switch (TYPE_PRECISION (parmtype))
+               {
+               case  8:  OB_PUTC ('b');  return;
+               case 16:  OB_PUTC ('w');  return;
+               }
+           }
+         else
+           {
+             switch (TYPE_PRECISION (parmtype))
+               {
+               case  8:  OB_PUTC ('c');  return;
+               case 16:  OB_PUTC ('s');  return;
+               case 32:  OB_PUTC ('i');  return;
+               case 64:  OB_PUTC ('x');  return;
+               }
+           }
+       }
+
       parmtype = TYPE_MAIN_VARIANT (parmtype);
       if (parmtype == integer_type_node
           || parmtype == unsigned_type_node)
index a471c82..7e79685 100644 (file)
@@ -318,8 +318,8 @@ parse_decl(declarator, specs_attrs, attributes, initialized, decl)
       used_extern_spec = 1;
     }
   sm = suspend_momentary ();
-  *decl = start_decl (declarator, current_declspecs, initialized);
-  cplus_decl_attributes (*decl, attributes, prefix_attributes);
+  *decl = start_decl (declarator, current_declspecs, initialized,
+                     attributes, prefix_attributes);
   return sm;
 }
 %}
@@ -942,9 +942,8 @@ condition:
                  }
                  current_declspecs = $1.t;
                  $<itype>5 = suspend_momentary ();
-                 $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1);
-                 cplus_decl_attributes ($<ttype>$, $4,
-                                        /*prefix_attributes*/ NULL_TREE);
+                 $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1,
+                                         $4, /*prefix_attributes*/ NULL_TREE);
                }
          init
                { 
@@ -1769,14 +1768,14 @@ maybeasm:
 
 initdcl:
          declarator maybeasm maybe_attribute '='
-               { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1);
-                 cplus_decl_attributes ($<ttype>$, $3, prefix_attributes); }
+               { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1,
+                                         $3, prefix_attributes); }
          init
 /* Note how the declaration of the variable is in effect while its init is parsed! */
                { cp_finish_decl ($<ttype>5, $6, $2, 1, LOOKUP_ONLYCONVERTING); }
        | declarator maybeasm maybe_attribute
-               { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0);
-                 cplus_decl_attributes ($<ttype>$, $3, prefix_attributes);
+               { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0,
+                                         $3, prefix_attributes);
                  cp_finish_decl ($<ttype>$, NULL_TREE, $2, 1, 0); }
        ;
 
index 1c632f7..4a7512e 100644 (file)
@@ -5014,7 +5014,7 @@ tsubst_expr (t, args, in_decl)
        dcl = start_decl
          (tsubst (TREE_OPERAND (t, 0), args, in_decl),
           tsubst (TREE_OPERAND (t, 1), args, in_decl),
-          TREE_OPERAND (t, 2) != 0);
+          TREE_OPERAND (t, 2) != 0, NULL_TREE, NULL_TREE);
        init = tsubst_expr (TREE_OPERAND (t, 2), args, in_decl);
        cp_finish_decl
          (dcl, init, NULL_TREE, 1, /*init ? LOOKUP_ONLYCONVERTING :*/ 0);