LCOV - code coverage report
Current view: top level - gcc/rust/backend - rust-compile-context.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.6 % 222 199
Test Date: 2026-10-17 16:30:31 Functions: 95.7 % 23 22
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
       2              : 
       3              : // This file is part of GCC.
       4              : 
       5              : // GCC is free software; you can redistribute it and/or modify it under
       6              : // the terms of the GNU General Public License as published by the Free
       7              : // Software Foundation; either version 3, or (at your option) any later
       8              : // version.
       9              : 
      10              : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11              : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12              : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13              : // for more details.
      14              : 
      15              : // You should have received a copy of the GNU General Public License
      16              : // along with GCC; see the file COPYING3.  If not see
      17              : // <http://www.gnu.org/licenses/>.
      18              : 
      19              : #ifndef RUST_COMPILE_CONTEXT
      20              : #define RUST_COMPILE_CONTEXT
      21              : 
      22              : #include "optional.h"
      23              : #include "rust-system.h"
      24              : #include "rust-compile-drop-candidate.h"
      25              : #include "rust-hir-map.h"
      26              : #include "rust-name-resolver.h"
      27              : #include "rust-hir-type-check.h"
      28              : #include "rust-backend.h"
      29              : #include "rust-hir-full.h"
      30              : #include "rust-mangle.h"
      31              : #include "rust-tree.h"
      32              : #include "rust-finalized-name-resolution-context.h"
      33              : 
      34              : namespace Rust {
      35              : namespace Compile {
      36              : 
      37              : struct fncontext
      38              : {
      39        16251 :   fncontext (tree fndecl, ::Bvariable *ret_addr, TyTy::BaseType *retty)
      40        16251 :     : fndecl (fndecl), ret_addr (ret_addr), retty (retty)
      41              :   {}
      42              : 
      43              :   tree fndecl;
      44              :   ::Bvariable *ret_addr;
      45              :   TyTy::BaseType *retty;
      46              : };
      47              : 
      48            0 : struct CustomDeriveInfo
      49              : {
      50              :   tree fndecl;
      51              :   std::string trait_name;
      52              :   std::vector<std::string> attributes;
      53              : };
      54              : 
      55              : class DropBuilder;
      56              : 
      57              : class Context
      58              : {
      59              : public:
      60              :   static Context *get ();
      61              : 
      62              :   void setup_builtins ();
      63              : 
      64              :   bool lookup_compiled_types (tree t, tree *type)
      65              :   {
      66              :     hashval_t h = type_hasher (t);
      67              :     auto it = compiled_type_map.find (h);
      68              :     if (it == compiled_type_map.end ())
      69              :       return false;
      70              : 
      71              :     *type = it->second;
      72              :     return true;
      73              :   }
      74              : 
      75       294014 :   tree insert_compiled_type (tree type)
      76              :   {
      77       294014 :     hashval_t h = type_hasher (type);
      78       294014 :     auto it = compiled_type_map.find (h);
      79       294014 :     if (it != compiled_type_map.end ())
      80       201995 :       return it->second;
      81              : 
      82        92019 :     compiled_type_map.insert ({h, type});
      83              : 
      84        92019 :     if (TYPE_NAME (type) != NULL)
      85        92019 :       push_type (type);
      86              : 
      87              :     return type;
      88              :   }
      89              : 
      90        22525 :   bool lookup_compiled_adt (const TyTy::ADTType &adt, tree *type) const
      91              :   {
      92        22525 :     auto it = compiled_adt_types.find (compiled_adt_key (adt));
      93        22525 :     if (it == compiled_adt_types.end ())
      94              :       return false;
      95              : 
      96           38 :     *type = it->second;
      97           38 :     return true;
      98              :   }
      99              : 
     100           19 :   void insert_compiled_adt (const TyTy::ADTType &adt, tree type)
     101              :   {
     102           19 :     auto key = compiled_adt_key (adt);
     103           19 :     rust_assert (compiled_adt_types.find (key) == compiled_adt_types.end ());
     104           19 :     compiled_adt_types.insert ({key, type});
     105           19 :   }
     106              : 
     107              :   void erase_compiled_adt (const TyTy::ADTType &adt)
     108              :   {
     109              :     rust_assert (compiled_adt_types.erase (compiled_adt_key (adt)) == 1);
     110              :   }
     111              : 
     112        13899 :   tree insert_main_variant (tree type)
     113              :   {
     114        13899 :     hashval_t h = type_hasher (type);
     115        13899 :     auto it = main_variants.find (h);
     116        13899 :     if (it != main_variants.end ())
     117         8877 :       return it->second;
     118              : 
     119         5022 :     main_variants.insert ({h, type});
     120         5022 :     return type;
     121              :   }
     122              : 
     123       392929 :   Resolver::TypeCheckContext *get_tyctx () { return tyctx; }
     124       247382 :   Analysis::Mappings &get_mappings () { return mappings; }
     125              : 
     126        46164 :   void push_block (tree scope)
     127              :   {
     128        46164 :     scope_stack.push_back (scope);
     129        46164 :     statements.push_back ({});
     130        46164 :     block_drop_candidates.emplace_back ();
     131        46164 :   }
     132              : 
     133         6845 :   tree pop_block () { return pop_block_impl (NULL_TREE, UNKNOWN_LOCATION); }
     134              : 
     135        39303 :   tree pop_block_with_cleanup (tree cleanup, location_t cleanup_locus)
     136              :   {
     137        39303 :     return pop_block_impl (cleanup, cleanup_locus);
     138              :   }
     139              : 
     140        30384 :   tree peek_enclosing_scope ()
     141              :   {
     142        30384 :     if (scope_stack.size () == 0)
     143              :       return nullptr;
     144              : 
     145        30384 :     return scope_stack.back ();
     146              :   }
     147              : 
     148              :   void add_statement_to_enclosing_scope (tree stmt)
     149              :   {
     150              :     statements.at (statements.size () - 2).push_back (stmt);
     151              :   }
     152              : 
     153       126853 :   void add_statement (tree stmt) { statements.back ().push_back (stmt); }
     154              : 
     155        26517 :   void insert_var_decl (HirId id, ::Bvariable *decl)
     156              :   {
     157        26517 :     compiled_var_decls[id] = decl;
     158              :   }
     159              : 
     160        58457 :   bool lookup_var_decl (HirId id, ::Bvariable **decl)
     161              :   {
     162        58457 :     auto it = compiled_var_decls.find (id);
     163        58457 :     if (it == compiled_var_decls.end ())
     164              :       return false;
     165              : 
     166        44561 :     *decl = it->second;
     167        44561 :     return true;
     168              :   }
     169              : 
     170            1 :   void insert_drop_flag (HirId id, ::Bvariable *flag)
     171              :   {
     172            1 :     drop_flags[{peek_fn ().fndecl, id}] = flag;
     173            1 :   }
     174              : 
     175        12029 :   bool lookup_drop_flag (HirId id, ::Bvariable **flag)
     176              :   {
     177        12029 :     auto it = drop_flags.find ({peek_fn ().fndecl, id});
     178        12029 :     if (it == drop_flags.end ())
     179              :       return false;
     180              : 
     181            4 :     *flag = it->second;
     182            4 :     return true;
     183              :   }
     184              : 
     185        15901 :   void insert_function_decl (const TyTy::FnType *ref, tree fn)
     186              :   {
     187        15901 :     auto id = ref->get_ty_ref ();
     188        15901 :     auto dId = ref->get_id ();
     189              : 
     190        15901 :     rust_assert (compiled_fn_map.find (id) == compiled_fn_map.end ());
     191        15901 :     compiled_fn_map[id] = fn;
     192              : 
     193        15901 :     auto it = mono_fns.find (dId);
     194        15901 :     if (it == mono_fns.end ())
     195        15636 :       mono_fns[dId] = {};
     196              : 
     197        15901 :     mono_fns[dId].emplace_back (ref, fn);
     198        15901 :   }
     199              : 
     200           61 :   void insert_closure_decl (const TyTy::ClosureType *ref, tree fn)
     201              :   {
     202           61 :     auto dId = ref->get_def_id ();
     203           61 :     auto it = mono_closure_fns.find (dId);
     204           61 :     if (it == mono_closure_fns.end ())
     205           61 :       mono_closure_fns[dId] = {};
     206              : 
     207           61 :     mono_closure_fns[dId].emplace_back (ref, fn);
     208           61 :   }
     209              : 
     210              :   tree lookup_closure_decl (const TyTy::ClosureType *ref)
     211              :   {
     212              :     auto dId = ref->get_def_id ();
     213              :     auto it = mono_closure_fns.find (dId);
     214              :     if (it == mono_closure_fns.end ())
     215              :       return error_mark_node;
     216              : 
     217              :     for (auto &i : it->second)
     218              :       {
     219              :         const TyTy::ClosureType *t = i.first;
     220              :         tree fn = i.second;
     221              : 
     222              :         if (ref->is_equal (*t))
     223              :           return fn;
     224              :       }
     225              : 
     226              :     return error_mark_node;
     227              :   }
     228              : 
     229        34785 :   bool lookup_function_decl (HirId id, tree *fn, DefId dId = UNKNOWN_DEFID,
     230              :                              const TyTy::BaseType *ref = nullptr,
     231              :                              const std::string &asm_name = std::string ())
     232              :   {
     233              :     // for for any monomorphized fns
     234        34785 :     if (ref != nullptr)
     235              :       {
     236        23365 :         rust_assert (dId != UNKNOWN_DEFID);
     237              : 
     238        23365 :         auto it = mono_fns.find (dId);
     239        23365 :         if (it == mono_fns.end ())
     240              :           return false;
     241              : 
     242         4909 :         for (auto &e : mono_fns[dId])
     243              :           {
     244         4651 :             const TyTy::BaseType *r = e.first;
     245         4651 :             tree f = e.second;
     246              : 
     247         4651 :             if (ref->is_equal (*r))
     248              :               {
     249         4280 :                 *fn = f;
     250         4280 :                 return true;
     251              :               }
     252              : 
     253          371 :             if (DECL_ASSEMBLER_NAME_SET_P (f) && !asm_name.empty ())
     254              :               {
     255          332 :                 tree raw = DECL_ASSEMBLER_NAME_RAW (f);
     256          332 :                 const char *rptr = IDENTIFIER_POINTER (raw);
     257              : 
     258          332 :                 bool lengths_match_p
     259          332 :                   = IDENTIFIER_LENGTH (raw) == asm_name.size ();
     260          332 :                 if (lengths_match_p
     261          332 :                     && strncmp (rptr, asm_name.c_str (),
     262          331 :                                 IDENTIFIER_LENGTH (raw))
     263              :                          == 0)
     264              :                   {
     265            0 :                     *fn = f;
     266            0 :                     return true;
     267              :                   }
     268              :               }
     269              :           }
     270              :         return false;
     271              :       }
     272              : 
     273        11420 :     auto it = compiled_fn_map.find (id);
     274        11420 :     if (it == compiled_fn_map.end ())
     275              :       return false;
     276              : 
     277         5877 :     *fn = it->second;
     278         5877 :     return true;
     279              :   }
     280              : 
     281          533 :   void insert_const_decl (HirId id, tree expr) { compiled_consts[id] = expr; }
     282              : 
     283        47573 :   bool lookup_const_decl (HirId id, tree *expr)
     284              :   {
     285        47573 :     auto it = compiled_consts.find (id);
     286        47573 :     if (it == compiled_consts.end ())
     287              :       return false;
     288              : 
     289          641 :     *expr = it->second;
     290          641 :     return true;
     291              :   }
     292              : 
     293              :   void insert_label_decl (HirId id, tree label) { compiled_labels[id] = label; }
     294              : 
     295            0 :   bool lookup_label_decl (HirId id, tree *label)
     296              :   {
     297            0 :     auto it = compiled_labels.find (id);
     298            0 :     if (it == compiled_labels.end ())
     299              :       return false;
     300              : 
     301            0 :     *label = it->second;
     302            0 :     return true;
     303              :   }
     304              : 
     305           54 :   void insert_break_label (HirId id, tree label)
     306              :   {
     307           54 :     compiled_break_labels[id] = label;
     308              :   }
     309              : 
     310           33 :   tl::optional<tree> lookup_break_label (HirId id)
     311              :   {
     312           33 :     auto it = compiled_break_labels.find (id);
     313           33 :     if (it == compiled_break_labels.end ())
     314            0 :       return tl::nullopt;
     315           33 :     return it->second;
     316              :   }
     317              : 
     318           51 :   void insert_continue_label (HirId id, tree label)
     319              :   {
     320           51 :     compiled_continue_labels[id] = label;
     321              :   }
     322              : 
     323            6 :   tl::optional<tree> lookup_continue_label (HirId id)
     324              :   {
     325            6 :     auto it = compiled_continue_labels.find (id);
     326            6 :     if (it == compiled_continue_labels.end ())
     327            0 :       return tl::nullopt;
     328            6 :     return it->second;
     329              :   }
     330              : 
     331          933 :   void insert_pattern_binding (HirId id, tree binding)
     332              :   {
     333          933 :     implicit_pattern_bindings[id] = binding;
     334              :   }
     335              : 
     336        13841 :   bool lookup_pattern_binding (HirId id, tree *binding)
     337              :   {
     338        13841 :     auto it = implicit_pattern_bindings.find (id);
     339        13841 :     if (it == implicit_pattern_bindings.end ())
     340              :       return false;
     341              : 
     342          877 :     *binding = it->second;
     343          877 :     return true;
     344              :   }
     345              : 
     346          167 :   void insert_vtable (std::pair<size_t, size_t> pair, ::Bvariable *vtable)
     347              :   {
     348          167 :     compiled_vtables[pair] = vtable;
     349              :   }
     350              : 
     351          174 :   bool lookup_vtable (std::pair<size_t, size_t> pair, ::Bvariable **vtable)
     352              :   {
     353          174 :     auto it = compiled_vtables.find (pair);
     354          174 :     if (it == compiled_vtables.end ())
     355              :       return false;
     356              : 
     357            7 :     *vtable = it->second;
     358            7 :     return true;
     359              :   }
     360              : 
     361        16251 :   void push_fn (tree fn, ::Bvariable *ret_addr, TyTy::BaseType *retty)
     362              :   {
     363        16251 :     fn_stack.emplace_back (fn, ret_addr, retty);
     364              :   }
     365        16251 :   void pop_fn () { fn_stack.pop_back (); }
     366              : 
     367         4435 :   bool in_fn () { return fn_stack.size () != 0; }
     368              : 
     369              :   // Note: it is undefined behavior to call peek_fn () if fn_stack is empty.
     370        71506 :   fncontext peek_fn ()
     371              :   {
     372        71506 :     rust_assert (!fn_stack.empty ());
     373        71506 :     return fn_stack.back ();
     374              :   }
     375              : 
     376        92019 :   void push_type (tree t) { type_decls.push_back (t); }
     377          222 :   void push_var (::Bvariable *v) { var_decls.push_back (v); }
     378          533 :   void push_const (tree c) { const_decls.push_back (c); }
     379        17622 :   void push_function (tree f) { func_decls.push_back (f); }
     380              : 
     381         4415 :   void write_to_backend ()
     382              :   {
     383         4415 :     Backend::write_global_definitions (type_decls, const_decls, func_decls,
     384         4415 :                                        var_decls);
     385              :   }
     386              : 
     387            0 :   bool function_completed (tree fn)
     388              :   {
     389            0 :     for (auto it = func_decls.begin (); it != func_decls.end (); it++)
     390              :       {
     391            0 :         tree i = (*it);
     392            0 :         if (i == fn)
     393              :           {
     394              :             return true;
     395              :           }
     396              :       }
     397              :     return false;
     398              :   }
     399              : 
     400          244 :   void push_loop_context (Bvariable *var) { loop_value_stack.push_back (var); }
     401              : 
     402           42 :   bool have_loop_context () const { return !loop_value_stack.empty (); }
     403              : 
     404           17 :   Bvariable *peek_loop_context ()
     405              :   {
     406           17 :     rust_assert (!loop_value_stack.empty ());
     407           17 :     return loop_value_stack.back ();
     408              :   }
     409              : 
     410          147 :   Bvariable *pop_loop_context ()
     411              :   {
     412          147 :     auto back = loop_value_stack.back ();
     413          147 :     loop_value_stack.pop_back ();
     414          147 :     return back;
     415              :   }
     416              : 
     417          244 :   void push_loop_begin_label (tree label)
     418              :   {
     419          244 :     loop_begin_labels.push_back (label);
     420              :   }
     421              : 
     422           25 :   tree peek_loop_begin_label ()
     423              :   {
     424           25 :     rust_assert (!loop_begin_labels.empty ());
     425           25 :     return loop_begin_labels.back ();
     426              :   }
     427              : 
     428          244 :   tree pop_loop_begin_label ()
     429              :   {
     430          244 :     tree pop = loop_begin_labels.back ();
     431          244 :     loop_begin_labels.pop_back ();
     432          244 :     return pop;
     433              :   }
     434              : 
     435          244 :   void push_loop_end_label (tree label) { loop_end_labels.push_back (label); }
     436              : 
     437              :   tree peek_loop_end_label ()
     438              :   {
     439              :     rust_assert (!loop_end_labels.empty ());
     440              :     return loop_end_labels.back ();
     441              :   }
     442              : 
     443          244 :   tree pop_loop_end_label ()
     444              :   {
     445          244 :     rust_assert (!loop_end_labels.empty ());
     446          244 :     tree pop = loop_end_labels.back ();
     447          244 :     loop_end_labels.pop_back ();
     448          244 :     return pop;
     449              :   }
     450              : 
     451         3932 :   void push_const_context (void) { const_context++; }
     452         3932 :   void pop_const_context (void)
     453              :   {
     454         3932 :     if (const_context > 0)
     455         3932 :       const_context--;
     456              :   }
     457        27443 :   bool const_context_p (void) { return (const_context > 0); }
     458              : 
     459        35091 :   std::string mangle_item (const TyTy::BaseType *ty,
     460              :                            const Resolver::CanonicalPath &path)
     461              :   {
     462        35091 :     return mangler.mangle_item (this, ty, path);
     463              :   }
     464              : 
     465              :   void push_closure_context (HirId id);
     466              :   void pop_closure_context ();
     467              :   void insert_closure_binding (HirId id, tree expr);
     468              :   bool lookup_closure_binding (HirId id, tree *expr);
     469              : 
     470              :   std::vector<tree> &get_type_decls () { return type_decls; }
     471         4394 :   std::vector<::Bvariable *> &get_var_decls () { return var_decls; }
     472         4394 :   std::vector<tree> &get_const_decls () { return const_decls; }
     473         4394 :   std::vector<tree> &get_func_decls () { return func_decls; }
     474              : 
     475              :   static hashval_t type_hasher (tree type);
     476              : 
     477            0 :   void collect_attribute_proc_macro (tree fndecl)
     478              :   {
     479            0 :     attribute_macros.push_back (fndecl);
     480              :   }
     481              : 
     482            0 :   void collect_bang_proc_macro (tree fndecl) { bang_macros.push_back (fndecl); }
     483              : 
     484            0 :   void collect_derive_proc_macro (CustomDeriveInfo macro)
     485              :   {
     486            0 :     custom_derive_macros.push_back (macro);
     487              :   }
     488              : 
     489            0 :   const std::vector<tree> &get_bang_proc_macros () const { return bang_macros; }
     490              :   const std::vector<tree> &get_attribute_proc_macros () const
     491              :   {
     492            0 :     return attribute_macros;
     493              :   }
     494              :   const std::vector<CustomDeriveInfo> &get_derive_proc_macros () const
     495              :   {
     496            0 :     return custom_derive_macros;
     497              :   }
     498              : 
     499              : private:
     500              :   friend class DropBuilder;
     501              :   Context ();
     502              : 
     503              :   static hashval_t type_hasher (tree type, hash_set<tree> &active_types);
     504              : 
     505        46148 :   tree pop_block_impl (tree cleanup, location_t cleanup_locus)
     506              :   {
     507        46148 :     auto block = scope_stack.back ();
     508        46148 :     scope_stack.pop_back ();
     509              : 
     510        46148 :     auto stmts = statements.back ();
     511        46148 :     statements.pop_back ();
     512              : 
     513        46148 :     rust_assert (!block_drop_candidates.empty ());
     514        46148 :     block_drop_candidates.pop_back ();
     515              : 
     516        46148 :     if (cleanup != NULL_TREE)
     517              :       {
     518           50 :         tree body = Backend::statement_list (stmts);
     519           50 :         if (body == NULL_TREE)
     520            0 :           body = build_empty_stmt (cleanup_locus);
     521              : 
     522           50 :         tree exceptional_cleanup = build_empty_stmt (cleanup_locus);
     523           50 :         tree cleanup_selector
     524           50 :           = build2_loc (cleanup_locus, EH_ELSE_EXPR, void_type_node, cleanup,
     525              :                         exceptional_cleanup);
     526              : 
     527           50 :         tree try_finally
     528           50 :           = Backend::exception_handler_statement (body, NULL_TREE,
     529              :                                                   cleanup_selector,
     530              :                                                   cleanup_locus);
     531           50 :         Backend::block_add_statements (block, {try_finally});
     532              :       }
     533              :     else
     534        46098 :       Backend::block_add_statements (block, stmts);
     535              : 
     536        46148 :     return block;
     537        46148 :   }
     538              : 
     539              :   // we cant just use DefId because we can setup Adt<u32> vs Adt<i32> so the
     540              :   // tyref gets us the uniqueness we need
     541        22544 :   static std::pair<DefId, HirId> compiled_adt_key (const TyTy::ADTType &adt)
     542              :   {
     543        22544 :     HirId substitution
     544        22544 :       = adt.has_substitutions_defined () ? adt.get_ty_ref () : UNKNOWN_HIRID;
     545        22544 :     return {adt.get_id (), substitution};
     546              :   }
     547              : 
     548              :   Resolver::TypeCheckContext *tyctx;
     549              :   Analysis::Mappings &mappings;
     550              :   Mangler mangler;
     551              : 
     552              :   // state
     553              :   std::vector<fncontext> fn_stack;
     554              :   std::map<HirId, ::Bvariable *> compiled_var_decls;
     555              :   std::map<std::pair<tree, HirId>, ::Bvariable *> drop_flags;
     556              :   std::map<hashval_t, tree> compiled_type_map;
     557              :   std::map<std::pair<DefId, HirId>, tree> compiled_adt_types;
     558              :   std::map<HirId, tree> compiled_fn_map;
     559              :   std::map<HirId, tree> compiled_consts;
     560              :   std::map<HirId, tree> compiled_labels;
     561              :   std::map<std::pair<size_t, size_t>, ::Bvariable *> compiled_vtables;
     562              :   std::map<HirId, tree> compiled_break_labels;
     563              :   std::map<HirId, tree> compiled_continue_labels;
     564              :   std::vector<::std::vector<tree>> statements;
     565              :   std::vector<tree> scope_stack;
     566              :   std::vector<::std::vector<DropCandidate>> block_drop_candidates;
     567              :   std::vector<::Bvariable *> loop_value_stack;
     568              :   std::vector<tree> loop_begin_labels;
     569              :   std::vector<tree> loop_end_labels;
     570              :   std::map<DefId, std::vector<std::pair<const TyTy::BaseType *, tree>>>
     571              :     mono_fns;
     572              :   std::map<DefId, std::vector<std::pair<const TyTy::ClosureType *, tree>>>
     573              :     mono_closure_fns;
     574              :   std::map<HirId, tree> implicit_pattern_bindings;
     575              :   std::map<hashval_t, tree> main_variants;
     576              : 
     577              :   std::vector<CustomDeriveInfo> custom_derive_macros;
     578              :   std::vector<tree> attribute_macros;
     579              :   std::vector<tree> bang_macros;
     580              : 
     581              :   // closure bindings
     582              :   std::vector<HirId> closure_scope_bindings;
     583              :   std::map<HirId, std::map<HirId, tree>> closure_bindings;
     584              : 
     585              :   // To GCC middle-end
     586              :   std::vector<tree> type_decls;
     587              :   std::vector<::Bvariable *> var_decls;
     588              :   std::vector<tree> const_decls;
     589              :   std::vector<tree> func_decls;
     590              : 
     591              :   // Nonzero iff we are currently compiling something inside a constant context.
     592              :   unsigned int const_context = 0;
     593              : };
     594              : 
     595              : } // namespace Compile
     596              : } // namespace Rust
     597              : 
     598              : #endif // RUST_COMPILE_CONTEXT
        

Generated by: LCOV version 2.5.0-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.