Synopsis - Cross-Reference

File: /Synopsis/Parsers/IDL/idlscope.h
  1// -*- c++ -*-
  2//                          Package   : omniidl
  3// idlscope.h               Created on: 1999/10/11
  4//			    Author    : Duncan Grisby (dpg1)
  5//
  6//    Copyright (C) 1999 AT&T Laboratories Cambridge
  7//
  8//  This file is part of omniidl.
  9//
 10//  omniidl is free software; you can redistribute it and/or modify it
 11//  under the terms of the GNU General Public License as published by
 12//  the Free Software Foundation; either version 2 of the License, or
 13//  (at your option) any later version.
 14//
 15//  This program is distributed in the hope that it will be useful,
 16//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 17//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18//  General Public License for more details.
 19//
 20//  You should have received a copy of the GNU General Public License
 21//  along with this program; if not, write to the Free Software
 22//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 23//  02111-1307, USA.
 24//
 25// Description:
 26//   
 27//   Definitions for scope manipulation
 28
 29// $Id: idlscope.h,v 1.9.2.1 2003/03/23 21:01:44 dgrisby Exp $
 30// $Log: idlscope.h,v $
 31// Revision 1.9.2.1  2003/03/23 21:01:44  dgrisby
 32// Start of omniORB 4.1.x development branch.
 33//
 34// Revision 1.5.2.4  2001/10/29 17:42:43  dpg1
 35// Support forward-declared structs/unions, ORB::create_recursive_tc().
 36//
 37// Revision 1.5.2.3  2000/10/27 16:31:10  dpg1
 38// Clean up of omniidl dependencies and types, from omni3_develop.
 39//
 40// Revision 1.5.2.2  2000/10/10 10:18:51  dpg1
 41// Update omniidl front-end from omni3_develop.
 42//
 43// Revision 1.3.2.2  2000/09/19 09:14:26  dpg1
 44// Scope::Entry::Kind renamed to Scope::Entry::EntryKind to avoid
 45// problems with over-keen compilers
 46//
 47// Revision 1.3.2.1  2000/08/29 15:20:29  dpg1
 48// New relativeScope() function. New -i flag to enter interactive loop
 49// after parsing
 50//
 51// Revision 1.3  1999/11/02 17:07:25  dpg1
 52// Changes to compile on Solaris.
 53//
 54// Revision 1.2  1999/10/29 10:01:50  dpg1
 55// Global scope initialisation changed.
 56//
 57// Revision 1.1  1999/10/27 14:05:55  dpg1
 58// *** empty log message ***
 59//
 60
 61#ifndef _idlscope_h_
 62#define _idlscope_h_
 63
 64#include <idlutil.h>
 65
 66
 67// Class to represent an absolute or relative scoped name as a list.
 68class ScopedName {
 69public:
 70
 71  class Fragment {
 72  public:
 73    // Constructor copies identifier
 74    Fragment(const char* identifier) :
 75      next_(0), identifier_(idl_strdup(identifier)) {}
 76
 77    ~Fragment() {
 78      delete [] identifier_;
 79    }
 80
 81    inline const char* identifier() const { return identifier_; }
 82    inline Fragment*   next()       const { return next_; };
 83
 84  protected:
 85    Fragment* next_;
 86
 87  private:
 88    char* identifier_;
 89
 90    friend class ScopedName;
 91  };
 92
 93  ScopedName(const char* identifier, IDL_Boolean absolute);
 94
 95  // Copy constructors
 96  ScopedName(const ScopedName* sn);
 97  ScopedName(const Fragment*   frags, IDL_Boolean absolute);
 98
 99  ~ScopedName();
100
101  // Return the scope list
102  Fragment* scopeList() const { return scopeList_; }
103
104  // Is the name absolute (i.e. ::A::... rather than A::...)
105  IDL_Boolean absolute() const { return absolute_; }
106
107  // toString() returns a new string containing the stringified
108  // name. The caller is responsible for deleting it. If qualify is
109  // true, and the name is absolute, prefix with ::, otherwise do not.
110  char* toString(IDL_Boolean qualify=0) const;
111
112  IDL_Boolean equal(const ScopedName* sn) const;
113
114  // Append a new fragment
115  void append(const char* identifier);
116
117private:
118  Fragment*      scopeList_;
119  Fragment*      last_;
120  IDL_Boolean    absolute_;
121};
122
123
124// Class to represent a scope
125
126class Decl;
127class IdlType;
128class InheritSpec;
129class ValueInheritSpec;
130
131class Scope {
132public:
133
134  class Entry;			// Entry in a scope
135  class EntryList;		// Linked list of entries
136
137  enum Kind { S_GLOBAL, S_MODULE, S_INTERFACE, S_STRUCT, S_EXCEPTION,
138	      S_UNION, S_OPERATION, S_VALUE };
139
140  // Static functions to return the current and global scopes
141  static Scope* global()  { return global_; }
142  static Scope* current() { return current_; }
143
144  // Static functions to initialise and clear the global and CORBA:: scopes
145  static void init();
146  static void clear();
147
148  // Functions to create new sub-scopes of the current scope. If
149  // newModuleScope() is asked to create a module scope which already
150  // exists, it re-opens the existing scope.
151  Scope* newModuleScope   (const char* identifier, const char* file, int line);
152  Scope* newInterfaceScope(const char* identifier, const char* file, int line);
153  Scope* newStructScope   (const char* identifier, const char* file, int line);
154  Scope* newExceptionScope(const char* identifier, const char* file, int line);
155  Scope* newUnionScope    (const char* identifier, const char* file, int line);
156  Scope* newOperationScope(const char* file, int line);
157  Scope* newValueScope    (const char* identifier, const char* file, int line);
158
159  // Change the current scope
160  static void startScope(Scope* s);
161  static void endScope();
162
163  // Create an unnamed or named scope. If the nestedUse flag is true,
164  // use of identifiers in child scopes are considered uses within
165  // this scope. This is true for scopes created by interfaces and
166  // valuetypes, but not those created by modules. If the parent scope
167  // has nestedUse true, this scope sets it too.
168  Scope(Scope* parent, Kind k, IDL_Boolean nestedUse,
169	const char* file, int line);
170  Scope(Scope* parent, const char* identifier,
171	Kind k, IDL_Boolean nestedUse,
172	const char* file, int line);
173
174  ~Scope();
175
176  // For interfaces, set a list of inherited Scopes. Checks that
177  // inheritance has not added any clashing operation or attribute
178  // names.
179  void setInherited(InheritSpec*      inherited, const char* file, int line);
180  void setInherited(ValueInheritSpec* inherited, const char* file, int line);
181
182  // Query interface
183  Scope*            parent()     const { return parent_; }
184  Kind              kind()       const { return kind_; }
185  const char*       identifier() const { return identifier_; }
186  const ScopedName* scopedName() const { return scopedName_; }
187  IDL_Boolean       nestedUse()  const { return nestedUse_; }
188  Entry*            entries()    const { return entries_; }
189
190  // Functions to lookup and add entries to the scope, reporting any
191  // violations of the IDL scope rules as errors.
192
193  // Find an entry in this scope.
194  Entry* find(const char* identifier) const;
195
196  // Find an entry in this scope, ignoring case
197  Entry* iFind(const char* identifier) const;
198
199  // Find entries in this scope or inherited scopes. Does not return
200  // USE or PARENT entries.
201  EntryList* findWithInheritance(const char* identifier) const;
202  EntryList* iFindWithInheritance(const char* identifier) const;
203
204  // Find an entry based on a ScopedName. File and line requesting the
205  // find are given so errors can be reported nicely. If file and line
206  // are zero, do not report errors.
207  const Entry* findScopedName(const ScopedName* sn,
208			      const char* file = 0, int line = 0) const;
209
210  // Find an entry based on a ScopedName, and mark it as used in this
211  // scope (and any parent scopes with nestedUse true).
212  const Entry* findForUse(const ScopedName* sn, const char* file, int line);
213
214  void addUse(const ScopedName* sn, const char* file, int line);
215
216  // Given source and destination ScopedNames, construct a relative or
217  // absolute ScopedName which uniquely identifies the destination
218  // from within the scope of the source. Returns 0 if either scoped
219  // name does not exist, or is not absolute.
220  static ScopedName* relativeScopedName(const ScopedName* from,
221					const ScopedName* to);
222
223
224  // The following add functions take identifiers with _ escape
225  // characters intact, so they can properly detect clashes with
226  // keywords.
227
228  // Add a module, or do nothing if the module was already added
229  void addModule(const char* identifier,
230		 Scope* scope,
231		 Decl* decl,
232		 const char* file, int line);
233
234  // Add a declaration
235  void addDecl(const char* identifier,
236	       Scope*      scope,   // Scope formed by this declaration, if any
237	       Decl*       decl,    // Decl object for this declaration
238	       IdlType*    idltype, // IdlType for this declaration
239	       const char* file, int line);
240
241  // Add an operation or attribute
242  void addCallable(const char* identifier, Scope* scope, Decl* decl,
243		   const char* file, int line);
244
245  // Add an inherited operation or attribute
246  void addInherited(const char* identifier, Scope* scope, Decl* decl,
247		    Entry* inh_from, const char* file, int line);
248
249  // Add an instance
250  void addInstance(const char* identifier,
251		   Decl* decl,	      // Declaration of the instance
252		   IdlType* idltype,  // Type of the instance
253		   const char* file, int line);
254
255  // Remove an entry. Only used to remove a forward declared interface
256  // when the full definition comes along.
257  void remEntry(Entry* e);
258
259  class Entry {
260  public:
261
262    enum EntryKind {
263      E_MODULE,			// Module
264      E_DECL,			// Declaration
265      E_CALLABLE,		// Operation or attribute
266      E_INHERITED,		// Inherited callable
267      E_INSTANCE,		// Instance of a type
268      E_USE,			// Identifier introduced through use
269      E_PARENT			// Name of enclosing scope
270    };
271
272    Entry(const Scope* container, EntryKind kind, const char* identifier,
273	  Scope* scope, Decl* decl, IdlType* idltype, Entry* inh_from,
274	  const char* file, int line);
275
276    ~Entry();
277
278    const Scope*      container()  const { return container_; }
279    EntryKind         kind()       const { return kind_; }
280    const char*       identifier() const { return identifier_; }
281    const ScopedName* scopedName() const { return scopedName_; }
282    const char*       file()       const { return file_; }
283    int               line()       const { return line_; }
284
285    // Scope, Decl, IdlType, and Entry inherited from, if appropriate,
286    // null if not
287    Scope*            scope()      const { return scope_; }
288    Decl*             decl()       const { return decl_; }
289    IdlType*          idltype()    const { return idltype_; }
290    Entry*            inh_from()   const { return inh_from_; }
291
292    // Linked list inside Scope
293    Entry*            next()       const { return next_; }
294
295  private:
296    const Scope*      container_;
297    EntryKind         kind_;
298    char*             identifier_;
299    ScopedName*       scopedName_;
300    Scope*            scope_;
301    Decl*             decl_;
302    IdlType*          idltype_;
303    Entry*            inh_from_;
304    char*             file_;
305    int               line_;
306    Entry*            next_;
307    
308    friend class Scope;
309  };
310
311  class EntryList {
312  public:
313    EntryList(const Entry* e) : head_(e), next_(0) { last_ = this; }
314
315    ~EntryList() { if (next_) delete next_; }
316
317    const Entry* head() const { return head_; }
318    EntryList*   tail() const { return next_; }
319
320    void append(EntryList* el) {
321      last_->next_ = el;
322      last_        = el->last_;
323    }
324    void merge(EntryList* ml);
325
326  private:
327    const Entry* head_;
328
329  protected:
330    EntryList* next_;
331    EntryList* last_;
332  };
333
334private:
335  Scope*            parent_;
336  Kind              kind_;
337  char*             identifier_;
338  ScopedName*       scopedName_;
339  IDL_Boolean       nestedUse_;
340  Entry*            entries_;
341  Entry*            last_;
342  InheritSpec*      inherited_;
343  ValueInheritSpec* valueInherited_;
344
345  static Scope*     global_;
346  static Scope*     current_;
347
348  void appendEntry(Entry* e);
349  IDL_Boolean keywordClash(const char* identifier,
350			   const char* file, int line);
351};
352
353#endif // _idlscope_h_