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, see http://www.gnu.org/licenses/ 22 // 23 // Description: 24 // 25 // Definitions for scope manipulation 26 27 #ifndef _idlscope_h_ 28 #define _idlscope_h_ 29 30 #include <idlutil.h> 31 32 33 // Class to represent an absolute or relative scoped name as a list. 34 class ScopedName { 35 public: 36 37 class Fragment { 38 public: 39 // Constructor copies identifier Fragment(const char * identifier)40 Fragment(const char* identifier) : 41 next_(0), identifier_(idl_strdup(identifier)) {} 42 ~Fragment()43 ~Fragment() { 44 delete [] identifier_; 45 } 46 identifier()47 inline const char* identifier() const { return identifier_; } next()48 inline Fragment* next() const { return next_; }; 49 50 protected: 51 Fragment* next_; 52 53 private: 54 char* identifier_; 55 56 friend class ScopedName; 57 }; 58 59 ScopedName(const char* identifier, IDL_Boolean absolute); 60 61 // Copy constructors 62 ScopedName(const ScopedName* sn); 63 ScopedName(const Fragment* frags, IDL_Boolean absolute); 64 65 ~ScopedName(); 66 67 // Return the scope list scopeList()68 Fragment* scopeList() const { return scopeList_; } 69 70 // Is the name absolute (i.e. ::A::... rather than A::...) absolute()71 IDL_Boolean absolute() const { return absolute_; } 72 73 // toString() returns a new string containing the stringified 74 // name. The caller is responsible for deleting it. If qualify is 75 // true, and the name is absolute, prefix with ::, otherwise do not. 76 char* toString(IDL_Boolean qualify=0) const; 77 78 IDL_Boolean equal(const ScopedName* sn) const; 79 80 // Append a new fragment 81 void append(const char* identifier); 82 83 private: 84 Fragment* scopeList_; 85 Fragment* last_; 86 IDL_Boolean absolute_; 87 }; 88 89 90 // Class to represent a scope 91 92 class Decl; 93 class IdlType; 94 class InheritSpec; 95 class ValueInheritSpec; 96 97 class Scope { 98 public: 99 100 class Entry; // Entry in a scope 101 class EntryList; // Linked list of entries 102 103 enum Kind { S_GLOBAL, S_MODULE, S_INTERFACE, S_STRUCT, S_EXCEPTION, 104 S_UNION, S_OPERATION, S_VALUE }; 105 106 // Static functions to return the current and global scopes global()107 static Scope* global() { return global_; } current()108 static Scope* current() { return current_; } 109 110 // Static functions to initialise and clear the global and CORBA:: scopes 111 static void init(); 112 static void clear(); 113 114 // Functions to create new sub-scopes of the current scope. If 115 // newModuleScope() is asked to create a module scope which already 116 // exists, it re-opens the existing scope. 117 Scope* newModuleScope (const char* identifier, const char* file, int line); 118 Scope* newInterfaceScope(const char* identifier, const char* file, int line); 119 Scope* newStructScope (const char* identifier, const char* file, int line); 120 Scope* newExceptionScope(const char* identifier, const char* file, int line); 121 Scope* newUnionScope (const char* identifier, const char* file, int line); 122 Scope* newOperationScope(const char* file, int line); 123 Scope* newValueScope (const char* identifier, const char* file, int line); 124 125 // Change the current scope 126 static void startScope(Scope* s); 127 static void endScope(); 128 129 // Create an unnamed or named scope. If the nestedUse flag is true, 130 // use of identifiers in child scopes are considered uses within 131 // this scope. This is true for scopes created by interfaces and 132 // valuetypes, but not those created by modules. If the parent scope 133 // has nestedUse true, this scope sets it too. 134 Scope(Scope* parent, Kind k, IDL_Boolean nestedUse, 135 const char* file, int line); 136 Scope(Scope* parent, const char* identifier, 137 Kind k, IDL_Boolean nestedUse, 138 const char* file, int line); 139 140 ~Scope(); 141 142 // For interfaces, set a list of inherited Scopes. Checks that 143 // inheritance has not added any clashing operation or attribute 144 // names. 145 void setInherited(InheritSpec* inherited, const char* file, int line); 146 void setInherited(ValueInheritSpec* inherited, const char* file, int line); 147 148 // Query interface parent()149 Scope* parent() const { return parent_; } kind()150 Kind kind() const { return kind_; } identifier()151 const char* identifier() const { return identifier_; } scopedName()152 const ScopedName* scopedName() const { return scopedName_; } nestedUse()153 IDL_Boolean nestedUse() const { return nestedUse_; } entries()154 Entry* entries() const { return entries_; } 155 156 // Functions to lookup and add entries to the scope, reporting any 157 // violations of the IDL scope rules as errors. 158 159 // Find an entry in this scope. 160 Entry* find(const char* identifier) const; 161 162 // Find an entry in this scope, ignoring case 163 Entry* iFind(const char* identifier) const; 164 165 // Find entries in this scope or inherited scopes. Does not return 166 // USE or PARENT entries. 167 EntryList* findWithInheritance(const char* identifier) const; 168 EntryList* iFindWithInheritance(const char* identifier) const; 169 170 // Find an entry based on a ScopedName. File and line requesting the 171 // find are given so errors can be reported nicely. If file and line 172 // are zero, do not report errors. 173 const Entry* findScopedName(const ScopedName* sn, 174 const char* file = 0, int line = 0) const; 175 176 // Find an entry based on a ScopedName, and mark it as used in this 177 // scope (and any parent scopes with nestedUse true). 178 const Entry* findForUse(const ScopedName* sn, const char* file, int line); 179 180 void addUse(const ScopedName* sn, const char* file, int line); 181 182 // Given source and destination ScopedNames, construct a relative or 183 // absolute ScopedName which uniquely identifies the destination 184 // from within the scope of the source. Returns 0 if either scoped 185 // name does not exist, or is not absolute. 186 static ScopedName* relativeScopedName(const ScopedName* from, 187 const ScopedName* to); 188 189 190 // The following add functions take identifiers with _ escape 191 // characters intact, so they can properly detect clashes with 192 // keywords. 193 194 // Add a module, or do nothing if the module was already added 195 void addModule(const char* identifier, 196 Scope* scope, 197 Decl* decl, 198 const char* file, int line); 199 200 // Add a declaration 201 void addDecl(const char* identifier, 202 Scope* scope, // Scope formed by this declaration, if any 203 Decl* decl, // Decl object for this declaration 204 IdlType* idltype, // IdlType for this declaration 205 const char* file, int line); 206 207 // Add an operation or attribute 208 void addCallable(const char* identifier, Scope* scope, Decl* decl, 209 const char* file, int line); 210 211 // Add an inherited operation or attribute 212 void addInherited(const char* identifier, Scope* scope, Decl* decl, 213 Entry* inh_from, const char* file, int line); 214 215 // Add an instance 216 void addInstance(const char* identifier, 217 Decl* decl, // Declaration of the instance 218 IdlType* idltype, // Type of the instance 219 const char* file, int line); 220 221 // Remove an entry. Only used to remove a forward declared interface 222 // when the full definition comes along. 223 void remEntry(Entry* e); 224 225 class Entry { 226 public: 227 228 enum EntryKind { 229 E_MODULE, // Module 230 E_DECL, // Declaration 231 E_CALLABLE, // Operation or attribute 232 E_INHERITED, // Inherited callable 233 E_INSTANCE, // Instance of a type 234 E_USE, // Identifier introduced through use 235 E_PARENT // Name of enclosing scope 236 }; 237 238 Entry(const Scope* container, EntryKind kind, const char* identifier, 239 Scope* scope, Decl* decl, IdlType* idltype, Entry* inh_from, 240 const char* file, int line); 241 242 ~Entry(); 243 container()244 const Scope* container() const { return container_; } kind()245 EntryKind kind() const { return kind_; } identifier()246 const char* identifier() const { return identifier_; } scopedName()247 const ScopedName* scopedName() const { return scopedName_; } file()248 const char* file() const { return file_; } line()249 int line() const { return line_; } 250 251 // Scope, Decl, IdlType, and Entry inherited from, if appropriate, 252 // null if not scope()253 Scope* scope() const { return scope_; } decl()254 Decl* decl() const { return decl_; } idltype()255 IdlType* idltype() const { return idltype_; } inh_from()256 Entry* inh_from() const { return inh_from_; } 257 258 // Linked list inside Scope next()259 Entry* next() const { return next_; } 260 261 private: 262 const Scope* container_; 263 EntryKind kind_; 264 char* identifier_; 265 ScopedName* scopedName_; 266 Scope* scope_; 267 Decl* decl_; 268 IdlType* idltype_; 269 Entry* inh_from_; 270 char* file_; 271 int line_; 272 Entry* next_; 273 274 friend class Scope; 275 }; 276 277 class EntryList { 278 public: EntryList(const Entry * e)279 EntryList(const Entry* e) : head_(e), next_(0) { last_ = this; } 280 ~EntryList()281 ~EntryList() { if (next_) delete next_; } 282 head()283 const Entry* head() const { return head_; } tail()284 EntryList* tail() const { return next_; } 285 append(EntryList * el)286 void append(EntryList* el) { 287 last_->next_ = el; 288 last_ = el->last_; 289 } 290 void merge(EntryList* ml); 291 292 private: 293 const Entry* head_; 294 295 protected: 296 EntryList* next_; 297 EntryList* last_; 298 }; 299 300 private: 301 Scope* parent_; 302 Kind kind_; 303 char* identifier_; 304 ScopedName* scopedName_; 305 IDL_Boolean nestedUse_; 306 Entry* entries_; 307 Entry* last_; 308 InheritSpec* inherited_; 309 ValueInheritSpec* valueInherited_; 310 311 static Scope* global_; 312 static Scope* current_; 313 314 void appendEntry(Entry* e); 315 IDL_Boolean keywordClash(const char* identifier, 316 const char* file, int line); 317 }; 318 319 #endif // _idlscope_h_ 320