diff src/symtab.h @ 14912:3d3c002ccc60

Add symbol_table::symbol_record_ref * src/symbtab.h (symbol_table::symbol_record_ref): New function. * src/pt-id.h (tree_identifier): Use symbol_record_ref instead of symbol_record. * src/pt-id.cc (tree_identifier): Use symbol_record_ref instead of symbol_record.
author Max Brister <max@2bass.com>
date Fri, 18 May 2012 08:53:26 -0600
parents f25d2224fa02
children c7071907a641
line wrap: on
line diff
--- a/src/symtab.h
+++ b/src/symtab.h
@@ -581,6 +581,60 @@
     symbol_record (symbol_record_rep *new_rep) : rep (new_rep) { }
   };
 
+  // Always access a symbol from the current scope.
+  // Useful for scripts, as they may be executed in more than one scope.
+  class
+  symbol_record_ref
+  {
+  public:
+    symbol_record_ref (void) : scope (-1) {}
+
+    symbol_record_ref (symbol_record record,
+                       scope_id curr_scope = symbol_table::current_scope ())
+      : scope (curr_scope), sym (record)
+    {}
+
+    symbol_record_ref& operator = (const symbol_record_ref& ref)
+    {
+      scope = ref.scope;
+      sym = ref.sym;
+      return *this;
+    }
+
+    // The name is the same regardless of scope.
+    const std::string& name (void) const { return sym.name (); }
+
+    symbol_record *operator-> (void)
+    {
+      update ();
+      return &sym;
+    }
+
+    // can be used to place symbol_record_ref in maps, we don't overload < as
+    // it doesn't make any sense for symbol_record_ref
+    struct comparator
+    {
+      bool operator ()(const symbol_record_ref& lhs,
+                       const symbol_record_ref& rhs) const
+      {
+        return lhs.name () < rhs.name ();
+      }
+    };
+  private:
+    void update (void)
+    {
+      scope_id curr_scope = symbol_table::current_scope ();
+      if (scope != curr_scope || ! sym.is_valid ())
+        {
+          scope = curr_scope;
+          sym = symbol_table::insert (sym.name ());
+        }
+    }
+
+    scope_id scope;
+    symbol_record sym;
+  };
+
   class
   fcn_info
   {