1 // $Id: symbol.h,v 1.86 2004/09/26 23:10:19 elliott-oss Exp $ -*- c++ -*-
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 2004 IBM Corporation and others. All Rights Reserved.
7 // You must accept the terms of that agreement to use this software.
8 //
9
10 #ifndef symbol_INCLUDED
11 #define symbol_INCLUDED
12
13 #include "platform.h"
14 #include "lookup.h"
15 #include "access.h"
16 #include "tuple.h"
17
18 #ifdef HAVE_JIKES_NAMESPACE
19 namespace Jikes { // Open namespace Jikes block
20 #endif
21
22 class Semantic;
23 class SemanticEnvironment;
24 class Ast;
25 class AstCompilationUnit;
26 class AstClassBody;
27 class AstMethodDeclarator;
28 class AstBlock;
29 class AstList;
30 class AstExpression;
31 class AstVariableDeclarator;
32 class ExpandedTypeTable;
33 class ExpandedFieldTable;
34 class ExpandedMethodTable;
35 class LexStream;
36 class SymbolTable;
37 class SymbolSet;
38 class SymbolMap;
39 class Zip;
40
41 template <typename Key, typename Value>
42 class Map;
43
44 class PackageSymbol;
45
46 class PathSymbol : public Symbol
47 {
48 public:
49 const NameSymbol* name_symbol;
50 Zip* zipfile;
51
52 PathSymbol(const NameSymbol*);
53 virtual ~PathSymbol();
54
Name()55 virtual const wchar_t* Name() const { return name_symbol -> Name(); }
NameLength()56 virtual unsigned NameLength() const { return name_symbol -> NameLength(); }
Identity()57 virtual const NameSymbol* Identity() const { return name_symbol; }
Utf8Name()58 const char* Utf8Name() const
59 {
60 return name_symbol -> Utf8_literal
61 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
62 }
Utf8NameLength()63 unsigned Utf8NameLength() const
64 {
65 return name_symbol -> Utf8_literal
66 ? name_symbol -> Utf8_literal -> length : 0;
67 }
68
IsZip()69 inline bool IsZip() { return zipfile != NULL; }
70
RootDirectory()71 inline DirectorySymbol* RootDirectory() { return root_directory; }
72
73 private:
74 friend class SymbolTable;
75 DirectorySymbol* root_directory;
76 };
77
78
79 class DirectorySymbol : public Symbol
80 {
81 public:
82 Symbol* owner;
83 const NameSymbol* name_symbol;
84
85 Tuple<DirectorySymbol*> subdirectories;
86
87 DirectorySymbol(const NameSymbol*, Symbol*, bool source_dir_only);
88 virtual ~DirectorySymbol();
89
Name()90 virtual const wchar_t* Name() const { return name_symbol -> Name(); }
NameLength()91 virtual unsigned NameLength() const { return name_symbol -> NameLength(); }
Identity()92 virtual const NameSymbol* Identity() const { return name_symbol; }
Utf8Name()93 const char* Utf8Name() const
94 {
95 return name_symbol -> Utf8_literal
96 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
97 }
Utf8NameLength()98 unsigned Utf8NameLength() const
99 {
100 return name_symbol -> Utf8_literal
101 ? name_symbol -> Utf8_literal -> length : 0;
102 }
IsSourceDirectory()103 bool IsSourceDirectory() { return source_dir_only; }
104
FindEntry(char * name,unsigned len)105 DirectoryEntry* FindEntry(char* name, unsigned len)
106 {
107 return entries ? entries -> FindEntry(name, len)
108 : (DirectoryEntry*) NULL;
109 }
110
111 #ifdef WIN32_FILE_SYSTEM
FindCaseInsensitiveEntry(char * name,unsigned length)112 DirectoryEntry* FindCaseInsensitiveEntry(char* name, unsigned length)
113 {
114 return entries ? entries -> FindCaseInsensitiveEntry(name, length)
115 : (DirectoryEntry*) NULL;
116 }
117
InsertEntry(char * name,unsigned length)118 void InsertEntry(char* name, unsigned length)
119 {
120 assert(entries);
121
122 DirectoryEntry* entry = entries -> InsertEntry(this, name, length);
123 entries -> InsertCaseInsensitiveEntry(entry);
124 }
125 #endif // WIN32_FILE_SYSTEM
126
PathSym()127 PathSymbol* PathSym()
128 {
129 return owner -> PathCast() ? (PathSymbol*) owner
130 : ((DirectorySymbol*) owner) -> PathSym();
131 }
132
IsZip()133 inline bool IsZip() { return PathSym() -> IsZip(); }
134
135 void SetDirectoryName();
DirectoryName()136 inline char* DirectoryName()
137 {
138 if (! directory_name)
139 SetDirectoryName();
140 return directory_name;
141 }
DirectoryNameLength()142 inline unsigned DirectoryNameLength()
143 {
144 if (! directory_name)
145 SetDirectoryName();
146 return directory_name_length;
147 }
148
149 inline DirectorySymbol* InsertDirectorySymbol(const NameSymbol*, bool);
150 inline DirectorySymbol* FindDirectorySymbol(const NameSymbol*);
151
152 inline FileSymbol* InsertFileSymbol(const NameSymbol*);
153 inline FileSymbol* FindFileSymbol(const NameSymbol*);
154
155 void ResetDirectory();
156
157 void ReadDirectory();
158
159 private:
160
161 time_t mtime;
162
163 SymbolTable* table;
164 inline SymbolTable* Table();
165
166 DirectoryTable* entries;
167 char* directory_name;
168 unsigned directory_name_length;
169
170 bool source_dir_only;
171 };
172
173
174 class FileSymbol : public Symbol
175 {
176 private:
177 enum FileKind
178 {
179 JAVA,
180 CLASS,
181 CLASS_ONLY
182 };
183
184 DirectorySymbol* output_directory;
185 char* file_name;
186 unsigned file_name_length;
187 Utf8LiteralValue* file_name_literal;
188
189 public:
190 const NameSymbol* name_symbol;
191 DirectorySymbol* directory_symbol;
192 PackageSymbol* package;
193 FileKind kind;
194
195 //
196 // These fields are used for files in zip packages.
197 //
198 u4 uncompressed_size;
199 u4 date_time;
200 long offset;
201
202 //
203 // This field holds the time of last data modification for a non-zip file
204 //
205 time_t mtime;
206
207 LexStream* lex_stream;
208 AstCompilationUnit* compilation_unit;
209 Semantic* semantic;
210
211 Tuple<TypeSymbol*> types;
212
FileSymbol(const NameSymbol * name_symbol_)213 FileSymbol(const NameSymbol* name_symbol_)
214 : output_directory(NULL)
215 , file_name(NULL)
216 , file_name_literal(NULL)
217 , name_symbol(name_symbol_)
218 , directory_symbol(NULL)
219 , package(NULL)
220 , mtime(0)
221 , lex_stream(NULL)
222 , compilation_unit(NULL)
223 , semantic(NULL)
224 , types(4)
225 {
226 Symbol::_kind = _FILE;
227 }
228
229 virtual ~FileSymbol();
230
Clone()231 FileSymbol* Clone()
232 {
233 FileSymbol* clone = new FileSymbol(name_symbol);
234
235 clone -> kind = kind;
236 clone -> directory_symbol = directory_symbol;
237 clone -> mtime = mtime;
238 return clone;
239 }
240
Name()241 virtual const wchar_t* Name() const { return name_symbol -> Name(); }
NameLength()242 virtual unsigned NameLength() const { return name_symbol -> NameLength(); }
Identity()243 virtual const NameSymbol* Identity() const { return name_symbol; }
Utf8Name()244 const char* Utf8Name() const
245 {
246 return name_symbol -> Utf8_literal
247 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
248 }
Utf8NameLength()249 unsigned Utf8NameLength() const
250 {
251 return name_symbol -> Utf8_literal
252 ? name_symbol -> Utf8_literal -> length : 0;
253 }
254
SetJava()255 inline void SetJava() { kind = JAVA; }
SetClass()256 inline void SetClass() { kind = CLASS; }
SetClassOnly()257 inline void SetClassOnly() { kind = CLASS_ONLY; }
258
IsJava()259 inline bool IsJava() { return kind == JAVA; }
IsClass()260 inline bool IsClass() { return kind >= CLASS; }
IsClassOnly()261 inline bool IsClassOnly() { return kind == CLASS_ONLY; }
262
PathSym()263 PathSymbol* PathSym()
264 {
265 return directory_symbol -> PathSym();
266 }
IsZip()267 inline bool IsZip() { return PathSym() -> IsZip(); }
Zipfile()268 inline Zip* Zipfile() { return PathSym() -> zipfile; }
269
270 static const char* java_suffix;
271 static unsigned java_suffix_length;
272 static const char* class_suffix;
273 static unsigned class_suffix_length;
274 static bool IsJavaSuffix(char* ptr);
275 static bool IsClassSuffix(char* ptr);
276
FileName()277 inline char* FileName()
278 {
279 if (! file_name)
280 SetFileName();
281 return file_name;
282 }
FileNameLength()283 inline unsigned FileNameLength()
284 {
285 if (! file_name)
286 SetFileName();
287 return file_name_length;
288 }
289
FileNameLiteral()290 inline Utf8LiteralValue* FileNameLiteral()
291 {
292 assert(file_name_literal);
293 return file_name_literal;
294 }
295
296 void SetFileNameLiteral(Control*);
297
298 DirectorySymbol* OutputDirectory();
299
300 void SetFileName();
301
302 void CleanUp();
303
Reset()304 void Reset()
305 {
306 CleanUp();
307
308 delete [] file_name;
309 file_name = NULL;
310 types.Reset();
311 }
312 };
313
314
315 class FileLocation
316 {
317 public:
318 wchar_t* location;
319
320 FileLocation(LexStream* lex_stream, TokenIndex token_index);
321
FileLocation(FileSymbol * file_symbol)322 FileLocation(FileSymbol* file_symbol)
323 {
324 char* file_name = file_symbol -> FileName();
325 unsigned length = file_symbol -> FileNameLength();
326 location = new wchar_t[length + 13];
327 for (unsigned i = 0; i < length; i++) {
328 location[i] = (wchar_t) file_name[i];
329 }
330 location[length] = U_NULL;
331 }
332
~FileLocation()333 ~FileLocation()
334 {
335 delete [] location;
336 }
337 };
338
339
340 class PackageSymbol : public Symbol
341 {
342 enum
343 {
344 DEPRECATED = 0x01
345 };
346
347 public:
348 Tuple<DirectorySymbol*> directory;
349 PackageSymbol* owner;
350
PackageSymbol(const NameSymbol * name_symbol_,PackageSymbol * owner_)351 PackageSymbol(const NameSymbol* name_symbol_, PackageSymbol* owner_)
352 : directory(4)
353 , owner(owner_)
354 , name_symbol(name_symbol_)
355 , table(NULL)
356 , package_name(NULL)
357 , status(0)
358 {
359 Symbol::_kind = PACKAGE;
360 }
361
362 virtual ~PackageSymbol();
363
Name()364 virtual const wchar_t* Name() const { return name_symbol -> Name(); }
NameLength()365 virtual unsigned NameLength() const { return name_symbol -> NameLength(); }
Identity()366 virtual const NameSymbol* Identity() const { return name_symbol; }
Utf8Name()367 const char* Utf8Name() const
368 {
369 return name_symbol -> Utf8_literal
370 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
371 }
Utf8NameLength()372 unsigned Utf8NameLength() const
373 {
374 return name_symbol -> Utf8_literal
375 ? name_symbol -> Utf8_literal -> length : 0;
376 }
377 // This name is fully qualified, using slashes.
378
379 void SetPackageName();
380 // This name is fully qualified, using slashes.
PackageName()381 wchar_t* PackageName()
382 {
383 if (! package_name)
384 SetPackageName();
385 return package_name;
386 }
PackageNameLength()387 unsigned PackageNameLength()
388 {
389 if (! package_name)
390 SetPackageName();
391 return package_name_length;
392 }
393
394 inline PackageSymbol* FindPackageSymbol(const NameSymbol*);
395 inline PackageSymbol* InsertPackageSymbol(NameSymbol*);
396
397 inline TypeSymbol* FindTypeSymbol(const NameSymbol*);
398 inline TypeSymbol* InsertSystemTypeSymbol(NameSymbol*);
399 inline TypeSymbol* InsertOuterTypeSymbol(NameSymbol*);
400 inline void DeleteTypeSymbol(TypeSymbol*);
401
MarkDeprecated()402 void MarkDeprecated() { status |= DEPRECATED; }
IsDeprecated()403 bool IsDeprecated() { return (status & DEPRECATED) != 0; }
404
405 private:
406 const NameSymbol* name_symbol;
407 SymbolTable* table;
408 inline SymbolTable* Table();
409
410 wchar_t* package_name;
411 unsigned package_name_length;
412 u1 status;
413 };
414
415
416 class MethodSymbol : public Symbol, public AccessFlags
417 {
418 enum
419 {
420 DEPRECATED = 0x01
421 };
422
423 public:
424 Ast* declaration; // AstMethodDeclaration or AstConstructorDeclaration
425 const NameSymbol* name_symbol;
426 TypeSymbol* containing_type;
427 BlockSymbol* block_symbol;
428 MethodSymbol* next_method;
429 Utf8LiteralValue* signature;
430 FileLocation* file_location;
431 // Index of element in symbol_pool (in the relevant symbol table) that
432 // points to this method.
433 unsigned pool_index;
434
435 unsigned max_block_depth;
436
437 //
438 // If this method is a method that permits access to a private member of an
439 // enclosing type then accessed_member identifies the member in question.
440 //
441 Symbol* accessed_member;
AccessesStaticMember()442 inline bool AccessesStaticMember()
443 {
444 return accessed_member &&
445 DYNAMIC_CAST<AccessFlags*> (accessed_member) -> ACC_STATIC();
446 }
447
Name()448 virtual const wchar_t* Name() const { return name_symbol -> Name(); }
NameLength()449 virtual unsigned NameLength() const { return name_symbol -> NameLength(); }
Identity()450 virtual const NameSymbol* Identity() const { return name_symbol; }
Utf8Name()451 const char* Utf8Name() const
452 {
453 return name_symbol -> Utf8_literal
454 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
455 }
Utf8NameLength()456 unsigned Utf8NameLength() const
457 {
458 return name_symbol -> Utf8_literal
459 ? name_symbol -> Utf8_literal -> length : 0;
460 }
461
FileLoc()462 wchar_t* FileLoc()
463 {
464 return (wchar_t*) (file_location ? file_location -> location : NULL);
465 }
466 void SetLocation();
467
MethodSymbol(const NameSymbol * name_symbol_)468 MethodSymbol(const NameSymbol* name_symbol_)
469 : declaration(NULL)
470 , name_symbol(name_symbol_)
471 , containing_type(NULL)
472 , block_symbol(NULL)
473 , next_method(NULL)
474 , signature(NULL)
475 , file_location(NULL)
476 , max_block_depth(1) // there must be at least one block in a method
477 // this default is useful for default constructors.
478 , accessed_member(NULL)
479 , external_name_symbol(NULL)
480 , status(0)
481 , header(NULL)
482 , type_(NULL)
483 , formal_parameters(NULL)
484 , throws(NULL)
485 , throws_signatures(NULL)
486 {
487 Symbol::_kind = METHOD;
488 }
489
490 virtual ~MethodSymbol();
491
IsTyped()492 bool IsTyped() const { return type_ != NULL; }
493
SetType(TypeSymbol * _type)494 void SetType(TypeSymbol* _type)
495 {
496 type_ = _type;
497 }
498
499 void ProcessMethodSignature(Semantic*, TokenIndex);
500 void ProcessMethodThrows(Semantic*, TokenIndex);
501
Type()502 TypeSymbol* Type()
503 {
504 // Make sure that the method signature associated with this method is
505 // processed prior to invoking this function.
506 // ( "this -> ProcessMethodSignature(sem, tok);" )
507 assert(type_);
508 return type_;
509 }
Type()510 const TypeSymbol* Type() const
511 {
512 assert(type_);
513 return type_;
514 }
515
NumFormalParameters()516 unsigned NumFormalParameters() const
517 {
518 assert(type_);
519 return formal_parameters ? formal_parameters -> Length() : 0;
520 }
FormalParameter(unsigned i)521 VariableSymbol* FormalParameter(unsigned i) const
522 {
523 return (*formal_parameters)[i];
524 }
AddFormalParameter(VariableSymbol * variable)525 void AddFormalParameter(VariableSymbol* variable)
526 {
527 if (! formal_parameters)
528 formal_parameters = new Tuple<VariableSymbol*>(8);
529 formal_parameters -> Next() = variable;
530 }
531
NumThrows()532 unsigned NumThrows()
533 {
534 assert(! throws_signatures);
535 return throws ? throws -> Length() : 0;
536 }
Throws(unsigned i)537 TypeSymbol* Throws(unsigned i)
538 {
539 return (*throws)[i];
540 }
AddThrows(TypeSymbol * exception)541 void AddThrows(TypeSymbol* exception)
542 {
543 if (! throws)
544 throws = new Tuple<TypeSymbol*>(8);
545 throws -> Next() = exception;
546 }
547
NumThrowsSignatures()548 unsigned NumThrowsSignatures()
549 {
550 return throws_signatures ? throws_signatures -> Length() : 0;
551 }
ThrowsSignature(unsigned i)552 char* ThrowsSignature(unsigned i)
553 {
554 return (*throws_signatures)[i];
555 }
AddThrowsSignature(const char * signature_,unsigned length)556 void AddThrowsSignature(const char* signature_, unsigned length)
557 {
558 char* signature = new char[length + 1];
559 strncpy(signature, signature_, length);
560 signature[length] = U_NULL;
561
562 if (! throws_signatures)
563 throws_signatures = new Tuple<char*>(8);
564 throws_signatures -> Next() = signature;
565 }
566
SetExternalIdentity(const NameSymbol * external_name_symbol_)567 void SetExternalIdentity(const NameSymbol* external_name_symbol_)
568 {
569 external_name_symbol = external_name_symbol_;
570 }
ExternalIdentity()571 const NameSymbol* ExternalIdentity() const
572 {
573 return external_name_symbol ? external_name_symbol : name_symbol;
574 }
ExternalName()575 const wchar_t* ExternalName() const
576 {
577 return external_name_symbol ? external_name_symbol -> Name()
578 : name_symbol -> Name();
579 }
ExternalNameLength()580 unsigned ExternalNameLength() const
581 {
582 return external_name_symbol ? external_name_symbol -> NameLength()
583 : name_symbol -> NameLength();
584 }
ExternalUtf8Name()585 const char* ExternalUtf8Name() const
586 {
587 return external_name_symbol
588 ? external_name_symbol -> Utf8_literal -> value
589 : name_symbol -> Utf8_literal
590 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
591 }
ExternalUtf8NameLength()592 unsigned ExternalUtf8NameLength() const
593 {
594 return external_name_symbol && external_name_symbol -> Utf8_literal
595 ? external_name_symbol -> Utf8_literal -> length
596 : name_symbol -> Utf8_literal
597 ? name_symbol -> Utf8_literal -> length : 0;
598 }
599
SetContainingType(TypeSymbol * containing_type_)600 void SetContainingType(TypeSymbol* containing_type_)
601 {
602 containing_type = containing_type_;
603 }
SetBlockSymbol(BlockSymbol * block_symbol_)604 void SetBlockSymbol(BlockSymbol* block_symbol_)
605 {
606 block_symbol = block_symbol_;
607 }
608 void SetSignature(Control&, TypeSymbol* = NULL);
SetSignature(Utf8LiteralValue * signature_)609 void SetSignature(Utf8LiteralValue* signature_) { signature = signature_; }
SignatureString()610 const char* SignatureString() const { return signature -> value; }
611 wchar_t* Header();
612
613 void CleanUp();
614
MarkDeprecated()615 void MarkDeprecated() { status |= DEPRECATED; }
IsDeprecated()616 bool IsDeprecated() { return (status & DEPRECATED) != 0; }
617
618 private:
619 const NameSymbol* external_name_symbol;
620
621 unsigned char status;
622 wchar_t* header;
623
624 // The return type of methods, and the containing type of constructors.
625 TypeSymbol* type_;
626
627 Tuple<VariableSymbol*>* formal_parameters;
628 Tuple<TypeSymbol*>* throws;
629 Tuple<char*>* throws_signatures;
630 };
631
632
633 class TypeSymbol : public Symbol, public AccessFlags
634 {
635 enum
636 {
637 CONSTRUCTOR_MEMBERS_PROCESSED = 0x0001,
638 METHOD_MEMBERS_PROCESSED = 0x0002,
639 FIELD_MEMBERS_PROCESSED = 0x0004,
640 LOCAL_CLASS_PROCESSING_COMPLETED = 0x0008,
641 SOURCE_PENDING = 0x0010,
642 ANONYMOUS = 0x0020,
643 HEADER_PROCESSED = 0x0040,
644 PRIMITIVE = 0x0080,
645 DEPRECATED = 0x0100,
646 ENUM_TYPE = 0x0200, // can't use ACC_ENUM on types :(
647 BAD = 0x0400,
648 CIRCULAR = 0x0800
649 };
650
651 public:
652 SemanticEnvironment* semantic_environment;
653 AstClassBody* declaration;
654
655 FileSymbol* file_symbol;
656 FileLocation* file_location;
657 const NameSymbol* name_symbol;
658 Symbol* owner;
659
660 // A nested class identifies the outer most type that contains it. If a
661 // class is not nested then it identifies itself as its outermost type.
662 TypeSymbol* outermost_type;
663
664 TypeSymbol* super;
665
666 // Indicates the base type (type of elements in the last dimension) of an
667 // array. For a normal type base_type is NULL. If base_type is a "bad"
668 // type it points to itself (this).
669 TypeSymbol* base_type;
670
671 // This variable is used in TypeCycleChecker to determine if this type
672 // forms an inter-type cycle in its "extends" or "implements" relationship.
673 int index;
674
675 // This variable is used in TypeCycleChecker to check if this type
676 // forms an intra-type cycle in its "extends" or "implements" relationship;
677 int unit_index;
678
679 // This variable is used in TypeCycleChecker to determine which types
680 // (files) need to be recompiled based on the "dependent" relationship.
681 int incremental_index;
682
NumLocalConstructorCallEnvironments()683 unsigned NumLocalConstructorCallEnvironments()
684 {
685 return local_constructor_call_environments
686 ? local_constructor_call_environments -> Length() : 0;
687 }
LocalConstructorCallEnvironment(unsigned i)688 SemanticEnvironment*& LocalConstructorCallEnvironment(unsigned i)
689 {
690 return (*local_constructor_call_environments)[i];
691 }
AddLocalConstructorCallEnvironment(SemanticEnvironment * environment)692 void AddLocalConstructorCallEnvironment(SemanticEnvironment* environment)
693 {
694 if (! local_constructor_call_environments)
695 local_constructor_call_environments =
696 new Tuple<SemanticEnvironment*>(8);
697 local_constructor_call_environments -> Next() = environment;
698 }
699
NumPrivateAccessMethods()700 unsigned NumPrivateAccessMethods()
701 {
702 return private_access_methods
703 ? private_access_methods -> Length() : 0;
704 }
PrivateAccessMethod(unsigned i)705 MethodSymbol*& PrivateAccessMethod(unsigned i)
706 {
707 return (*private_access_methods)[i];
708 }
AddPrivateAccessMethod(MethodSymbol * method_symbol)709 void AddPrivateAccessMethod(MethodSymbol* method_symbol)
710 {
711 if (! private_access_methods)
712 private_access_methods = new Tuple<MethodSymbol*>(8);
713 private_access_methods -> Next() = method_symbol;
714 }
715
NumPrivateAccessConstructors()716 unsigned NumPrivateAccessConstructors()
717 {
718 return private_access_constructors
719 ? private_access_constructors -> Length() : 0;
720 }
PrivateAccessConstructor(unsigned i)721 MethodSymbol*& PrivateAccessConstructor(unsigned i)
722 {
723 return (*private_access_constructors)[i];
724 }
AddPrivateAccessConstructor(MethodSymbol * constructor_symbol)725 void AddPrivateAccessConstructor(MethodSymbol* constructor_symbol)
726 {
727 if (! private_access_constructors)
728 private_access_constructors = new Tuple<MethodSymbol*>(8);
729 private_access_constructors -> Next() = constructor_symbol;
730 }
731
NumConstructorParameters()732 unsigned NumConstructorParameters()
733 {
734 return constructor_parameters
735 ? constructor_parameters -> Length() : 0;
736 }
ConstructorParameter(unsigned i)737 VariableSymbol*& ConstructorParameter(unsigned i)
738 {
739 return (*constructor_parameters)[i];
740 }
AddConstructorParameter(VariableSymbol * variable_symbol)741 void AddConstructorParameter(VariableSymbol* variable_symbol)
742 {
743 if (! constructor_parameters)
744 constructor_parameters = new Tuple<VariableSymbol*>(8);
745 constructor_parameters -> Next() = variable_symbol;
746 }
747
EnclosingInstance()748 VariableSymbol*& EnclosingInstance()
749 {
750 return enclosing_instance;
751 }
752
NumClassLiterals()753 unsigned NumClassLiterals()
754 {
755 return class_literals ? class_literals -> Length() : 0;
756 }
ClassLiteral(unsigned i)757 VariableSymbol*& ClassLiteral(unsigned i) { return (*class_literals)[i]; }
AddClassLiteral(VariableSymbol * literal_symbol)758 void AddClassLiteral(VariableSymbol* literal_symbol)
759 {
760 if (! class_literals)
761 class_literals = new Tuple<VariableSymbol*>(8);
762 class_literals -> Next() = literal_symbol;
763 }
764
AssertVariable()765 VariableSymbol* AssertVariable() { return assert_variable; }
766
NumNestedTypes()767 unsigned NumNestedTypes()
768 {
769 return nested_types ? nested_types -> Length() : 0;
770 }
NestedType(unsigned i)771 TypeSymbol*& NestedType(unsigned i) { return (*nested_types)[i]; }
AddNestedType(TypeSymbol * type_symbol)772 void AddNestedType(TypeSymbol* type_symbol)
773 {
774 if (! nested_types)
775 nested_types = new Tuple<TypeSymbol*>(8);
776 nested_types -> Next() = type_symbol;
777 }
778
NumInterfaces()779 unsigned NumInterfaces() const
780 {
781 return interfaces ? interfaces -> Length() : 0;
782 }
ResetInterfaces()783 void ResetInterfaces()
784 {
785 delete interfaces;
786 interfaces = NULL;
787 }
Interface(unsigned i)788 TypeSymbol* Interface(unsigned i) const { return (*interfaces)[i]; }
AddInterface(TypeSymbol * type_symbol)789 void AddInterface(TypeSymbol* type_symbol)
790 {
791 if (! interfaces)
792 interfaces = new Tuple<TypeSymbol*>(8);
793 interfaces -> Next() = type_symbol;
794 }
795
NumAnonymousTypes()796 unsigned NumAnonymousTypes()
797 {
798 return anonymous_types ? anonymous_types -> Length() : 0;
799 }
AnonymousType(unsigned i)800 TypeSymbol*& AnonymousType(unsigned i) { return (*anonymous_types)[i]; }
AddAnonymousType(TypeSymbol * type_symbol)801 void AddAnonymousType(TypeSymbol* type_symbol)
802 {
803 if (! anonymous_types)
804 anonymous_types = new Tuple<TypeSymbol*>(8);
805 anonymous_types -> Next() = type_symbol;
806 if (! outermost_type -> placeholder_type)
807 outermost_type -> placeholder_type = type_symbol;
808 }
809 void DeleteAnonymousTypes();
810 unsigned NumLocalTypes();
811
812 SymbolSet* local;
813 SymbolSet* non_local;
814 SymbolSet* supertypes_closure;
815 SymbolSet* subtypes;
816 SymbolSet* subtypes_closure;
817 SymbolSet* innertypes_closure;
818 SymbolSet* dependents;
819 SymbolSet* parents;
820 SymbolSet* static_parents;
821 SymbolSet* dependents_closure; // processed in cycle.cpp
822 SymbolSet* parents_closure; // processed in cycle.cpp
823
824 // Index of element in symbol_pool (in the relevant symbol table) that
825 // points to this type.
826 unsigned pool_index;
827
828 Utf8LiteralValue* signature;
829 Utf8LiteralValue* fully_qualified_name;
830
831 ExpandedTypeTable* expanded_type_table;
832 ExpandedFieldTable* expanded_field_table;
833 ExpandedMethodTable* expanded_method_table;
834
835 unsigned num_dimensions;
836
837 //
838 // Initializer blocks and variable declarations which require
839 // initialization are coalesced into these two methods. Notice that
840 // bytecode.cpp emits an actual method named '<clinit>' for the static
841 // case, and one named 'this' for the instance case (yes, that is a legal
842 // VM name, but an illegal Java source code name). Constructors that do
843 // not invoke another constructor via the this() statement will defer
844 // variable initialization to a generated call to the method 'this'. This
845 // relies on VM's allowing the assignment of final instance fields in an
846 // instance method instead of a constructor.
847 //
848 MethodSymbol* instance_initializer_method;
849 MethodSymbol* static_initializer_method;
850
Name()851 virtual const wchar_t* Name() const { return name_symbol -> Name(); }
NameLength()852 virtual unsigned NameLength() const { return name_symbol -> NameLength(); }
Identity()853 virtual const NameSymbol* Identity() const { return name_symbol; }
Utf8Name()854 const char* Utf8Name() const
855 {
856 return name_symbol -> Utf8_literal
857 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
858 }
Utf8NameLength()859 unsigned Utf8NameLength() const
860 {
861 return name_symbol -> Utf8_literal
862 ? name_symbol -> Utf8_literal -> length : 0;
863 }
864
865
SetExternalIdentity(const NameSymbol * external_name_symbol_)866 void SetExternalIdentity(const NameSymbol* external_name_symbol_)
867 {
868 external_name_symbol = external_name_symbol_;
869 }
ExternalIdentity()870 const NameSymbol* ExternalIdentity() const
871 {
872 return external_name_symbol ? external_name_symbol : name_symbol;
873 }
ExternalName()874 const wchar_t* ExternalName() const
875 {
876 return external_name_symbol ? external_name_symbol -> Name()
877 : name_symbol -> Name();
878 }
ExternalNameLength()879 unsigned ExternalNameLength() const
880 {
881 return external_name_symbol ? external_name_symbol -> NameLength()
882 : name_symbol -> NameLength();
883 }
ExternalUtf8Name()884 const char* ExternalUtf8Name() const
885 {
886 return external_name_symbol
887 ? external_name_symbol -> Utf8_literal -> value
888 : name_symbol -> Utf8_literal
889 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
890 }
ExternalUtf8NameLength()891 unsigned ExternalUtf8NameLength() const
892 {
893 return external_name_symbol && external_name_symbol -> Utf8_literal
894 ? external_name_symbol -> Utf8_literal -> length
895 : name_symbol -> Utf8_literal
896 ? name_symbol -> Utf8_literal -> length : 0;
897 }
898
899 TypeSymbol(const NameSymbol*);
900 virtual ~TypeSymbol();
901
902 void ProcessTypeHeaders();
903 void ProcessMembers();
904 void CompleteSymbolTable();
905 void ProcessExecutableBodies();
906 void RemoveCompilationReferences();
907
908 VariableSymbol* InsertThis0();
909
910 TypeSymbol* FindOrInsertClassLiteralClass();
911 MethodSymbol* FindOrInsertClassLiteralMethod(Control&);
ClassLiteralMethod()912 MethodSymbol* ClassLiteralMethod()
913 {
914 return class_literal_method;
915 }
916 Utf8LiteralValue* FindOrInsertClassLiteralName(Control&);
917 VariableSymbol* FindOrInsertClassLiteral(TypeSymbol*);
918 VariableSymbol* FindOrInsertLocalShadow(VariableSymbol*);
919 VariableSymbol* FindOrInsertAssertVariable();
920
921 //
922 // Get an accessor method in this class for the given symbol, with
923 // qualifying type defaulting to this type if unspecified
924 //
925 MethodSymbol* GetReadAccessMethod(MethodSymbol*, TypeSymbol* = NULL);
926 MethodSymbol* GetReadAccessConstructor(MethodSymbol*);
927 MethodSymbol* GetReadAccessMethod(VariableSymbol*, TypeSymbol* = NULL);
928 MethodSymbol* GetWriteAccessMethod(VariableSymbol*, TypeSymbol* = NULL);
929 MethodSymbol* GetWriteAccessFromReadAccess(MethodSymbol*);
930 TypeSymbol* GetPlaceholderType();
931
IsArray()932 bool IsArray() const { return num_dimensions > 0; }
933
SetOwner(Symbol * owner_)934 void SetOwner(Symbol* owner_) { owner = owner_; }
935
IsOwner(TypeSymbol * type)936 bool IsOwner(TypeSymbol* type)
937 {
938 Symbol* sym = type -> owner;
939 while (! sym -> PackageCast())
940 {
941 if (sym == this)
942 return true;
943
944 MethodSymbol* method = sym -> MethodCast();
945 sym = (method ? method -> containing_type
946 : ((TypeSymbol*) sym) -> owner);
947 }
948 return false;
949 }
950
ContainingType()951 TypeSymbol* ContainingType()
952 {
953 if (owner)
954 {
955 TypeSymbol* type = owner -> TypeCast();
956 if (type)
957 return type;
958 MethodSymbol* method = owner -> MethodCast();
959 if (method)
960 return method -> containing_type;
961 }
962 return NULL;
963 }
ContainingType()964 const TypeSymbol* ContainingType() const
965 {
966 if (owner)
967 {
968 TypeSymbol* type = owner -> TypeCast();
969 if (type)
970 return type;
971 MethodSymbol* method = owner -> MethodCast();
972 if (method)
973 return method -> containing_type;
974 }
975 return NULL;
976 }
977
978 TypeSymbol* EnclosingType();
979 bool HasEnclosingInstance(TypeSymbol*, bool = false);
980 bool HasProtectedAccessTo(TypeSymbol*);
981
982 //
983 // For JSR 201, control.int_class -> BoxedType() returns control.Integer(),
984 // types without boxing return themselves. UnboxedType() works the other
985 // direction.
986 //
987 TypeSymbol* BoxedType(Control&);
988 TypeSymbol* UnboxedType(Control&);
989
990 //
991 // Note that this test considers a class a subclass of itself, and also
992 // interfaces are a subclass of Object. See also IsSubtype.
993 //
IsSubclass(const TypeSymbol * super_class)994 bool IsSubclass(const TypeSymbol* super_class) const
995 {
996 for (const TypeSymbol* type = this; type; type = type -> super)
997 if (type == super_class)
998 return true;
999 return false;
1000 }
1001
1002 //
1003 // Note that this test considers an interface a subtype of itself, but
1004 // does not work for classes. See also IsSubtype.
1005 //
IsSubinterface(const TypeSymbol * super_interface)1006 bool IsSubinterface(const TypeSymbol* super_interface) const
1007 {
1008 if (this == super_interface)
1009 return true;
1010 for (unsigned i = 0; i < NumInterfaces(); i++)
1011 {
1012 if (Interface(i) -> IsSubinterface(super_interface))
1013 return true;
1014 }
1015 return false;
1016 }
1017
1018 //
1019 // This test works for classes, but not for interfaces. See also IsSubtype.
1020 //
Implements(const TypeSymbol * inter)1021 bool Implements(const TypeSymbol* inter) const
1022 {
1023 for (unsigned i = 0; i < NumInterfaces(); i++)
1024 {
1025 if (Interface(i) -> IsSubinterface(inter))
1026 return true;
1027 }
1028 return super && super -> Implements(inter);
1029 }
1030
1031 //
1032 // The most generic subtype relation; returns true if this type is a
1033 // subtype of the argument type. This correctly checks a class's
1034 // superclasses and superinterfaces, an interfaces's superinterfaces and
1035 // Object, and an array's compatible types (smaller dimensions of Object,
1036 // Cloneable, Serializable, and all equal dimension arrays where the
1037 // element type is a subtype). For simplicity, a type subtypes itself.
1038 //
IsSubtype(const TypeSymbol * type)1039 bool IsSubtype(const TypeSymbol* type) const
1040 {
1041 if (ACC_INTERFACE())
1042 return (type -> ACC_INTERFACE() && IsSubinterface(type)) ||
1043 super == type;
1044 if (num_dimensions)
1045 {
1046 const TypeSymbol* base =
1047 type -> base_type ? type -> base_type : type;
1048 return (num_dimensions > type -> num_dimensions &&
1049 ((base -> ACC_INTERFACE() && Implements(base)) ||
1050 super == base)) ||
1051 (num_dimensions == type -> num_dimensions &&
1052 base_type -> IsSubtype(base));
1053 }
1054 return type -> ACC_INTERFACE() ? Implements(type) : IsSubclass(type);
1055 }
1056
FileLoc()1057 wchar_t* FileLoc()
1058 {
1059 return file_location ? file_location -> location : (wchar_t*) NULL;
1060 }
1061
1062 void SetLocation();
1063
1064 //
1065 // Returns the array type of the given number of dims with the same base
1066 // type as this (ie. Object[] -> GetArrayType(...,2) returns Object[][]).
1067 //
1068 TypeSymbol* GetArrayType(Semantic*, unsigned);
1069
ArraySubtype()1070 TypeSymbol* ArraySubtype() const
1071 {
1072 assert(num_dimensions);
1073 return base_type -> Array(num_dimensions - 1);
1074 }
1075
1076 void SetSignature(Control&);
SetSignature(Utf8LiteralValue * signature_)1077 void SetSignature(Utf8LiteralValue* signature_) { signature = signature_; }
SignatureString()1078 const char* SignatureString() const { return signature -> value; }
1079
SetClassLiteralName(Utf8LiteralValue * class_literal_name_)1080 void SetClassLiteralName(Utf8LiteralValue* class_literal_name_)
1081 {
1082 class_literal_name = class_literal_name_;
1083 }
1084
ContainingPackage()1085 PackageSymbol* ContainingPackage() const
1086 {
1087 return outermost_type -> owner -> PackageCast();
1088 }
1089 // Returns the fully-qualified '/' separated package name.
ContainingPackageName()1090 const wchar_t* ContainingPackageName() const
1091 {
1092 return outermost_type -> owner -> PackageCast() -> PackageName();
1093 }
1094
1095 bool IsNestedIn(TypeSymbol*);
1096
IsNested()1097 bool IsNested() const { return outermost_type != this; }
1098
1099 //
1100 // JLS2 8.1.2 states that ALL local and anonymous classes are inner
1101 // classes, even when they occur in a static context. Even in the static
1102 // context, such classes are not implicitly static, they simply lack an
1103 // enclosing instance. In other words, the JLS definition of inner class
1104 // is lame. If everything works correctly, these classes will correctly
1105 // be marked nested, yet never static.
1106 //
IsInner()1107 bool IsInner() const
1108 {
1109 assert((! IsLocal() && ! Anonymous()) ||
1110 (IsNested() && ! ACC_STATIC()));
1111 return IsNested() && ! ACC_STATIC();
1112 }
1113
IsLocal()1114 bool IsLocal() const
1115 {
1116 for (Symbol* sym = owner;
1117 ! sym -> PackageCast(); sym = ((TypeSymbol*) sym) -> owner)
1118 {
1119 if (sym -> MethodCast())
1120 return true;
1121 }
1122 return false;
1123 }
1124
ClassName()1125 inline const char* ClassName()
1126 {
1127 if (! class_name)
1128 SetClassName();
1129 return class_name;
1130 }
1131
MarkConstructorMembersProcessed()1132 void MarkConstructorMembersProcessed()
1133 {
1134 status |= CONSTRUCTOR_MEMBERS_PROCESSED;
1135 }
ConstructorMembersProcessed()1136 bool ConstructorMembersProcessed() const
1137 {
1138 return (status & CONSTRUCTOR_MEMBERS_PROCESSED) != 0;
1139 }
1140
MarkMethodMembersProcessed()1141 void MarkMethodMembersProcessed()
1142 {
1143 status |= METHOD_MEMBERS_PROCESSED;
1144 }
MethodMembersProcessed()1145 bool MethodMembersProcessed() const
1146 {
1147 return (status & METHOD_MEMBERS_PROCESSED) != 0;
1148 }
1149
MarkFieldMembersProcessed()1150 void MarkFieldMembersProcessed()
1151 {
1152 status |= FIELD_MEMBERS_PROCESSED;
1153 }
FieldMembersProcessed()1154 bool FieldMembersProcessed() const
1155 {
1156 return (status & FIELD_MEMBERS_PROCESSED) != 0;
1157 }
1158
MarkLocalClassProcessingCompleted()1159 void MarkLocalClassProcessingCompleted()
1160 {
1161 status |= LOCAL_CLASS_PROCESSING_COMPLETED;
1162 }
LocalClassProcessingCompleted()1163 bool LocalClassProcessingCompleted() const
1164 {
1165 return (status & LOCAL_CLASS_PROCESSING_COMPLETED) != 0;
1166 }
1167
MarkSourcePending()1168 void MarkSourcePending() { status |= SOURCE_PENDING; }
MarkSourceNoLongerPending()1169 void MarkSourceNoLongerPending() { status &= ~ SOURCE_PENDING; }
SourcePending()1170 bool SourcePending() const { return (status & SOURCE_PENDING) != 0; }
1171
MarkAnonymous()1172 void MarkAnonymous() { status |= ANONYMOUS; }
Anonymous()1173 bool Anonymous() const { return (status & ANONYMOUS) != 0; }
1174
MarkHeaderProcessed()1175 void MarkHeaderProcessed() { status |= HEADER_PROCESSED; }
HeaderProcessed()1176 bool HeaderProcessed() const { return (status & HEADER_PROCESSED) != 0; }
1177
MarkPrimitive()1178 void MarkPrimitive() { status |= PRIMITIVE; }
Primitive()1179 bool Primitive() const { return (status & PRIMITIVE) != 0; }
1180
MarkDeprecated()1181 void MarkDeprecated() { status |= DEPRECATED; }
ResetDeprecated()1182 void ResetDeprecated() { status &= ~DEPRECATED; }
IsDeprecated()1183 bool IsDeprecated() const { return (status & DEPRECATED) != 0; }
1184
MarkEnum()1185 void MarkEnum() { status |= ENUM_TYPE; }
ResetEnum()1186 void ResetEnum() { status &= ~ENUM_TYPE; }
IsEnum()1187 bool IsEnum() const { return (status & ENUM_TYPE) != 0; }
1188
MarkBad()1189 void MarkBad()
1190 {
1191 SetACC_PUBLIC();
1192 status |= (BAD | HEADER_PROCESSED | CONSTRUCTOR_MEMBERS_PROCESSED |
1193 METHOD_MEMBERS_PROCESSED | FIELD_MEMBERS_PROCESSED |
1194 LOCAL_CLASS_PROCESSING_COMPLETED);
1195 MarkSourceNoLongerPending();
1196 }
Bad()1197 bool Bad() const { return (status & BAD) != 0; }
1198
MarkCircular()1199 void MarkCircular()
1200 {
1201 status |= CIRCULAR;
1202 MarkBad();
1203 }
MarkNonCircular()1204 void MarkNonCircular() { status &= ~ CIRCULAR; }
Circular()1205 bool Circular() const { return (status & CIRCULAR) != 0; }
1206
1207 void ProcessNestedTypeSignatures(Semantic*, TokenIndex);
1208
NestedTypesProcessed()1209 bool NestedTypesProcessed() { return nested_type_signatures == NULL; }
1210
NumNestedTypeSignatures()1211 unsigned NumNestedTypeSignatures()
1212 {
1213 return nested_type_signatures
1214 ? nested_type_signatures -> Length() : 0;
1215 }
NestedTypeSignature(unsigned i)1216 char* NestedTypeSignature(unsigned i)
1217 {
1218 return (*nested_type_signatures)[i];
1219 }
AddNestedTypeSignature(const char * signature_,unsigned length)1220 void AddNestedTypeSignature(const char* signature_, unsigned length)
1221 {
1222 char* signature = new char[length + 1];
1223 strncpy(signature, signature_, length);
1224 signature[length] = U_NULL;
1225
1226 if (! nested_type_signatures)
1227 nested_type_signatures = new Tuple<char*>(8);
1228 nested_type_signatures -> Next() = signature;
1229 }
1230
1231 inline void SetSymbolTable(unsigned);
1232 inline SymbolTable* Table();
1233
1234 unsigned NumVariableSymbols();
1235 VariableSymbol* VariableSym(unsigned);
1236
1237 unsigned NumMethodSymbols();
1238 MethodSymbol* MethodSym(unsigned);
1239
1240 unsigned NumTypeSymbols();
1241 TypeSymbol* TypeSym(unsigned);
1242
1243 inline TypeSymbol* InsertAnonymousTypeSymbol(NameSymbol*);
1244 inline TypeSymbol* InsertNestedTypeSymbol(NameSymbol*);
1245 inline TypeSymbol* FindTypeSymbol(const NameSymbol*);
1246
1247 inline VariableSymbol* InsertVariableSymbol(const NameSymbol*);
1248 inline void InsertVariableSymbol(VariableSymbol*);
1249 inline VariableSymbol* FindVariableSymbol(const NameSymbol*);
1250
1251 inline MethodSymbol* InsertMethodSymbol(const NameSymbol*);
1252 inline void InsertMethodSymbol(MethodSymbol*);
1253 inline MethodSymbol* FindMethodSymbol(const NameSymbol*);
1254 MethodSymbol* FindOverloadMethod(MethodSymbol*, AstMethodDeclarator*);
1255
1256 inline void CompressSpace();
1257 void UnlinkFromParents();
1258
1259 private:
1260 //
1261 // The fields hash_address and next_type are used in the class
1262 // TypeLookupTable to contruct a mapping from each fully_qualified name
1263 // into the type that it defines.
1264 //
1265 friend class TypeLookupTable;
1266 unsigned hash_address;
1267 TypeSymbol* next_type;
1268
1269 const NameSymbol* external_name_symbol;
1270
1271 SymbolTable* table;
1272 SymbolMap* local_shadow_map;
1273
1274 unsigned short status;
1275
1276 PackageSymbol* package;
1277 char* class_name;
1278
1279 void SetClassName();
1280
1281 MethodSymbol* class_literal_method;
1282 Utf8LiteralValue* class_literal_name;
1283 VariableSymbol* assert_variable;
1284
1285 //
1286 // For a local type, when we first encounter an embedded call to one of
1287 // its constructors or a constructor of one of its inner types, either via
1288 // a ClassCreationExpression or an ExplicitConstructorInvocation, we record
1289 // it and resolve it after we have computed all necessary information
1290 // about the type and its inner types.
1291 //
1292 Tuple<SemanticEnvironment*>* local_constructor_call_environments;
1293
1294 //
1295 // When an inner class tries to access a private member of one of its
1296 // enclosing classes, one (or two) access method(s) to read (and/or write)
1297 // the private member is (are) generated.
1298 //
1299 // The maps read_methods and write_methods are used to keep track of the
1300 // read and write method to which a member has been mapped.
1301 //
1302 Tuple<MethodSymbol*>* private_access_methods;
1303 Tuple<MethodSymbol*>* private_access_constructors;
1304
1305 inline void MapSymbolToReadMethod(Symbol*, TypeSymbol*, MethodSymbol*);
1306 inline MethodSymbol* ReadMethod(Symbol*, TypeSymbol*);
1307 inline void MapSymbolToWriteMethod(VariableSymbol*, TypeSymbol*,
1308 MethodSymbol*);
1309 inline MethodSymbol* WriteMethod(VariableSymbol*, TypeSymbol*);
1310
1311 Map<Symbol, Map<TypeSymbol, MethodSymbol> >* read_methods;
1312 Map<VariableSymbol, Map<TypeSymbol, MethodSymbol> >* write_methods;
1313 TypeSymbol* placeholder_type;
1314
1315 //
1316 // For an accessible inner class the first element in this array
1317 // identifies the "this$0" pointer of the containing type. For a local
1318 // class, in addition to the this$0 pointer (if it is needed), all local
1319 // variables that are referred to in the local type are passed as argument
1320 // to the local type and copied in the constructor into a local field.
1321 // These local variables are stored in constructor_parameters.
1322 //
1323 // The array enclosing_instances is there for optimization purposes.
1324 // If this type is deeply nested within several other types and it makes
1325 // references to members in the enclosing types, then it might
1326 // be useful to keep a reference to each of these enclosing
1327 // instances in the form of this$0, this$1, this$2, ...
1328 //
1329 // The array class_identities is used to store static variables of type
1330 // Class that contain the proper value for a given type.
1331 //
1332 Tuple<VariableSymbol*>* constructor_parameters;
1333 VariableSymbol* enclosing_instance;
1334 Tuple<VariableSymbol*>* class_literals;
1335
1336 Tuple<char*>* nested_type_signatures;
1337
1338 //
1339 // The inner types that appear immediately within this type in the order
1340 // in which they should be processed (compiled).
1341 //
1342 Tuple<TypeSymbol*>* nested_types;
1343 // The interfaces that were declared in the header of the type.
1344 Tuple<TypeSymbol*>* interfaces;
1345 // The anonymous types that were declared in this type.
1346 Tuple<TypeSymbol*>* anonymous_types;
1347
1348 //
1349 // The arrays of this type that were declared.
1350 //
1351 Tuple<TypeSymbol*>* array;
NumArrays()1352 inline unsigned NumArrays()
1353 {
1354 return array ? array -> Length() : 0;
1355 }
Array(unsigned i)1356 inline TypeSymbol* Array(unsigned i)
1357 {
1358 return (*array)[i];
1359 }
AddArrayType(TypeSymbol * type_symbol)1360 inline void AddArrayType(TypeSymbol* type_symbol)
1361 {
1362 if (! array)
1363 array = new Tuple<TypeSymbol*>(4);
1364 array -> Next() = type_symbol;
1365 }
1366 };
1367
1368
1369 class VariableSymbol : public Symbol, public AccessFlags
1370 {
1371 enum
1372 {
1373 COMPLETE = 0x01, // Used to prevent use of field before declaration
1374 DEPRECATED = 0x02, // Used to mark deprecated fields
1375 INITIALIZED = 0x04 // Used when initial value of final field is known
1376 };
1377
1378 public:
1379 AstVariableDeclarator* declarator;
1380 FileLocation* file_location;
1381 const NameSymbol* name_symbol;
1382 Symbol* owner;
1383 LiteralValue* initial_value;
1384 Utf8LiteralValue* signature;
1385
1386 // Index of element in symbol_pool (in the relevant symbol table) that
1387 // points to this variable.
1388 unsigned pool_index;
1389
1390 VariableSymbol* accessed_local;
1391
Name()1392 virtual const wchar_t* Name() const { return name_symbol -> Name(); }
NameLength()1393 virtual unsigned NameLength() const { return name_symbol -> NameLength(); }
Identity()1394 virtual const NameSymbol* Identity() const { return name_symbol; }
1395 void SetLocation();
Utf8Name()1396 const char* Utf8Name() const
1397 {
1398 return name_symbol -> Utf8_literal
1399 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
1400 }
Utf8NameLength()1401 unsigned Utf8NameLength() const
1402 {
1403 return name_symbol -> Utf8_literal
1404 ? name_symbol -> Utf8_literal -> length : 0;
1405 }
1406
FileLoc()1407 wchar_t* FileLoc()
1408 {
1409 return (wchar_t*) (file_location ? file_location -> location : NULL);
1410 }
SetExternalIdentity(const NameSymbol * external_name_symbol_)1411 void SetExternalIdentity(const NameSymbol* external_name_symbol_)
1412 {
1413 external_name_symbol = external_name_symbol_;
1414 }
ExternalIdentity()1415 const NameSymbol* ExternalIdentity() const
1416 {
1417 return external_name_symbol ? external_name_symbol : name_symbol;
1418 }
ExternalName()1419 const wchar_t* ExternalName() const
1420 {
1421 return external_name_symbol ? external_name_symbol -> Name()
1422 : name_symbol -> Name();
1423 }
ExternalNameLength()1424 unsigned ExternalNameLength() const
1425 {
1426 return external_name_symbol ? external_name_symbol -> NameLength()
1427 : name_symbol -> NameLength();
1428 }
ExternalUtf8Name()1429 const char* ExternalUtf8Name() const
1430 {
1431 return external_name_symbol
1432 ? external_name_symbol -> Utf8_literal -> value
1433 : name_symbol -> Utf8_literal
1434 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
1435 }
ExternalUtf8NameLength()1436 unsigned ExternalUtf8NameLength() const
1437 {
1438 return external_name_symbol && external_name_symbol -> Utf8_literal
1439 ? external_name_symbol -> Utf8_literal -> length
1440 : name_symbol -> Utf8_literal
1441 ? name_symbol -> Utf8_literal -> length : 0;
1442 }
1443
VariableSymbol(const NameSymbol * name_symbol_)1444 VariableSymbol(const NameSymbol* name_symbol_)
1445 : declarator(NULL)
1446 , file_location(NULL)
1447 , name_symbol(name_symbol_)
1448 , owner(NULL)
1449 , initial_value(NULL)
1450 , signature(NULL)
1451 , accessed_local(NULL)
1452 , external_name_symbol(NULL)
1453 , status(0)
1454 , local_variable_index(-1)
1455 , type_(NULL)
1456 , signature_string(NULL)
1457 {
1458 Symbol::_kind = VARIABLE;
1459 }
1460
~VariableSymbol()1461 virtual ~VariableSymbol() { delete [] signature_string; }
1462
SetOwner(Symbol * owner_)1463 void SetOwner(Symbol* owner_)
1464 {
1465 owner = owner_;
1466 assert(owner -> TypeCast() || owner -> MethodCast());
1467 }
1468
ContainingType()1469 TypeSymbol* ContainingType()
1470 {
1471 MethodSymbol* method_owner = owner -> MethodCast();
1472 return method_owner ? method_owner -> containing_type
1473 : owner -> TypeCast();
1474 }
ContainingType()1475 const TypeSymbol* ContainingType() const
1476 {
1477 MethodSymbol* method_owner = owner -> MethodCast();
1478 return method_owner ? method_owner -> containing_type
1479 : owner -> TypeCast();
1480 }
1481
SetLocalVariableIndex(int index)1482 void SetLocalVariableIndex(int index) { local_variable_index = index; }
1483 //
1484 // For local variables, returns the index allocated to the variable.
1485 //
LocalVariableIndex()1486 int LocalVariableIndex() { return local_variable_index; }
1487 //
1488 // Returns the local variable index, but for local variables, it adds an
1489 // offset to account for all final fields. This version should only be
1490 // needed for definite assignment analysis.
1491 //
1492 int LocalVariableIndex(Semantic*);
1493
IsTyped()1494 bool IsTyped() const { return type_ != NULL; }
1495
SetType(TypeSymbol * _type)1496 void SetType(TypeSymbol* _type)
1497 {
1498 type_ = _type;
1499 signature = type_ -> signature;
1500 }
1501
1502 void ProcessVariableSignature(Semantic*, TokenIndex);
1503
Type()1504 TypeSymbol* Type()
1505 {
1506 // Make sure that the method signature associated with this method is
1507 // processed prior to invoking this function.
1508 // ( "this -> ProcessVariableSignature(sem, tok);" )
1509 assert(type_);
1510 return type_;
1511 }
Type()1512 const TypeSymbol* Type() const
1513 {
1514 assert(type_);
1515 return type_;
1516 }
1517
SetSignatureString(const char * signature_,unsigned length)1518 void SetSignatureString(const char* signature_, unsigned length)
1519 {
1520 signature_string = new char[length + 1];
1521 strncpy(signature_string, signature_, length);
1522 signature_string[length] = U_NULL;
1523 }
1524
1525 // Is variable a local variable?
IsLocal()1526 bool IsLocal() { return owner -> MethodCast() != NULL; }
1527 // Is variable local to a particular method ?
IsLocal(MethodSymbol * method)1528 bool IsLocal(MethodSymbol* method) { return owner == method; }
1529
IsFinal(TypeSymbol * type)1530 bool IsFinal(TypeSymbol* type) { return owner == type && ACC_FINAL(); }
1531
1532 //
1533 // These functions are used to identify when the declaration of a field
1534 // in the body of a class is complete.
1535 //
MarkComplete()1536 void MarkComplete() { status |= COMPLETE; }
IsDeclarationComplete()1537 bool IsDeclarationComplete() { return (status & COMPLETE) != 0; }
1538
MarkDeprecated()1539 void MarkDeprecated() { status |= DEPRECATED; }
IsDeprecated()1540 bool IsDeprecated() { return (status & DEPRECATED) != 0; }
1541
MarkInitialized()1542 void MarkInitialized() { status |= INITIALIZED; }
IsInitialized()1543 bool IsInitialized() { return (status & INITIALIZED) != 0; }
1544
1545 private:
1546 const NameSymbol* external_name_symbol;
1547
1548 unsigned char status;
1549 int local_variable_index;
1550 TypeSymbol* type_;
1551 char* signature_string;
1552 };
1553
1554
1555 class BlockSymbol : public Symbol
1556 {
1557 public:
1558 int max_variable_index;
1559 // try, synchronized, and foreach need synthetic helper variables
1560 int helper_variable_index;
1561
1562 BlockSymbol(unsigned hash_size);
1563 virtual ~BlockSymbol();
1564
1565 unsigned NumVariableSymbols();
1566 VariableSymbol* VariableSym(unsigned);
1567
1568 inline VariableSymbol* FindVariableSymbol(const NameSymbol*);
1569 inline VariableSymbol* InsertVariableSymbol(const NameSymbol*);
1570 inline void InsertVariableSymbol(VariableSymbol*);
1571 inline BlockSymbol* InsertBlockSymbol(unsigned);
1572
1573 inline void CompressSpace();
1574
1575 inline SymbolTable* Table();
1576
1577 private:
1578 SymbolTable* table;
1579 };
1580
1581
1582 class LabelSymbol : public Symbol
1583 {
1584 public:
1585 AstBlock* block; // the block that is labeled by this symbol
1586 const NameSymbol* name_symbol;
1587
1588 unsigned nesting_level;
1589
Name()1590 virtual const wchar_t* Name() const { return name_symbol -> Name(); }
NameLength()1591 virtual unsigned NameLength() const { return name_symbol -> NameLength(); }
Identity()1592 virtual const NameSymbol* Identity() const { return name_symbol; }
Utf8Name()1593 const char* Utf8Name() const
1594 {
1595 return name_symbol -> Utf8_literal
1596 ? name_symbol -> Utf8_literal -> value : (char*) NULL;
1597 }
Utf8NameLength()1598 unsigned Utf8NameLength() const
1599 {
1600 return name_symbol -> Utf8_literal
1601 ? name_symbol -> Utf8_literal -> length : 0;
1602 }
1603
LabelSymbol(const NameSymbol * name_symbol_)1604 LabelSymbol(const NameSymbol* name_symbol_)
1605 : block(NULL)
1606 , name_symbol(name_symbol_)
1607 , nesting_level(0)
1608 {
1609 Symbol::_kind = LABEL;
1610 }
1611
~LabelSymbol()1612 virtual ~LabelSymbol() {}
1613 };
1614
1615
1616 class SymbolTable
1617 {
1618 public:
1619 enum
1620 {
1621 DEFAULT_HASH_SIZE = 13,
1622 MAX_HASH_SIZE = 1021
1623 };
1624
NumAnonymousSymbols()1625 unsigned NumAnonymousSymbols()
1626 {
1627 return anonymous_symbol_pool ? anonymous_symbol_pool -> Length() : 0;
1628 }
AnonymousSym(unsigned i)1629 TypeSymbol* AnonymousSym(unsigned i)
1630 {
1631 return (*anonymous_symbol_pool)[i];
1632 }
AddAnonymousSymbol(TypeSymbol * symbol)1633 void AddAnonymousSymbol(TypeSymbol* symbol)
1634 {
1635 if (! anonymous_symbol_pool)
1636 anonymous_symbol_pool = new ConvertibleArray<TypeSymbol*>(256);
1637 anonymous_symbol_pool -> Next() = symbol;
1638 // not hashed, because anonymous types have no name
1639 }
1640
NumTypeSymbols()1641 unsigned NumTypeSymbols()
1642 {
1643 return type_symbol_pool ? type_symbol_pool -> Length() : 0;
1644 }
TypeSym(unsigned i)1645 TypeSymbol*& TypeSym(unsigned i)
1646 {
1647 return (*type_symbol_pool)[i];
1648 }
AddTypeSymbol(TypeSymbol * symbol)1649 void AddTypeSymbol(TypeSymbol* symbol)
1650 {
1651 symbol -> pool_index = NumTypeSymbols();
1652 if (! type_symbol_pool)
1653 type_symbol_pool = new Tuple<TypeSymbol*>(256);
1654 type_symbol_pool -> Next() = symbol;
1655 Hash(symbol);
1656 }
1657
NumMethodSymbols()1658 unsigned NumMethodSymbols()
1659 {
1660 return method_symbol_pool ? method_symbol_pool -> Length() : 0;
1661 }
MethodSym(unsigned i)1662 MethodSymbol* MethodSym(unsigned i)
1663 {
1664 return (*method_symbol_pool)[i];
1665 }
AddMethodSymbol(MethodSymbol * symbol)1666 void AddMethodSymbol(MethodSymbol* symbol)
1667 {
1668 symbol -> pool_index = NumMethodSymbols();
1669 if (! method_symbol_pool)
1670 method_symbol_pool = new ConvertibleArray<MethodSymbol*>(256);
1671 method_symbol_pool -> Next() = symbol;
1672 // not hashed, because of method overloading
1673 }
1674
NumVariableSymbols()1675 unsigned NumVariableSymbols()
1676 {
1677 return variable_symbol_pool ? variable_symbol_pool -> Length() : 0;
1678 }
VariableSym(unsigned i)1679 VariableSymbol* VariableSym(unsigned i)
1680 {
1681 return (*variable_symbol_pool)[i];
1682 }
AddVariableSymbol(VariableSymbol * symbol)1683 void AddVariableSymbol(VariableSymbol* symbol)
1684 {
1685 symbol -> pool_index = NumVariableSymbols();
1686 if (! variable_symbol_pool)
1687 variable_symbol_pool = new ConvertibleArray<VariableSymbol*>(256);
1688 variable_symbol_pool -> Next() = symbol;
1689 Hash(symbol);
1690 }
1691
NumOtherSymbols()1692 unsigned NumOtherSymbols()
1693 {
1694 return other_symbol_pool ? other_symbol_pool -> Length() : 0;
1695 }
OtherSym(unsigned i)1696 Symbol* OtherSym(unsigned i)
1697 {
1698 return (*other_symbol_pool)[i];
1699 }
AddOtherSymbol(Symbol * symbol)1700 void AddOtherSymbol(Symbol* symbol)
1701 {
1702 if (! other_symbol_pool)
1703 other_symbol_pool = new ConvertibleArray<Symbol*>(256);
1704 other_symbol_pool -> Next() = symbol;
1705 // not hashed, because not all symbols have names
1706 }
1707
1708 SymbolTable(unsigned hash_size_ = DEFAULT_HASH_SIZE);
1709 ~SymbolTable();
1710
CompressSpace()1711 inline void CompressSpace()
1712 {
1713 if (anonymous_symbol_pool)
1714 anonymous_symbol_pool -> Array();
1715 if (method_symbol_pool)
1716 method_symbol_pool -> Array();
1717 if (variable_symbol_pool)
1718 variable_symbol_pool -> Array();
1719 if (other_symbol_pool)
1720 other_symbol_pool -> Array();
1721 }
1722
1723 private:
1724
1725 // This array should not be convertible. See SymbolTable::DeleteTypeSymbol
1726 Tuple<TypeSymbol*>* type_symbol_pool;
1727
1728 ConvertibleArray<TypeSymbol*>* anonymous_symbol_pool;
1729 ConvertibleArray<MethodSymbol*>* method_symbol_pool;
1730 ConvertibleArray<VariableSymbol*>* variable_symbol_pool;
1731 ConvertibleArray<Symbol*>* other_symbol_pool;
1732
1733 Symbol** base;
1734 unsigned hash_size;
1735
1736 static unsigned primes[];
1737 int prime_index;
1738
Size()1739 unsigned Size()
1740 {
1741 return NumAnonymousSymbols() + NumTypeSymbols() + NumMethodSymbols() +
1742 NumVariableSymbols() + NumOtherSymbols();
1743 }
Hash(Symbol * symbol)1744 void Hash(Symbol* symbol)
1745 {
1746 unsigned k = symbol -> Identity() -> index % hash_size;
1747 symbol -> next = base[k];
1748 base[k] = symbol;
1749 //
1750 // If the set is "adjustable" and the number of unique elements in it
1751 // exceeds 2 times the size of the base, and we have not yet reached
1752 // the maximum allowable size for a base, reallocate a larger base and
1753 // rehash the elements.
1754 //
1755 if (Size() > (hash_size << 1) && hash_size < MAX_HASH_SIZE)
1756 Rehash();
1757 }
1758 void Rehash();
1759
1760 public:
1761
1762 inline PathSymbol* InsertPathSymbol(NameSymbol*, DirectorySymbol*);
1763 inline PathSymbol* FindPathSymbol(const NameSymbol*);
1764
1765 inline DirectorySymbol* InsertDirectorySymbol(const NameSymbol*, Symbol*,
1766 bool source_path);
1767 inline DirectorySymbol* FindDirectorySymbol(const NameSymbol*);
1768
1769 inline FileSymbol* InsertFileSymbol(const NameSymbol*);
1770 inline FileSymbol* FindFileSymbol(const NameSymbol*);
1771
1772 inline PackageSymbol* InsertPackageSymbol(NameSymbol*, PackageSymbol*);
1773 inline PackageSymbol* FindPackageSymbol(const NameSymbol*);
1774
1775 inline TypeSymbol* InsertAnonymousTypeSymbol(NameSymbol*);
1776 inline TypeSymbol* InsertTypeSymbol(NameSymbol*);
1777 inline void DeleteTypeSymbol(TypeSymbol*);
1778 inline void DeleteAnonymousTypes();
1779 inline TypeSymbol* FindTypeSymbol(const NameSymbol*);
1780
1781 inline MethodSymbol* InsertMethodSymbol(MethodSymbol*);
1782 inline MethodSymbol* FindMethodSymbol(const NameSymbol*);
1783 MethodSymbol* FindOverloadMethod(MethodSymbol*, AstMethodDeclarator*);
1784
1785 inline VariableSymbol* InsertVariableSymbol(const NameSymbol*);
1786 inline VariableSymbol* InsertVariableSymbol(VariableSymbol*);
1787 inline VariableSymbol* FindVariableSymbol(const NameSymbol*);
1788
1789 inline LabelSymbol* InsertLabelSymbol(NameSymbol*);
1790 inline LabelSymbol* FindLabelSymbol(const NameSymbol*);
1791
1792 inline BlockSymbol* InsertBlockSymbol(unsigned);
1793 };
1794
NumVariableSymbols()1795 inline unsigned TypeSymbol::NumVariableSymbols()
1796 {
1797 return table ? table -> NumVariableSymbols() : 0;
1798 }
VariableSym(unsigned i)1799 inline VariableSymbol* TypeSymbol::VariableSym(unsigned i)
1800 {
1801 return table -> VariableSym(i);
1802 }
1803
NumVariableSymbols()1804 inline unsigned BlockSymbol::NumVariableSymbols()
1805 {
1806 return table ? table -> NumVariableSymbols() : 0;
1807 }
VariableSym(unsigned i)1808 inline VariableSymbol* BlockSymbol::VariableSym(unsigned i)
1809 {
1810 return table -> VariableSym(i);
1811 }
1812
NumMethodSymbols()1813 inline unsigned TypeSymbol::NumMethodSymbols()
1814 {
1815 return table ? table -> NumMethodSymbols() : 0;
1816 }
MethodSym(unsigned i)1817 inline MethodSymbol* TypeSymbol::MethodSym(unsigned i)
1818 {
1819 return table -> MethodSym(i);
1820 }
1821
NumTypeSymbols()1822 inline unsigned TypeSymbol::NumTypeSymbols()
1823 {
1824 return table ? table -> NumTypeSymbols() : 0;
1825 }
TypeSym(unsigned i)1826 inline TypeSymbol* TypeSymbol::TypeSym(unsigned i)
1827 {
1828 return table -> TypeSym(i);
1829 }
1830
CompressSpace()1831 inline void TypeSymbol::CompressSpace()
1832 {
1833 if (table)
1834 table -> CompressSpace();
1835 }
CompressSpace()1836 inline void BlockSymbol::CompressSpace()
1837 {
1838 if (table)
1839 table -> CompressSpace();
1840 }
1841
InsertPathSymbol(NameSymbol * name_symbol,DirectorySymbol * directory_symbol)1842 inline PathSymbol* SymbolTable::InsertPathSymbol(NameSymbol* name_symbol,
1843 DirectorySymbol* directory_symbol)
1844 {
1845 assert(base);
1846
1847 PathSymbol* symbol = new PathSymbol(name_symbol);
1848 directory_symbol -> owner = symbol;
1849 symbol -> root_directory = directory_symbol;
1850 AddOtherSymbol(symbol);
1851 Hash(symbol);
1852 return symbol;
1853 }
1854
1855
FindPathSymbol(const NameSymbol * name_symbol)1856 inline PathSymbol* SymbolTable::FindPathSymbol(const NameSymbol* name_symbol)
1857 {
1858 assert(base);
1859 for (Symbol* symbol = base[name_symbol -> index % hash_size];
1860 symbol; symbol = symbol -> next)
1861 {
1862 if (name_symbol == symbol -> Identity() && symbol -> PathCast())
1863 return (PathSymbol*) symbol;
1864 }
1865 return NULL;
1866 }
1867
1868
InsertDirectorySymbol(const NameSymbol * name_symbol,Symbol * owner,bool source_path)1869 inline DirectorySymbol* SymbolTable::InsertDirectorySymbol(const NameSymbol* name_symbol,
1870 Symbol* owner,
1871 bool source_path)
1872 {
1873 assert(base);
1874 DirectorySymbol* symbol = new DirectorySymbol(name_symbol, owner,
1875 source_path);
1876 AddOtherSymbol(symbol);
1877 Hash(symbol);
1878 return symbol;
1879 }
1880
1881
InsertDirectorySymbol(const NameSymbol * name_symbol,bool source_dir)1882 inline DirectorySymbol* DirectorySymbol::InsertDirectorySymbol(const NameSymbol* name_symbol,
1883 bool source_dir)
1884 {
1885 DirectorySymbol* subdirectory_symbol =
1886 Table() -> InsertDirectorySymbol(name_symbol, this,
1887 source_dir && source_dir_only);
1888 subdirectories.Next() = subdirectory_symbol;
1889 return subdirectory_symbol;
1890 }
1891
1892
FindDirectorySymbol(const NameSymbol * name_symbol)1893 inline DirectorySymbol* SymbolTable::FindDirectorySymbol(const NameSymbol* name_symbol)
1894 {
1895 assert(base);
1896 for (Symbol* symbol = base[name_symbol -> index % hash_size];
1897 symbol; symbol = symbol -> next)
1898 {
1899 if (name_symbol == symbol -> Identity() && symbol -> DirectoryCast())
1900 return (DirectorySymbol*) symbol;
1901 }
1902 return NULL;
1903 }
1904
1905
FindDirectorySymbol(const NameSymbol * name_symbol)1906 inline DirectorySymbol* DirectorySymbol::FindDirectorySymbol(const NameSymbol* name_symbol)
1907 {
1908 return table ? table -> FindDirectorySymbol(name_symbol)
1909 : (DirectorySymbol*) NULL;
1910 }
1911
1912
InsertFileSymbol(const NameSymbol * name_symbol)1913 inline FileSymbol* SymbolTable::InsertFileSymbol(const NameSymbol* name_symbol)
1914 {
1915 assert(base);
1916 FileSymbol* symbol = new FileSymbol(name_symbol);
1917 AddOtherSymbol(symbol);
1918 Hash(symbol);
1919 return symbol;
1920 }
1921
1922
InsertFileSymbol(const NameSymbol * name_symbol)1923 inline FileSymbol* DirectorySymbol::InsertFileSymbol(const NameSymbol* name_symbol)
1924 {
1925 return Table() -> InsertFileSymbol(name_symbol);
1926 }
1927
1928
FindFileSymbol(const NameSymbol * name_symbol)1929 inline FileSymbol* SymbolTable::FindFileSymbol(const NameSymbol* name_symbol)
1930 {
1931 assert(base);
1932 for (Symbol* symbol = base[name_symbol -> index % hash_size];
1933 symbol; symbol = symbol -> next)
1934 {
1935 if (name_symbol == symbol -> Identity() && symbol -> FileCast())
1936 return (FileSymbol*) symbol;
1937 }
1938 return NULL;
1939 }
1940
1941
FindFileSymbol(const NameSymbol * name_symbol)1942 inline FileSymbol* DirectorySymbol::FindFileSymbol(const NameSymbol* name_symbol)
1943 {
1944 return table ? table -> FindFileSymbol(name_symbol)
1945 : (FileSymbol*) NULL;
1946 }
1947
1948
InsertPackageSymbol(NameSymbol * name_symbol,PackageSymbol * owner)1949 inline PackageSymbol* SymbolTable::InsertPackageSymbol(NameSymbol* name_symbol,
1950 PackageSymbol* owner)
1951 {
1952 assert(base);
1953 PackageSymbol* symbol = new PackageSymbol(name_symbol, owner);
1954 AddOtherSymbol(symbol);
1955 Hash(symbol);
1956 return symbol;
1957 }
1958
1959
InsertPackageSymbol(NameSymbol * name_symbol)1960 inline PackageSymbol* PackageSymbol::InsertPackageSymbol(NameSymbol* name_symbol)
1961 {
1962 return Table() -> InsertPackageSymbol(name_symbol, this);
1963 }
1964
1965
FindPackageSymbol(const NameSymbol * name_symbol)1966 inline PackageSymbol* SymbolTable::FindPackageSymbol(const NameSymbol* name_symbol)
1967 {
1968 assert(base);
1969 for (Symbol* symbol = base[name_symbol -> index % hash_size];
1970 symbol; symbol = symbol -> next)
1971 {
1972 if (name_symbol == symbol -> Identity() && symbol -> PackageCast())
1973 return (PackageSymbol*) symbol;
1974 }
1975 return NULL;
1976 }
1977
1978
FindPackageSymbol(const NameSymbol * name_symbol)1979 inline PackageSymbol* PackageSymbol::FindPackageSymbol(const NameSymbol* name_symbol)
1980 {
1981 return table ? table -> FindPackageSymbol(name_symbol)
1982 : (PackageSymbol*) NULL;
1983 }
1984
InsertAnonymousTypeSymbol(NameSymbol * name_symbol)1985 inline TypeSymbol* SymbolTable::InsertAnonymousTypeSymbol(NameSymbol* name_symbol)
1986 {
1987 TypeSymbol* symbol = new TypeSymbol(name_symbol);
1988 AddAnonymousSymbol(symbol);
1989 return symbol;
1990 }
1991
1992
InsertAnonymousTypeSymbol(NameSymbol * name_symbol)1993 inline TypeSymbol* TypeSymbol::InsertAnonymousTypeSymbol(NameSymbol* name_symbol)
1994 {
1995 return Table() -> InsertAnonymousTypeSymbol(name_symbol);
1996 }
1997
1998
InsertTypeSymbol(NameSymbol * name_symbol)1999 inline TypeSymbol* SymbolTable::InsertTypeSymbol(NameSymbol* name_symbol)
2000 {
2001 assert(base);
2002 TypeSymbol* symbol = new TypeSymbol(name_symbol);
2003 AddTypeSymbol(symbol);
2004 return symbol;
2005 }
2006
2007
InsertSystemTypeSymbol(NameSymbol * name_symbol)2008 inline TypeSymbol* PackageSymbol::InsertSystemTypeSymbol(NameSymbol* name_symbol)
2009 {
2010 return Table() -> InsertTypeSymbol(name_symbol);
2011 }
2012
InsertOuterTypeSymbol(NameSymbol * name_symbol)2013 inline TypeSymbol* PackageSymbol::InsertOuterTypeSymbol(NameSymbol* name_symbol)
2014 {
2015 return Table() -> InsertTypeSymbol(name_symbol);
2016 }
2017
InsertNestedTypeSymbol(NameSymbol * name_symbol)2018 inline TypeSymbol* TypeSymbol::InsertNestedTypeSymbol(NameSymbol* name_symbol)
2019 {
2020 return Table() -> InsertTypeSymbol(name_symbol);
2021 }
2022
2023
DeleteTypeSymbol(TypeSymbol * type)2024 inline void SymbolTable::DeleteTypeSymbol(TypeSymbol* type)
2025 {
2026 assert(base);
2027 unsigned k = type -> name_symbol -> index % hash_size;
2028 if (type == base[k])
2029 base[k] = type -> next;
2030 else
2031 {
2032 Symbol* previous = base[k];
2033 for (Symbol* symbol = previous -> next;
2034 symbol != type; previous = symbol, symbol = symbol -> next)
2035 ;
2036 previous -> next = type -> next;
2037 }
2038
2039 unsigned last_index = NumTypeSymbols() - 1;
2040 if (type -> pool_index != last_index)
2041 {
2042 // Move last element to position previously occupied by element being
2043 // deleted
2044 TypeSym(last_index) -> pool_index = type -> pool_index;
2045 TypeSym(type -> pool_index) = TypeSym(last_index);
2046 }
2047
2048 type_symbol_pool -> Reset(last_index); // remove last slot in symbol_pool
2049 delete type;
2050 }
2051
2052
DeleteTypeSymbol(TypeSymbol * type)2053 inline void PackageSymbol::DeleteTypeSymbol(TypeSymbol* type)
2054 {
2055 if (table)
2056 table -> DeleteTypeSymbol(type);
2057 }
2058
2059
DeleteAnonymousTypes()2060 inline void SymbolTable::DeleteAnonymousTypes()
2061 {
2062 for (unsigned i = 0; i < NumAnonymousSymbols(); i++)
2063 {
2064 TypeSymbol* symbol = AnonymousSym(i);
2065 symbol -> UnlinkFromParents();
2066 delete symbol;
2067 }
2068 delete anonymous_symbol_pool;
2069 anonymous_symbol_pool = NULL;
2070 }
2071
2072
DeleteAnonymousTypes()2073 inline void TypeSymbol::DeleteAnonymousTypes()
2074 {
2075 delete anonymous_types;
2076 anonymous_types = NULL;
2077 if (table)
2078 table -> DeleteAnonymousTypes();
2079 }
2080
FindTypeSymbol(const NameSymbol * name_symbol)2081 inline TypeSymbol* SymbolTable::FindTypeSymbol(const NameSymbol* name_symbol)
2082 {
2083 assert(base);
2084 for (Symbol* symbol = base[name_symbol -> index % hash_size];
2085 symbol; symbol = symbol -> next)
2086 {
2087 if (name_symbol == symbol -> Identity() && symbol -> TypeCast())
2088 return (TypeSymbol*) symbol;
2089 }
2090 return NULL;
2091 }
2092
2093
FindTypeSymbol(const NameSymbol * name_symbol)2094 inline TypeSymbol* PackageSymbol::FindTypeSymbol(const NameSymbol* name_symbol)
2095 {
2096 return table ? table -> FindTypeSymbol(name_symbol)
2097 : (TypeSymbol*) NULL;
2098 }
2099
2100
FindTypeSymbol(const NameSymbol * name_symbol)2101 inline TypeSymbol* TypeSymbol::FindTypeSymbol(const NameSymbol* name_symbol)
2102 {
2103 return table ? table -> FindTypeSymbol(name_symbol)
2104 : (TypeSymbol*) NULL;
2105 }
2106
2107
InsertMethodSymbol(MethodSymbol * symbol)2108 inline MethodSymbol* SymbolTable::InsertMethodSymbol(MethodSymbol* symbol)
2109 {
2110 assert(base);
2111 AddMethodSymbol(symbol);
2112 const NameSymbol* name_symbol = symbol -> Identity();
2113 MethodSymbol* base_method = NULL;
2114 Symbol* candidate;
2115 for (candidate = base[name_symbol -> index % hash_size];
2116 candidate; candidate = candidate -> next)
2117 {
2118 if (name_symbol == candidate -> Identity() &&
2119 candidate -> MethodCast())
2120 {
2121 base_method = (MethodSymbol*) candidate;
2122 break;
2123 }
2124 }
2125 if (base_method)
2126 {
2127 symbol -> next = symbol; // mark method as overloaded
2128 symbol -> next_method = base_method -> next_method;
2129 base_method -> next_method = symbol;
2130 }
2131 else Hash(symbol);
2132 return symbol;
2133 }
2134
2135
InsertMethodSymbol(const NameSymbol * name_symbol)2136 inline MethodSymbol* TypeSymbol::InsertMethodSymbol(const NameSymbol* name_symbol)
2137 {
2138 return Table() -> InsertMethodSymbol(new MethodSymbol(name_symbol));
2139 }
2140
2141
InsertMethodSymbol(MethodSymbol * method_symbol)2142 inline void TypeSymbol::InsertMethodSymbol(MethodSymbol* method_symbol)
2143 {
2144 Table() -> InsertMethodSymbol(method_symbol);
2145 }
2146
2147
FindMethodSymbol(const NameSymbol * name_symbol)2148 inline MethodSymbol* SymbolTable::FindMethodSymbol(const NameSymbol* name_symbol)
2149 {
2150 assert(base);
2151 for (Symbol* symbol = base[name_symbol -> index % hash_size];
2152 symbol; symbol = symbol -> next)
2153 {
2154 if (name_symbol == symbol -> Identity() && symbol -> MethodCast())
2155 return (MethodSymbol*) symbol;
2156 }
2157 return NULL;
2158 }
2159
2160
FindMethodSymbol(const NameSymbol * name_symbol)2161 inline MethodSymbol* TypeSymbol::FindMethodSymbol(const NameSymbol* name_symbol)
2162 {
2163 return table ? table -> FindMethodSymbol(name_symbol)
2164 : (MethodSymbol*) NULL;
2165 }
2166
2167
FindOverloadMethod(MethodSymbol * base_method,AstMethodDeclarator * method_declarator)2168 inline MethodSymbol* TypeSymbol::FindOverloadMethod(MethodSymbol* base_method,
2169 AstMethodDeclarator* method_declarator)
2170 {
2171 return table ? table -> FindOverloadMethod(base_method, method_declarator)
2172 : (MethodSymbol*) NULL;
2173 }
2174
2175
InsertVariableSymbol(const NameSymbol * name_symbol)2176 inline VariableSymbol* SymbolTable::InsertVariableSymbol(const NameSymbol* name_symbol)
2177 {
2178 assert(base);
2179 VariableSymbol* symbol = new VariableSymbol(name_symbol);
2180 AddVariableSymbol(symbol);
2181 return symbol;
2182 }
2183
2184
InsertVariableSymbol(const NameSymbol * name_symbol)2185 inline VariableSymbol* TypeSymbol::InsertVariableSymbol(const NameSymbol* name_symbol)
2186 {
2187 return Table() -> InsertVariableSymbol(name_symbol);
2188 }
2189
2190
InsertVariableSymbol(const NameSymbol * name_symbol)2191 inline VariableSymbol* BlockSymbol::InsertVariableSymbol(const NameSymbol* name_symbol)
2192 {
2193 return Table() -> InsertVariableSymbol(name_symbol);
2194 }
2195
2196
InsertVariableSymbol(VariableSymbol * symbol)2197 inline VariableSymbol* SymbolTable::InsertVariableSymbol(VariableSymbol* symbol)
2198 {
2199 assert(base);
2200 AddVariableSymbol(symbol);
2201 return symbol;
2202 }
2203
2204
InsertVariableSymbol(VariableSymbol * variable_symbol)2205 inline void TypeSymbol::InsertVariableSymbol(VariableSymbol* variable_symbol)
2206 {
2207 Table() -> InsertVariableSymbol(variable_symbol);
2208 }
2209
2210
InsertVariableSymbol(VariableSymbol * variable_symbol)2211 inline void BlockSymbol::InsertVariableSymbol(VariableSymbol* variable_symbol)
2212 {
2213 Table() -> InsertVariableSymbol(variable_symbol);
2214 }
2215
2216
FindVariableSymbol(const NameSymbol * name_symbol)2217 inline VariableSymbol* SymbolTable::FindVariableSymbol(const NameSymbol* name_symbol)
2218 {
2219 assert(base);
2220 for (Symbol* symbol = base[name_symbol -> index % hash_size];
2221 symbol; symbol = symbol -> next)
2222 {
2223 if (name_symbol == symbol -> Identity() && symbol -> VariableCast())
2224 return (VariableSymbol*) symbol;
2225 }
2226 return NULL;
2227 }
2228
2229
FindVariableSymbol(const NameSymbol * name_symbol)2230 inline VariableSymbol* TypeSymbol::FindVariableSymbol(const NameSymbol* name_symbol)
2231 {
2232 return table ? table -> FindVariableSymbol(name_symbol)
2233 : (VariableSymbol*) NULL;
2234 }
2235
2236
FindVariableSymbol(const NameSymbol * name_symbol)2237 inline VariableSymbol* BlockSymbol::FindVariableSymbol(const NameSymbol* name_symbol)
2238 {
2239 return table ? table -> FindVariableSymbol(name_symbol)
2240 : (VariableSymbol*) NULL;
2241 }
2242
2243
InsertLabelSymbol(NameSymbol * name_symbol)2244 inline LabelSymbol* SymbolTable::InsertLabelSymbol(NameSymbol* name_symbol)
2245 {
2246 assert(base);
2247 LabelSymbol* symbol = new LabelSymbol(name_symbol);
2248 AddOtherSymbol(symbol);
2249 Hash(symbol);
2250 return symbol;
2251 }
2252
2253
FindLabelSymbol(const NameSymbol * name_symbol)2254 inline LabelSymbol* SymbolTable::FindLabelSymbol(const NameSymbol* name_symbol)
2255 {
2256 assert(base);
2257 for (Symbol* symbol = base[name_symbol -> index % hash_size];
2258 symbol; symbol = symbol -> next)
2259 {
2260 if (name_symbol == symbol -> Identity() && symbol -> LabelCast())
2261 return (LabelSymbol*) symbol;
2262 }
2263 return NULL;
2264 }
2265
2266 inline BlockSymbol* SymbolTable::InsertBlockSymbol(unsigned hash_size = 0)
2267 {
2268 BlockSymbol* symbol = new BlockSymbol(hash_size);
2269 AddOtherSymbol(symbol);
2270 return symbol;
2271 }
2272
2273
2274 inline BlockSymbol* BlockSymbol::InsertBlockSymbol(unsigned hash_size = 0)
2275 {
2276 return Table() -> InsertBlockSymbol(hash_size);
2277 }
2278
2279
Table()2280 inline SymbolTable* DirectorySymbol::Table()
2281 {
2282 return table ? table : table = new SymbolTable(101);
2283 }
2284
Table()2285 inline SymbolTable* PackageSymbol::Table()
2286 {
2287 return table ? table : table = new SymbolTable(101);
2288 }
2289
SetSymbolTable(unsigned estimate)2290 inline void TypeSymbol::SetSymbolTable(unsigned estimate)
2291 {
2292 // If table was not yet allocated, allocate one based on the estimate
2293 if (! table)
2294 table = new SymbolTable(estimate);
2295 }
2296
Table()2297 inline SymbolTable* TypeSymbol::Table()
2298 {
2299 return table ? table : table = new SymbolTable();
2300 }
2301
Table()2302 inline SymbolTable* BlockSymbol::Table()
2303 {
2304 return table ? table : table = new SymbolTable();
2305 }
2306
2307 #ifdef HAVE_JIKES_NAMESPACE
2308 } // Close namespace Jikes block
2309 #endif
2310
2311 #endif // symbol_INCLUDED
2312
2313