This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

(C++) patch to add -fms-extensions


For people forced to deal with MS code and are still interested in problems
in their own code.

1999-08-11  Jason Merrill  <jason@yorick.cygnus.com>

	* lang-options.h: Add -fms-extensions.
	* cp-tree.h: Declare flag_ms_extensions.
	* decl2.c: Define it.
	* class.c (instantiate_type): Don't complain about taking the address
	of a bound member function if -fms-extensions.
	* typeck.c (build_unary_op): Likewise.
	* decl.c (grokdeclarator): Or about implicit int.
	* init.c (resolve_offset_ref): Or about implicit '&'.

Index: invoke.texi
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/invoke.texi,v
retrieving revision 1.128
diff -c -p -r1.128 invoke.texi
*** invoke.texi	1999/08/07 07:51:09	1.128
--- invoke.texi	1999/08/12 06:49:59
*************** To save space, do not emit out-of-line c
*** 1083,1088 ****
--- 1083,1092 ----
  controlled by @samp{#pragma implementation}.  This will cause linker
  errors if these functions are not inlined everywhere they are called.
  
+ @item -fms-extensions
+ Disable pedwarns about constructs used in MFC, such as implicit int and
+ getting a pointer to member function via non-standard syntax.
+ 
  @item -fname-mangling-version-@var{n}
  Control the way in which names are mangled.  Version 0 is compatible
  with versions of g++ before 2.8.  Version 1 is the default.  Version 1
Index: class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.175
diff -c -p -r1.175 class.c
*** class.c	1999/08/09 14:00:18	1.175
--- class.c	1999/08/12 06:47:25
*************** instantiate_type (lhstype, rhs, flags)
*** 5145,5176 ****
  
      case COMPONENT_REF:
        {
! 	tree field = TREE_OPERAND (rhs, 1);
! 	tree r;
  
! 	r = instantiate_type (lhstype, field, flags);
! 
! 	if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype))
  	  {
! 	    if (complain)
! 	      {
! 	        tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype);
  
! 	        if (TREE_CODE (field) == OVERLOAD)
! 	          field = OVL_FUNCTION (field);
! 	        if (TREE_CODE (field) == FUNCTION_DECL)
! 	          {
! 		    cp_pedwarn ("object-dependent reference `%E' can only be used in a call",
! 		    	      DECL_NAME (field));
!   	    	    cp_pedwarn ("  to form a pointer to member function, say `&%T::%E'",
! 		    	      t, DECL_NAME (field));
!     	          }
! 	        else
! 	          cp_pedwarn ("object-dependent reference can only be used in a call");
! 	      }
! 	    return r;
  	  }
! 	
  	return r;
        }
  
--- 5145,5171 ----
  
      case COMPONENT_REF:
        {
! 	tree r = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
  
! 	if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)
! 	    && complain && !flag_ms_extensions)
  	  {
! 	    /* Note: we check this after the recursive call to avoid
! 	       complaining about cases where overload resolution fails.  */
! 
! 	    tree t = TREE_TYPE (TREE_OPERAND (rhs, 0));
! 	    tree fn = PTRMEM_CST_MEMBER (r);
  
! 	    my_friendly_assert (TREE_CODE (r) == PTRMEM_CST, 990811);
! 
! 	    cp_pedwarn
! 	      ("object-dependent reference to `%E' can only be used in a call",
! 	       DECL_NAME (fn));
! 	    cp_pedwarn
! 	      ("  to form a pointer to member function, say `&%T::%E'",
! 	       t, DECL_NAME (fn));
  	  }
! 
  	return r;
        }
  
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.258
diff -c -p -r1.258 cp-tree.h
*** cp-tree.h	1999/08/09 10:44:05	1.258
--- cp-tree.h	1999/08/12 06:47:25
*************** extern int strict_prototypes_lang_c, str
*** 2221,2226 ****
--- 2221,2229 ----
     applies, use the value of the label.  */
  extern int flag_labels_ok;
  
+ /* Nonzero means allow Microsoft extensions without a pedwarn.  */
+ extern int flag_ms_extensions;
+ 
  /* Non-zero means to collect statistics which might be expensive
     and to print them when we are done.  */
  extern int flag_detailed_statistics;
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.402
diff -c -p -r1.402 decl.c
*** decl.c	1999/08/10 06:19:35	1.402
--- decl.c	1999/08/12 06:47:25
*************** grokdeclarator (declarator, declspecs, d
*** 9529,9535 ****
  			 && in_namespace == NULL_TREE
  			 && current_namespace == global_namespace);
  
! 	  if (in_system_header)
  	    /* Allow it, sigh.  */;
  	  else if (pedantic || ! is_main)
  	    cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type",
--- 9529,9535 ----
  			 && in_namespace == NULL_TREE
  			 && current_namespace == global_namespace);
  
! 	  if (in_system_header || flag_ms_extensions)
  	    /* Allow it, sigh.  */;
  	  else if (pedantic || ! is_main)
  	    cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type",
