Synopsis - Cross-Reference
File: /Synopsis/Parsers/IDL/idlscope.h1// -*- 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_