Synopsis - Synopsis/SymbolLookup/Scope.hh

File: Synopsis/SymbolLookup/Scope.hh

      1//
      2// Copyright (C) 2004 Stefan Seefeld
      3// All rights reserved.
      4// Licensed to the public under the terms of the GNU LGPL (>= 2),
      5// see the file COPYING for details.
      6//
      7#ifndef Synopsis_SymbolLookup_Scope_hh_
      8#define Synopsis_SymbolLookup_Scope_hh_
      9
     10#include <Synopsis/SymbolLookup/Symbol.hh>
     11#include <map>
     12#include <set>
     13
     14namespace Synopsis
     15{
     16namespace SymbolLookup
     17{
     18struct TypeError : std::exception
     19{
     20  TypeError(PTree::Encoding const &n, PTree::Encoding const &t)
     21    : name(n), type(t) {}
     22  virtual ~TypeError() throw() {}
     23  virtual char const * what() const throw() { return "TypeError";}
     24  PTree::Encoding name;
     25  PTree::Encoding type;
     26};
     27
     28struct Undefined : std::exception
     29{
     30  Undefined(PTree::Encoding const &n, PTree::Node const *ref = 0)
     31    : name(n), ptree(ref) {}
     32  virtual ~Undefined() throw() {}
     33  virtual char const * what() const throw() { return "Undefined";}
     34  PTree::Encoding     name;
     35  PTree::Node const * ptree;
     36};
     37
     38struct MultiplyDefined : std::exception
     39{
     40  MultiplyDefined(PTree::Encoding const &n,
     41		  PTree::Node const *decl,
     42		  PTree::Node const *orig)
     43    : name(n), declaration(decl), original(orig) {}
     44  virtual ~MultiplyDefined() throw() {}
     45  virtual char const * what() const throw() { return "MultiplyDefined";}
     46  PTree::Encoding name;
     47  PTree::Node const * declaration;
     48  PTree::Node const * original;
     49};
     50
     51class InternalError : public std::exception
     52{
     53public:
     54  InternalError(std::string const &what) : my_what(what) {}
     55  virtual ~InternalError() throw() {}
     56  virtual char const * what() const throw() { return my_what.c_str();}
     57private:
     58  std::string my_what;
     59};
     60
     61typedef std::set<Symbol const *> SymbolSet;
     62
     63class ScopeVisitor;
     64
     65//. A Scope contains symbol definitions.
     66class Scope
     67{
     68protected:
     69  //. SymbolTable provides a mapping from (encoded) names to Symbols declared
     70  //. in this scope.
     71  typedef std::multimap<PTree::Encoding, Symbol const *> SymbolTable;
     72  //. ScopeTable provides a mapping from scope nodes to Scopes,
     73  //. which can be used to traverse the scope tree in parallel with
     74  //. the associated parse tree. As this traversal is also done
     75  //. during the parsing, the scopes can not be const.
     76  typedef std::map<PTree::Node const *, Scope *> ScopeTable;
     77
     78public:
     79  typedef SymbolTable::const_iterator symbol_iterator;
     80  typedef ScopeTable::const_iterator scope_iterator;
     81
     82  typedef unsigned int LookupContext;
     83  static LookupContext const DEFAULT = 0x0;
     84  static LookupContext const SCOPE = 0x1; // lookup a scope, see [basic.lookup.qual]
     85  static LookupContext const USING = 0x2; // lookup in the context of a using directive
     86  static LookupContext const ELABORATE = 0x4; // elaborate name lookup
     87  static LookupContext const DECLARATION = 0x8; // see 3.4.3.2/6 [namespace.qual]
     88
     89  Scope() : my_refcount(1) {}
     90  Scope *ref() { ++my_refcount; return this;}
     91  Scope const *ref() const { ++my_refcount; return this;}
     92  void unref() const { if (!--my_refcount) delete this;}
     93
     94  virtual Scope const *outer_scope() const = 0;
     95  Scope const *global_scope() const;
     96
     97  virtual void accept(ScopeVisitor *v) = 0;
     98
     99  symbol_iterator symbols_begin() const { return my_symbols.begin();}
    100  symbol_iterator symbols_end() const { return my_symbols.end();}
    101
    102  scope_iterator scopes_begin() const { return my_scopes.begin();}
    103  scope_iterator scopes_end() const { return my_scopes.end();}
    104
    105  //. declare the given symbol in the local scope
    106  //. using the given encoded name.
    107  void declare(PTree::Encoding const &name, Symbol const *symbol);
    108
    109  //. declare a nested scope
    110  void declare_scope(PTree::Node const *, Scope *);
    111
    112  //. declare a 'using' directive.
    113  //. The default implementation raises an exception,
    114  //. as it is only well-formed when the current scope
    115  //. is a function scope or a namespace.
    116  virtual void use(PTree::UsingDirective const *);
    117
    118  //. find a nested scope by declaration
    119  Scope *find_scope(PTree::Node const *) const;
    120  //. find a nested scope by symbol.
    121  //. The encoded name is provided for diagnostic purposes only.
    122  Scope *find_scope(PTree::Encoding const &, Symbol const *) const;
    123  //. Remove the given nested scope from the scope.
    124  void remove_scope(PTree::Node const*);
    125  //. find a nested scope by name
    126  //Scope *find_scope(PTree::Encoding const &) const;
    127
    128  //. find the encoded name declared in this scope and
    129  //. return a set of matching symbols.
    130  SymbolSet find(PTree::Encoding const &, LookupContext) const throw();
    131  //. Remove the given symbol from the scope.
    132  //. s shall not be used after its removal.
    133  void remove(Symbol const *s);
    134
    135  //. look up the encoded name and return a set of matching symbols.
    136  SymbolSet lookup(PTree::Encoding const &, LookupContext = DEFAULT) const;
    137
    138  virtual SymbolSet unqualified_lookup(PTree::Encoding const &,
    139				       LookupContext = DEFAULT) const = 0;
    140  virtual SymbolSet qualified_lookup(PTree::Encoding const &,
    141				     LookupContext = DEFAULT) const;
    142
    143protected:
    144
    145  //. Scopes are ref counted, and thus are deleted only by 'unref()'
    146  virtual ~Scope();
    147
    148  SymbolTable    my_symbols;
    149  ScopeTable     my_scopes;
    150  mutable size_t my_refcount;
    151};
    152
    153inline void Scope::declare_scope(PTree::Node const *node, Scope *scope)
    154{
    155  my_scopes[node] = scope->ref();
    156}
    157
    158inline Scope *Scope::find_scope(PTree::Node const *node) const
    159{
    160  ScopeTable::const_iterator i = my_scopes.find(node);
    161  return i == my_scopes.end() ? 0 : i->second;
    162}
    163
    164inline Scope const *Scope::global_scope() const
    165{
    166  Scope const *scope = this;
    167  while (Scope const *outer = scope->outer_scope())
    168    scope = outer;
    169  return scope;
    170}
    171
    172}
    173}
    174
    175#endif

Generated on Thu Apr 16 16:28:03 2009 by
synopsis (version devel)