Index: decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.230
diff -c -p -r1.230 decl2.c
*** decl2.c	1999/08/09 14:00:20	1.230
--- decl2.c	1999/08/12 06:47:26
*************** int strict_prototypes_lang_c, strict_pro
*** 370,375 ****
--- 370,379 ----
  
  int flag_labels_ok;
  
+ /* Nonzero means allow Microsoft extensions without a pedwarn.  */
+ 
+ int flag_ms_extensions;
+ 
  /* Non-zero means to collect statistics which might be expensive
     and to print them when we are done.  */
  int flag_detailed_statistics;
*************** lang_f_options[] =
*** 516,521 ****
--- 520,526 ----
    {"implicit-inline-templates", &flag_implicit_inline_templates, 1},
    {"implicit-templates", &flag_implicit_templates, 1},
    {"labels-ok", &flag_labels_ok, 1},
+   {"ms-extensions", &flag_ms_extensions, 1},
    {"nonansi-builtins", &flag_no_nonansi_builtin, 0},
    {"operator-names", &flag_operator_names, 1},
    {"optional-diags", &flag_optional_diags, 1},
Index: init.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/init.c,v
retrieving revision 1.116
diff -c -p -r1.116 init.c
*** init.c	1999/08/09 14:00:20	1.116
--- init.c	1999/08/12 06:47:26
*************** resolve_offset_ref (exp)
*** 1755,1767 ****
  
    if (BASELINK_P (member))
      {
!       cp_pedwarn ("assuming & on overloaded member function");
        return build_unary_op (ADDR_EXPR, exp, 0);
      }
  
    if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
      {
!       cp_pedwarn ("assuming & on `%E'", member);
        return build_unary_op (ADDR_EXPR, exp, 0);
      }
  
--- 1755,1769 ----
  
    if (BASELINK_P (member))
      {
!       if (! flag_ms_extensions)
! 	cp_pedwarn ("assuming & on overloaded member function");
        return build_unary_op (ADDR_EXPR, exp, 0);
      }
  
    if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
      {
!       if (! flag_ms_extensions)
! 	cp_pedwarn ("assuming & on `%E'", member);
        return build_unary_op (ADDR_EXPR, exp, 0);
      }
  
Index: lang-options.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/lang-options.h,v
retrieving revision 1.25
diff -c -p -r1.25 lang-options.h
*** lang-options.h	1999/08/03 01:37:47	1.25
--- lang-options.h	1999/08/12 06:47:26
*************** DEFINE_LANG_NAME ("C++")
*** 74,79 ****
--- 74,81 ----
    { "-fno-labels-ok", "" },
    { "-fmemoize-lookups", "" },
    { "-fno-memoize-lookups", "" },
+   { "-fms-extensions", "Don't pedwarn about uses of Microsoft extensions" },
+   { "-fno-ms-extensions", "" },
    { "-fname-mangling-version-", "" },
    { "-fnew-abi", "Enable experimental ABI changes" },
    { "-fno-new-abi", "" },
Index: typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.190
diff -c -p -r1.190 typeck.c
*** typeck.c	1999/08/09 14:00:21	1.190
--- typeck.c	1999/08/12 06:47:26
*************** build_unary_op (code, xarg, noconvert)
*** 4822,4842 ****
  	  && OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
  	{
  	  /* They're trying to take the address of a unique non-static
! 	     member function.  This is ill-formed, but let's try to DTRT.  */
! 	  tree base, name;
  
! 	  if (current_class_type
! 	      && TREE_OPERAND (arg, 0) == current_class_ref)
! 	    /* An expression like &memfn.  */
! 	    pedwarn ("taking the address of a non-static member function");
! 	  else
! 	    pedwarn ("taking the address of a bound member function");
  
! 	  base = TREE_TYPE (TREE_OPERAND (arg, 0));
! 	  name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
  
! 	  cp_pedwarn ("  to form a pointer to member function, say `&%T::%D'",
! 		      base, name);
  	  arg = build_offset_ref (base, name);
  	}
  
--- 4822,4850 ----
  	  && OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
  	{
  	  /* They're trying to take the address of a unique non-static
! 	     member function.  This is ill-formed, but let's try to DTRT.
! 	     Note: We only handle unique functions here because we don't
! 	     want to complain if there's a static overload; non-unique
! 	     cases will be handled by instantiate_type.  But we need to
! 	     handle this case here to allow casts on the resulting PMF.  */
  
! 	  tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
! 	  tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
  
! 	  if (! flag_ms_extensions)
! 	    {
! 	      if (current_class_type
! 		  && TREE_OPERAND (arg, 0) == current_class_ref)
! 		/* An expression like &memfn.  */
! 		pedwarn ("taking the address of a non-static member function");
! 	      else
! 		pedwarn ("taking the address of a bound member function");
  
! 	      cp_pedwarn
! 		("  to form a pointer to member function, say `&%T::%D'",
! 		 base, name);
! 	    }
! 
  	  arg = build_offset_ref (base, name);
  	}
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]