LCOV - code coverage report
Current view: top level - gcc/cp - lex.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.7 % 505 473
Test Date: 2026-04-20 14:57:17 Functions: 92.3 % 39 36
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Separate lexical analyzer for GNU C++.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              :    Hacked by Michael Tiemann (tiemann@cygnus.com)
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify
       8              : it under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful,
      13              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15              : GNU General Public License for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : 
      22              : /* This file is the lexical analyzer for GNU C++.  */
      23              : 
      24              : #include "config.h"
      25              : /* For use with name_hint.  */
      26              : #include "system.h"
      27              : #include "coretypes.h"
      28              : #include "cp-tree.h"
      29              : #include "stringpool.h"
      30              : #include "c-family/c-pragma.h"
      31              : #include "c-family/c-objc.h"
      32              : #include "gcc-rich-location.h"
      33              : #include "cp-name-hint.h"
      34              : #include "langhooks.h"
      35              : 
      36              : static int interface_strcmp (const char *);
      37              : static void init_cp_traits (void);
      38              : static void init_cp_pragma (void);
      39              : 
      40              : static tree parse_strconst_pragma (const char *, int);
      41              : static void handle_pragma_vtable (cpp_reader *);
      42              : static void handle_pragma_unit (cpp_reader *);
      43              : static void handle_pragma_interface (cpp_reader *);
      44              : static void handle_pragma_implementation (cpp_reader *);
      45              : 
      46              : static void init_operators (void);
      47              : static void copy_lang_type (tree);
      48              : 
      49              : /* A constraint that can be tested at compile time.  */
      50              : #define CONSTRAINT(name, expr) extern int constraint_##name [(expr) ? 1 : -1]
      51              : 
      52              : /* Functions and data structures for #pragma interface.
      53              : 
      54              :    `#pragma implementation' means that the main file being compiled
      55              :    is considered to implement (provide) the classes that appear in
      56              :    its main body.  I.e., if this is file "foo.cc", and class `bar'
      57              :    is defined in "foo.cc", then we say that "foo.cc implements bar".
      58              : 
      59              :    All main input files "implement" themselves automagically.
      60              : 
      61              :    `#pragma interface' means that unless this file (of the form "foo.h"
      62              :    is not presently being included by file "foo.cc", the
      63              :    CLASSTYPE_INTERFACE_ONLY bit gets set.  The effect is that none
      64              :    of the vtables nor any of the inline functions defined in foo.h
      65              :    will ever be output.
      66              : 
      67              :    There are cases when we want to link files such as "defs.h" and
      68              :    "main.cc".  In this case, we give "defs.h" a `#pragma interface',
      69              :    and "main.cc" has `#pragma implementation "defs.h"'.  */
      70              : 
      71              : struct impl_files
      72              : {
      73              :   const char *filename;
      74              :   struct impl_files *next;
      75              : };
      76              : 
      77              : static struct impl_files *impl_file_chain;
      78              : 
      79              : void
      80        98140 : cxx_finish (void)
      81              : {
      82        98140 :   c_common_finish ();
      83        98140 : }
      84              : 
      85              : ovl_op_info_t ovl_op_info[2][OVL_OP_MAX] =
      86              :   {
      87              :     {
      88              :       {NULL_TREE, NULL, NULL, NULL, ERROR_MARK, OVL_OP_ERROR_MARK, 0},
      89              :       {NULL_TREE, NULL, NULL, NULL, NOP_EXPR, OVL_OP_NOP_EXPR, 0},
      90              : #define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS, META) \
      91              :       {NULL_TREE, NAME, MANGLING, META, CODE, OVL_OP_##CODE, FLAGS},
      92              : #define OPERATOR_TRANSITION }, {                        \
      93              :       {NULL_TREE, NULL, NULL, NULL, ERROR_MARK, OVL_OP_ERROR_MARK, 0},
      94              : #include "operators.def"
      95              :     }
      96              :   };
      97              : unsigned char ovl_op_mapping[MAX_TREE_CODES];
      98              : unsigned char ovl_op_alternate[OVL_OP_MAX];
      99              : 
     100              : /* The trait table, declared in cp-tree.h.  */
     101              : const cp_trait cp_traits[] =
     102              : {
     103              : #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
     104              :   { NAME, CPTK_##CODE, ARITY, (TCC == tcc_type) },
     105              : #include "cp-trait.def"
     106              : #undef DEFTRAIT
     107              : };
     108              : /* The trait table cannot have more than 255 (addr_space_t) entries since
     109              :    the index is retrieved through IDENTIFIER_CP_INDEX.  */
     110              : static_assert(ARRAY_SIZE (cp_traits) <= 255,
     111              :               "cp_traits array cannot have more than 255 entries");
     112              : 
     113              : /* Get the name of the kind of identifier T.  */
     114              : 
     115              : const char *
     116            0 : get_identifier_kind_name (tree id)
     117              : {
     118              :   /* Keep in sync with cp_id_kind enumeration.  */
     119            0 :   static const char *const names[cik_max] = {
     120              :     "normal", "keyword", "constructor", "destructor",
     121              :     "simple-op", "assign-op", "conv-op", "<reserved>udlit-op"
     122              :   };
     123              : 
     124            0 :   unsigned kind = 0;
     125            0 :   kind |= IDENTIFIER_KIND_BIT_2 (id) << 2;
     126            0 :   kind |= IDENTIFIER_KIND_BIT_1 (id) << 1;
     127            0 :   kind |= IDENTIFIER_KIND_BIT_0 (id) << 0;
     128              : 
     129            0 :   return names[kind];
     130              : }
     131              : 
     132              : /* Set the identifier kind, which we expect to currently be zero.  */
     133              : 
     134              : void
     135     26715646 : set_identifier_kind (tree id, cp_identifier_kind kind)
     136              : {
     137     26715646 :   gcc_checking_assert (!IDENTIFIER_KIND_BIT_2 (id)
     138              :                        & !IDENTIFIER_KIND_BIT_1 (id)
     139              :                        & !IDENTIFIER_KIND_BIT_0 (id));
     140     26715646 :   IDENTIFIER_KIND_BIT_2 (id) |= (kind >> 2) & 1;
     141     26715646 :   IDENTIFIER_KIND_BIT_1 (id) |= (kind >> 1) & 1;
     142     26715646 :   IDENTIFIER_KIND_BIT_0 (id) |= (kind >> 0) & 1;
     143     26715646 : }
     144              : 
     145              : /* Create and tag the internal operator name for the overloaded
     146              :    operator PTR describes.  */
     147              : 
     148              : static tree
     149      5506648 : set_operator_ident (ovl_op_info_t *ptr)
     150              : {
     151      5506648 :   char buffer[32];
     152     11013296 :   size_t len = snprintf (buffer, sizeof (buffer), "operator%s%s",
     153      5506648 :                          &" "[ptr->name[0] && ptr->name[0] != '_'
     154      5506648 :                               && !ISALPHA (ptr->name[0])],
     155      5506648 :                          ptr->name);
     156      5506648 :   gcc_checking_assert (len < sizeof (buffer));
     157              : 
     158      5506648 :   tree ident = get_identifier_with_length (buffer, len);
     159      5506648 :   ptr->identifier = ident;
     160              : 
     161      5506648 :   return ident;
     162              : }
     163              : 
     164              : /* Initialize data structures that keep track of operator names.  */
     165              : 
     166              : static void
     167        98333 : init_operators (void)
     168              : {
     169              :   /* We rely on both these being zero.  */
     170        98333 :   gcc_checking_assert (!OVL_OP_ERROR_MARK && !ERROR_MARK);
     171              : 
     172              :   /* This loop iterates backwards because we need to move the
     173              :      assignment operators down to their correct slots.  I.e. morally
     174              :      equivalent to an overlapping memmove where dest > src.  Slot
     175              :      zero is for error_mark, so has no operator.  */
     176      5703314 :   for (unsigned ix = OVL_OP_MAX; --ix;)
     177              :     {
     178      5604981 :       ovl_op_info_t *op_ptr = &ovl_op_info[false][ix];
     179              : 
     180      5604981 :       if (op_ptr->name)
     181              :         {
     182      4424985 :           tree ident = set_operator_ident (op_ptr);
     183      4424985 :           if (unsigned index = IDENTIFIER_CP_INDEX (ident))
     184              :             {
     185       589998 :               ovl_op_info_t *bin_ptr = &ovl_op_info[false][index];
     186              : 
     187              :               /* They should only differ in unary/binary ness.  */
     188       589998 :               gcc_checking_assert ((op_ptr->flags ^ bin_ptr->flags)
     189              :                                    == OVL_OP_FLAG_AMBIARY);
     190       589998 :               bin_ptr->flags |= op_ptr->flags;
     191       589998 :               ovl_op_alternate[index] = ix;
     192              :             }
     193              :           else
     194              :             {
     195      3834987 :               IDENTIFIER_CP_INDEX (ident) = ix;
     196      3834987 :               set_identifier_kind (ident, cik_simple_op);
     197              :             }
     198              :         }
     199      5604981 :       if (op_ptr->tree_code)
     200              :         {
     201      5604981 :           gcc_checking_assert (op_ptr->ovl_op_code == ix
     202              :                                && !ovl_op_mapping[op_ptr->tree_code]);
     203      5604981 :           ovl_op_mapping[op_ptr->tree_code] = op_ptr->ovl_op_code;
     204              :         }
     205              : 
     206      5604981 :       ovl_op_info_t *as_ptr = &ovl_op_info[true][ix];
     207      5604981 :       if (as_ptr->name)
     208              :         {
     209              :           /* These will be placed at the start of the array, move to
     210              :              the correct slot and initialize.  */
     211      1081663 :           if (as_ptr->ovl_op_code != ix)
     212              :             {
     213       983330 :               ovl_op_info_t *dst_ptr = &ovl_op_info[true][as_ptr->ovl_op_code];
     214       983330 :               gcc_assert (as_ptr->ovl_op_code > ix && !dst_ptr->tree_code);
     215       983330 :               memcpy (dst_ptr, as_ptr, sizeof (*dst_ptr));
     216       983330 :               memset (as_ptr, 0, sizeof (*as_ptr));
     217       983330 :               as_ptr = dst_ptr;
     218              :             }
     219              : 
     220      1081663 :           tree ident = set_operator_ident (as_ptr);
     221      1081663 :           gcc_checking_assert (!IDENTIFIER_CP_INDEX (ident));
     222      1081663 :           IDENTIFIER_CP_INDEX (ident) = as_ptr->ovl_op_code;
     223      1081663 :           set_identifier_kind (ident, cik_assign_op);
     224              : 
     225      1081663 :           gcc_checking_assert (!ovl_op_mapping[as_ptr->tree_code]
     226              :                                || (ovl_op_mapping[as_ptr->tree_code]
     227              :                                    == as_ptr->ovl_op_code));
     228      1081663 :           ovl_op_mapping[as_ptr->tree_code] = as_ptr->ovl_op_code;
     229              :         }
     230              :     }
     231        98333 : }
     232              : 
     233              : /* Initialize the reserved words.  */
     234              : 
     235              : void
     236        98333 : init_reswords (void)
     237              : {
     238        98333 :   unsigned int i;
     239        98333 :   tree id;
     240        98333 :   int mask = 0;
     241              : 
     242        98333 :   if (cxx_dialect < cxx11)
     243        14193 :     mask |= D_CXX11;
     244        98333 :   if (cxx_dialect < cxx20)
     245        25284 :     mask |= D_CXX20;
     246        98333 :   if (cxx_dialect < cxx26)
     247        74667 :     mask |= D_CXX26;
     248        98333 :   if (!flag_concepts)
     249        25121 :     mask |= D_CXX_CONCEPTS;
     250        98333 :   if (!flag_coroutines)
     251        24320 :     mask |= D_CXX_COROUTINES;
     252        98333 :   if (!flag_modules)
     253        93479 :     mask |= D_CXX_MODULES;
     254        98333 :   if (!flag_tm)
     255        98012 :     mask |= D_TRANSMEM;
     256        98333 :   if (!flag_char8_t)
     257        25266 :     mask |= D_CXX_CHAR8_T;
     258        98333 :   if (flag_no_asm)
     259            3 :     mask |= D_ASM | D_EXT | D_EXT11;
     260        98333 :   if (flag_no_gnu_keywords)
     261        52204 :     mask |= D_EXT | D_EXT11;
     262              : 
     263              :   /* The Objective-C keywords are all context-dependent.  */
     264        98333 :   mask |= D_OBJC;
     265              : 
     266        98333 :   ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
     267     22911589 :   for (i = 0; i < num_c_common_reswords; i++)
     268              :     {
     269     22813256 :       if (c_common_reswords[i].disable & D_CONLY)
     270      4916650 :         continue;
     271     17896606 :       id = get_identifier (c_common_reswords[i].word);
     272     17896606 :       C_SET_RID_CODE (id, c_common_reswords[i].rid);
     273     17896606 :       ridpointers [(int) c_common_reswords[i].rid] = id;
     274     17896606 :       if (! (c_common_reswords[i].disable & mask))
     275     13338289 :         set_identifier_kind (id, cik_keyword);
     276              :     }
     277              : 
     278       196666 :   for (i = 0; i < NUM_INT_N_ENTS; i++)
     279              :     {
     280        98333 :       char name[50];
     281        98333 :       sprintf (name, "__int%d", int_n_data[i].bitsize);
     282        98333 :       id = get_identifier (name);
     283        98333 :       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
     284        98333 :       set_identifier_kind (id, cik_keyword);
     285              : 
     286        98333 :       sprintf (name, "__int%d__", int_n_data[i].bitsize);
     287        98333 :       id = get_identifier (name);
     288        98333 :       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
     289        98333 :       set_identifier_kind (id, cik_keyword);
     290              :     }
     291              : 
     292        98333 :   if (flag_openmp)
     293              :     {
     294         4069 :       id = get_identifier ("omp_all_memory");
     295         4069 :       C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
     296         4069 :       set_identifier_kind (id, cik_keyword);
     297         4069 :       ridpointers [RID_OMP_ALL_MEMORY] = id;
     298              :     }
     299        98333 : }
     300              : 
     301              : /* Initialize the C++ traits.  */
     302              : static void
     303        98333 : init_cp_traits (void)
     304              : {
     305        98333 :   tree id;
     306              : 
     307      7473308 :   for (unsigned int i = 0; i < ARRAY_SIZE (cp_traits); ++i)
     308              :     {
     309      7374975 :       id = get_identifier (cp_traits[i].name);
     310      7374975 :       IDENTIFIER_CP_INDEX (id) = cp_traits[i].kind;
     311      7374975 :       set_identifier_kind (id, cik_trait);
     312              :     }
     313              : 
     314              :   /* An alias for __is_same.  */
     315        98333 :   id = get_identifier ("__is_same_as");
     316        98333 :   IDENTIFIER_CP_INDEX (id) = CPTK_IS_SAME;
     317        98333 :   set_identifier_kind (id, cik_trait);
     318        98333 : }
     319              : 
     320              : static void
     321        96949 : init_cp_pragma (void)
     322              : {
     323        96949 :   c_register_pragma (0, "vtable", handle_pragma_vtable);
     324        96949 :   c_register_pragma (0, "unit", handle_pragma_unit);
     325        96949 :   c_register_pragma (0, "interface", handle_pragma_interface);
     326        96949 :   c_register_pragma (0, "implementation", handle_pragma_implementation);
     327        96949 :   c_register_pragma ("GCC", "interface", handle_pragma_interface);
     328        96949 :   c_register_pragma ("GCC", "implementation", handle_pragma_implementation);
     329        96949 : }
     330              : 
     331              : /* TRUE if a code represents a statement.  */
     332              : 
     333              : bool statement_code_p[MAX_TREE_CODES];
     334              : 
     335              : /* Initialize the C++ front end.  This function is very sensitive to
     336              :    the exact order that things are done here.  It would be nice if the
     337              :    initialization done by this routine were moved to its subroutines,
     338              :    and the ordering dependencies clarified and reduced.  */
     339              : bool
     340        98333 : cxx_init (void)
     341              : {
     342        98333 :   location_t saved_loc;
     343        98333 :   unsigned int i;
     344        98333 :   static const enum tree_code stmt_codes[] = {
     345              :    CTOR_INITIALIZER,    TRY_BLOCK,      HANDLER,
     346              :    EH_SPEC_BLOCK,       USING_STMT,     TAG_DEFN,
     347              :    IF_STMT,             CLEANUP_STMT,   FOR_STMT,
     348              :    RANGE_FOR_STMT,      WHILE_STMT,     DO_STMT,
     349              :    BREAK_STMT,          CONTINUE_STMT,  SWITCH_STMT,
     350              :    EXPR_STMT,           OMP_DEPOBJ
     351              :   };
     352              : 
     353        98333 :   memset (&statement_code_p, 0, sizeof (statement_code_p));
     354      1769994 :   for (i = 0; i < ARRAY_SIZE (stmt_codes); i++)
     355      1671661 :     statement_code_p[stmt_codes[i]] = true;
     356              : 
     357        98333 :   saved_loc = input_location;
     358        98333 :   input_location = BUILTINS_LOCATION;
     359              : 
     360        98333 :   init_reswords ();
     361        98333 :   init_cp_traits ();
     362        98333 :   init_tree ();
     363        98333 :   init_cp_semantics ();
     364        98333 :   init_operators ();
     365        98333 :   init_method ();
     366              : 
     367        98333 :   current_function_decl = NULL;
     368              : 
     369        98333 :   class_type_node = ridpointers[(int) RID_CLASS];
     370              : 
     371        98333 :   cxx_init_decl_processing ();
     372              : 
     373        98333 :   if (warn_keyword_macro)
     374              :     {
     375      3477059 :       for (unsigned int i = 0; i < num_c_common_reswords; ++i)
     376              :         /* For C++ none of the keywords in [lex.key] starts with underscore,
     377              :            don't register anything like that.  Don't complain about
     378              :            ObjC or Transactional Memory keywords.  */
     379      3462136 :         if (c_common_reswords[i].word[0] == '_')
     380      1581838 :           continue;
     381      1880298 :         else if (c_common_reswords[i].disable & (D_TRANSMEM | D_OBJC))
     382       567074 :           continue;
     383              :         else
     384              :           {
     385      1313224 :             tree id = get_identifier (c_common_reswords[i].word);
     386      1313224 :             if (IDENTIFIER_KEYWORD_P (id)
     387              :                 /* Don't register keywords with spaces.  */
     388      2541764 :                 && IDENTIFIER_POINTER (id)[IDENTIFIER_LENGTH (id) - 1] != ' ')
     389      1223812 :               cpp_warn (parse_in, IDENTIFIER_POINTER (id),
     390      1223812 :                         IDENTIFIER_LENGTH (id));
     391              :           }
     392        14923 :       if (cxx_dialect >= cxx11)
     393              :         {
     394        14922 :           cpp_warn (parse_in, "final");
     395        14922 :           cpp_warn (parse_in, "override");
     396        14922 :           cpp_warn (parse_in, "noreturn");
     397        14922 :           if (cxx_dialect < cxx26)
     398           11 :             cpp_warn (parse_in, "carries_dependency");
     399              :         }
     400        14923 :       if (cxx_dialect >= cxx14)
     401        14920 :         cpp_warn (parse_in, "deprecated");
     402        14923 :       if (cxx_dialect >= cxx17)
     403              :         {
     404        14918 :           cpp_warn (parse_in, "fallthrough");
     405        14918 :           cpp_warn (parse_in, "maybe_unused");
     406        14918 :           cpp_warn (parse_in, "nodiscard");
     407              :         }
     408        14923 :       if (cxx_dialect >= cxx20)
     409              :         {
     410        14916 :           cpp_warn (parse_in, "likely");
     411        14916 :           cpp_warn (parse_in, "unlikely");
     412        14916 :           cpp_warn (parse_in, "no_unique_address");
     413              :         }
     414        14923 :       if (flag_modules)
     415              :         {
     416         1576 :           cpp_warn (parse_in, "import");
     417         1576 :           cpp_warn (parse_in, "module");
     418              :         }
     419        14923 :       if (cxx_dialect >= cxx23)
     420        14913 :         cpp_warn (parse_in, "assume");
     421        14923 :       if (cxx_dialect >= cxx26)
     422              :         {
     423        14911 :           if (flag_contracts)
     424              :             {
     425        14911 :               cpp_warn (parse_in, "pre");
     426        14911 :               cpp_warn (parse_in, "post");
     427              :             }
     428        14911 :           cpp_warn (parse_in, "indeterminate");
     429              :         }
     430              :     }
     431              : 
     432        98333 :   if (c_common_init () == false)
     433              :     {
     434         1346 :       input_location = saved_loc;
     435         1346 :       return false;
     436              :     }
     437              : 
     438        96949 :   init_cp_pragma ();
     439              : 
     440        96949 :   input_location = saved_loc;
     441        96949 :   return true;
     442              : }
     443              : 
     444              : /* Return nonzero if S is not considered part of an
     445              :    INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */
     446              : 
     447              : static int
     448           79 : interface_strcmp (const char* s)
     449              : {
     450              :   /* Set the interface/implementation bits for this scope.  */
     451           79 :   struct impl_files *ifiles;
     452           79 :   const char *s1;
     453              : 
     454           91 :   for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
     455              :     {
     456           48 :       const char *t1 = ifiles->filename;
     457           48 :       s1 = s;
     458              : 
     459           48 :       if (*s1 == 0 || filename_ncmp (s1, t1, 1) != 0)
     460            6 :         continue;
     461              : 
     462          462 :       while (*s1 != 0 && filename_ncmp (s1, t1, 1) == 0)
     463          420 :         s1++, t1++;
     464              : 
     465              :       /* A match.  */
     466           42 :       if (*s1 == *t1)
     467              :         return 0;
     468              : 
     469              :       /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc.  */
     470           18 :       if (strchr (s1, '.') || strchr (t1, '.'))
     471            6 :         continue;
     472              : 
     473           12 :       if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
     474            0 :         continue;
     475              : 
     476              :       /* A match.  */
     477              :       return 0;
     478              :     }
     479              : 
     480              :   /* No matches.  */
     481              :   return 1;
     482              : }
     483              : 
     484              : /* We've just read a cpp-token, figure out our next state.  Hey, this
     485              :    is a hand-coded co-routine!  */
     486              : 
     487              : struct module_token_filter
     488              : {
     489              :   enum state
     490              :   {
     491              :    idle,
     492              :    module_first,
     493              :    module_cont,
     494              :    module_end,
     495              :   };
     496              : 
     497              :   enum state state : 8;
     498              :   bool is_import : 1;
     499              :   bool got_export : 1;
     500              :   bool got_colon : 1;
     501              :   bool want_dot : 1;
     502              : 
     503              :   location_t token_loc;
     504              :   cpp_reader *reader;
     505              :   module_state *module;
     506              :   module_state *import;
     507              : 
     508         4854 :   module_token_filter (cpp_reader *reader)
     509         4854 :     : state (idle), is_import (false),
     510         4854 :     got_export (false), got_colon (false), want_dot (false),
     511         4854 :     token_loc (UNKNOWN_LOCATION),
     512         4854 :     reader (reader), module (NULL), import (NULL)
     513              :   {
     514              :   };
     515              : 
     516              :   /* Process the next token.  Note we cannot see CPP_EOF inside a
     517              :      pragma -- a CPP_PRAGMA_EOL always happens.  */
     518     29251779 :   uintptr_t resume (int type, int keyword, tree value, location_t loc)
     519              :   {
     520     29251779 :     unsigned res = 0;
     521              : 
     522     29251779 :     switch (state)
     523              :       {
     524     29234181 :       case idle:
     525     29234181 :         if (type == CPP_KEYWORD)
     526      4955318 :           switch (keyword)
     527              :             {
     528              :             default:
     529              :               break;
     530              : 
     531         2242 :             case RID__EXPORT:
     532         2242 :               got_export = true;
     533         2242 :               res = lang_hooks::PT_begin_pragma;
     534         2242 :               break;
     535              : 
     536         2598 :             case RID__IMPORT:
     537         2598 :               is_import = true;
     538              :               /* FALLTHRU */
     539         5404 :             case RID__MODULE:
     540         5404 :               state = module_first;
     541         5404 :               want_dot = false;
     542         5404 :               got_colon = false;
     543         5404 :               token_loc = loc;
     544         5404 :               import = NULL;
     545         5404 :               if (!got_export)
     546         5404 :                 res = lang_hooks::PT_begin_pragma;
     547              :               break;
     548              :             }
     549              :         break;
     550              : 
     551         5419 :       case module_first:
     552         5419 :         if (is_import && type == CPP_HEADER_NAME)
     553              :           {
     554              :             /* A header name.  The preprocessor will have already
     555              :                done include searching and canonicalization.  */
     556          911 :             state = module_end;
     557          911 :             goto header_unit;
     558              :           }
     559              : 
     560         4508 :         if (type == CPP_PADDING || type == CPP_COMMENT)
     561              :           break;
     562              : 
     563         4493 :         state = module_cont;
     564         4493 :         if (type == CPP_COLON && module)
     565              :           {
     566          238 :             got_colon = true;
     567          238 :             import = module;
     568          238 :             break;
     569              :           }
     570              :         /* FALLTHROUGH  */
     571              : 
     572         9766 :       case module_cont:
     573         9766 :         switch (type)
     574              :           {
     575              :           case CPP_PADDING:
     576              :           case CPP_COMMENT:
     577              :             break;
     578              : 
     579         4475 :           default:
     580              :             /* If we ever need to pay attention to attributes for
     581              :                header modules, more logic will be needed.  */
     582         4475 :             state = module_end;
     583         4475 :             break;
     584              : 
     585          277 :           case CPP_COLON:
     586          277 :             if (got_colon)
     587            0 :               state = module_end;
     588          277 :             got_colon = true;
     589              :             /* FALLTHROUGH  */
     590          595 :           case CPP_DOT:
     591          595 :             if (!want_dot)
     592            9 :               state = module_end;
     593          595 :             want_dot = false;
     594          595 :             break;
     595              : 
     596            9 :           case CPP_PRAGMA_EOL:
     597            9 :             goto module_end;
     598              : 
     599         4606 :           case CPP_NAME:
     600         4606 :             if (want_dot)
     601              :               {
     602              :                 /* Got name instead of [.:].  */
     603            0 :                 state = module_end;
     604            0 :                 break;
     605              :               }
     606         4606 :           header_unit:
     607         5517 :             import = get_module (value, import, got_colon);
     608         5517 :             want_dot = true;
     609         5517 :             break;
     610              :           }
     611              :         break;
     612              : 
     613         6668 :       case module_end:
     614         6668 :         if (type == CPP_PRAGMA_EOL)
     615              :           {
     616         5395 :           module_end:;
     617              :             /* End of the directive, handle the name.  */
     618         5404 :             if (import && (is_import || !flag_header_unit))
     619         9898 :               if (module_state *m
     620         4949 :                   = preprocess_module (import, token_loc, module != NULL,
     621         4949 :                                        is_import, got_export, reader))
     622         2312 :                 if (!module)
     623         2312 :                   module = m;
     624              : 
     625         5404 :             is_import = got_export = false;
     626         5404 :             state = idle;
     627              :           }
     628              :         break;
     629              :       }
     630              : 
     631     29251779 :     return res;
     632              :   }
     633              : };
     634              : 
     635              : /* Initialize or teardown.  */
     636              : 
     637              : uintptr_t
     638        10942 : module_token_cdtor (cpp_reader *pfile, uintptr_t data_)
     639              : {
     640        10942 :   if (module_token_filter *filter = reinterpret_cast<module_token_filter *> (data_))
     641              :     {
     642         4854 :       preprocessed_module (pfile);
     643         4851 :       delete filter;
     644         4851 :       data_ = 0;
     645              :     }
     646         6088 :   else if (modules_p ())
     647         4854 :     data_ = reinterpret_cast<uintptr_t > (new module_token_filter (pfile));
     648              : 
     649        10939 :   return data_;
     650              : }
     651              : 
     652              : uintptr_t
     653     29251779 : module_token_lang (int type, int keyword, tree value, location_t loc,
     654              :                    uintptr_t data_)
     655              : {
     656     29251779 :   module_token_filter *filter = reinterpret_cast<module_token_filter *> (data_);
     657     29251779 :   return filter->resume (type, keyword, value, loc);
     658              : }
     659              : 
     660              : uintptr_t
     661       765639 : module_token_pre (cpp_reader *pfile, const cpp_token *tok, uintptr_t data_)
     662              : {
     663       765639 :   if (!tok)
     664         1522 :     return module_token_cdtor (pfile, data_);
     665              : 
     666       764117 :   int type = tok->type;
     667       764117 :   int keyword = RID_MAX;
     668       764117 :   tree value = NULL_TREE;
     669              : 
     670       764117 :   if (tok->type == CPP_NAME)
     671              :     {
     672       325584 :       value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node));
     673       325584 :       if (IDENTIFIER_KEYWORD_P (value))
     674              :         {
     675       127152 :           keyword = C_RID_CODE (value);
     676       127152 :           type = CPP_KEYWORD;
     677              :         }
     678              :     }
     679       438533 :   else if (tok->type == CPP_HEADER_NAME)
     680           48 :     value = build_string (tok->val.str.len, (const char *)tok->val.str.text);
     681              : 
     682       764117 :   return module_token_lang (type, keyword, value, tok->src_loc, data_);
     683              : }
     684              : 
     685              : /* Parse a #pragma whose sole argument is a string constant.
     686              :    If OPT is true, the argument is optional.  */
     687              : static tree
     688          121 : parse_strconst_pragma (const char* name, int opt)
     689              : {
     690          121 :   tree result, x;
     691          121 :   enum cpp_ttype t;
     692              : 
     693          121 :   t = pragma_lex (&result);
     694          121 :   if (t == CPP_STRING)
     695              :     {
     696           48 :       if (pragma_lex (&x) != CPP_EOF)
     697            0 :         warning (0, "junk at end of %<#pragma %s%>", name);
     698           48 :       return result;
     699              :     }
     700              : 
     701           73 :   if (t == CPP_EOF && opt)
     702              :     return NULL_TREE;
     703              : 
     704            0 :   error ("invalid %<#pragma %s%>", name);
     705            0 :   return error_mark_node;
     706              : }
     707              : 
     708              : static void
     709            0 : handle_pragma_vtable (cpp_reader* /*dfile*/)
     710              : {
     711            0 :   parse_strconst_pragma ("vtable", 0);
     712            0 :   sorry ("%<#pragma vtable%> no longer supported");
     713            0 : }
     714              : 
     715              : static void
     716            0 : handle_pragma_unit (cpp_reader* /*dfile*/)
     717              : {
     718              :   /* Validate syntax, but don't do anything.  */
     719            0 :   parse_strconst_pragma ("unit", 0);
     720            0 : }
     721              : 
     722              : static void
     723           79 : handle_pragma_interface (cpp_reader* /*dfile*/)
     724              : {
     725           79 :   tree fname = parse_strconst_pragma ("interface", 1);
     726           79 :   struct c_fileinfo *finfo;
     727           79 :   const char *filename;
     728              : 
     729           79 :   if (fname == error_mark_node)
     730              :     return;
     731           79 :   else if (fname == 0)
     732           61 :     filename = lbasename (LOCATION_FILE (input_location));
     733              :   else
     734           18 :     filename = TREE_STRING_POINTER (fname);
     735              : 
     736           79 :   finfo = get_fileinfo (LOCATION_FILE (input_location));
     737              : 
     738           79 :   if (impl_file_chain == 0)
     739              :     {
     740              :       /* If this is zero at this point, then we are
     741              :          auto-implementing.  */
     742           34 :       if (main_input_filename == 0)
     743            0 :         main_input_filename = LOCATION_FILE (input_location);
     744              :     }
     745              : 
     746           79 :   finfo->interface_only = interface_strcmp (filename);
     747              :   /* If MULTIPLE_SYMBOL_SPACES is set, we cannot assume that we can see
     748              :      a definition in another file.  */
     749           79 :   if (!MULTIPLE_SYMBOL_SPACES || !finfo->interface_only)
     750           79 :     finfo->interface_unknown = 0;
     751              : }
     752              : 
     753              : /* Note that we have seen a #pragma implementation for the key MAIN_FILENAME.
     754              :    We used to only allow this at toplevel, but that restriction was buggy
     755              :    in older compilers and it seems reasonable to allow it in the headers
     756              :    themselves, too.  It only needs to precede the matching #p interface.
     757              : 
     758              :    We don't touch finfo->interface_only or finfo->interface_unknown;
     759              :    the user must specify a matching #p interface for this to have
     760              :    any effect.  */
     761              : 
     762              : static void
     763           42 : handle_pragma_implementation (cpp_reader* /*dfile*/)
     764              : {
     765           42 :   tree fname = parse_strconst_pragma ("implementation", 1);
     766           42 :   const char *filename;
     767           42 :   struct impl_files *ifiles = impl_file_chain;
     768              : 
     769           42 :   if (fname == error_mark_node)
     770              :     return;
     771              : 
     772           42 :   if (fname == 0)
     773              :     {
     774           12 :       if (main_input_filename)
     775              :         filename = main_input_filename;
     776              :       else
     777            0 :         filename = LOCATION_FILE (input_location);
     778           12 :       filename = lbasename (filename);
     779              :     }
     780              :   else
     781              :     {
     782           30 :       filename = TREE_STRING_POINTER (fname);
     783           30 :       if (cpp_included_before (parse_in, filename, input_location))
     784            3 :         warning (0, "%<#pragma implementation%> for %qs appears after "
     785              :                  "file is included", filename);
     786              :     }
     787              : 
     788           45 :   for (; ifiles; ifiles = ifiles->next)
     789              :     {
     790            3 :       if (! filename_cmp (ifiles->filename, filename))
     791              :         break;
     792              :     }
     793           42 :   if (ifiles == 0)
     794              :     {
     795           42 :       ifiles = XNEW (struct impl_files);
     796           42 :       ifiles->filename = xstrdup (filename);
     797           42 :       ifiles->next = impl_file_chain;
     798           42 :       impl_file_chain = ifiles;
     799              :     }
     800              : }
     801              : 
     802              : /* Issue an error message indicating that the lookup of NAME (an
     803              :    IDENTIFIER_NODE) failed.  Returns the ERROR_MARK_NODE.  */
     804              : 
     805              : tree
     806         1815 : unqualified_name_lookup_error (tree name, location_t loc)
     807              : {
     808         1815 :   if (loc == UNKNOWN_LOCATION)
     809         1349 :     loc = cp_expr_loc_or_input_loc (name);
     810              : 
     811         1815 :   if (IDENTIFIER_ANY_OP_P (name))
     812            9 :     error_at (loc, "%qD not defined", name);
     813         1806 :   else if (!flag_concepts && name == ridpointers[(int)RID_REQUIRES])
     814            0 :     error_at (loc, "%<requires%> only available with %<-std=c++20%> or "
     815              :               "%<-fconcepts%>");
     816              :   else
     817              :     {
     818         1806 :       if (!objc_diagnose_private_ivar (name))
     819              :         {
     820         1806 :           auto_diagnostic_group d;
     821         1806 :           name_hint hint = suggest_alternatives_for (loc, name, true);
     822         1806 :           if (const char *suggestion = hint.suggestion ())
     823              :             {
     824          253 :               gcc_rich_location richloc (loc);
     825          253 :               richloc.add_fixit_replace (suggestion);
     826          253 :               error_at (&richloc,
     827              :                         "%qD was not declared in this scope; did you mean %qs?",
     828              :                         name, suggestion);
     829          253 :             }
     830              :           else
     831         1553 :             error_at (loc, "%qD was not declared in this scope", name);
     832         1806 :         }
     833              :       /* Prevent repeated error messages by creating a VAR_DECL with
     834              :          this NAME in the innermost block scope.  */
     835         1806 :       if (local_bindings_p ())
     836              :         {
     837         1418 :           tree decl = build_decl (loc, VAR_DECL, name, error_mark_node);
     838         1418 :           TREE_USED (decl) = true;
     839         1418 :           pushdecl (decl);
     840              :         }
     841              :     }
     842              : 
     843         1815 :   return error_mark_node;
     844              : }
     845              : 
     846              : /* Like unqualified_name_lookup_error, but NAME_EXPR is an unqualified-id
     847              :    NAME, encapsulated with its location in a CP_EXPR, used as a function.
     848              :    Returns an appropriate expression for NAME.  */
     849              : 
     850              : tree
     851          531 : unqualified_fn_lookup_error (cp_expr name_expr)
     852              : {
     853          531 :   tree name = name_expr.get_value ();
     854          531 :   location_t loc = name_expr.get_location ();
     855          531 :   if (loc == UNKNOWN_LOCATION)
     856           57 :     loc = input_location;
     857              : 
     858          531 :   if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
     859            3 :     name = TREE_OPERAND (name, 0);
     860              : 
     861          531 :   if (processing_template_decl)
     862              :     {
     863              :       /* In a template, it is invalid to write "f()" or "f(3)" if no
     864              :          declaration of "f" is available.  Historically, G++ and most
     865              :          other compilers accepted that usage since they deferred all name
     866              :          lookup until instantiation time rather than doing unqualified
     867              :          name lookup at template definition time; explain to the user what
     868              :          is going wrong.
     869              : 
     870              :          Note that we have the exact wording of the following message in
     871              :          the manual (trouble.texi, node "Name lookup"), so they need to
     872              :          be kept in synch.  */
     873           65 :       auto_diagnostic_group d;
     874           65 :       permerror (loc, "there are no arguments to %qD that depend on a template "
     875              :                  "parameter, so a declaration of %qD must be available",
     876              :                  name, name);
     877              : 
     878           65 :       if (!flag_permissive)
     879              :         {
     880           47 :           static bool hint;
     881           47 :           if (!hint)
     882              :             {
     883           38 :               inform (loc, "(if you use %<-fpermissive%>, G++ will accept your "
     884              :                       "code, but allowing the use of an undeclared name is "
     885              :                       "deprecated)");
     886           38 :               hint = true;
     887              :             }
     888              :         }
     889           65 :       return name;
     890           65 :     }
     891              : 
     892          466 :   return unqualified_name_lookup_error (name, loc);
     893              : }
     894              : 
     895              : 
     896              : /* Hasher for the conversion operator name hash table.  */
     897              : struct conv_type_hasher : ggc_ptr_hash<tree_node>
     898              : {
     899              :   /* Hash NODE, an identifier node in the table.  TYPE_UID is
     900              :      suitable, as we're not concerned about matching canonicalness
     901              :      here.  */
     902     20167988 :   static hashval_t hash (tree node)
     903              :   {
     904     20167988 :     return (hashval_t) TYPE_UID (TREE_TYPE (node));
     905              :   }
     906              : 
     907              :   /* Compare NODE, an identifier node in the table, against TYPE, an
     908              :      incoming TYPE being looked up.  */
     909     23767222 :   static bool equal (tree node, tree type)
     910              :   {
     911     23767222 :     return TREE_TYPE (node) == type;
     912              :   }
     913              : };
     914              : 
     915              : /* This hash table maps TYPEs to the IDENTIFIER for a conversion
     916              :    operator to TYPE.  The nodes are IDENTIFIERs whose TREE_TYPE is the
     917              :    TYPE.  */
     918              : 
     919              : static GTY (()) hash_table<conv_type_hasher> *conv_type_names;
     920              : 
     921              : /* Return an identifier for a conversion operator to TYPE.  We can get
     922              :    from the returned identifier to the type.  We store TYPE, which is
     923              :    not necessarily the canonical type,  which allows us to report the
     924              :    form the user used in error messages.  All these identifiers are
     925              :    not in the identifier hash table, and have the same string name.
     926              :    These IDENTIFIERS are not in the identifier hash table, and all
     927              :    have the same IDENTIFIER_STRING.  */
     928              : 
     929              : tree
     930      3546364 : make_conv_op_name (tree type)
     931              : {
     932      3546364 :   if (type == error_mark_node)
     933              :     return error_mark_node;
     934              : 
     935      3546361 :   if (conv_type_names == NULL)
     936        19851 :     conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);
     937              : 
     938      3546361 :   tree *slot = conv_type_names->find_slot_with_hash
     939      3546361 :     (type, (hashval_t) TYPE_UID (type), INSERT);
     940      3546361 :   tree identifier = *slot;
     941      3546361 :   if (!identifier)
     942              :     {
     943              :       /* Create a raw IDENTIFIER outside of the identifier hash
     944              :          table.  */
     945      1467988 :       identifier = copy_node (conv_op_identifier);
     946              : 
     947              :       /* Just in case something managed to bind.  */
     948      1467988 :       IDENTIFIER_BINDING (identifier) = NULL;
     949              : 
     950              :       /* Hang TYPE off the identifier so it can be found easily later
     951              :          when performing conversions.  */
     952      1467988 :       TREE_TYPE (identifier) = type;
     953              : 
     954      1467988 :       *slot = identifier;
     955              :     }
     956              : 
     957              :   return identifier;
     958              : }
     959              : 
     960              : /* Wrapper around build_lang_decl_loc(). Should gradually move to
     961              :    build_lang_decl_loc() and then rename build_lang_decl_loc() back to
     962              :    build_lang_decl().  */
     963              : 
     964              : tree
     965    304959599 : build_lang_decl (enum tree_code code, tree name, tree type)
     966              : {
     967    304959599 :   return build_lang_decl_loc (input_location, code, name, type);
     968              : }
     969              : 
     970              : /* Build a decl from CODE, NAME, TYPE declared at LOC, and then add
     971              :    DECL_LANG_SPECIFIC info to the result.  */
     972              : 
     973              : tree
     974    536460941 : build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type)
     975              : {
     976    536460941 :   tree t;
     977              : 
     978    536460941 :   t = build_decl (loc, code, name, type);
     979    536460941 :   retrofit_lang_decl (t);
     980              : 
     981    536460941 :   return t;
     982              : }
     983              : 
     984              : /* Maybe add a raw lang_decl to T, a decl.  Return true if it needed
     985              :    one.  */
     986              : 
     987              : bool
     988   1079100098 : maybe_add_lang_decl_raw (tree t, bool decomp_p)
     989              : {
     990   1079100098 :   size_t size;
     991   1079100098 :   lang_decl_selector sel;
     992              : 
     993   1079100098 :   if (decomp_p)
     994              :     sel = lds_decomp, size = sizeof (struct lang_decl_decomp);
     995   1078431954 :   else if (TREE_CODE (t) == FUNCTION_DECL)
     996              :     sel = lds_fn, size = sizeof (struct lang_decl_fn);
     997              :   else if (TREE_CODE (t) == NAMESPACE_DECL)
     998              :     sel = lds_ns, size = sizeof (struct lang_decl_ns);
     999              :   else if (TREE_CODE (t) == PARM_DECL)
    1000              :     sel = lds_parm, size = sizeof (struct lang_decl_parm);
    1001              :   else if (LANG_DECL_HAS_MIN (t))
    1002              :     sel = lds_min, size = sizeof (struct lang_decl_min);
    1003              :   else
    1004              :     return false;
    1005              : 
    1006   1079100098 :   struct lang_decl *ld
    1007   1079100098 :     = (struct lang_decl *) ggc_internal_cleared_alloc (size);
    1008              : 
    1009   1079100098 :   ld->u.base.selector = sel;
    1010   1079100098 :   DECL_LANG_SPECIFIC (t) = ld;
    1011              : 
    1012   1079100098 :   if (sel == lds_ns)
    1013              :     /* Who'd create a namespace, only to put nothing in it?  */
    1014      1118649 :     ld->u.ns.bindings = hash_table<named_decl_hash>::create_ggc (499);
    1015              : 
    1016              :   if (GATHER_STATISTICS)
    1017              :     {
    1018              :       tree_node_counts[(int)lang_decl] += 1;
    1019              :       tree_node_sizes[(int)lang_decl] += size;
    1020              :     }
    1021              :   return true;
    1022              : }
    1023              : 
    1024              : /* T has just had a decl_lang_specific added.  Initialize its
    1025              :    linkage.  */
    1026              : 
    1027              : static void
    1028   1076969756 : set_decl_linkage (tree t)
    1029              : {
    1030   1076969756 :   if (current_lang_name == lang_name_cplusplus
    1031   1076969756 :       || decl_linkage (t) == lk_none)
    1032    820964833 :     SET_DECL_LANGUAGE (t, lang_cplusplus);
    1033    256004923 :   else if (current_lang_name == lang_name_c)
    1034    256004923 :     SET_DECL_LANGUAGE (t, lang_c);
    1035              :   else
    1036            0 :     gcc_unreachable ();
    1037   1076969756 : }
    1038              : 
    1039              : /* T is a VAR_DECL node that needs to be a decomposition of BASE.  */
    1040              : 
    1041              : void
    1042      1245285 : fit_decomposition_lang_decl (tree t, tree base)
    1043              : {
    1044      1245285 :   if (struct lang_decl *orig_ld = DECL_LANG_SPECIFIC (t))
    1045              :     {
    1046       580481 :       if (orig_ld->u.base.selector == lds_min)
    1047              :         {
    1048         1308 :           maybe_add_lang_decl_raw (t, true);
    1049         1308 :           memcpy (DECL_LANG_SPECIFIC (t), orig_ld,
    1050              :                   sizeof (struct lang_decl_min));
    1051              :           /* Reset selector, which will have been bashed by the
    1052              :              memcpy.  */
    1053         1308 :           DECL_LANG_SPECIFIC (t)->u.base.selector = lds_decomp;
    1054              :         }
    1055              :       else
    1056       579173 :         gcc_checking_assert (orig_ld->u.base.selector == lds_decomp);
    1057              :     }
    1058              :   else
    1059              :     {
    1060       664804 :       maybe_add_lang_decl_raw (t, true);
    1061       664804 :       set_decl_linkage (t);
    1062              :     }
    1063              : 
    1064      1245285 :   DECL_DECOMP_BASE (t) = base;
    1065      1245285 : }
    1066              : 
    1067              : /* Add DECL_LANG_SPECIFIC info to T, if it needs one.  Generally
    1068              :    every C++ decl needs one, but C builtins etc do not.   */
    1069              : 
    1070              : void
    1071   1316510868 : retrofit_lang_decl (tree t)
    1072              : {
    1073   1316510868 :   if (DECL_LANG_SPECIFIC (t))
    1074              :     return;
    1075              : 
    1076   1076304952 :   if (maybe_add_lang_decl_raw (t, false))
    1077   1076304952 :     set_decl_linkage (t);
    1078              : }
    1079              : 
    1080              : void
    1081    888236414 : cxx_dup_lang_specific_decl (tree node)
    1082              : {
    1083    888236414 :   int size;
    1084              : 
    1085    888236414 :   if (! DECL_LANG_SPECIFIC (node))
    1086              :     return;
    1087              : 
    1088    647450172 :   switch (DECL_LANG_SPECIFIC (node)->u.base.selector)
    1089              :     {
    1090              :     case lds_min:
    1091              :       size = sizeof (struct lang_decl_min);
    1092              :       break;
    1093              :     case lds_fn:
    1094              :       size = sizeof (struct lang_decl_fn);
    1095              :       break;
    1096              :     case lds_ns:
    1097              :       size = sizeof (struct lang_decl_ns);
    1098              :       break;
    1099              :     case lds_parm:
    1100              :       size = sizeof (struct lang_decl_parm);
    1101              :       break;
    1102              :     case lds_decomp:
    1103              :       size = sizeof (struct lang_decl_decomp);
    1104              :       break;
    1105            0 :     default:
    1106            0 :       gcc_unreachable ();
    1107              :     }
    1108              : 
    1109    647450172 :   struct lang_decl *ld = (struct lang_decl *) ggc_internal_alloc (size);
    1110    647450172 :   memcpy (ld, DECL_LANG_SPECIFIC (node), size);
    1111    647450172 :   DECL_LANG_SPECIFIC (node) = ld;
    1112              : 
    1113              :   /* Directly clear some flags that do not apply to the copy
    1114              :      (module_purview_p still does).  */
    1115    647450172 :   ld->u.base.module_entity_p = false;
    1116    647450172 :   ld->u.base.module_import_p = false;
    1117    647450172 :   ld->u.base.module_keyed_decls_p = false;
    1118              : 
    1119    647450172 :   if (GATHER_STATISTICS)
    1120              :     {
    1121              :       tree_node_counts[(int)lang_decl] += 1;
    1122              :       tree_node_sizes[(int)lang_decl] += size;
    1123              :     }
    1124              : }
    1125              : 
    1126              : /* Copy DECL, including any language-specific parts.  */
    1127              : 
    1128              : tree
    1129    508139499 : copy_decl (tree decl MEM_STAT_DECL)
    1130              : {
    1131    508139499 :   tree copy;
    1132              : 
    1133    508139499 :   copy = copy_node (decl PASS_MEM_STAT);
    1134    508139499 :   cxx_dup_lang_specific_decl (copy);
    1135    508139499 :   return copy;
    1136              : }
    1137              : 
    1138              : /* Replace the shared language-specific parts of NODE with a new copy.  */
    1139              : 
    1140              : static void
    1141     14145011 : copy_lang_type (tree node)
    1142              : {
    1143     14145011 :   if (! TYPE_LANG_SPECIFIC (node))
    1144              :     return;
    1145              : 
    1146            0 :   size_t sz = (c_dialect_objc () ? sizeof (struct lang_type)
    1147              :                : offsetof (struct lang_type, info));
    1148            0 :   auto *lt = (struct lang_type *) ggc_internal_alloc (sz);
    1149              : 
    1150            0 :   memcpy (lt, TYPE_LANG_SPECIFIC (node), sz);
    1151            0 :   TYPE_LANG_SPECIFIC (node) = lt;
    1152              : 
    1153            0 :   if (GATHER_STATISTICS)
    1154              :     {
    1155              :       tree_node_counts[(int)lang_type] += 1;
    1156              :       tree_node_sizes[(int)lang_type] += sz;
    1157              :     }
    1158              : }
    1159              : 
    1160              : /* Copy TYPE, including any language-specific parts.  */
    1161              : 
    1162              : tree
    1163     14145011 : copy_type (tree type MEM_STAT_DECL)
    1164              : {
    1165     14145011 :   tree copy;
    1166              : 
    1167     14145011 :   copy = copy_node (type PASS_MEM_STAT);
    1168     14145011 :   copy_lang_type (copy);
    1169     14145011 :   return copy;
    1170              : }
    1171              : 
    1172              : /* Add a raw lang_type to T, a type, should it need one.  */
    1173              : 
    1174              : bool
    1175    779430345 : maybe_add_lang_type_raw (tree t)
    1176              : {
    1177    779430345 :   if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t)))
    1178              :     return false;
    1179              : 
    1180    129428253 :   size_t sz = (c_dialect_objc () ? sizeof (struct lang_type)
    1181              :                : offsetof (struct lang_type, info));
    1182    129428253 :   auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc (sz));
    1183    129428253 :   TYPE_LANG_SPECIFIC (t) = lt;
    1184              : 
    1185    129428253 :   if (GATHER_STATISTICS)
    1186              :     {
    1187              :       tree_node_counts[(int)lang_type] += 1;
    1188              :       tree_node_sizes[(int)lang_type] += sz;
    1189              :     }
    1190              : 
    1191    129428253 :   return true;
    1192              : }
    1193              : 
    1194              : tree
    1195    779279163 : cxx_make_type (enum tree_code code MEM_STAT_DECL)
    1196              : {
    1197    779279163 :   tree t = make_node (code PASS_MEM_STAT);
    1198              : 
    1199    779279163 :   if (maybe_add_lang_type_raw (t))
    1200              :     {
    1201              :       /* Set up some flags that give proper default behavior.  */
    1202    129277071 :       struct c_fileinfo *finfo
    1203    129277071 :         = get_fileinfo (LOCATION_FILE (input_location));
    1204    129277071 :       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
    1205    129277071 :       CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
    1206              :     }
    1207              : 
    1208    779279163 :   if (code == RECORD_TYPE || code == UNION_TYPE)
    1209    129277071 :     TYPE_CXX_ODR_P (t) = 1;
    1210              : 
    1211    779279163 :   return t;
    1212              : }
    1213              : 
    1214              : /* A wrapper without the memory stats for LANG_HOOKS_MAKE_TYPE.  */
    1215              : 
    1216              : tree
    1217       129441 : cxx_make_type_hook (enum tree_code code)
    1218              : {
    1219       129441 :   return cxx_make_type (code);
    1220              : }
    1221              : 
    1222              : tree
    1223    129147528 : make_class_type (enum tree_code code MEM_STAT_DECL)
    1224              : {
    1225    129147528 :   tree t = cxx_make_type (code PASS_MEM_STAT);
    1226    129147528 :   SET_CLASS_TYPE_P (t, 1);
    1227    129147528 :   return t;
    1228              : }
    1229              : 
    1230              : /* Returns true if we are currently in the main source file, or in a
    1231              :    template instantiation started from the main source file.  */
    1232              : 
    1233              : bool
    1234          142 : in_main_input_context (void)
    1235              : {
    1236          142 :   struct tinst_level *tl = outermost_tinst_level();
    1237              : 
    1238          142 :   if (tl)
    1239            9 :     return filename_cmp (main_input_filename,
    1240           18 :                          LOCATION_FILE (tl->locus)) == 0;
    1241              :   else
    1242          133 :     return filename_cmp (main_input_filename, LOCATION_FILE (input_location)) == 0;
    1243              : }
    1244              : 
    1245              : #include "gt-cp-lex.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.