(root)/
gcc-13.2.0/
gcc/
cp/
gen-cxxapi-file.py
       1  #!/usr/bin/env python3
       2  
       3  # Copyright (C) 2022-2023 Free Software Foundation, Inc.
       4  # This file is part of GCC.
       5  
       6  # GCC is free software; you can redistribute it and/or modify
       7  # it under the terms of the GNU General Public License as published by
       8  # the Free Software Foundation; either version 3, or (at your option)
       9  # any later version.
      10  
      11  # GCC is distributed in the hope that it will be useful,
      12  # but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  # GNU General Public License for more details.
      15  
      16  # You should have received a copy of the GNU General Public License
      17  # along with GCC; see the file COPYING3.  If not see
      18  # <http://www.gnu.org/licenses/>.
      19  
      20  
      21  # Generate gcc source files:
      22  # - the export description of the standard C++ library module
      23  # - the gperf tables used to hint at actions to fix problems
      24  #   related to missing symbols in the std:: namespace
      25  
      26  import csv
      27  import os
      28  import time
      29  
      30  # The CSV file contains the following columns:
      31  #  column  value
      32  #       1  header file, including angle brackets
      33  #       2  symbol name without std:: prefix
      34  #       3  nonzero if to be exported
      35  #       4  "no" if not to be added to the hint table else the appropriate enum cxx_dialect value
      36  #       5  optional, a string used after #if in a line inserted first to enable conditional definitions
      37  
      38  
      39  def print_condition(prev, e):
      40      if len(e) > 4 and e[4] != '':
      41          if not prev or prev != e[4]:
      42              if prev:
      43                  print('#endif')
      44              print(f'#if {e[4]}')
      45          return e[4]
      46      if prev:
      47          print('#endif')
      48      return None
      49  
      50  
      51  def export(script, content):
      52      print("""// This file is auto-generated by {:s}.
      53  #if __cplusplus <= 202002L
      54  # if __cplusplus == 202002L
      55  #  ifdef __STRICT_ANSI__
      56  #   error "module `std' is only available before C++23 if using -std=gnu++20"
      57  #  endif
      58  # else
      59  #  error "module `std' is not available before C++23"
      60  # endif
      61  #endif
      62  
      63  export module std;
      64  
      65  import <bits/stdc++.h>;
      66  
      67  // new/delete operators in global namespace from <new>
      68  export using ::operator new;
      69  export using ::operator delete;
      70  export using ::operator new[];
      71  export using ::operator delete[];""".format(script))
      72      header = ''
      73      printed_header = False
      74      cond = None
      75      for e in content:
      76          if e[0] != header:
      77              header = e[0]
      78              printed_header = False
      79          if e[2] != 0:
      80              if not printed_header:
      81                  if cond:
      82                      print('#endif')
      83                      cond = None
      84                  print(f'\n// {header}')
      85                  printed_header = True
      86              cond = print_condition(cond, e)
      87              print(f'export using std::{e[1]};')
      88      if cond:
      89          print('#endif')
      90  
      91  
      92  def hints(script, content):
      93      print("""%language=C++
      94  %define class-name std_name_hint_lookup
      95  %struct-type
      96  %{{
      97  /* This file is auto-generated by {:s}.  */
      98  /* Copyright (C) {:s} Free Software Foundation, Inc.
      99  
     100  This file is part of GCC.
     101  
     102  GCC is free software; you can redistribute it and/or modify it under
     103  the terms of the GNU General Public License as published by the Free
     104  Software Foundation; either version 3, or (at your option) any later
     105  version.
     106  
     107  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     108  WARRANTY; without even the implied warranty of MERCHANTABILITY or
     109  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     110  for more details.
     111  
     112  You should have received a copy of the GNU General Public License
     113  along with GCC; see the file COPYING3.  If not see
     114  <http://www.gnu.org/licenses/>.  */
     115  %}}
     116  struct std_name_hint
     117  {{
     118    /* A name within "std::".  */
     119    const char *name;
     120  
     121    /* The header name defining it within the C++ Standard Library
     122       (with '<' and '>').  */
     123    const char* header;
     124  
     125    /* The dialect of C++ in which this was added.  */
     126    enum cxx_dialect min_dialect;
     127  }};
     128  %%
     129  # The standard-defined types, functions, and options in the std:: namespace
     130  # as defined in the C++ language specification.  The result is used in the
     131  # get_std_name_hint functions.
     132  #   throws an exception.
     133  #""".format(script, time.strftime('%Y')))
     134      header = ''
     135      printed_header = False
     136      for e in content:
     137          if e[0] != header:
     138              header = e[0]
     139              printed_header = False
     140          if e[3] != 'no':
     141              if not printed_header:
     142                  print(f'# {header}')
     143                  printed_header = True
     144              print(f'{e[1]}, "{e[0]}", {e[3]}')
     145  
     146  
     147  def remove_comment(f):
     148      for row in f:
     149          row = row.strip()
     150          if row[0] != '#':
     151              yield row
     152  
     153  
     154  modes = {
     155      'export': export,
     156      'hints': hints
     157  }
     158  
     159  
     160  def usage(script):
     161      print(f'Usage: {script} [{"|".join(modes.keys())}] CSVFILE')
     162      exit(1)
     163  
     164  
     165  def main(argv):
     166      if len(argv) < 3:
     167          usage(argv[0] if len(argv) > 0 else '???')
     168  
     169      script = argv[0]
     170      mode = argv[1]
     171      filename = argv[2]
     172  
     173      if mode not in modes:
     174          print(f"{script}: unrecognized mode '{mode}'")
     175          usage(script)
     176  
     177      try:
     178          with open(filename, 'r') as csvfile:
     179              modes[mode](os.path.basename(script), sorted(csv.reader(remove_comment(csvfile), delimiter=',')))
     180      except FileNotFoundError:
     181          print(f"{script}: cannot find CSV file '{filename}'")
     182          exit(1)
     183      except PermissionError:
     184          print(f"{script}: insufficient permission to read CSV file '{filename}'")
     185          exit(1)
     186  
     187  
     188  if __name__ == '__main__':
     189      import sys
     190      main(sys.argv)