Patch for COMPLEX support (part 1)

Weiwen Liu weiwen.liu@yale.edu
Wed Jan 7 17:22:00 GMT 1998


Wed Jan  7 17:23:00 1998  Weiwen Liu <liu@hepunix.physics.yale.edu>

        * c-common.c (type_for_mode): Add complex_{integer, long_integer,
	long_long_integer}_type_node support.
	* c-decl.c: Likewise.
	* c-lex.c: Likewise.
	* c-tree.h: Likewise.
	* c-typeck.c: Likewise.
	* cp/cp-tree.h: Likewise.
	* cp/decl.c: Likewise.

--- gcc/c-common.c.orig	Sat Dec  6 12:18:57 1997
+++ gcc/c-common.c	Tue Jan  6 17:26:46 1998
@@ -1889,6 +1889,21 @@ type_for_mode (mode, unsignedp)
   if (mode == TYPE_MODE (intDI_type_node))
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
 
+  if (mode == TYPE_MODE (complex_integer_type_node))
+    return complex_integer_type_node;
+
+  if (mode == TYPE_MODE (complex_long_integer_type_node))
+    return complex_long_integer_type_node;
+
+  if (mode == TYPE_MODE (complex_long_long_integer_type_node))
+    return complex_long_long_integer_type_node;
+
+  if (mode == TYPE_MODE (complex_float_type_node))
+    return complex_float_type_node;
+
+  if (mode == TYPE_MODE (complex_double_type_node))
+    return complex_double_type_node;
+
   if (mode == TYPE_MODE (float_type_node))
     return float_type_node;
 
--- gcc/c-decl.c.orig	Sun Dec 21 10:24:43 1997
+++ gcc/c-decl.c	Tue Jan  6 17:26:48 1998
@@ -135,6 +135,8 @@ tree double_type_node;
 tree long_double_type_node;
 
 tree complex_integer_type_node;
+tree complex_long_integer_type_node;
+tree complex_long_long_integer_type_node;
 tree complex_float_type_node;
 tree complex_double_type_node;
 tree complex_long_double_type_node;
@@ -1647,7 +1649,9 @@ duplicate_decls (newdecl, olddecl, diffe
 		}
 
 	      if (TYPE_MAIN_VARIANT (type) == float_type_node
-		  || C_PROMOTING_INTEGER_TYPE_P (type))
+		  || C_PROMOTING_INTEGER_TYPE_P (type)
+		  || (TREE_CODE (type) == COMPLEX_TYPE
+		      && C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (type))))
 		{
 		  error ("An argument type that has a default promotion");
 		  error ("can't match an empty parameter name list declaration.");
@@ -3028,6 +3032,18 @@ init_decl_processing ()
   TREE_TYPE (complex_integer_type_node) = integer_type_node;
   layout_type (complex_integer_type_node);
 
+  complex_long_integer_type_node = make_node (COMPLEX_TYPE);
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long int"),
+			complex_long_integer_type_node));
+  TREE_TYPE (complex_long_integer_type_node) = long_integer_type_node;
+  layout_type (complex_long_integer_type_node);
+
+  complex_long_long_integer_type_node = make_node (COMPLEX_TYPE);
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long long int"),
+			complex_long_long_integer_type_node));
+  TREE_TYPE (complex_long_long_integer_type_node) = long_long_integer_type_node;
+  layout_type (complex_long_long_integer_type_node);
+
   complex_float_type_node = make_node (COMPLEX_TYPE);
   pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
 			complex_float_type_node));
