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