File: Synopsis/SymbolLookup/Scopes.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_Scopes_hh_
  8#define Synopsis_SymbolLookup_Scopes_hh_
  9
 10#include <Synopsis/SymbolLookup/Scope.hh>
 11#include <string>
 12#include <vector>
 13#include <list>
 14
 15namespace Synopsis
 16{
 17namespace SymbolLookup
 18{
 19
 20class TemplateParameterScope;
 21class LocalScope;
 22class PrototypeScope;
 23class FunctionScope;
 24class Class;
 25class Namespace;
 26
 27//. A Visitor for Scopes.
 28//. The default implementation does nothing, so
 29//. users only need to implement the ones they need.
 30class ScopeVisitor
 31{
 32public:
 33  virtual ~ScopeVisitor() {}
 34
 35  virtual void visit(TemplateParameterScope *) {}
 36  virtual void visit(LocalScope *) {}
 37  virtual void visit(PrototypeScope *) {}
 38  virtual void visit(FunctionScope *) {}
 39  virtual void visit(Class *) {}
 40  virtual void visit(Namespace *) {}
 41};
 42
 43class TemplateParameterScope : public Scope
 44{
 45public:
 46  TemplateParameterScope(PTree::List const *node, Scope const *outer)
 47    : my_node(node), my_outer(outer->ref()) {}
 48
 49  virtual SymbolSet
 50  unqualified_lookup(PTree::Encoding const &, LookupContext) const;
 51
 52  virtual Scope const *outer_scope() const { return my_outer;}
 53  virtual void accept(ScopeVisitor *v) { v->visit(this);}
 54
 55protected:
 56  ~TemplateParameterScope() { my_outer->unref();}
 57
 58private:
 59  PTree::List const *my_node;
 60  Scope       const *my_outer;
 61};
 62
 63class LocalScope : public Scope
 64{
 65public:
 66  LocalScope(PTree::List const *node, Scope const *outer)
 67    : my_node(node), my_outer(outer->ref()) {}
 68
 69  virtual Scope const *outer_scope() const { return my_outer;}
 70
 71  virtual SymbolSet 
 72  unqualified_lookup(PTree::Encoding const &, LookupContext) const;
 73
 74  virtual void accept(ScopeVisitor *v) { v->visit(this);}
 75
 76protected:
 77  ~LocalScope() { my_outer->unref();}
 78
 79private:
 80  PTree::List const *my_node;
 81  Scope       const *my_outer;
 82};
 83
 84class FunctionScope : public Scope
 85{
 86public:
 87  FunctionScope(PTree::Declaration const *, PrototypeScope *, Scope const *);
 88
 89  virtual void use(PTree::UsingDirective const *);
 90  virtual Scope const *outer_scope() const { return my_outer;}
 91  virtual SymbolSet 
 92  unqualified_lookup(PTree::Encoding const &, LookupContext) const;
 93  virtual SymbolSet 
 94  qualified_lookup(PTree::Encoding const &, LookupContext) const;
 95
 96  // FIXME: what is 'name' ? (template parameters...)
 97  std::string name() const;
 98
 99  virtual void accept(ScopeVisitor *v) { v->visit(this);}
100
101protected:
102  ~FunctionScope() { my_outer->unref();}
103
104private:
105  typedef std::set<Namespace const *> Using;
106
107  PTree::Declaration const *    my_decl;
108  Scope const *                 my_outer;
109  Class const *                 my_class;
110  TemplateParameterScope const *my_parameters;
111  Using                         my_using;
112};
113
114class PrototypeScope : public Scope
115{
116  friend class FunctionScope;
117public:
118  PrototypeScope(PTree::Node const *decl, Scope const *outer,
119		 TemplateParameterScope const *params)
120    : my_decl(decl), my_outer(outer->ref()), my_parameters(params) {}
121
122  virtual Scope const *outer_scope() const { return my_outer;}
123  virtual SymbolSet 
124  unqualified_lookup(PTree::Encoding const &, LookupContext) const;
125
126  PTree::Node const *declaration() const { return my_decl;}
127  TemplateParameterScope const *parameters() const { return my_parameters;}
128
129  std::string name() const;
130
131  virtual void accept(ScopeVisitor *v) { v->visit(this);}
132
133protected:
134  ~PrototypeScope() { my_outer->unref();}
135
136private:
137  PTree::Node const *           my_decl;
138  Scope const *                 my_outer;
139  TemplateParameterScope const *my_parameters;
140};
141
142class Class : public Scope
143{
144public:
145  typedef std::vector<Class const *> Bases;
146
147  Class(PTree::ClassSpec const *spec, Scope const *outer,
148	Bases const &bases, TemplateParameterScope const *params)
149    : my_spec(spec), my_outer(outer->ref()), my_bases(bases), my_parameters(params)
150  {
151  }
152
153  virtual Scope const *outer_scope() const { return my_outer;}
154  virtual SymbolSet 
155  unqualified_lookup(PTree::Encoding const &, LookupContext) const;
156
157  // FIXME: what is 'name' ? (template parameters...)
158  std::string name() const;
159
160  virtual void accept(ScopeVisitor *v) { v->visit(this);}
161
162protected:
163  ~Class() { my_outer->unref();}
164
165private:
166  PTree::ClassSpec       const *my_spec;
167  Scope                  const *my_outer;
168  Bases                         my_bases;
169  TemplateParameterScope const *my_parameters;
170};
171
172class Namespace : public Scope
173{
174public:
175  Namespace(PTree::NamespaceSpec const *spec, Namespace const *outer)
176    : my_spec(spec),
177      my_outer(outer ? static_cast<Namespace const *>(outer->ref()) : 0)
178  {
179  }
180  //. Find a nested namespace.
181  Namespace *find_namespace(PTree::NamespaceSpec const *name) const;
182
183  virtual void use(PTree::UsingDirective const *);
184  virtual Scope const *outer_scope() const { return my_outer;}
185  virtual SymbolSet 
186  unqualified_lookup(PTree::Encoding const &, LookupContext) const;
187  virtual SymbolSet 
188  qualified_lookup(PTree::Encoding const &, LookupContext) const;
189
190  // FIXME: should that really be a string ? It may be better to be conform with
191  // Class::name, which, if the class is a template, can't be a string (or can it ?)
192  std::string name() const;
193
194  virtual void accept(ScopeVisitor *v) { v->visit(this);}
195
196protected:
197  ~Namespace() { if (my_outer) my_outer->unref();}
198
199private:
200  typedef std::set<Namespace const *> Using;
201
202  SymbolSet 
203  unqualified_lookup(PTree::Encoding const &, LookupContext, Using &) const;
204  SymbolSet 
205  qualified_lookup(PTree::Encoding const &, LookupContext, Using &) const;
206
207  PTree::NamespaceSpec const *my_spec;
208  Namespace const *           my_outer;
209  Using                       my_using;
210};
211
212}
213}
214
215#endif