@@ -4536,6 +4552,10 @@ grokdeclarator (declarator, declspecs, d
 	type = complex_double_type_node;
       else if (type == integer_type_node)
 	type = complex_integer_type_node;
+      else if (type == long_integer_type_node)
+	type = complex_long_integer_type_node;
+      else if (type == long_long_integer_type_node)
+	type = complex_long_long_integer_type_node;
       else if (type == float_type_node)
 	type = complex_float_type_node;
       else if (type == double_type_node)
@@ -5073,6 +5093,11 @@ grokdeclarator (declarator, declspecs, d
 	    else
 	      DECL_ARG_TYPE (decl) = integer_type_node;
 	  }
+	else if (TREE_CODE (main_type) == COMPLEX_TYPE
+		 && C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (main_type)))
+	  {
+	      DECL_ARG_TYPE (decl) = complex_integer_type_node;
+	  }
 
 	DECL_ARG_TYPE_AS_WRITTEN (decl) = type_as_written;
       }
@@ -5454,6 +5479,11 @@ get_parm_info (void_at_end)
 	     || TREE_CODE (type) == ENUMERAL_TYPE)
 	    && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
 	  DECL_ARG_TYPE (decl) = integer_type_node;
+	else if (TREE_CODE (type) == COMPLEX_TYPE
+                 && GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (type))) == MODE_INT
+                 && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)))
+                 < GET_MODE_SIZE (SImode))
+          DECL_ARG_TYPE (decl) = complex_integer_type_node;
 #endif
 
 	types = saveable_tree_cons (NULL_TREE, TREE_TYPE (decl), types);
@@ -6454,6 +6484,12 @@ start_function (declspecs, declarator, p
       else
 	restype = integer_type_node;
     }
+  /* Promote COMPLEX integer value before returning it. */
+  else if (TREE_CODE (restype) == COMPLEX_TYPE
+	   && C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (restype)))
+    {
+      restype = complex_integer_type_node;
+    }
   DECL_RESULT (current_function_decl)
     = build_decl (RESULT_DECL, NULL_TREE, restype);
 
@@ -6788,6 +6824,12 @@ store_parm_decls ()
 			  && TYPE_PRECISION (TREE_TYPE (parm))
 			  < TYPE_PRECISION (integer_type_node))
 			DECL_ARG_TYPE (parm) = integer_type_node;
+                      else if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
+                               && GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (parm))))
+                               == MODE_INT
+                               && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (parm))))
+                               < GET_MODE_SIZE (SImode))
+                        DECL_ARG_TYPE (parm) = complex_integer_type_node;
 #endif
 		      if (pedantic)
 			{
--- gcc/c-lex.c.orig	Sat Dec 20 06:31:15 1997
+++ gcc/c-lex.c	Tue Jan  6 17:26:48 1998
@@ -1829,6 +1829,18 @@ yylex ()
 		    = build_complex (NULL_TREE, integer_zero_node,
 				     convert (integer_type_node,
 					      yylval.ttype));
+		else if (TYPE_PRECISION (type)
+		    <= TYPE_PRECISION (long_integer_type_node))
+		  yylval.ttype
+		    = build_complex (NULL_TREE, integer_zero_node,
+				     convert (long_integer_type_node,
+					      yylval.ttype));
+		else if (TYPE_PRECISION (type)
+		    <= TYPE_PRECISION (long_long_integer_type_node))
+		  yylval.ttype
+		    = build_complex (NULL_TREE, integer_zero_node,
+				     convert (long_long_integer_type_node,
+					      yylval.ttype));
 		else
 		  error ("complex integer constant is too wide for `complex int'");
 	      }
--- gcc/c-tree.h.orig	Sun Nov  2 03:39:14 1997
+++ gcc/c-tree.h	Tue Jan  6 17:26:49 1998
@@ -219,6 +219,8 @@ extern tree long_long_integer_type_node;
 extern tree long_long_unsigned_type_node;
 extern tree long_unsigned_type_node;
 extern tree complex_integer_type_node;
+extern tree complex_long_integer_type_node;
+extern tree complex_long_long_integer_type_node;
 extern tree complex_float_type_node;
 extern tree complex_double_type_node;
 extern tree complex_long_double_type_node;
--- gcc/c-typeck.c.orig	Sat Dec 20 06:31:17 1997
+++ gcc/c-typeck.c	Tue Jan  6 17:26:50 1998
@@ -717,6 +717,10 @@ self_promoting_args_p (parms)
 
       if (C_PROMOTING_INTEGER_TYPE_P (type))
 	return 0;
