(root)/
gcc-13.2.0/
gcc/
rust/
resolve/
rust-name-resolver.h
       1  // Copyright (C) 2020-2023 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_NAME_RESOLVER_H
      20  #define RUST_NAME_RESOLVER_H
      21  
      22  #include "rust-system.h"
      23  #include "rust-canonical-path.h"
      24  #include "rust-hir-map.h"
      25  #include "rust-hir-type-check.h"
      26  
      27  namespace Rust {
      28  namespace Resolver {
      29  
      30  class Rib
      31  {
      32  public:
      33    enum ItemType
      34    {
      35      Var,
      36      Param,
      37      Function,
      38      Type,
      39      Module,
      40      Static,
      41      Const,
      42      Trait,
      43      Impl,
      44      TraitImpl,
      45      ExternCrate,
      46      MacroDecl,
      47      Label,
      48      Unknown
      49    };
      50  
      51    // FIXME
      52    // Rust uses local_def_ids assigned by def_collector on the AST. Consider
      53    // moving to a local-def-id
      54    Rib (CrateNum crateNum, NodeId node_id);
      55  
      56    // this takes the relative paths of items within a compilation unit for lookup
      57    void insert_name (
      58      const CanonicalPath &path, NodeId id, Location locus, bool shadow,
      59      ItemType type,
      60      std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb);
      61  
      62    bool lookup_canonical_path (const NodeId &id, CanonicalPath *ident);
      63    bool lookup_name (const CanonicalPath &ident, NodeId *id);
      64    void clear_name (const CanonicalPath &ident, NodeId id);
      65    void append_reference_for_def (NodeId def, NodeId ref);
      66    bool have_references_for_node (NodeId def) const;
      67    bool decl_was_declared_here (NodeId def) const;
      68    bool lookup_decl_type (NodeId def, ItemType *type) const;
      69    void debug () const;
      70    std::string debug_str () const;
      71  
      72    CrateNum get_crate_num () const { return crate_num; }
      73    NodeId get_node_id () const { return node_id; }
      74    std::map<NodeId, Location> &get_declarations () { return decls_within_rib; }
      75  
      76  private:
      77    CrateNum crate_num;
      78    NodeId node_id;
      79    std::map<CanonicalPath, NodeId> path_mappings;
      80    std::map<NodeId, CanonicalPath> reverse_path_mappings;
      81    std::map<NodeId, Location> decls_within_rib;
      82    std::map<NodeId, std::set<NodeId>> references;
      83    std::map<NodeId, ItemType> decl_type_mappings;
      84  };
      85  
      86  class Scope
      87  {
      88  public:
      89    Scope (CrateNum crate_num);
      90  
      91    void
      92    insert (const CanonicalPath &ident, NodeId id, Location locus, bool shadow,
      93  	  Rib::ItemType type,
      94  	  std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb);
      95  
      96    void insert (const CanonicalPath &ident, NodeId id, Location locus,
      97  	       Rib::ItemType type = Rib::ItemType::Unknown);
      98    bool lookup (const CanonicalPath &ident, NodeId *id);
      99    bool lookup_decl_type (NodeId id, Rib::ItemType *type);
     100    bool lookup_rib_for_decl (NodeId id, const Rib **rib);
     101  
     102    void iterate (std::function<bool (Rib *)> cb);
     103    void iterate (std::function<bool (const Rib *)> cb) const;
     104  
     105    Rib *peek ();
     106    void push (NodeId id);
     107    Rib *pop ();
     108  
     109    bool decl_was_declared_here (NodeId def) const;
     110    void append_reference_for_def (NodeId refId, NodeId defId);
     111  
     112    CrateNum get_crate_num () const { return crate_num; }
     113  
     114    const std::vector<Rib *> &get_context () const { return stack; };
     115  
     116  private:
     117    CrateNum crate_num;
     118    std::vector<Rib *> stack;
     119  };
     120  
     121  class Resolver
     122  {
     123  public:
     124    static Resolver *get ();
     125    ~Resolver () {}
     126  
     127    // these builtin types
     128    void insert_builtin_types (Rib *r);
     129  
     130    // these will be required for type resolution passes to
     131    // map back to tyty nodes
     132    std::vector<AST::Type *> &get_builtin_types ();
     133  
     134    void push_new_name_rib (Rib *r);
     135    void push_new_type_rib (Rib *r);
     136    void push_new_label_rib (Rib *r);
     137    void push_new_macro_rib (Rib *r);
     138  
     139    bool find_name_rib (NodeId id, Rib **rib);
     140    bool find_type_rib (NodeId id, Rib **rib);
     141    bool find_label_rib (NodeId id, Rib **rib);
     142    bool find_macro_rib (NodeId id, Rib **rib);
     143  
     144    void insert_resolved_name (NodeId refId, NodeId defId);
     145    bool lookup_resolved_name (NodeId refId, NodeId *defId);
     146  
     147    void insert_resolved_type (NodeId refId, NodeId defId);
     148    bool lookup_resolved_type (NodeId refId, NodeId *defId);
     149  
     150    void insert_resolved_label (NodeId refId, NodeId defId);
     151    bool lookup_resolved_label (NodeId refId, NodeId *defId);
     152  
     153    void insert_resolved_macro (NodeId refId, NodeId defId);
     154    bool lookup_resolved_macro (NodeId refId, NodeId *defId);
     155  
     156    void insert_resolved_misc (NodeId refId, NodeId defId);
     157    bool lookup_resolved_misc (NodeId refId, NodeId *defId);
     158  
     159    // proxy for scoping
     160    Scope &get_name_scope () { return name_scope; }
     161    Scope &get_type_scope () { return type_scope; }
     162    Scope &get_label_scope () { return label_scope; }
     163    Scope &get_macro_scope () { return macro_scope; }
     164  
     165    NodeId get_global_type_node_id () { return global_type_node_id; }
     166    void set_unit_type_node_id (NodeId id) { unit_ty_node_id = id; }
     167    NodeId get_unit_type_node_id () { return unit_ty_node_id; }
     168  
     169    void push_new_module_scope (NodeId module_id)
     170    {
     171      current_module_stack.push_back (module_id);
     172    }
     173  
     174    void pop_module_scope ()
     175    {
     176      rust_assert (!current_module_stack.empty ());
     177      current_module_stack.pop_back ();
     178    }
     179  
     180    NodeId peek_current_module_scope () const
     181    {
     182      rust_assert (!current_module_stack.empty ());
     183      return current_module_stack.back ();
     184    }
     185  
     186    NodeId peek_crate_module_scope () const
     187    {
     188      rust_assert (!current_module_stack.empty ());
     189      return current_module_stack.front ();
     190    }
     191  
     192    NodeId peek_parent_module_scope () const
     193    {
     194      rust_assert (current_module_stack.size () > 1);
     195      return current_module_stack.at (current_module_stack.size () - 2);
     196    }
     197  
     198    void push_closure_context (NodeId closure_expr_id);
     199    void pop_closure_context ();
     200    void insert_captured_item (NodeId id);
     201    const std::set<NodeId> &get_captures (NodeId id) const;
     202  
     203  protected:
     204    bool decl_needs_capture (NodeId decl_rib_node_id, NodeId closure_rib_node_id,
     205  			   const Scope &scope);
     206  
     207  private:
     208    Resolver ();
     209  
     210    void generate_builtins ();
     211    void setup_builtin (const std::string &name, TyTy::BaseType *tyty);
     212  
     213    Analysis::Mappings *mappings;
     214    TypeCheckContext *tyctx;
     215  
     216    std::vector<AST::Type *> builtins;
     217  
     218    Scope name_scope;
     219    Scope type_scope;
     220    Scope label_scope;
     221    Scope macro_scope;
     222  
     223    NodeId global_type_node_id;
     224    NodeId unit_ty_node_id;
     225  
     226    // map a AST Node to a Rib
     227    std::map<NodeId, Rib *> name_ribs;
     228    std::map<NodeId, Rib *> type_ribs;
     229    std::map<NodeId, Rib *> label_ribs;
     230    std::map<NodeId, Rib *> macro_ribs;
     231  
     232    // Rust uses DefIds to namespace these under a crate_num
     233    // but then it uses the def_collector to assign local_defids
     234    // to each ast node as well. not sure if this is going to fit
     235    // with gcc very well to compile a full crate in one go but we will
     236    // see.
     237  
     238    // these are of the form ref->Def-NodeId
     239    // we need two namespaces one for names and ones for types
     240    std::map<NodeId, NodeId> resolved_names;
     241    std::map<NodeId, NodeId> resolved_types;
     242    std::map<NodeId, NodeId> resolved_labels;
     243    std::map<NodeId, NodeId> resolved_macros;
     244  
     245    // misc
     246    std::map<NodeId, NodeId> misc_resolved_items;
     247  
     248    // keep track of the current module scope ids
     249    std::vector<NodeId> current_module_stack;
     250  
     251    // captured variables mappings
     252    std::vector<NodeId> closure_context;
     253    std::map<NodeId, std::set<NodeId>> closures_capture_mappings;
     254  };
     255  
     256  } // namespace Resolver
     257  } // namespace Rust
     258  
     259  #endif // RUST_NAME_RESOLVER_H