LCOV - code coverage report
Current view: top level - gcc/cp - lex.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.7 % 504 472
Test Date: 2026-02-28 14:20:25 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        97210 : cxx_finish (void)
      81              : {
      82        97210 :   c_common_finish ();
      83        97210 : }
      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     26460065 : set_identifier_kind (tree id, cp_identifier_kind kind)
     136              : {
     137     26460065 :   gcc_checking_assert (!IDENTIFIER_KIND_BIT_2 (id)
     138              :                        & !IDENTIFIER_KIND_BIT_1 (id)
     139              :                        & !IDENTIFIER_KIND_BIT_0 (id));
     140     26460065 :   IDENTIFIER_KIND_BIT_2 (id) |= (kind >> 2) & 1;
     141     26460065 :   IDENTIFIER_KIND_BIT_1 (id) |= (kind >> 1) & 1;
     142     26460065 :   IDENTIFIER_KIND_BIT_0 (id) |= (kind >> 0) & 1;
     143     26460065 : }
     144              : 
     145              : /* Create and tag the internal operator name for the overloaded
     146              :    operator PTR describes.  */
     147              : 
     148              : static tree
     149      5454512 : set_operator_ident (ovl_op_info_t *ptr)
     150              : {
     151      5454512 :   char buffer[32];
     152     10909024 :   size_t len = snprintf (buffer, sizeof (buffer), "operator%s%s",
     153      5454512 :                          &" "[ptr->name[0] && ptr->name[0] != '_'
     154      5454512 :                               && !ISALPHA (ptr->name[0])],
     155      5454512 :                          ptr->name);
     156      5454512 :   gcc_checking_assert (len < sizeof (buffer));
     157              : 
     158      5454512 :   tree ident = get_identifier_with_length (buffer, len);
     159      5454512 :   ptr->identifier = ident;
     160              : 
     161      5454512 :   return ident;
     162              : }
     163              : 
     164              : /* Initialize data structures that keep track of operator names.  */
     165              : 
     166              : static void
     167        97402 : init_operators (void)
     168              : {
     169              :   /* We rely on both these being zero.  */
     170        97402 :   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      5649316 :   for (unsigned ix = OVL_OP_MAX; --ix;)
     177              :     {
     178      5551914 :       ovl_op_info_t *op_ptr = &ovl_op_info[false][ix];
     179              : 
     180      5551914 :       if (op_ptr->name)
     181              :         {
     182      4383090 :           tree ident = set_operator_ident (op_ptr);
     183      4383090 :           if (unsigned index = IDENTIFIER_CP_INDEX (ident))
     184              :             {
     185       584412 :               ovl_op_info_t *bin_ptr = &ovl_op_info[false][index];
     186              : 
     187              :               /* They should only differ in unary/binary ness.  */
     188       584412 :               gcc_checking_assert ((op_ptr->flags ^ bin_ptr->flags)
     189              :                                    == OVL_OP_FLAG_AMBIARY);
     190       584412 :               bin_ptr->flags |= op_ptr->flags;
     191       584412 :               ovl_op_alternate[index] = ix;
     192              :             }
     193              :           else
     194              :             {
     195      3798678 :               IDENTIFIER_CP_INDEX (ident) = ix;
     196      3798678 :               set_identifier_kind (ident, cik_simple_op);
     197              :             }
     198              :         }
     199      5551914 :       if (op_ptr->tree_code)
     200              :         {
     201      5551914 :           gcc_checking_assert (op_ptr->ovl_op_code == ix
     202              :                                && !ovl_op_mapping[op_ptr->tree_code]);
     203      5551914 :           ovl_op_mapping[op_ptr->tree_code] = op_ptr->ovl_op_code;
     204              :         }
     205              : 
     206      5551914 :       ovl_op_info_t *as_ptr = &ovl_op_info[true][ix];
     207      5551914 :       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      1071422 :           if (as_ptr->ovl_op_code != ix)
     212              :             {
     213       974020 :               ovl_op_info_t *dst_ptr = &ovl_op_info[true][as_ptr->ovl_op_code];
     214       974020 :               gcc_assert (as_ptr->ovl_op_code > ix && !dst_ptr->tree_code);
     215       974020 :               memcpy (dst_ptr, as_ptr, sizeof (*dst_ptr));
     216       974020 :               memset (as_ptr, 0, sizeof (*as_ptr));
     217       974020 :               as_ptr = dst_ptr;
     218              :             }
     219              : 
     220      1071422 :           tree ident = set_operator_ident (as_ptr);
     221      1071422 :           gcc_checking_assert (!IDENTIFIER_CP_INDEX (ident));
     222      1071422 :           IDENTIFIER_CP_INDEX (ident) = as_ptr->ovl_op_code;
     223      1071422 :           set_identifier_kind (ident, cik_assign_op);
     224              : 
     225      1071422 :           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      1071422 :           ovl_op_mapping[as_ptr->tree_code] = as_ptr->ovl_op_code;
     229              :         }
     230              :     }
     231        97402 : }
     232              : 
     233              : /* Initialize the reserved words.  */
     234              : 
     235              : void
     236        97402 : init_reswords (void)
     237              : {
     238        97402 :   unsigned int i;
     239        97402 :   tree id;
     240        97402 :   int mask = 0;
     241              : 
     242        97402 :   if (cxx_dialect < cxx11)
     243        14166 :     mask |= D_CXX11;
     244        97402 :   if (cxx_dialect < cxx20)
     245        25192 :     mask |= D_CXX20;
     246        97402 :   if (cxx_dialect < cxx26)
     247        73936 :     mask |= D_CXX26;
     248        97402 :   if (!flag_concepts)
     249        25029 :     mask |= D_CXX_CONCEPTS;
     250        97402 :   if (!flag_coroutines)
     251        24229 :     mask |= D_CXX_COROUTINES;
     252        97402 :   if (!flag_modules)
     253        92693 :     mask |= D_CXX_MODULES;
     254        97402 :   if (!flag_tm)
     255        97084 :     mask |= D_TRANSMEM;
     256        97402 :   if (!flag_char8_t)
     257        25174 :     mask |= D_CXX_CHAR8_T;
     258        97402 :   if (flag_no_asm)
     259            3 :     mask |= D_ASM | D_EXT | D_EXT11;
     260        97402 :   if (flag_no_gnu_keywords)
     261        51893 :     mask |= D_EXT | D_EXT11;
     262              : 
     263              :   /* The Objective-C keywords are all context-dependent.  */
     264        97402 :   mask |= D_OBJC;
     265              : 
     266        97402 :   ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
     267     22694666 :   for (i = 0; i < num_c_common_reswords; i++)
     268              :     {
     269     22597264 :       if (c_common_reswords[i].disable & D_CONLY)
     270      4870100 :         continue;
     271     17727164 :       id = get_identifier (c_common_reswords[i].word);
     272     17727164 :       C_SET_RID_CODE (id, c_common_reswords[i].rid);
     273     17727164 :       ridpointers [(int) c_common_reswords[i].rid] = id;
     274     17727164 :       if (! (c_common_reswords[i].disable & mask))
     275     13209347 :         set_identifier_kind (id, cik_keyword);
     276              :     }
     277              : 
     278       194804 :   for (i = 0; i < NUM_INT_N_ENTS; i++)
     279              :     {
     280        97402 :       char name[50];
     281        97402 :       sprintf (name, "__int%d", int_n_data[i].bitsize);
     282        97402 :       id = get_identifier (name);
     283        97402 :       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
     284        97402 :       set_identifier_kind (id, cik_keyword);
     285              : 
     286        97402 :       sprintf (name, "__int%d__", int_n_data[i].bitsize);
     287        97402 :       id = get_identifier (name);
     288        97402 :       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
     289        97402 :       set_identifier_kind (id, cik_keyword);
     290              :     }
     291              : 
     292        97402 :   if (flag_openmp)
     293              :     {
     294         4046 :       id = get_identifier ("omp_all_memory");
     295         4046 :       C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
     296         4046 :       set_identifier_kind (id, cik_keyword);
     297         4046 :       ridpointers [RID_OMP_ALL_MEMORY] = id;
     298              :     }
     299        97402 : }
     300              : 
     301              : /* Initialize the C++ traits.  */
     302              : static void
     303        97402 : init_cp_traits (void)
     304              : {
     305        97402 :   tree id;
     306              : 
     307      7402552 :   for (unsigned int i = 0; i < ARRAY_SIZE (cp_traits); ++i)
     308              :     {
     309      7305150 :       id = get_identifier (cp_traits[i].name);
     310      7305150 :       IDENTIFIER_CP_INDEX (id) = cp_traits[i].kind;
     311      7305150 :       set_identifier_kind (id, cik_trait);
     312              :     }
     313              : 
     314              :   /* An alias for __is_same.  */
     315        97402 :   id = get_identifier ("__is_same_as");
     316        97402 :   IDENTIFIER_CP_INDEX (id) = CPTK_IS_SAME;
     317        97402 :   set_identifier_kind (id, cik_trait);
     318        97402 : }
     319              : 
     320              : static void
     321        96030 : init_cp_pragma (void)
     322              : {
     323        96030 :   c_register_pragma (0, "vtable", handle_pragma_vtable);
     324        96030 :   c_register_pragma (0, "unit", handle_pragma_unit);
     325        96030 :   c_register_pragma (0, "interface", handle_pragma_interface);
     326        96030 :   c_register_pragma (0, "implementation", handle_pragma_implementation);
     327        96030 :   c_register_pragma ("GCC", "interface", handle_pragma_interface);
     328        96030 :   c_register_pragma ("GCC", "implementation", handle_pragma_implementation);
     329        96030 : }
     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        97402 : cxx_init (void)
     341              : {
     342        97402 :   location_t saved_loc;
     343        97402 :   unsigned int i;
     344        97402 :   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        97402 :   memset (&statement_code_p, 0, sizeof (statement_code_p));
     354      1753236 :   for (i = 0; i < ARRAY_SIZE (stmt_codes); i++)
     355      1655834 :     statement_code_p[stmt_codes[i]] = true;
     356              : 
     357        97402 :   saved_loc = input_location;
     358        97402 :   input_location = BUILTINS_LOCATION;
     359              : 
     360        97402 :   init_reswords ();
     361        97402 :   init_cp_traits ();
     362        97402 :   init_tree ();
     363        97402 :   init_cp_semantics ();
     364        97402 :   init_operators ();
     365        97402 :   init_method ();
     366              : 
     367        97402 :   current_function_decl = NULL;
     368              : 
     369        97402 :   class_type_node = ridpointers[(int) RID_CLASS];
     370              : 
     371        97402 :   cxx_init_decl_processing ();
     372              : 
     373        97402 :   if (warn_keyword_macro)
     374              :     {
     375      3439546 :       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      3424784 :         if (c_common_reswords[i].word[0] == '_')
     380      1564772 :           continue;
     381      1860012 :         else if (c_common_reswords[i].disable & (D_TRANSMEM | D_OBJC))
     382       560956 :           continue;
     383              :         else
     384              :           {
     385      1299056 :             tree id = get_identifier (c_common_reswords[i].word);
     386      1299056 :             if (IDENTIFIER_KEYWORD_P (id)
     387              :                 /* Don't register keywords with spaces.  */
     388      2514241 :                 && IDENTIFIER_POINTER (id)[IDENTIFIER_LENGTH (id) - 1] != ' ')
     389      1210610 :               cpp_warn (parse_in, IDENTIFIER_POINTER (id),
     390      1210610 :                         IDENTIFIER_LENGTH (id));
     391              :           }
     392        14762 :       if (cxx_dialect >= cxx11)
     393              :         {
     394        14761 :           cpp_warn (parse_in, "final");
     395        14761 :           cpp_warn (parse_in, "override");
     396        14761 :           cpp_warn (parse_in, "noreturn");
     397        14761 :           if (cxx_dialect < cxx26)
     398           11 :             cpp_warn (parse_in, "carries_dependency");
     399              :         }
     400        14762 :       if (cxx_dialect >= cxx14)
     401        14759 :         cpp_warn (parse_in, "deprecated");
     402        14762 :       if (cxx_dialect >= cxx17)
     403              :         {
     404        14757 :           cpp_warn (parse_in, "fallthrough");
     405        14757 :           cpp_warn (parse_in, "maybe_unused");
     406        14757 :           cpp_warn (parse_in, "nodiscard");
     407              :         }
     408        14762 :       if (cxx_dialect >= cxx20)
     409              :         {
     410        14755 :           cpp_warn (parse_in, "likely");
     411        14755 :           cpp_warn (parse_in, "unlikely");
     412        14755 :           cpp_warn (parse_in, "no_unique_address");
     413              :         }
     414        14762 :       if (flag_modules)
     415              :         {
     416         1525 :           cpp_warn (parse_in, "import");
     417         1525 :           cpp_warn (parse_in, "module");
     418              :         }
     419        14762 :       if (cxx_dialect >= cxx23)
     420        14752 :         cpp_warn (parse_in, "assume");
     421        14762 :       if (cxx_dialect >= cxx26)
     422              :         {
     423        14750 :           if (flag_contracts)
     424           81 :             cpp_warn (parse_in, "contract_assert");
     425        14750 :           cpp_warn (parse_in, "indeterminate");
     426              :         }
     427              :     }
     428              : 
     429        97402 :   if (c_common_init () == false)
     430              :     {
     431         1334 :       input_location = saved_loc;
     432         1334 :       return false;
     433              :     }
     434              : 
     435        96030 :   init_cp_pragma ();
     436              : 
     437        96030 :   input_location = saved_loc;
     438        96030 :   return true;
     439              : }
     440              : 
     441              : /* Return nonzero if S is not considered part of an
     442              :    INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */
     443              : 
     444              : static int
     445           79 : interface_strcmp (const char* s)
     446              : {
     447              :   /* Set the interface/implementation bits for this scope.  */
     448           79 :   struct impl_files *ifiles;
     449           79 :   const char *s1;
     450              : 
     451           91 :   for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
     452              :     {
     453           48 :       const char *t1 = ifiles->filename;
     454           48 :       s1 = s;
     455              : 
     456           48 :       if (*s1 == 0 || filename_ncmp (s1, t1, 1) != 0)
     457            6 :         continue;
     458              : 
     459          462 :       while (*s1 != 0 && filename_ncmp (s1, t1, 1) == 0)
     460          420 :         s1++, t1++;
     461              : 
     462              :       /* A match.  */
     463           42 :       if (*s1 == *t1)
     464              :         return 0;
     465              : 
     466              :       /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc.  */
     467           18 :       if (strchr (s1, '.') || strchr (t1, '.'))
     468            6 :         continue;
     469              : 
     470           12 :       if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
     471            0 :         continue;
     472              : 
     473              :       /* A match.  */
     474              :       return 0;
     475              :     }
     476              : 
     477              :   /* No matches.  */
     478              :   return 1;
     479              : }
     480              : 
     481              : /* We've just read a cpp-token, figure out our next state.  Hey, this
     482              :    is a hand-coded co-routine!  */
     483              : 
     484              : struct module_token_filter
     485              : {
     486              :   enum state
     487              :   {
     488              :    idle,
     489              :    module_first,
     490              :    module_cont,
     491              :    module_end,
     492              :   };
     493              : 
     494              :   enum state state : 8;
     495              :   bool is_import : 1;
     496              :   bool got_export : 1;
     497              :   bool got_colon : 1;
     498              :   bool want_dot : 1;
     499              : 
     500              :   location_t token_loc;
     501              :   cpp_reader *reader;
     502              :   module_state *module;
     503              :   module_state *import;
     504              : 
     505         4709 :   module_token_filter (cpp_reader *reader)
     506         4709 :     : state (idle), is_import (false),
     507         4709 :     got_export (false), got_colon (false), want_dot (false),
     508         4709 :     token_loc (UNKNOWN_LOCATION),
     509         4709 :     reader (reader), module (NULL), import (NULL)
     510              :   {
     511              :   };
     512              : 
     513              :   /* Process the next token.  Note we cannot see CPP_EOF inside a
     514              :      pragma -- a CPP_PRAGMA_EOL always happens.  */
     515     26514083 :   uintptr_t resume (int type, int keyword, tree value, location_t loc)
     516              :   {
     517     26514083 :     unsigned res = 0;
     518              : 
     519     26514083 :     switch (state)
     520              :       {
     521     26497129 :       case idle:
     522     26497129 :         if (type == CPP_KEYWORD)
     523      4520253 :           switch (keyword)
     524              :             {
     525              :             default:
     526              :               break;
     527              : 
     528         2120 :             case RID__EXPORT:
     529         2120 :               got_export = true;
     530         2120 :               res = lang_hooks::PT_begin_pragma;
     531         2120 :               break;
     532              : 
     533         2502 :             case RID__IMPORT:
     534         2502 :               is_import = true;
     535              :               /* FALLTHRU */
     536         5195 :             case RID__MODULE:
     537         5195 :               state = module_first;
     538         5195 :               want_dot = false;
     539         5195 :               got_colon = false;
     540         5195 :               token_loc = loc;
     541         5195 :               import = NULL;
     542         5195 :               if (!got_export)
     543         5195 :                 res = lang_hooks::PT_begin_pragma;
     544              :               break;
     545              :             }
     546              :         break;
     547              : 
     548         5210 :       case module_first:
     549         5210 :         if (is_import && type == CPP_HEADER_NAME)
     550              :           {
     551              :             /* A header name.  The preprocessor will have already
     552              :                done include searching and canonicalization.  */
     553          900 :             state = module_end;
     554          900 :             goto header_unit;
     555              :           }
     556              : 
     557         4310 :         if (type == CPP_PADDING || type == CPP_COMMENT)
     558              :           break;
     559              : 
     560         4295 :         state = module_cont;
     561         4295 :         if (type == CPP_COLON && module)
     562              :           {
     563          229 :             got_colon = true;
     564          229 :             import = module;
     565          229 :             break;
     566              :           }
     567              :         /* FALLTHROUGH  */
     568              : 
     569         9362 :       case module_cont:
     570         9362 :         switch (type)
     571              :           {
     572              :           case CPP_PADDING:
     573              :           case CPP_COMMENT:
     574              :             break;
     575              : 
     576         4277 :           default:
     577              :             /* If we ever need to pay attention to attributes for
     578              :                header modules, more logic will be needed.  */
     579         4277 :             state = module_end;
     580         4277 :             break;
     581              : 
     582          265 :           case CPP_COLON:
     583          265 :             if (got_colon)
     584            0 :               state = module_end;
     585          265 :             got_colon = true;
     586              :             /* FALLTHROUGH  */
     587          581 :           case CPP_DOT:
     588          581 :             if (!want_dot)
     589            9 :               state = module_end;
     590          581 :             want_dot = false;
     591          581 :             break;
     592              : 
     593            9 :           case CPP_PRAGMA_EOL:
     594            9 :             goto module_end;
     595              : 
     596         4414 :           case CPP_NAME:
     597         4414 :             if (want_dot)
     598              :               {
     599              :                 /* Got name instead of [.:].  */
     600            0 :                 state = module_end;
     601            0 :                 break;
     602              :               }
     603         4414 :           header_unit:
     604         5314 :             import = get_module (value, import, got_colon);
     605         5314 :             want_dot = true;
     606         5314 :             break;
     607              :           }
     608              :         break;
     609              : 
     610         6448 :       case module_end:
     611         6448 :         if (type == CPP_PRAGMA_EOL)
     612              :           {
     613         5186 :           module_end:;
     614              :             /* End of the directive, handle the name.  */
     615         5195 :             if (import && (is_import || !flag_header_unit))
     616         9520 :               if (module_state *m
     617         4760 :                   = preprocess_module (import, token_loc, module != NULL,
     618         4760 :                                        is_import, got_export, reader))
     619         2219 :                 if (!module)
     620         2219 :                   module = m;
     621              : 
     622         5195 :             is_import = got_export = false;
     623         5195 :             state = idle;
     624              :           }
     625              :         break;
     626              :       }
     627              : 
     628     26514083 :     return res;
     629              :   }
     630              : };
     631              : 
     632              : /* Initialize or teardown.  */
     633              : 
     634              : uintptr_t
     635        10643 : module_token_cdtor (cpp_reader *pfile, uintptr_t data_)
     636              : {
     637        10643 :   if (module_token_filter *filter = reinterpret_cast<module_token_filter *> (data_))
     638              :     {
     639         4709 :       preprocessed_module (pfile);
     640         4706 :       delete filter;
     641         4706 :       data_ = 0;
     642              :     }
     643         5934 :   else if (modules_p ())
     644         4709 :     data_ = reinterpret_cast<uintptr_t > (new module_token_filter (pfile));
     645              : 
     646        10640 :   return data_;
     647              : }
     648              : 
     649              : uintptr_t
     650     26514083 : module_token_lang (int type, int keyword, tree value, location_t loc,
     651              :                    uintptr_t data_)
     652              : {
     653     26514083 :   module_token_filter *filter = reinterpret_cast<module_token_filter *> (data_);
     654     26514083 :   return filter->resume (type, keyword, value, loc);
     655              : }
     656              : 
     657              : uintptr_t
     658       765032 : module_token_pre (cpp_reader *pfile, const cpp_token *tok, uintptr_t data_)
     659              : {
     660       765032 :   if (!tok)
     661         1507 :     return module_token_cdtor (pfile, data_);
     662              : 
     663       763525 :   int type = tok->type;
     664       763525 :   int keyword = RID_MAX;
     665       763525 :   tree value = NULL_TREE;
     666              : 
     667       763525 :   if (tok->type == CPP_NAME)
     668              :     {
     669       325292 :       value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node));
     670       325292 :       if (IDENTIFIER_KEYWORD_P (value))
     671              :         {
     672       127044 :           keyword = C_RID_CODE (value);
     673       127044 :           type = CPP_KEYWORD;
     674              :         }
     675              :     }
     676       438233 :   else if (tok->type == CPP_HEADER_NAME)
     677           45 :     value = build_string (tok->val.str.len, (const char *)tok->val.str.text);
     678              : 
     679       763525 :   return module_token_lang (type, keyword, value, tok->src_loc, data_);
     680              : }
     681              : 
     682              : /* Parse a #pragma whose sole argument is a string constant.
     683              :    If OPT is true, the argument is optional.  */
     684              : static tree
     685          121 : parse_strconst_pragma (const char* name, int opt)
     686              : {
     687          121 :   tree result, x;
     688          121 :   enum cpp_ttype t;
     689              : 
     690          121 :   t = pragma_lex (&result);
     691          121 :   if (t == CPP_STRING)
     692              :     {
     693           48 :       if (pragma_lex (&x) != CPP_EOF)
     694            0 :         warning (0, "junk at end of %<#pragma %s%>", name);
     695           48 :       return result;
     696              :     }
     697              : 
     698           73 :   if (t == CPP_EOF && opt)
     699              :     return NULL_TREE;
     700              : 
     701            0 :   error ("invalid %<#pragma %s%>", name);
     702            0 :   return error_mark_node;
     703              : }
     704              : 
     705              : static void
     706            0 : handle_pragma_vtable (cpp_reader* /*dfile*/)
     707              : {
     708            0 :   parse_strconst_pragma ("vtable", 0);
     709            0 :   sorry ("%<#pragma vtable%> no longer supported");
     710            0 : }
     711              : 
     712              : static void
     713            0 : handle_pragma_unit (cpp_reader* /*dfile*/)
     714              : {
     715              :   /* Validate syntax, but don't do anything.  */
     716            0 :   parse_strconst_pragma ("unit", 0);
     717            0 : }
     718              : 
     719              : static void
     720           79 : handle_pragma_interface (cpp_reader* /*dfile*/)
     721              : {
     722           79 :   tree fname = parse_strconst_pragma ("interface", 1);
     723           79 :   struct c_fileinfo *finfo;
     724           79 :   const char *filename;
     725              : 
     726           79 :   if (fname == error_mark_node)
     727              :     return;
     728           79 :   else if (fname == 0)
     729           61 :     filename = lbasename (LOCATION_FILE (input_location));
     730              :   else
     731           18 :     filename = TREE_STRING_POINTER (fname);
     732              : 
     733           79 :   finfo = get_fileinfo (LOCATION_FILE (input_location));
     734              : 
     735           79 :   if (impl_file_chain == 0)
     736              :     {
     737              :       /* If this is zero at this point, then we are
     738              :          auto-implementing.  */
     739           34 :       if (main_input_filename == 0)
     740            0 :         main_input_filename = LOCATION_FILE (input_location);
     741              :     }
     742              : 
     743           79 :   finfo->interface_only = interface_strcmp (filename);
     744              :   /* If MULTIPLE_SYMBOL_SPACES is set, we cannot assume that we can see
     745              :      a definition in another file.  */
     746           79 :   if (!MULTIPLE_SYMBOL_SPACES || !finfo->interface_only)
     747           79 :     finfo->interface_unknown = 0;
     748              : }
     749              : 
     750              : /* Note that we have seen a #pragma implementation for the key MAIN_FILENAME.
     751              :    We used to only allow this at toplevel, but that restriction was buggy
     752              :    in older compilers and it seems reasonable to allow it in the headers
     753              :    themselves, too.  It only needs to precede the matching #p interface.
     754              : 
     755              :    We don't touch finfo->interface_only or finfo->interface_unknown;
     756              :    the user must specify a matching #p interface for this to have
     757              :    any effect.  */
     758              : 
     759              : static void
     760           42 : handle_pragma_implementation (cpp_reader* /*dfile*/)
     761              : {
     762           42 :   tree fname = parse_strconst_pragma ("implementation", 1);
     763           42 :   const char *filename;
     764           42 :   struct impl_files *ifiles = impl_file_chain;
     765              : 
     766           42 :   if (fname == error_mark_node)
     767              :     return;
     768              : 
     769           42 :   if (fname == 0)
     770              :     {
     771           12 :       if (main_input_filename)
     772              :         filename = main_input_filename;
     773              :       else
     774            0 :         filename = LOCATION_FILE (input_location);
     775           12 :       filename = lbasename (filename);
     776              :     }
     777              :   else
     778              :     {
     779           30 :       filename = TREE_STRING_POINTER (fname);
     780           30 :       if (cpp_included_before (parse_in, filename, input_location))
     781            3 :         warning (0, "%<#pragma implementation%> for %qs appears after "
     782              :                  "file is included", filename);
     783              :     }
     784              : 
     785           45 :   for (; ifiles; ifiles = ifiles->next)
     786              :     {
     787            3 :       if (! filename_cmp (ifiles->filename, filename))
     788              :         break;
     789              :     }
     790           42 :   if (ifiles == 0)
     791              :     {
     792           42 :       ifiles = XNEW (struct impl_files);
     793           42 :       ifiles->filename = xstrdup (filename);
     794           42 :       ifiles->next = impl_file_chain;
     795           42 :       impl_file_chain = ifiles;
     796              :     }
     797              : }
     798              : 
     799              : /* Issue an error message indicating that the lookup of NAME (an
     800              :    IDENTIFIER_NODE) failed.  Returns the ERROR_MARK_NODE.  */
     801              : 
     802              : tree
     803         1809 : unqualified_name_lookup_error (tree name, location_t loc)
     804              : {
     805         1809 :   if (loc == UNKNOWN_LOCATION)
     806         1344 :     loc = cp_expr_loc_or_input_loc (name);
     807              : 
     808         1809 :   if (IDENTIFIER_ANY_OP_P (name))
     809            9 :     error_at (loc, "%qD not defined", name);
     810         1800 :   else if (!flag_concepts && name == ridpointers[(int)RID_REQUIRES])
     811            0 :     error_at (loc, "%<requires%> only available with %<-std=c++20%> or "
     812              :               "%<-fconcepts%>");
     813              :   else
     814              :     {
     815         1800 :       if (!objc_diagnose_private_ivar (name))
     816              :         {
     817         1800 :           auto_diagnostic_group d;
     818         1800 :           name_hint hint = suggest_alternatives_for (loc, name, true);
     819         1800 :           if (const char *suggestion = hint.suggestion ())
     820              :             {
     821          253 :               gcc_rich_location richloc (loc);
     822          253 :               richloc.add_fixit_replace (suggestion);
     823          253 :               error_at (&richloc,
     824              :                         "%qD was not declared in this scope; did you mean %qs?",
     825              :                         name, suggestion);
     826          253 :             }
     827              :           else
     828         1547 :             error_at (loc, "%qD was not declared in this scope", name);
     829         1800 :         }
     830              :       /* Prevent repeated error messages by creating a VAR_DECL with
     831              :          this NAME in the innermost block scope.  */
     832         1800 :       if (local_bindings_p ())
     833              :         {
     834         1418 :           tree decl = build_decl (loc, VAR_DECL, name, error_mark_node);
     835         1418 :           TREE_USED (decl) = true;
     836         1418 :           pushdecl (decl);
     837              :         }
     838              :     }
     839              : 
     840         1809 :   return error_mark_node;
     841              : }
     842              : 
     843              : /* Like unqualified_name_lookup_error, but NAME_EXPR is an unqualified-id
     844              :    NAME, encapsulated with its location in a CP_EXPR, used as a function.
     845              :    Returns an appropriate expression for NAME.  */
     846              : 
     847              : tree
     848          530 : unqualified_fn_lookup_error (cp_expr name_expr)
     849              : {
     850          530 :   tree name = name_expr.get_value ();
     851          530 :   location_t loc = name_expr.get_location ();
     852          530 :   if (loc == UNKNOWN_LOCATION)
     853           57 :     loc = input_location;
     854              : 
     855          530 :   if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
     856            2 :     name = TREE_OPERAND (name, 0);
     857              : 
     858          530 :   if (processing_template_decl)
     859              :     {
     860              :       /* In a template, it is invalid to write "f()" or "f(3)" if no
     861              :          declaration of "f" is available.  Historically, G++ and most
     862              :          other compilers accepted that usage since they deferred all name
     863              :          lookup until instantiation time rather than doing unqualified
     864              :          name lookup at template definition time; explain to the user what
     865              :          is going wrong.
     866              : 
     867              :          Note that we have the exact wording of the following message in
     868              :          the manual (trouble.texi, node "Name lookup"), so they need to
     869              :          be kept in synch.  */
     870           65 :       auto_diagnostic_group d;
     871           65 :       permerror (loc, "there are no arguments to %qD that depend on a template "
     872              :                  "parameter, so a declaration of %qD must be available",
     873              :                  name, name);
     874              : 
     875           65 :       if (!flag_permissive)
     876              :         {
     877           47 :           static bool hint;
     878           47 :           if (!hint)
     879              :             {
     880           38 :               inform (loc, "(if you use %<-fpermissive%>, G++ will accept your "
     881              :                       "code, but allowing the use of an undeclared name is "
     882              :                       "deprecated)");
     883           38 :               hint = true;
     884              :             }
     885              :         }
     886           65 :       return name;
     887           65 :     }
     888              : 
     889          465 :   return unqualified_name_lookup_error (name, loc);
     890              : }
     891              : 
     892              : 
     893              : /* Hasher for the conversion operator name hash table.  */
     894              : struct conv_type_hasher : ggc_ptr_hash<tree_node>
     895              : {
     896              :   /* Hash NODE, an identifier node in the table.  TYPE_UID is
     897              :      suitable, as we're not concerned about matching canonicalness
     898              :      here.  */
     899     21125404 :   static hashval_t hash (tree node)
     900              :   {
     901     21125404 :     return (hashval_t) TYPE_UID (TREE_TYPE (node));
     902              :   }
     903              : 
     904              :   /* Compare NODE, an identifier node in the table, against TYPE, an
     905              :      incoming TYPE being looked up.  */
     906     24656338 :   static bool equal (tree node, tree type)
     907              :   {
     908     24656338 :     return TREE_TYPE (node) == type;
     909              :   }
     910              : };
     911              : 
     912              : /* This hash table maps TYPEs to the IDENTIFIER for a conversion
     913              :    operator to TYPE.  The nodes are IDENTIFIERs whose TREE_TYPE is the
     914              :    TYPE.  */
     915              : 
     916              : static GTY (()) hash_table<conv_type_hasher> *conv_type_names;
     917              : 
     918              : /* Return an identifier for a conversion operator to TYPE.  We can get
     919              :    from the returned identifier to the type.  We store TYPE, which is
     920              :    not necessarily the canonical type,  which allows us to report the
     921              :    form the user used in error messages.  All these identifiers are
     922              :    not in the identifier hash table, and have the same string name.
     923              :    These IDENTIFIERS are not in the identifier hash table, and all
     924              :    have the same IDENTIFIER_STRING.  */
     925              : 
     926              : tree
     927      3760259 : make_conv_op_name (tree type)
     928              : {
     929      3760259 :   if (type == error_mark_node)
     930              :     return error_mark_node;
     931              : 
     932      3760256 :   if (conv_type_names == NULL)
     933        19461 :     conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);
     934              : 
     935      3760256 :   tree *slot = conv_type_names->find_slot_with_hash
     936      3760256 :     (type, (hashval_t) TYPE_UID (type), INSERT);
     937      3760256 :   tree identifier = *slot;
     938      3760256 :   if (!identifier)
     939              :     {
     940              :       /* Create a raw IDENTIFIER outside of the identifier hash
     941              :          table.  */
     942      1490747 :       identifier = copy_node (conv_op_identifier);
     943              : 
     944              :       /* Just in case something managed to bind.  */
     945      1490747 :       IDENTIFIER_BINDING (identifier) = NULL;
     946              : 
     947              :       /* Hang TYPE off the identifier so it can be found easily later
     948              :          when performing conversions.  */
     949      1490747 :       TREE_TYPE (identifier) = type;
     950              : 
     951      1490747 :       *slot = identifier;
     952              :     }
     953              : 
     954              :   return identifier;
     955              : }
     956              : 
     957              : /* Wrapper around build_lang_decl_loc(). Should gradually move to
     958              :    build_lang_decl_loc() and then rename build_lang_decl_loc() back to
     959              :    build_lang_decl().  */
     960              : 
     961              : tree
     962    306637713 : build_lang_decl (enum tree_code code, tree name, tree type)
     963              : {
     964    306637713 :   return build_lang_decl_loc (input_location, code, name, type);
     965              : }
     966              : 
     967              : /* Build a decl from CODE, NAME, TYPE declared at LOC, and then add
     968              :    DECL_LANG_SPECIFIC info to the result.  */
     969              : 
     970              : tree
     971    535196735 : build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type)
     972              : {
     973    535196735 :   tree t;
     974              : 
     975    535196735 :   t = build_decl (loc, code, name, type);
     976    535196735 :   retrofit_lang_decl (t);
     977              : 
     978    535196735 :   return t;
     979              : }
     980              : 
     981              : /* Maybe add a raw lang_decl to T, a decl.  Return true if it needed
     982              :    one.  */
     983              : 
     984              : bool
     985   1076069599 : maybe_add_lang_decl_raw (tree t, bool decomp_p)
     986              : {
     987   1076069599 :   size_t size;
     988   1076069599 :   lang_decl_selector sel;
     989              : 
     990   1076069599 :   if (decomp_p)
     991              :     sel = lds_decomp, size = sizeof (struct lang_decl_decomp);
     992   1075392209 :   else if (TREE_CODE (t) == FUNCTION_DECL)
     993              :     sel = lds_fn, size = sizeof (struct lang_decl_fn);
     994              :   else if (TREE_CODE (t) == NAMESPACE_DECL)
     995              :     sel = lds_ns, size = sizeof (struct lang_decl_ns);
     996              :   else if (TREE_CODE (t) == PARM_DECL)
     997              :     sel = lds_parm, size = sizeof (struct lang_decl_parm);
     998              :   else if (LANG_DECL_HAS_MIN (t))
     999              :     sel = lds_min, size = sizeof (struct lang_decl_min);
    1000              :   else
    1001              :     return false;
    1002              : 
    1003   1076069599 :   struct lang_decl *ld
    1004   1076069599 :     = (struct lang_decl *) ggc_internal_cleared_alloc (size);
    1005              : 
    1006   1076069599 :   ld->u.base.selector = sel;
    1007   1076069599 :   DECL_LANG_SPECIFIC (t) = ld;
    1008              : 
    1009   1076069599 :   if (sel == lds_ns)
    1010              :     /* Who'd create a namespace, only to put nothing in it?  */
    1011      1101997 :     ld->u.ns.bindings = hash_table<named_decl_hash>::create_ggc (499);
    1012              : 
    1013              :   if (GATHER_STATISTICS)
    1014              :     {
    1015              :       tree_node_counts[(int)lang_decl] += 1;
    1016              :       tree_node_sizes[(int)lang_decl] += size;
    1017              :     }
    1018              :   return true;
    1019              : }
    1020              : 
    1021              : /* T has just had a decl_lang_specific added.  Initialize its
    1022              :    linkage.  */
    1023              : 
    1024              : static void
    1025   1074117931 : set_decl_linkage (tree t)
    1026              : {
    1027   1074117931 :   if (current_lang_name == lang_name_cplusplus
    1028   1074117931 :       || decl_linkage (t) == lk_none)
    1029    820724681 :     SET_DECL_LANGUAGE (t, lang_cplusplus);
    1030    253393250 :   else if (current_lang_name == lang_name_c)
    1031    253393250 :     SET_DECL_LANGUAGE (t, lang_c);
    1032              :   else
    1033            0 :     gcc_unreachable ();
    1034   1074117931 : }
    1035              : 
    1036              : /* T is a VAR_DECL node that needs to be a decomposition of BASE.  */
    1037              : 
    1038              : void
    1039      1462034 : fit_decomposition_lang_decl (tree t, tree base)
    1040              : {
    1041      1462034 :   if (struct lang_decl *orig_ld = DECL_LANG_SPECIFIC (t))
    1042              :     {
    1043       787672 :       if (orig_ld->u.base.selector == lds_min)
    1044              :         {
    1045         1212 :           maybe_add_lang_decl_raw (t, true);
    1046         1212 :           memcpy (DECL_LANG_SPECIFIC (t), orig_ld,
    1047              :                   sizeof (struct lang_decl_min));
    1048              :           /* Reset selector, which will have been bashed by the
    1049              :              memcpy.  */
    1050         1212 :           DECL_LANG_SPECIFIC (t)->u.base.selector = lds_decomp;
    1051              :         }
    1052              :       else
    1053       786460 :         gcc_checking_assert (orig_ld->u.base.selector == lds_decomp);
    1054              :     }
    1055              :   else
    1056              :     {
    1057       674362 :       maybe_add_lang_decl_raw (t, true);
    1058       674362 :       set_decl_linkage (t);
    1059              :     }
    1060              : 
    1061      1462034 :   DECL_DECOMP_BASE (t) = base;
    1062      1462034 : }
    1063              : 
    1064              : /* Add DECL_LANG_SPECIFIC info to T, if it needs one.  Generally
    1065              :    every C++ decl needs one, but C builtins etc do not.   */
    1066              : 
    1067              : void
    1068   1310223150 : retrofit_lang_decl (tree t)
    1069              : {
    1070   1310223150 :   if (DECL_LANG_SPECIFIC (t))
    1071              :     return;
    1072              : 
    1073   1073443569 :   if (maybe_add_lang_decl_raw (t, false))
    1074   1073443569 :     set_decl_linkage (t);
    1075              : }
    1076              : 
    1077              : void
    1078    969123849 : cxx_dup_lang_specific_decl (tree node)
    1079              : {
    1080    969123849 :   int size;
    1081              : 
    1082    969123849 :   if (! DECL_LANG_SPECIFIC (node))
    1083              :     return;
    1084              : 
    1085    696813712 :   switch (DECL_LANG_SPECIFIC (node)->u.base.selector)
    1086              :     {
    1087              :     case lds_min:
    1088              :       size = sizeof (struct lang_decl_min);
    1089              :       break;
    1090              :     case lds_fn:
    1091              :       size = sizeof (struct lang_decl_fn);
    1092              :       break;
    1093              :     case lds_ns:
    1094              :       size = sizeof (struct lang_decl_ns);
    1095              :       break;
    1096              :     case lds_parm:
    1097              :       size = sizeof (struct lang_decl_parm);
    1098              :       break;
    1099              :     case lds_decomp:
    1100              :       size = sizeof (struct lang_decl_decomp);
    1101              :       break;
    1102            0 :     default:
    1103            0 :       gcc_unreachable ();
    1104              :     }
    1105              : 
    1106    696813712 :   struct lang_decl *ld = (struct lang_decl *) ggc_internal_alloc (size);
    1107    696813712 :   memcpy (ld, DECL_LANG_SPECIFIC (node), size);
    1108    696813712 :   DECL_LANG_SPECIFIC (node) = ld;
    1109              : 
    1110              :   /* Directly clear some flags that do not apply to the copy
    1111              :      (module_purview_p still does).  */
    1112    696813712 :   ld->u.base.module_entity_p = false;
    1113    696813712 :   ld->u.base.module_import_p = false;
    1114    696813712 :   ld->u.base.module_keyed_decls_p = false;
    1115              : 
    1116    696813712 :   if (GATHER_STATISTICS)
    1117              :     {
    1118              :       tree_node_counts[(int)lang_decl] += 1;
    1119              :       tree_node_sizes[(int)lang_decl] += size;
    1120              :     }
    1121              : }
    1122              : 
    1123              : /* Copy DECL, including any language-specific parts.  */
    1124              : 
    1125              : tree
    1126    557851292 : copy_decl (tree decl MEM_STAT_DECL)
    1127              : {
    1128    557851292 :   tree copy;
    1129              : 
    1130    557851292 :   copy = copy_node (decl PASS_MEM_STAT);
    1131    557851292 :   cxx_dup_lang_specific_decl (copy);
    1132    557851292 :   return copy;
    1133              : }
    1134              : 
    1135              : /* Replace the shared language-specific parts of NODE with a new copy.  */
    1136              : 
    1137              : static void
    1138     15382269 : copy_lang_type (tree node)
    1139              : {
    1140     15382269 :   if (! TYPE_LANG_SPECIFIC (node))
    1141              :     return;
    1142              : 
    1143            0 :   size_t sz = (c_dialect_objc () ? sizeof (struct lang_type)
    1144              :                : offsetof (struct lang_type, info));
    1145            0 :   auto *lt = (struct lang_type *) ggc_internal_alloc (sz);
    1146              : 
    1147            0 :   memcpy (lt, TYPE_LANG_SPECIFIC (node), sz);
    1148            0 :   TYPE_LANG_SPECIFIC (node) = lt;
    1149              : 
    1150            0 :   if (GATHER_STATISTICS)
    1151              :     {
    1152              :       tree_node_counts[(int)lang_type] += 1;
    1153              :       tree_node_sizes[(int)lang_type] += sz;
    1154              :     }
    1155              : }
    1156              : 
    1157              : /* Copy TYPE, including any language-specific parts.  */
    1158              : 
    1159              : tree
    1160     15382269 : copy_type (tree type MEM_STAT_DECL)
    1161              : {
    1162     15382269 :   tree copy;
    1163              : 
    1164     15382269 :   copy = copy_node (type PASS_MEM_STAT);
    1165     15382269 :   copy_lang_type (copy);
    1166     15382269 :   return copy;
    1167              : }
    1168              : 
    1169              : /* Add a raw lang_type to T, a type, should it need one.  */
    1170              : 
    1171              : bool
    1172    823124925 : maybe_add_lang_type_raw (tree t)
    1173              : {
    1174    823124925 :   if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t)))
    1175              :     return false;
    1176              : 
    1177    134121186 :   size_t sz = (c_dialect_objc () ? sizeof (struct lang_type)
    1178              :                : offsetof (struct lang_type, info));
    1179    134121186 :   auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc (sz));
    1180    134121186 :   TYPE_LANG_SPECIFIC (t) = lt;
    1181              : 
    1182    134121186 :   if (GATHER_STATISTICS)
    1183              :     {
    1184              :       tree_node_counts[(int)lang_type] += 1;
    1185              :       tree_node_sizes[(int)lang_type] += sz;
    1186              :     }
    1187              : 
    1188    134121186 :   return true;
    1189              : }
    1190              : 
    1191              : tree
    1192    822986316 : cxx_make_type (enum tree_code code MEM_STAT_DECL)
    1193              : {
    1194    822986316 :   tree t = make_node (code PASS_MEM_STAT);
    1195              : 
    1196    822986316 :   if (maybe_add_lang_type_raw (t))
    1197              :     {
    1198              :       /* Set up some flags that give proper default behavior.  */
    1199    133982577 :       struct c_fileinfo *finfo
    1200    133982577 :         = get_fileinfo (LOCATION_FILE (input_location));
    1201    133982577 :       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
    1202    133982577 :       CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
    1203              :     }
    1204              : 
    1205    822986316 :   if (code == RECORD_TYPE || code == UNION_TYPE)
    1206    133982577 :     TYPE_CXX_ODR_P (t) = 1;
    1207              : 
    1208    822986316 :   return t;
    1209              : }
    1210              : 
    1211              : /* A wrapper without the memory stats for LANG_HOOKS_MAKE_TYPE.  */
    1212              : 
    1213              : tree
    1214       128490 : cxx_make_type_hook (enum tree_code code)
    1215              : {
    1216       128490 :   return cxx_make_type (code);
    1217              : }
    1218              : 
    1219              : tree
    1220    133853986 : make_class_type (enum tree_code code MEM_STAT_DECL)
    1221              : {
    1222    133853986 :   tree t = cxx_make_type (code PASS_MEM_STAT);
    1223    133853986 :   SET_CLASS_TYPE_P (t, 1);
    1224    133853986 :   return t;
    1225              : }
    1226              : 
    1227              : /* Returns true if we are currently in the main source file, or in a
    1228              :    template instantiation started from the main source file.  */
    1229              : 
    1230              : bool
    1231          142 : in_main_input_context (void)
    1232              : {
    1233          142 :   struct tinst_level *tl = outermost_tinst_level();
    1234              : 
    1235          142 :   if (tl)
    1236            9 :     return filename_cmp (main_input_filename,
    1237           18 :                          LOCATION_FILE (tl->locus)) == 0;
    1238              :   else
    1239          133 :     return filename_cmp (main_input_filename, LOCATION_FILE (input_location)) == 0;
    1240              : }
    1241              : 
    1242              : #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.