+
+      if (TREE_CODE (type) == COMPLEX_TYPE
+	  && C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (type)))
+	return 0;
     }
   return 1;
 }
@@ -733,6 +737,10 @@ self_promoting_type_p (type)
   if (C_PROMOTING_INTEGER_TYPE_P (type))
     return 0;
 
+  if (TREE_CODE (type) == COMPLEX_TYPE
+      && C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (type)))
+    return 0;
+
   return 1;
 }
 
@@ -1058,6 +1066,11 @@ default_conversion (exp)
 	}
     }
 
+  if (code == COMPLEX_TYPE && C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (type)))
+    {
+      return convert (complex_integer_type_node, exp);
+    }
+  
   if (C_PROMOTING_INTEGER_TYPE_P (type))
     {
       /* Traditionally, unsignedness is preserved in default promotions.
@@ -1780,6 +1793,11 @@ convert_arguments (typelist, values, nam
 		   || TREE_CODE (type) == ENUMERAL_TYPE)
 		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
 		parmval = default_conversion (parmval);
+              else if (TREE_CODE (type) == COMPLEX_TYPE
+                       && GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (type))) == MODE_INT
+                       && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)))
+                       < GET_MODE_SIZE (SImode))
+                parmval = default_conversion (parmval);
 #endif
 	    }
 	  result = tree_cons (NULL_TREE, parmval, result);
--- gcc/cp/cp-tree.h.orig	Fri Dec 12 19:27:54 1997
+++ gcc/cp/cp-tree.h	Tue Jan  6 17:27:05 1998
@@ -137,6 +137,8 @@ extern tree wchar_array_type_node;
 extern tree wchar_type_node, signed_wchar_type_node, unsigned_wchar_type_node;
 
 extern tree complex_integer_type_node;
+extern tree complex_long_integer_type_node;
+extern tree complex_long_long_integer_type_node;
 extern tree complex_float_type_node;
 extern tree complex_double_type_node;
 extern tree complex_long_double_type_node;
--- gcc/cp/decl.c.orig	Thu Dec 18 11:45:28 1997
+++ gcc/cp/decl.c	Tue Jan  6 17:27:07 1998
@@ -217,6 +217,8 @@ tree double_type_node;
 tree long_double_type_node;
 
 tree complex_integer_type_node;
+tree complex_long_integer_type_node;
+tree complex_long_long_integer_type_node;
 tree complex_float_type_node;
 tree complex_double_type_node;
 tree complex_long_double_type_node;
@@ -4978,6 +4980,18 @@ init_decl_processing ()
   TREE_TYPE (complex_integer_type_node) = integer_type_node;
   layout_type (complex_integer_type_node);
 
+  complex_long_integer_type_node = make_node (COMPLEX_TYPE);
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long int"),
+			complex_long_integer_type_node));
+  TREE_TYPE (complex_long_integer_type_node) = long_integer_type_node;
+  layout_type (complex_long_integer_type_node);
+
+  complex_long_long_integer_type_node = make_node (COMPLEX_TYPE);
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long long int"),
+			complex_long_long_integer_type_node));
+  TREE_TYPE (complex_long_long_integer_type_node) = long_long_integer_type_node;
+  layout_type (complex_long_long_integer_type_node);
+
   complex_float_type_node = make_node (COMPLEX_TYPE);
   pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
 			complex_float_type_node));
@@ -8341,6 +8355,10 @@ grokdeclarator (declarator, declspecs, d
 	type = complex_double_type_node;
       else if (type == integer_type_node)
 	type = complex_integer_type_node;
+      else if (type == long_integer_type_node)
+	type = complex_long_integer_type_node;
+      else if (type == long_long_integer_type_node)
+	type = complex_long_long_integer_type_node;
       else if (type == float_type_node)
 	type = complex_float_type_node;
       else if (type == double_type_node)




More information about the Gcc mailing list