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