LCOV - code coverage report
Current view: top level - gcc/rust/ast - rust-ast-builder.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.2 % 29 25
Test Date: 2026-08-22 16:33:35 Functions: 100.0 % 11 11
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 AST_BUILDER_H
      20              : #define AST_BUILDER_H
      21              : 
      22              : #include "rust-ast-full.h"
      23              : #include "rust-expr.h"
      24              : #include "rust-ast.h"
      25              : #include "rust-item.h"
      26              : #include "rust-operators.h"
      27              : #include "options.h"
      28              : #include "rust-system.h"
      29              : 
      30              : namespace Rust {
      31              : namespace AST {
      32              : 
      33              : template <typename T>
      34              : std::vector<std::unique_ptr<T>>
      35         2004 : vec (std::unique_ptr<T> &&t)
      36              : {
      37         2004 :   auto v = std::vector<std::unique_ptr<T>> ();
      38              : 
      39         2004 :   v.emplace_back (std::move (t));
      40              : 
      41              :   return v;
      42              : }
      43              : 
      44              : template <typename T>
      45              : std::vector<std::unique_ptr<T>>
      46         1513 : vec (std::unique_ptr<T> &&t1, std::unique_ptr<T> &&t2)
      47              : {
      48         1513 :   auto v = std::vector<std::unique_ptr<T>> ();
      49              : 
      50         1513 :   v.emplace_back (std::move (t1));
      51         1513 :   v.emplace_back (std::move (t2));
      52              : 
      53         1513 :   return v;
      54              : }
      55              : 
      56              : template <typename T>
      57              : std::vector<std::unique_ptr<T>>
      58           63 : vec (std::unique_ptr<T> &&t1, std::unique_ptr<T> &&t2, std::unique_ptr<T> &&t3)
      59              : {
      60           63 :   auto v = std::vector<std::unique_ptr<T>> ();
      61              : 
      62           63 :   v.emplace_back (std::move (t1));
      63           63 :   v.emplace_back (std::move (t2));
      64           63 :   v.emplace_back (std::move (t3));
      65              : 
      66           63 :   return v;
      67              : }
      68              : 
      69              : /* Pointer-ify something */
      70              : template <typename T>
      71              : static std::unique_ptr<T>
      72         1434 : ptrify (T value)
      73              : {
      74         1434 :   return std::unique_ptr<T> (new T (value));
      75              : }
      76              : 
      77              : // TODO: Use this builder when expanding regular macros
      78              : /* Builder class with helper methods to create AST nodes. This builder is
      79              :  * tailored towards generating multiple AST nodes from a single location, and
      80              :  * may not be suitable to other purposes */
      81              : class Builder
      82              : {
      83              : public:
      84              :   /**
      85              :    * Are we building AST nodes for paths within `core`, or any other crate? This
      86              :    * affects the leading path segment when constructing canonical paths, and is
      87              :    * especially important when deriving items.
      88              :    */
      89              :   enum class Source
      90              :   {
      91              :     InCore,
      92              :     Any,
      93              :   };
      94              : 
      95         1686 :   Builder (location_t loc, Source item_source)
      96         1686 :     : loc (loc), item_source (item_source)
      97              :   {}
      98              : 
      99              :   /* Create an expression statement from an expression */
     100              :   std::unique_ptr<Stmt> statementify (std::unique_ptr<Expr> &&value,
     101              :                                       bool semicolon_followed = true) const;
     102              : 
     103              :   /* Create a string literal expression ("content") */
     104              :   std::unique_ptr<Expr> literal_string (std::string &&content) const;
     105              : 
     106              :   /* Create a boolean literal expression (true) */
     107              :   std::unique_ptr<Expr> literal_bool (bool b) const;
     108              : 
     109              :   /* Create an identifier expression (`variable`) */
     110              :   std::unique_ptr<Expr> identifier (std::string name) const;
     111              :   std::unique_ptr<Pattern> identifier_pattern (std::string name,
     112              :                                                bool mut = false) const;
     113              : 
     114              :   /* Create a tuple index expression (`receiver.0`) */
     115              :   std::unique_ptr<Expr> tuple_idx (std::string receiver, int idx) const;
     116              : 
     117              :   /* Create a tuple expression (`(a1, a2, a3)`) */
     118              :   std::unique_ptr<Expr> tuple (std::vector<std::unique_ptr<Expr>> &&values
     119              :                                = {}) const;
     120              : 
     121              :   /* Create a reference to an expression (`&of`) */
     122              :   std::unique_ptr<Expr> ref (std::unique_ptr<Expr> &&of,
     123              :                              bool mut = false) const;
     124              : 
     125              :   /* Create a dereference of an expression (`*of`) */
     126              :   std::unique_ptr<Expr> deref (std::unique_ptr<Expr> &&of) const;
     127              : 
     128              :   /* Build a comparison expression (`lhs == rhs`) */
     129              :   std::unique_ptr<Expr> comparison_expr (std::unique_ptr<Expr> &&lhs,
     130              :                                          std::unique_ptr<Expr> &&rhs,
     131              :                                          ComparisonOperator op) const;
     132              : 
     133              :   /* Build a lazy boolean operator expression (`lhs && rhs`) */
     134              :   std::unique_ptr<Expr> boolean_operation (std::unique_ptr<Expr> &&lhs,
     135              :                                            std::unique_ptr<Expr> &&rhs,
     136              :                                            LazyBooleanOperator op) const;
     137              : 
     138              :   /* Create a block with an optional tail expression */
     139              :   std::unique_ptr<BlockExpr> block (std::vector<std::unique_ptr<Stmt>> &&stmts,
     140              :                                     std::unique_ptr<Expr> &&tail_expr
     141              :                                     = nullptr) const;
     142              :   std::unique_ptr<BlockExpr> block (tl::optional<std::unique_ptr<Stmt>> &&stmt,
     143              :                                     std::unique_ptr<Expr> &&tail_expr
     144              :                                     = nullptr) const;
     145              :   /* Create an empty block */
     146              :   std::unique_ptr<BlockExpr> block () const;
     147              : 
     148              :   /* Create a block with just a tail expression */
     149              :   std::unique_ptr<BlockExpr> block (std::unique_ptr<Expr> &&tail_expr) const;
     150              : 
     151              :   /* Create an early return expression with an optional expression */
     152              :   std::unique_ptr<Expr> return_expr (std::unique_ptr<Expr> &&to_return
     153              :                                      = nullptr);
     154              : 
     155              :   /* Create a let binding with an optional type and initializer (`let <name> :
     156              :    * <type> = <init>`) */
     157              :   std::unique_ptr<Stmt> let (std::unique_ptr<Pattern> &&pattern,
     158              :                              std::unique_ptr<Type> &&type = nullptr,
     159              :                              std::unique_ptr<Expr> &&init = nullptr) const;
     160              : 
     161              :   /**
     162              :    * Create a call expression to a function, struct or enum variant, given its
     163              :    * arguments (`path(arg0, arg1, arg2)`)
     164              :    */
     165              :   std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path,
     166              :                               std::vector<std::unique_ptr<Expr>> &&args
     167              :                               = {}) const;
     168              :   std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path,
     169              :                               std::unique_ptr<Expr> &&arg) const;
     170              : 
     171              :   /**
     172              :    * Create an array expression (`[member0, member1, member2]`)
     173              :    */
     174              :   std::unique_ptr<Expr>
     175              :   array (std::vector<std::unique_ptr<Expr>> &&members) const;
     176              : 
     177              :   /* Create a qualified path in expression (`<type as Trait>::seg::expr`) */
     178              :   std::unique_ptr<Expr>
     179              :   qualified_path_in_expression (std::unique_ptr<Type> &&type, TypePath trait,
     180              :                                 PathExprSegment segment) const;
     181              :   std::unique_ptr<Expr>
     182              :   qualified_path_in_expression (std::unique_ptr<Type> &&type, TypePath trait,
     183              :                                 std::vector<PathExprSegment> &&segments
     184              :                                 = {}) const;
     185              : 
     186              :   std::unique_ptr<Expr>
     187              :   qualified_call (std::vector<std::string> &&segments,
     188              :                   std::vector<std::unique_ptr<Expr>> &&args) const;
     189              : 
     190              :   /* Self parameter for a function definition (`&self`) */
     191              :   std::unique_ptr<Param> self_ref_param (bool mutability = false) const;
     192              :   /* A regular named function parameter for a definition (`a: type`) */
     193              :   std::unique_ptr<Param> function_param (std::unique_ptr<Pattern> &&pattern,
     194              :                                          std::unique_ptr<Type> &&type) const;
     195              : 
     196              :   /* Empty function qualifiers, with no specific qualifiers */
     197              :   FunctionQualifiers fn_qualifiers () const;
     198              : 
     199              :   std::unique_ptr<Function>
     200              :   function (std::string function_name,
     201              :             std::vector<std::unique_ptr<Param>> params,
     202              :             std::unique_ptr<Type> return_type, std::unique_ptr<BlockExpr> block,
     203              :             std::vector<std::unique_ptr<GenericParam>> generic_params = {},
     204              :             FunctionQualifiers qualifiers
     205              :             = FunctionQualifiers (UNKNOWN_LOCATION, Default::No, Async::No,
     206              :                                   Const::No, Unsafety::Normal),
     207              :             WhereClause where_clause = WhereClause::create_empty (),
     208              :             Visibility visibility = Visibility::create_private ()) const;
     209              : 
     210              :   /* Create a single path segment from one string */
     211              :   PathExprSegment path_segment (std::string seg) const;
     212              : 
     213              :   /* And similarly for type path segments */
     214              :   std::unique_ptr<TypePathSegment> type_path_segment (std::string seg) const;
     215              :   std::unique_ptr<TypePathSegment>
     216              :   type_path_segment (LangItem::Kind lang_item) const;
     217              : 
     218              :   std::unique_ptr<TypePathSegment>
     219              :   type_path_segment_generic (std::string seg, GenericArgs args) const;
     220              :   std::unique_ptr<TypePathSegment>
     221              :   type_path_segment_generic (LangItem::Kind lang_item, GenericArgs args) const;
     222              : 
     223              :   /* Create a Type from a single string - the most basic kind of type in our AST
     224              :    */
     225              :   std::unique_ptr<Type> single_type_path (std::string type) const;
     226              :   std::unique_ptr<Type> single_type_path (LangItem::Kind lang_item) const;
     227              : 
     228              :   std::unique_ptr<Type> single_generic_type_path (std::string type,
     229              :                                                   GenericArgs args) const;
     230              :   std::unique_ptr<Type> single_generic_type_path (LangItem::Kind lang_item,
     231              :                                                   GenericArgs args) const;
     232              : 
     233              :   TypePath type_path (std::vector<std::unique_ptr<TypePathSegment>> &&segment,
     234              :                       bool opening_scope = false) const;
     235              :   TypePath type_path (std::vector<std::string> &&segments,
     236              :                       bool opening_scope = false) const;
     237              :   TypePath type_path (std::unique_ptr<TypePathSegment> &&segment) const;
     238              :   TypePath type_path (std::string type) const;
     239              :   TypePath type_path (LangItem::Kind lang_item) const;
     240              : 
     241              :   std::unique_ptr<Type>
     242              :   reference_type (std::unique_ptr<TypeNoBounds> &&inner_type,
     243              :                   bool mutability = false) const;
     244              : 
     245              :   /**
     246              :    * Create a path in expression from multiple segments (`Clone::clone`). You
     247              :    * do not need to separate the segments using `::`, you can simply provide a
     248              :    * vector of strings to the functions which will get turned into path segments
     249              :    */
     250              :   PathInExpression path_in_expression (std::vector<std::string> &&segments,
     251              :                                        bool opening_scope = false) const;
     252              : 
     253              :   /**
     254              :    * Create a path in expression from a lang item.
     255              :    */
     256              :   PathInExpression path_in_expression (LangItem::Kind lang_item) const;
     257              : 
     258              :   /* Create the path to an enum's variant (`Result::Ok`) */
     259              :   PathInExpression variant_path (const std::string &enum_path,
     260              :                                  const std::string &variant) const;
     261              : 
     262              :   /* Create a new struct */
     263              :   std::unique_ptr<Stmt>
     264              :   struct_struct (std::string struct_name,
     265              :                  std::vector<std::unique_ptr<GenericParam>> &&generics,
     266              :                  std::vector<StructField> &&fields);
     267              : 
     268              :   /* Create a struct expression for unit structs (`S`) */
     269              :   std::unique_ptr<Expr> struct_expr_struct (std::string struct_name) const;
     270              : 
     271              :   /**
     272              :    * Create an expression for struct instantiation with fields (`S { a, b: c }`)
     273              :    * Named tuple expressions (`S(a, b, c)`) are call expressions and can thus be
     274              :    * constructed with `call`
     275              :    */
     276              :   std::unique_ptr<Expr>
     277              :   struct_expr (std::string struct_name,
     278              :                std::vector<std::unique_ptr<StructExprField>> &&fields) const;
     279              :   std::unique_ptr<Expr>
     280              :   struct_expr (PathInExpression struct_name,
     281              :                std::vector<std::unique_ptr<StructExprField>> &&fields) const;
     282              : 
     283              :   /* Create a field expression for struct instantiation (`field_name: value`) */
     284              :   std::unique_ptr<StructExprField>
     285              :   struct_expr_field (std::string field_name,
     286              :                      std::unique_ptr<Expr> &&value) const;
     287              : 
     288              :   /* Create a field access expression (`instance.field`) */
     289              :   std::unique_ptr<Expr> field_access (std::unique_ptr<Expr> &&instance,
     290              :                                       std::string field) const;
     291              : 
     292              :   std::unique_ptr<StructPatternField>
     293              :   struct_pattern_ident_pattern (std::string field_name,
     294              :                                 std::unique_ptr<Pattern> &&pattern);
     295              : 
     296              :   /* Create a wildcard pattern (`_`) */
     297              :   std::unique_ptr<Pattern> wildcard () const;
     298              :   /* Create a reference pattern (`&pattern`) */
     299              :   std::unique_ptr<Pattern> ref_pattern (std::unique_ptr<Pattern> &&inner) const;
     300              : 
     301              :   /* Create a lang item path usable as a general path */
     302              :   std::unique_ptr<Path> lang_item_path (LangItem::Kind) const;
     303              : 
     304              :   /* Create match expressions and their components */
     305              :   std::unique_ptr<Expr> match (std::unique_ptr<Expr> &&scrutinee,
     306              :                                std::vector<MatchCase> &&cases);
     307              :   MatchArm match_arm (std::unique_ptr<Pattern> &&pattern);
     308              :   MatchCase match_case (std::unique_ptr<Pattern> &&pattern,
     309              :                         std::unique_ptr<Expr> &&expr);
     310              :   MatchCase match_case (MatchArm &&arm, std::unique_ptr<Expr> &&expr);
     311              : 
     312              :   /* Create a loop expression */
     313              :   std::unique_ptr<Expr> loop (std::vector<std::unique_ptr<Stmt>> &&stmts);
     314              : 
     315              :   std::unique_ptr<TypeParamBound> trait_bound (TypePath bound);
     316              :   std::unique_ptr<Item>
     317              :   trait_impl (TypePath trait_path, std::unique_ptr<Type> target,
     318              :               std::vector<std::unique_ptr<AssociatedItem>> trait_items = {},
     319              :               std::vector<std::unique_ptr<GenericParam>> generics = {},
     320              :               WhereClause where_clause = WhereClause::create_empty (),
     321              :               Visibility visibility = Visibility::create_private ()) const;
     322              : 
     323              :   std::unique_ptr<GenericParam>
     324              :   generic_type_param (std::string type_representation,
     325              :                       std::vector<std::unique_ptr<TypeParamBound>> &&bounds,
     326              :                       std::unique_ptr<Type> &&type = nullptr);
     327              : 
     328              :   /**
     329              :    * Create a let statement with the discriminant value of a given enum
     330              :    * instance. This helper exists since it is a common operation in a lot of the
     331              :    * derive implementations, and it sucks to repeat all the steps every time.
     332              :    */
     333              :   std::unique_ptr<Stmt> discriminant_value (std::string binding_name,
     334           16 :                                             std::string instance = "self");
     335              : 
     336              :   static std::unique_ptr<GenericParam>
     337              :   new_lifetime_param (LifetimeParam &param);
     338              : 
     339              :   std::unique_ptr<GenericParam>
     340              :   new_const_param (ConstGenericParam &param) const;
     341              : 
     342              :   static std::unique_ptr<GenericParam> new_type_param (
     343              :     TypeParam &param,
     344              :     std::vector<std::unique_ptr<TypeParamBound>> extra_trait_bounds = {});
     345              : 
     346              :   static Lifetime new_lifetime (const Lifetime &lifetime);
     347              : 
     348              :   static GenericArgs new_generic_args (GenericArgs &args);
     349              : 
     350              :   /* Location of the generated AST nodes */
     351              :   location_t loc;
     352              : 
     353              :   /* The source in which we are creating AST nodes */
     354              :   Builder::Source item_source;
     355              : 
     356       672611 :   static Builder::Source get_item_source (const AST::Crate &crate)
     357              :   {
     358     23213835 :     for (const auto &attr : crate.inner_attrs)
     359     23213835 :       if (attr.as_string () == "no_core")
     360       672611 :         return Source::InCore;
     361              : 
     362              :     return Source::Any;
     363              :   }
     364              : 
     365         2839 :   const char *get_path_start () const
     366              :   {
     367         2839 :     switch (item_source)
     368              :       {
     369              :       case Builder::Source::InCore:
     370              :         return "crate";
     371            0 :       case Builder::Source::Any:
     372            0 :         return "core";
     373            0 :       default:
     374            0 :         rust_unreachable ();
     375              :       }
     376              :   }
     377              : };
     378              : 
     379              : } // namespace AST
     380              : } // namespace Rust
     381              : 
     382              : #endif // AST_BUILDER_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.