Synopsis - Cross-Reference

File: /Synopsis/Parsers/Cxx/Builder.hh
  1//
  2// Copyright (C) 2002 Stephen Davies
  3// Copyright (C) 2002 Stefan Seefeld
  4// All rights reserved.
  5// Licensed to the public under the terms of the GNU LGPL (>= 2),
  6// see the file COPYING for details.
  7//
  8
  9#ifndef Builder_hh_
 10#define Builder_hh_
 11
 12#include <map>
 13#include "ASG.hh"
 14#include "common.hh"
 15
 16// Forward declare some Types::Types
 17namespace Types
 18{
 19class Type;
 20class Base;
 21class Named;
 22class Unknown;
 23class TemplateType;
 24class FuncPtr;
 25class Dependent;
 26}
 27
 28// Forward declare the Walker class
 29class Walker;
 30
 31// Forward declare the Lookup class
 32class Lookup;
 33
 34class ScopeInfo;
 35typedef std::vector<ScopeInfo*> ScopeSearch; // TODO: move to common
 36
 37//. Enumeration of namespace types for use in Builder::start_namespace()
 38enum NamespaceType
 39{
 40    NamespaceNamed, //.< Normal, named, namespace. name is its given name
 41    NamespaceAnon, //.< An anonymous namespace. name is the filename
 42    NamespaceUnique, //.< A unique namespace. name is the type (for, while, etc.)
 43    NamespaceTemplate, //.< A template namespace. name is empty
 44};
 45
 46
 47//. ASG Builder.
 48//. This class manages the building of an ASG, including queries on the
 49//. existing ASG such as name and type lookups. The building functions are
 50//. called by Walker as it walks the parse tree.
 51class Builder
 52{
 53    friend class Lookup;
 54public:
 55    //. Constructor
 56    Builder(ASG::SourceFile* file);
 57
 58    //. Destructor. Recursively destroys all ASG objects
 59    ~Builder();
 60
 61    //. Sets the swalker
 62    void set_walker(Walker* walker)
 63    {
 64        m_walker = walker;
 65    }
 66
 67    //. Changes the current accessability for the current scope
 68    void set_access(ASG::Access);
 69
 70    //. Returns the current file
 71    ASG::SourceFile* file() const
 72    {
 73        return m_file;
 74    }
 75    //. Changes the current file
 76    void set_file(ASG::SourceFile*);
 77
 78    //. Returns the list of builtin decls ("__null_t", "true", etc.)
 79    const ASG::Declaration::vector& builtin_decls() const;
 80
 81    //
 82    // State Methods
 83    //
 84
 85    //. Returns the current scope
 86    ASG::Scope* scope()
 87    {
 88        return m_scope;
 89    }
 90
 91    //. Returns the current ScopeInfo for the current Scope
 92    ScopeInfo* scopeinfo()
 93    {
 94        return m_scopes.back();
 95    }
 96
 97    //. Returns the global scope
 98    ASG::Scope* global()
 99    {
100        return m_global;
101    }
102
103    //. Returns the Lookup object for the builder
104    Lookup* lookup()
105    {
106        return m_lookup;
107    }
108
109    //
110    // ASG Methods
111    //
112
113    //. Add the given Declaration to the current scope. If is_template is true,
114    //. then it is added to the parent of the current scope, assuming that the
115    //. current scope is the temporary template scope
116    void add(ASG::Declaration* declaration, bool is_template = false);
117
118    //. Add the given non-declaration type to the current scope
119    void add(Types::Named* named);
120
121    //. Adds the given Macros to the global scope. This method should only be
122    //. called once, with the macros stored in order from the preprocessing
123    //. stage.
124    void add_macros(const std::vector<ASG::Macro*>&);
125
126    //. Construct and open a new Namespace. The Namespace becomes the
127    //. current scope, and the old one is pushed onto the stack. If name is
128    //. empty then a unique name is generated of the form `ns1
129    ASG::Namespace* start_namespace(const std::string& name, NamespaceType type);
130
131    //. End the current namespace and pop the previous Scope off the stack
132    void end_namespace();
133
134    //. Starts a new template namespace
135    ASG::Namespace* start_template();
136
137    //. End the current template namespace
138    void end_template();
139
140    //. Construct and open a new Class. The Class becomes the current scope,
141    //. and the old one is pushed onto the stack. The type argument is the
142    //. type, ie: "class" or "struct". This is tested to determine the default
143    //. accessability. If this is a template class, the templ_params vector must
144    //. be non-null pointer
145    ASG::Class* start_class(int, const std::string& type, const std::string& name,
146                            ASG::Parameter::vector* templ_params, std::string const &primary_name);
147
148    //. Construct and open a new Class with a qualified name
149    ASG::Class* start_class(int, const std::string& type, const ScopedName& names);
150
151    //. Update the search to include base classes. Call this method after
152    //. startClass(), and after filling in the parents() vector of the returned
153    //. ASG::Class object. After calling this method, name and type lookups
154    //. will correctly search the base classes of this class.
155    void update_class_base_search();
156
157    //. End the current class and pop the previous Scope off the stack
158    void end_class();
159
160    //. Start function impl scope
161    void start_function_impl(const ScopedName& name);
162
163    //. End function impl scope
164    void end_function_impl();
165
166    //. Add an function
167    ASG::Function* add_function(int, const std::string& name,
168                                const std::vector<std::string>& premod,
169				Types::Type* ret,
170                                const std::vector<std::string>& postmod,
171                                const std::string& realname,
172				ASG::Parameter::vector* templ_params);
173
174    //. Add a variable
175    ASG::Variable* add_variable(int, const std::string& name, Types::Type* vtype, bool constr, const std::string& type);
176
177    //. Add a const
178    ASG::Const* add_constant(int, const std::string& name, Types::Type* ctype, std::string const &type, std::string const &value = "");
179
180    //. Add a variable to represent 'this', iff we are in a method
181    void add_this_variable();
182
183    //. Add a typedef
184    ASG::Typedef* add_typedef(int, const std::string& name, Types::Type* alias, bool constr);
185
186    //. Add an enumerator
187    ASG::Enumerator* add_enumerator(int, const std::string& name, const std::string& value);
188
189    //. Add an enum
190    ASG::Enum* add_enum(int, const std::string& name, const ASG::Enumerator::vector &);
191
192    //. Add a tail comment. This will be a builtin with name 'EOS'
193    ASG::Builtin *add_tail_comment(int line);
194
195    //
196    // Using methods
197    //
198
199    //. Add a using directive.
200    ASG::UsingDirective *add_using_directive(int, Types::Named* type);
201
202    //. Add a namespace alias using declaration.
203    void add_aliased_using_namespace(Types::Named* type, const std::string& alias);
204
205    //. Add a using declaration.
206    ASG::UsingDeclaration *add_using_declaration(int, Types::Named* type);
207
208
209    //. Maps a scoped name into a vector of scopes and the final type. Returns
210    //. true on success.
211    bool mapName(const ScopedName& name, std::vector<ASG::Scope*>&, Types::Named*&);
212
213    //. Create a Base type for the given name in the current scope
214    Types::Base* create_base(const std::string& name);
215
216    //. Create a Dependent type for the given name in the current scope
217    Types::Dependent* create_dependent(const std::string& name);
218
219    //. Create an Unknown type for the given name in the current scope
220    Types::Unknown* create_unknown(const ScopedName& name);
221
222    //. Create a Template type for the given name in the current scope
223    Types::Template* create_template(const std::string& name, const std::vector<Types::Type*>&);
224
225    //. Add an Unknown decl for given name if it doesnt already exist
226    Types::Unknown* add_unknown(const std::string& name);
227
228    //. Add an Templated Forward decl for given name if it doesnt already exist
229    ASG::Forward* add_forward(int lineno, const std::string& name, const std::string &type,
230                              ASG::Parameter::vector* templ_params);
231
232private:
233    //. Current file
234    ASG::SourceFile* m_file;
235
236    //. The global scope object
237    ASG::Scope* m_global;
238
239    //. Current scope object
240    ASG::Scope* m_scope;
241
242    //. A counter used to generate unique namespace names
243    int m_unique;
244
245    //. The stack of Builder::Scopes
246    std::vector<ScopeInfo*> m_scopes;
247
248    //. Private data which uses map
249    struct Private;
250    //. Private data which uses map instance
251    Private* m;
252
253    //. Return a ScopeInfo* for the given Declaration. This method first looks for
254    //. an existing Scope* in the Private map.
255    ScopeInfo* find_info(ASG::Scope*);
256
257    //. Utility method to recursively add base classes to given search
258    void add_class_bases(ASG::Class* clas, ScopeSearch& search);
259
260    //. Formats the search of the given Scope for logging
261    std::string dump_search(ScopeInfo* scope);
262
263    //. Recursively adds 'target' as using in 'scope'
264    void do_add_using_directive(ScopeInfo* target, ScopeInfo* scope);
265
266    //. A class that compares Scopes
267    class EqualScope;
268
269    //. A pointer to the Walker. This is set explicitly by the Walker during
270    //. its constructor (which takes a Builder).
271    Walker* m_walker;
272
273    //. A pointer to the Lookup
274    Lookup* m_lookup;
275
276};
277
278#endif