LCOV - code coverage report
Current view: top level - gcc/cp - friend.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.1 % 253 223
Test Date: 2026-02-28 14:20:25 Functions: 83.3 % 6 5
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Help friends in C++.
       2              :    Copyright (C) 1997-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify
       7              : it under the terms of the GNU General Public License as published by
       8              : the Free Software Foundation; either version 3, or (at your option)
       9              : any later version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful,
      12              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : GNU General Public License for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "cp-tree.h"
      24              : 
      25              : /* Friend data structures are described in cp-tree.h.  */
      26              : 
      27              : 
      28              : /* The GLOBAL_FRIEND scope (functions, classes, or templates) is
      29              :    regarded as a friend of every class.  This is only used by libcc1,
      30              :    to enable GDB's code snippets to access private members without
      31              :    disabling access control in general, which could cause different
      32              :    template overload resolution results when accessibility matters
      33              :    (e.g. tests for an accessible member).  */
      34              : 
      35              : static GTY(()) tree global_friend;
      36              : 
      37              : /* Set the GLOBAL_FRIEND for this compilation session.  It might be
      38              :    set multiple times, but always to the same scope.  */
      39              : 
      40              : void
      41            0 : set_global_friend (tree scope)
      42              : {
      43            0 :   gcc_checking_assert (scope != NULL_TREE);
      44            0 :   gcc_assert (!global_friend || global_friend == scope);
      45            0 :   global_friend = scope;
      46            0 : }
      47              : 
      48              : /* Return TRUE if SCOPE is the global friend.  */
      49              : 
      50              : bool
      51     91095652 : is_global_friend (tree scope)
      52              : {
      53     91095652 :   gcc_checking_assert (scope != NULL_TREE);
      54              : 
      55     91095652 :   if (global_friend == scope)
      56              :     return true;
      57              : 
      58     91095652 :   if (!global_friend)
      59              :     return false;
      60              : 
      61            0 :   if (is_specialization_of_friend (global_friend, scope))
      62              :     return true;
      63              : 
      64              :   return false;
      65              : }
      66              : 
      67              : /* Returns nonzero if SUPPLICANT is a friend of TYPE.  */
      68              : 
      69              : int
      70     39151989 : is_friend (tree type, tree supplicant)
      71              : {
      72     74094570 :   int declp;
      73     74094570 :   tree list;
      74     74094570 :   tree context;
      75              : 
      76     74094570 :   if (supplicant == NULL_TREE || type == NULL_TREE)
      77              :     return 0;
      78              : 
      79     74094570 :   if (is_global_friend (supplicant))
      80              :     return 1;
      81              : 
      82     74094570 :   declp = DECL_P (supplicant);
      83              : 
      84     74094570 :   if (declp)
      85              :     /* It's a function decl.  */
      86              :     {
      87     35331262 :       tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
      88     35331262 :       tree name = DECL_NAME (supplicant);
      89              : 
      90     64335659 :       for (; list ; list = TREE_CHAIN (list))
      91              :         {
      92     30500057 :           if (name == FRIEND_NAME (list))
      93              :             {
      94      1495660 :               tree friends = FRIEND_DECLS (list);
      95      2087815 :               for (; friends ; friends = TREE_CHAIN (friends))
      96              :                 {
      97      1938377 :                   tree this_friend = TREE_VALUE (friends);
      98              : 
      99      1938377 :                   if (this_friend == NULL_TREE)
     100            0 :                     continue;
     101              : 
     102      1938377 :                   if (supplicant == this_friend)
     103              :                     return 1;
     104              : 
     105       891644 :                   if (is_specialization_of_friend (supplicant, this_friend))
     106              :                     return 1;
     107              :                 }
     108              :               break;
     109              :             }
     110              :         }
     111              :     }
     112              :   else
     113              :     /* It's a type.  */
     114              :     {
     115     38763308 :       if (same_type_p (supplicant, type))
     116              :         return 1;
     117              : 
     118      1588346 :       list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
     119      2501582 :       for (; list ; list = TREE_CHAIN (list))
     120              :         {
     121      1513079 :           tree t = TREE_VALUE (list);
     122              : 
     123      3026158 :           if (TREE_CODE (t) == TEMPLATE_DECL ?
     124       765143 :               is_specialization_of_friend (TYPE_MAIN_DECL (supplicant), t) :
     125       747936 :               same_type_p (supplicant, t))
     126              :             return 1;
     127              :         }
     128              :     }
     129              : 
     130     34973543 :   if (declp)
     131              :     {
     132     33985040 :       if (DECL_FUNCTION_MEMBER_P (supplicant))
     133     33983268 :         context = DECL_CONTEXT (supplicant);
     134         3544 :       else if (tree fc = DECL_FRIEND_CONTEXT (supplicant))
     135              :         context = fc;
     136              :       else
     137              :         context = NULL_TREE;
     138              :     }
     139              :   else
     140              :     {
     141       988503 :       if (TYPE_CLASS_SCOPE_P (supplicant))
     142              :         /* Nested classes get the same access as their enclosing types, as
     143              :            per DR 45 (this is a change from the standard).  */
     144       655852 :         context = TYPE_CONTEXT (supplicant);
     145              :       else
     146              :         /* Local classes have the same access as the enclosing function.  */
     147       332651 :         context = decl_function_context (TYPE_MAIN_DECL (supplicant));
     148              :     }
     149              : 
     150              :   /* A namespace is not friend to anybody.  */
     151     34972246 :   if (context && TREE_CODE (context) == NAMESPACE_DECL)
     152              :     context = NULL_TREE;
     153              : 
     154              :   if (context)
     155              :     return is_friend (type, context);
     156              : 
     157              :   return 0;
     158              : }
     159              : 
     160              : /* Add a new friend to the friends of the aggregate type TYPE.
     161              :    DECL is the FUNCTION_DECL of the friend being added.
     162              : 
     163              :    If COMPLAIN is true, warning about duplicate friend is issued.
     164              :    We want to have this diagnostics during parsing but not
     165              :    when a template is being instantiated.  */
     166              : 
     167              : void
     168      8868346 : add_friend (tree type, tree decl, bool complain)
     169              : {
     170      8868346 :   tree typedecl;
     171      8868346 :   tree list;
     172      8868346 :   tree name;
     173      8868346 :   tree ctx;
     174              : 
     175      8868346 :   if (decl == error_mark_node)
     176              :     return;
     177              : 
     178      8868299 :   typedecl = TYPE_MAIN_DECL (type);
     179      8868299 :   list = DECL_FRIENDLIST (typedecl);
     180      8868299 :   name = DECL_NAME (decl);
     181      8868299 :   type = TREE_TYPE (typedecl);
     182              : 
     183     22455448 :   while (list)
     184              :     {
     185     15985787 :       if (name == FRIEND_NAME (list))
     186              :         {
     187      2398638 :           tree friends = FRIEND_DECLS (list);
     188      6900118 :           for (; friends ; friends = TREE_CHAIN (friends))
     189              :             {
     190      4501558 :               if (decl == TREE_VALUE (friends))
     191              :                 {
     192           78 :                   if (complain)
     193           72 :                     warning (OPT_Wredundant_decls,
     194              :                              "%qD is already a friend of class %qT",
     195              :                              decl, type);
     196           78 :                   return;
     197              :                 }
     198              :             }
     199              : 
     200      2398560 :           TREE_VALUE (list) = tree_cons (NULL_TREE, decl,
     201      2398560 :                                          TREE_VALUE (list));
     202      2398560 :           break;
     203              :         }
     204     13587149 :       list = TREE_CHAIN (list);
     205              :     }
     206              : 
     207      8868221 :   ctx = DECL_CONTEXT (decl);
     208      8868221 :   if (ctx && CLASS_TYPE_P (ctx) && !uses_template_parms (ctx))
     209          117 :     perform_or_defer_access_check (TYPE_BINFO (ctx), decl, decl,
     210              :                                    tf_warning_or_error);
     211              : 
     212      8868221 :   maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
     213              : 
     214      8868221 :   if (!list)
     215      6469661 :     DECL_FRIENDLIST (typedecl)
     216     12939322 :       = tree_cons (DECL_NAME (decl), build_tree_list (NULL_TREE, decl),
     217      6469661 :                    DECL_FRIENDLIST (typedecl));
     218      8868221 :   if (!uses_template_parms (type))
     219      5972763 :     DECL_BEFRIENDING_CLASSES (decl)
     220      5972763 :       = tree_cons (NULL_TREE, type,
     221      5972763 :                    DECL_BEFRIENDING_CLASSES (decl));
     222              : }
     223              : 
     224              : /* Make FRIEND_TYPE a friend class to TYPE.  If FRIEND_TYPE has already
     225              :    been defined, we make all of its member functions friends of
     226              :    TYPE.  If not, we make it a pending friend, which can later be added
     227              :    when its definition is seen.  If a type is defined, then its TYPE_DECL's
     228              :    DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
     229              :    classes that are not defined.  If a type has not yet been defined,
     230              :    then the DECL_WAITING_FRIENDS contains a list of types
     231              :    waiting to make it their friend.  Note that these two can both
     232              :    be in use at the same time!
     233              : 
     234              :    If COMPLAIN is true, warning about duplicate friend is issued.
     235              :    We want to have this diagnostics during parsing but not
     236              :    when a template is being instantiated.  */
     237              : 
     238              : void
     239      3122442 : make_friend_class (tree type, tree friend_type, bool complain)
     240              : {
     241      3122442 :   tree classes;
     242              : 
     243              :   /* CLASS_TEMPLATE_DEPTH counts the number of template headers for
     244              :      the enclosing class.  FRIEND_DEPTH counts the number of template
     245              :      headers used for this friend declaration.  TEMPLATE_MEMBER_P,
     246              :      defined inside the `if' block for TYPENAME_TYPE case, is true if
     247              :      a template header in FRIEND_DEPTH is intended for DECLARATOR.
     248              :      For example, the code
     249              : 
     250              :        template <class T> struct A {
     251              :          template <class U> struct B {
     252              :            template <class V> template <class W>
     253              :              friend class C<V>::D;
     254              :          };
     255              :        };
     256              : 
     257              :      will eventually give the following results
     258              : 
     259              :      1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
     260              :      2. FRIEND_DEPTH equals 2 (for `V' and `W').
     261              :      3. TEMPLATE_MEMBER_P is true (for `W').
     262              : 
     263              :      The friend is a template friend iff FRIEND_DEPTH is nonzero.  */
     264              : 
     265      3122442 :   int class_template_depth = template_class_depth (type);
     266      3122442 :   int friend_depth = 0;
     267      3122442 :   if (current_template_depth)
     268              :     /* When processing a friend declaration at parse time, just compare the
     269              :        current depth to that of the class template.  */
     270      1499012 :     friend_depth = current_template_depth - class_template_depth;
     271              :   else
     272              :     {
     273              :       /* Otherwise, we got here from instantiate_class_template.  Determine
     274              :          the friend depth by looking at the template parameters used within
     275              :          FRIEND_TYPE.  */
     276      1623430 :       gcc_checking_assert (class_template_depth == 0);
     277      2223059 :       while (uses_template_parms_level (friend_type, friend_depth + 1))
     278              :         ++friend_depth;
     279              :     }
     280              : 
     281      3122442 :   if (! MAYBE_CLASS_TYPE_P (friend_type)
     282           42 :       && TREE_CODE (friend_type) != TEMPLATE_TEMPLATE_PARM
     283           39 :       && TREE_CODE (friend_type) != TYPE_PACK_EXPANSION)
     284              :     {
     285              :       /* N1791: If the type specifier in a friend declaration designates a
     286              :          (possibly cv-qualified) class type, that class is declared as a
     287              :          friend; otherwise, the friend declaration is ignored.
     288              : 
     289              :          So don't complain in C++11 mode.  */
     290           27 :       if (cxx_dialect < cxx11)
     291            0 :         pedwarn (input_location, complain ? 0 : OPT_Wpedantic,
     292              :                  "invalid type %qT declared %<friend%>", friend_type);
     293           27 :       return;
     294              :     }
     295              : 
     296      3122415 :   friend_type = cv_unqualified (friend_type);
     297              : 
     298      3122415 :   if (check_for_bare_parameter_packs (friend_type))
     299              :     return;
     300              : 
     301      3122412 :   if (friend_depth)
     302              :     {
     303              :       /* [temp.friend] Friend declarations shall not declare partial
     304              :          specializations.  */
     305      1298398 :       if (CLASS_TYPE_P (friend_type)
     306      1298398 :           && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
     307      1298473 :           && uses_template_parms (friend_type))
     308              :         {
     309            0 :           error ("partial specialization %qT declared %<friend%>",
     310              :                  friend_type);
     311            0 :           return;
     312              :         }
     313              : 
     314      1298470 :       if (TYPE_TEMPLATE_INFO (friend_type)
     315      1298398 :           && !PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (friend_type)))
     316              :         {
     317            3 :           auto_diagnostic_group d;
     318            3 :           error ("%qT is not a template", friend_type);
     319            3 :           inform (location_of (friend_type), "previous declaration here");
     320            6 :           if (TYPE_CLASS_SCOPE_P (friend_type)
     321            3 :               && CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (friend_type))
     322            6 :               && currently_open_class (TYPE_CONTEXT (friend_type)))
     323            3 :             inform (input_location, "perhaps you need explicit template "
     324              :                     "arguments in your nested-name-specifier");
     325            3 :           return;
     326            3 :         }
     327              :     }
     328              : 
     329              :   /* It makes sense for a template class to be friends with itself,
     330              :      that means the instantiations can be friendly.  Other cases are
     331              :      not so meaningful.  */
     332      1823942 :   if (!friend_depth && same_type_p (type, friend_type))
     333              :     {
     334            6 :       if (complain)
     335            0 :         warning (0, "class %qT is implicitly friends with itself",
     336              :                  type);
     337            6 :       return;
     338              :     }
     339              : 
     340              :   /* [temp.friend]
     341              : 
     342              :      A friend of a class or class template can be a function or
     343              :      class template, a specialization of a function template or
     344              :      class template, or an ordinary (nontemplate) function or
     345              :      class.  */
     346      3122403 :   if (!friend_depth)
     347              :     ;/* ok */
     348      1298467 :   else if (TREE_CODE (friend_type) == TYPENAME_TYPE)
     349              :     {
     350           69 :       if (TREE_CODE (TYPENAME_TYPE_FULLNAME (friend_type))
     351              :           == TEMPLATE_ID_EXPR)
     352              :         {
     353              :           /* template <class U> friend class T::X<U>; */
     354              :           /* [temp.friend]
     355              :              Friend declarations shall not declare partial
     356              :              specializations.  */
     357            0 :           error ("partial specialization %qT declared %<friend%>",
     358              :                  friend_type);
     359            0 :           return;
     360              :         }
     361              :       else
     362              :         {
     363              :           /* We will figure this out later.  */
     364           69 :           bool template_member_p = false;
     365              : 
     366           69 :           tree ctype = TYPE_CONTEXT (friend_type);
     367           69 :           tree name = TYPE_IDENTIFIER (friend_type);
     368           69 :           tree decl;
     369              : 
     370              :           /* We need to distinguish a TYPENAME_TYPE for the non-template
     371              :              class B in
     372              :                template<class T> friend class A<T>::B;
     373              :              vs for the class template B in
     374              :                template<class T> template<class U> friend class A<T>::B;  */
     375           69 :           if (current_template_depth
     376           57 :               && !uses_template_parms_level (ctype, current_template_depth))
     377              :             template_member_p = true;
     378              : 
     379           69 :           if (class_template_depth)
     380              :             {
     381              :               /* We rely on tsubst_friend_class to check the
     382              :                  validity of the declaration later.  */
     383           27 :               if (template_member_p)
     384           15 :                 friend_type
     385           15 :                   = make_unbound_class_template (ctype,
     386              :                                                  name,
     387              :                                                  current_template_parms,
     388              :                                                  tf_error);
     389              :               else
     390           12 :                 friend_type
     391           12 :                   = make_typename_type (ctype, name, class_type, tf_error);
     392              :             }
     393              :           else
     394              :             {
     395           42 :               decl = lookup_member (ctype, name, 0, true, tf_warning_or_error);
     396           42 :               if (!decl)
     397              :                 {
     398            0 :                   error ("%qT is not a member of %qT", name, ctype);
     399            0 :                   return;
     400              :                 }
     401           42 :               if (template_member_p && !DECL_CLASS_TEMPLATE_P (decl))
     402              :                 {
     403            0 :                   auto_diagnostic_group d;
     404            0 :                   error ("%qT is not a member class template of %qT",
     405              :                          name, ctype);
     406            0 :                   inform (DECL_SOURCE_LOCATION (decl),
     407              :                           "%qD declared here", decl);
     408            0 :                   return;
     409            0 :                 }
     410           42 :               if (!template_member_p && (TREE_CODE (decl) != TYPE_DECL
     411           33 :                                          || !CLASS_TYPE_P (TREE_TYPE (decl))))
     412              :                 {
     413            0 :                   auto_diagnostic_group d;
     414            0 :                   error ("%qT is not a nested class of %qT",
     415              :                          name, ctype);
     416            0 :                   inform (DECL_SOURCE_LOCATION (decl),
     417              :                           "%qD declared here", decl);
     418            0 :                   return;
     419            0 :                 }
     420              : 
     421           42 :               friend_type = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl));
     422              :             }
     423              :         }
     424              :     }
     425      1298398 :   else if (TREE_CODE (friend_type) == TEMPLATE_TYPE_PARM)
     426              :     {
     427              :       /* template <class T> friend class T; */
     428            0 :       error ("template parameter type %qT declared %<friend%>", friend_type);
     429            0 :       return;
     430              :     }
     431      1298398 :   else if (TREE_CODE (friend_type) == TEMPLATE_TEMPLATE_PARM)
     432            3 :     friend_type = TYPE_NAME (friend_type);
     433      1298395 :   else if (!CLASSTYPE_TEMPLATE_INFO (friend_type))
     434              :     {
     435              :       /* template <class T> friend class A; where A is not a template */
     436            0 :       error ("%q#T is not a template", friend_type);
     437            0 :       return;
     438              :     }
     439              :   else
     440              :     /* template <class T> friend class A; where A is a template */
     441      1298395 :     friend_type = CLASSTYPE_TI_TEMPLATE (friend_type);
     442              : 
     443      3122403 :   if (friend_type == error_mark_node)
     444              :     return;
     445              : 
     446              :   /* See if it is already a friend.  */
     447      3122403 :   for (classes = CLASSTYPE_FRIEND_CLASSES (type);
     448      4712715 :        classes;
     449      1590312 :        classes = TREE_CHAIN (classes))
     450              :     {
     451      1590943 :       tree probe = TREE_VALUE (classes);
     452              : 
     453      1590943 :       if (TREE_CODE (friend_type) == TEMPLATE_DECL)
     454              :         {
     455       505071 :           if (friend_type == probe)
     456              :             {
     457            6 :               if (complain)
     458            0 :                 warning (OPT_Wredundant_decls,
     459              :                          "%qD is already a friend of %qT", probe, type);
     460              :               break;
     461              :             }
     462              :         }
     463      1085872 :       else if (TREE_CODE (probe) != TEMPLATE_DECL)
     464              :         {
     465       752323 :           if (same_type_p (probe, friend_type))
     466              :             {
     467          625 :               if (complain)
     468          622 :                 warning (OPT_Wredundant_decls,
     469              :                          "%qT is already a friend of %qT", probe, type);
     470              :               break;
     471              :             }
     472              :         }
     473              :     }
     474              : 
     475      3122403 :   if (!classes)
     476              :     {
     477      3121772 :       maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);
     478              : 
     479      3121772 :       CLASSTYPE_FRIEND_CLASSES (type)
     480      3121772 :         = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
     481      3121772 :       if (TREE_CODE (friend_type) == TEMPLATE_DECL)
     482      1298434 :         friend_type = TREE_TYPE (friend_type);
     483      3121772 :       if (!uses_template_parms (type))
     484      1701863 :         CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
     485      1701863 :           = tree_cons (NULL_TREE, type,
     486      1701863 :                        CLASSTYPE_BEFRIENDING_CLASSES (friend_type));
     487              :     }
     488              : }
     489              : 
     490              : /* Record DECL (a FUNCTION_DECL) as a friend of the
     491              :    CURRENT_CLASS_TYPE.  If DECL is a member function, SCOPE is the
     492              :    class of which it is a member, as named in the friend declaration.
     493              :    If the friend declaration was explicitly namespace-qualified, SCOPE
     494              :    is that namespace.
     495              :    DECLARATOR is the name of the friend.  FUNCDEF_FLAG is true if the
     496              :    friend declaration is a definition of the function.  FLAGS is as
     497              :    for grokclass fn.  */
     498              : 
     499              : tree
     500      6213022 : do_friend (tree scope, tree declarator, tree decl,
     501              :            enum overload_flags flags,
     502              :            bool funcdef_flag)
     503              : {
     504      6213022 :   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
     505              : 
     506      6213022 :   tree ctype = NULL_TREE;
     507      6213022 :   tree in_namespace = NULL_TREE;
     508      6213022 :   if (!scope)
     509              :     ;
     510       218263 :   else if (MAYBE_CLASS_TYPE_P (scope))
     511              :     ctype = scope;
     512              :   else
     513              :     {
     514       218038 :       gcc_checking_assert (TREE_CODE (scope) == NAMESPACE_DECL);
     515              :       in_namespace = scope;
     516              :     }
     517              : 
     518              :   /* Friend functions are unique, until proved otherwise.  */
     519      6213022 :   DECL_UNIQUE_FRIEND_P (decl) = 1;
     520              : 
     521     12426041 :   if (DECL_OVERRIDE_P (decl) || DECL_FINAL_P (decl))
     522            6 :     error ("friend declaration %qD may not have virt-specifiers",
     523              :            decl);
     524              : 
     525      6213022 :   tree orig_declarator = declarator;
     526      6213022 :   if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
     527              :     {
     528        89989 :       declarator = TREE_OPERAND (declarator, 0);
     529       179967 :       if (!identifier_p (declarator))
     530        89976 :         declarator = OVL_NAME (declarator);
     531              :     }
     532              : 
     533              :   /* CLASS_TEMPLATE_DEPTH counts the number of template headers for
     534              :      the enclosing class.  FRIEND_DEPTH counts the number of template
     535              :      headers used for this friend declaration.  TEMPLATE_MEMBER_P is
     536              :      true if a template header in FRIEND_DEPTH is intended for
     537              :      DECLARATOR.  For example, the code
     538              : 
     539              :      template <class T> struct A {
     540              :        template <class U> struct B {
     541              :          template <class V> template <class W>
     542              :            friend void C<V>::f(W);
     543              :        };
     544              :      };
     545              : 
     546              :      will eventually give the following results
     547              : 
     548              :      1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
     549              :      2. FRIEND_DEPTH equals 2 (for `V' and `W').
     550              :      3. CTYPE_DEPTH equals 1 (for `V').
     551              :      4. TEMPLATE_MEMBER_P is true (for `W').  */
     552              : 
     553      6213022 :   int class_template_depth = template_class_depth (current_class_type);
     554      6213022 :   int friend_depth = current_template_depth - class_template_depth;
     555      6213022 :   int ctype_depth = num_template_headers_for_class (ctype);
     556      6213022 :   bool template_member_p = friend_depth > ctype_depth;
     557              : 
     558      6213022 :   if (ctype)
     559              :     {
     560          225 :       tree cname = TYPE_NAME (ctype);
     561          225 :       if (TREE_CODE (cname) == TYPE_DECL)
     562          225 :         cname = DECL_NAME (cname);
     563              : 
     564              :       /* A method friend.  */
     565          225 :       if (flags == NO_SPECIAL && declarator == cname)
     566           24 :         DECL_CXX_CONSTRUCTOR_P (decl) = 1;
     567              : 
     568          225 :       grokclassfn (ctype, decl, flags);
     569              : 
     570              :       /* A nested class may declare a member of an enclosing class
     571              :          to be a friend, so we do lookup here even if CTYPE is in
     572              :          the process of being defined.  */
     573          225 :       if (class_template_depth
     574          225 :           || COMPLETE_OR_OPEN_TYPE_P (ctype))
     575              :         {
     576          216 :           if (DECL_TEMPLATE_INFO (decl))
     577              :             /* DECL is a template specialization.  No need to
     578              :                build a new TEMPLATE_DECL.  */
     579              :             ;
     580          204 :           else if (class_template_depth)
     581              :             /* We rely on tsubst_friend_function to check the
     582              :                validity of the declaration later.  */
     583           87 :             decl = push_template_decl (decl, /*is_friend=*/true);
     584              :           else
     585          144 :             decl = check_classfn (ctype, decl,
     586              :                                   template_member_p
     587           27 :                                   ? current_template_parms
     588              :                                   : NULL_TREE);
     589              : 
     590          216 :           if ((template_member_p
     591              :                /* Always pull out the TEMPLATE_DECL if we have a friend
     592              :                   template in a class template so that it gets tsubsted
     593              :                   properly later on (59956).  tsubst_friend_function knows
     594              :                   how to tell this apart from a member template.  */
     595          180 :                || (class_template_depth && friend_depth))
     596           66 :               && decl && TREE_CODE (decl) == FUNCTION_DECL)
     597           39 :             decl = DECL_TI_TEMPLATE (decl);
     598              :         }
     599              :       else
     600            9 :         error ("member %qD declared as friend before type %qT defined",
     601              :                   decl, ctype);
     602              :     }
     603              :   else
     604              :     {
     605              :       /* Namespace-scope friend function.  */
     606              : 
     607      6212797 :       if (funcdef_flag)
     608      4439113 :         SET_DECL_FRIEND_CONTEXT (decl, current_class_type);
     609              : 
     610      6212797 :       if (! DECL_USE_TEMPLATE (decl))
     611              :         {
     612              :           /* We must check whether the decl refers to template
     613              :              arguments before push_template_decl adds a reference to
     614              :              the containing template class.  */
     615      6122811 :           int warn = (warn_nontemplate_friend
     616      6122763 :                       && ! funcdef_flag && ! friend_depth
     617       542765 :                       && current_template_parms
     618      6133907 :                       && uses_template_parms (decl));
     619              : 
     620      6122811 :           if (friend_depth || class_template_depth)
     621              :             /* We can't call pushdecl for a template class, since in
     622              :                general, such a declaration depends on template
     623              :                parameters.  Instead, we call pushdecl when the class
     624              :                is instantiated.  */
     625      3591227 :             decl = push_template_decl (decl, /*is_friend=*/true);
     626      2531584 :           else if (current_function_decl && !in_namespace)
     627              :             /* pushdecl will check there's a local decl already.  */
     628           12 :             decl = pushdecl (decl, /*hiding=*/true);
     629              :           else
     630              :             {
     631              :               /* We can't use pushdecl, as we might be in a template
     632              :                  class specialization, and pushdecl will insert an
     633              :                  unqualified friend decl into the template parameter
     634              :                  scope, rather than the namespace containing it.  */
     635      2531572 :               tree ns = decl_namespace_context (decl);
     636              : 
     637      2531572 :               push_nested_namespace (ns);
     638      2531572 :               decl = pushdecl_namespace_level (decl, /*hiding=*/true);
     639      2531572 :               pop_nested_namespace (ns);
     640              :             }
     641              : 
     642      6122811 :           if (warn)
     643              :             {
     644           18 :               static int explained;
     645           18 :               bool warned;
     646              : 
     647           18 :               auto_diagnostic_group d;
     648           18 :               warned = warning (OPT_Wnon_template_friend, "friend declaration "
     649              :                                 "%q#D declares a non-template function", decl);
     650           18 :               if (! explained && warned)
     651              :                 {
     652           15 :                   inform (input_location, "(if this is not what you intended, "
     653              :                           "make sure the function template has already been "
     654              :                           "declared and add %<<>%> after the function name "
     655              :                           "here)");
     656           15 :                   explained = 1;
     657              :                 }
     658           18 :             }
     659              :         }
     660              :     }
     661              : 
     662      6213022 :   if (decl == error_mark_node)
     663              :     return error_mark_node;
     664              : 
     665      6212977 :   if (!class_template_depth
     666      6212977 :       && decl_specialization_friend_p (decl))
     667              :     /* "[if no non-template match is found,] each remaining function template
     668              :        is replaced with the specialization chosen by deduction from the
     669              :        friend declaration or discarded if deduction fails."
     670              : 
     671              :        set_decl_namespace or check_classfn set DECL_IMPLICIT_INSTANTIATION to
     672              :        indicate that we need a template match, so ask
     673              :        check_explicit_specialization to find one.  */
     674        76796 :     decl = (check_explicit_specialization
     675        76796 :             (orig_declarator, decl, ctype_depth,
     676        76796 :              2 * funcdef_flag + 4));
     677              : 
     678     14478406 :   add_friend (current_class_type,
     679      6212977 :               (!ctype && friend_depth) ? DECL_TI_TEMPLATE (decl) : decl,
     680              :               /*complain=*/true);
     681              : 
     682      6212977 :   return decl;
     683              : }
     684              : 
     685              : #include "gt-cp-friend.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.