FreeBSD/contrib/gcc/cp/class.c
/* Issue warnings about T having private constructors, but no friends,
   and so forth.

   HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or
   static members.  HAS_NONPRIVATE_STATIC_FN is nonzero if T has any
   non-private static member functions.  */
Issue warnings about T having private constructors, but no friends,
and so forth.

HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or
static members.  HAS_NONPRIVATE_STATIC_FN is nonzero if T has any
non-private static member functions.
Issue warnings about T having private constructors but no friends and so forth . HAS_NONPRIVATE_METHOD is nonzero if T has any non - private methods or static members . HAS_NONPRIVATE_STATIC_FN is nonzero if T has any non - private static member functions .
static void
maybe_warn_about_overly_private_class (tree t)
{
  int has_member_fn = 0;
  int has_nonprivate_method = 0;
  tree fn;
  if (!warn_ctor_dtor_privacy
      || (CLASSTYPE_FRIEND_CLASSES (t)
	  || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
      || CLASSTYPE_TEMPLATE_INSTANTIATION (t))
    return;
  for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
    if (!DECL_ARTIFICIAL (fn))
      {
	if (!TREE_PRIVATE (fn))
	  {
	    if (DECL_STATIC_FUNCTION_P (fn))
	      return;
	    has_nonprivate_method = 1;
	  }
	else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
	  has_member_fn = 1;
      }
  if (!has_nonprivate_method && has_member_fn)
    {
      unsigned i;
      tree binfo = TYPE_BINFO (t);
      for (i = 0; i != BINFO_N_BASE_BINFOS (binfo); i++)
	if (BINFO_BASE_ACCESS (binfo, i) != access_private_node)
	  {
	    has_nonprivate_method = 1;
	    break;
	  }
      if (!has_nonprivate_method)
	{
	  warning (OPT_Wctor_dtor_privacy,
		   "all member functions in class %qT are private", t);
	  return;
	}
    }
  fn = CLASSTYPE_DESTRUCTORS (t);
  if (fn && TREE_PRIVATE (fn))
    {
      warning (OPT_Wctor_dtor_privacy,
	       "%q#T only defines a private destructor and has no friends",
	       t);
      return;
    }
  if (TYPE_HAS_CONSTRUCTOR (t)
      && (!CLASSTYPE_LAZY_DEFAULT_CTOR (t)
	  || !CLASSTYPE_LAZY_COPY_CTOR (t)))
    {
      int nonprivate_ctor = 0;
      if (!TYPE_HAS_INIT_REF (t))
	nonprivate_ctor = 1;
      else
	for (fn = CLASSTYPE_CONSTRUCTORS (t); fn; fn = OVL_NEXT (fn))
	  {
	    tree ctor = OVL_CURRENT (fn);
	    if (! TREE_PRIVATE (ctor))
	      {
		nonprivate_ctor = 1;
		break;
	      }
	  }
      if (nonprivate_ctor == 0)
	{
	  warning (OPT_Wctor_dtor_privacy,
		   "%q#T only defines private constructors and has no friends",
		   t);
	  return;
	}
    }
}
static void maybe_warn_about_overly_private_class ( tree t ) { int has_member_fn = 0 ; int has_nonprivate_method = 0 ; tree fn ; if ( ! warn_ctor_dtor_privacy || ( CLASSTYPE_FRIEND_CLASSES ( t ) || DECL_FRIENDLIST ( TYPE_MAIN_DECL ( t ) ) ) || CLASSTYPE_TEMPLATE_INSTANTIATION ( t ) ) return ; for ( fn = TYPE_METHODS ( t ) ; fn ; fn = TREE_CHAIN ( fn ) ) if ( ! DECL_ARTIFICIAL ( fn ) ) { if ( ! TREE_PRIVATE ( fn ) ) { if ( DECL_STATIC_FUNCTION_P ( fn ) ) return ; has_nonprivate_method = 1 ; } else if ( ! DECL_CONSTRUCTOR_P ( fn ) && ! DECL_DESTRUCTOR_P ( fn ) ) has_member_fn = 1 ; } if ( ! has_nonprivate_method && has_member_fn ) { unsigned i ; tree binfo = TYPE_BINFO ( t ) ; for ( i = 0 ; i != BINFO_N_BASE_BINFOS ( binfo ) ; i ++ ) if ( BINFO_BASE_ACCESS ( binfo , i ) != access_private_node ) { has_nonprivate_method = 1 ; break ; } if ( ! has_nonprivate_method ) { warning ( OPT_Wctor_dtor_privacy , " " , t ) ; return ; } } fn = CLASSTYPE_DESTRUCTORS ( t ) ; if ( fn && TREE_PRIVATE ( fn ) ) { warning ( OPT_Wctor_dtor_privacy , " " , t ) ; return ; } if ( TYPE_HAS_CONSTRUCTOR ( t ) && ( ! CLASSTYPE_LAZY_DEFAULT_CTOR ( t ) || ! CLASSTYPE_LAZY_COPY_CTOR ( t ) ) ) { int nonprivate_ctor = 0 ; if ( ! TYPE_HAS_INIT_REF ( t ) ) nonprivate_ctor = 1 ; else for ( fn = CLASSTYPE_CONSTRUCTORS ( t ) ; fn ; fn = OVL_NEXT ( fn ) ) { tree ctor = OVL_CURRENT ( fn ) ; if ( ! TREE_PRIVATE ( ctor ) ) { nonprivate_ctor = 1 ; break ; } } if ( nonprivate_ctor == 0 ) { warning ( OPT_Wctor_dtor_privacy , " " , t ) ; return ; } } }
Issue warnings about T having private constructors, but no friends,
and so forth.
Issue warnings about T having private constructors but no friends and so forth .
/* If the class has friends, those entities might create and
	 access instances, so we should not warn.  */ /* We will have warned when the template was declared; there's
	 no need to warn on every instantiation.  */ /* There's no reason to even consider warning about this
       class.  */ /* We only issue one warning, if more than one applies, because
     otherwise, on code like:

     class A {
       // Oops - forgot `public:'
       A();
       A(const A&);
       ~A();
     };

     we warn several times about essentially the same problem.  */ /* Check to see if all (non-constructor, non-destructor) member
     functions are private.  (Since there are no friends or
     non-private statics, we can't ever call any of the private member
     functions.)  */ /* We're not interested in compiler-generated methods; they don't
       provide any way to call private members.  */ /* A non-private static member function is just like a
		 friend; it can create and invoke private member
		 functions, and be accessed without a class
		 instance.  */ /* Keep searching for a static member function.  */ /* There are no non-private methods, and there's at least one
	 private member function that isn't a constructor or
	 destructor.  (If all the private members are
	 constructors/destructors we want to use the code below that
	 issues error messages specifically referring to
	 constructors/destructors.)  */ /* Even if some of the member functions are non-private, the class
     won't be useful for much if all the constructors or destructors
     are private: such an object can never be created or destroyed.  */ /* Implicitly generated constructors are always public.  */ /* If a non-template class does not define a copy
	 constructor, one is defined for it, enabling it to avoid
	 this warning.  For a template class, this does not
	 happen, and so we would normally get a warning on:

	   template <class T> class C { private: C(); };

	 To avoid this asymmetry, we check TYPE_HAS_INIT_REF.  All
	 complete non-template or fully instantiated classes have this
	 flag set.  */ /* Ideally, we wouldn't count copy constructors (or, in
	       fact, any constructor that takes an argument of the
	       class type as a parameter) because such things cannot
	       be used to construct an instance of the class unless
	       you already have one.  But, for now at least, we're
	       more generous.  */