home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / Jikes / Source / src / symbol.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-03  |  69.7 KB  |  1,928 lines

  1. // $Id: symbol.cpp,v 1.39 2001/01/10 16:49:45 mdejong Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler Open
  4. // Source License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "symbol.h"
  11. #include "stream.h"
  12. #include "control.h"
  13. #include "ast.h"
  14. #include "semantic.h"
  15. #include "table.h"
  16. #include "zip.h"
  17. #include "set.h"
  18. #include "case.h"
  19.  
  20. #ifdef    HAVE_JIKES_NAMESPACE
  21. namespace Jikes {    // Open namespace Jikes block
  22. #endif
  23.  
  24. char *FileSymbol::java_suffix = StringConstant::U8S__DO_java;
  25. int FileSymbol::java_suffix_length = strlen(java_suffix);
  26. char *FileSymbol::class_suffix = StringConstant::U8S__DO_class;
  27. int FileSymbol::class_suffix_length = strlen(class_suffix);
  28.  
  29. bool MethodSymbol::IsFinal()
  30. {
  31.     return ((AccessFlags *) this) -> ACC_FINAL() || ((AccessFlags *) this) -> ACC_PRIVATE() || containing_type -> ACC_FINAL();
  32. }
  33.  
  34. wchar_t *MethodSymbol::Header()
  35. {
  36.     assert(type_);
  37.  
  38.     if (! header)
  39.     {
  40.         bool is_constructor = false;
  41.         for (MethodSymbol *constr = containing_type -> FindConstructorSymbol(); constr; constr = constr -> next_method)
  42.         {
  43.             if (this == constr)
  44.             {
  45.                 is_constructor = true;
  46.                 break;
  47.             }
  48.         }
  49.  
  50.         int length = this -> Type() -> ContainingPackage() -> PackageNameLength() +
  51.                      this -> Type() -> ExternalNameLength() +
  52.                      (is_constructor ? containing_type -> NameLength() : this -> NameLength()) + 5; // '/' after package_name
  53.                                                                                                     // ' ' after type
  54.                                                                                                     // '(' after name
  55.                                                                                                     // ')' after all parameters
  56.                                                                                                     // ';' to terminate
  57.         for (int i = 0; i < NumFormalParameters(); i++)
  58.         {
  59.             VariableSymbol *formal = FormalParameter(i);
  60.             length += (formal -> Type() -> ContainingPackage() -> PackageNameLength() +
  61.                        formal -> Type() -> ExternalNameLength() +
  62.                        formal -> NameLength() + 4); // '/' after package_name
  63.                                                     // ' ' after type
  64.                                                     // ',' and ' ' to separate this formal parameter from the next one
  65.         }
  66.  
  67.         header = new wchar_t[length + 1]; // +1 for '\0'
  68.         wchar_t *s = header;
  69.  
  70.         if (is_constructor)
  71.         {
  72.             for (wchar_t *s2 = this -> containing_type -> Name(); *s2; s2++)
  73.                  *s++ = *s2;
  74.         }
  75.         else
  76.         {
  77.             PackageSymbol *package = this -> Type() -> ContainingPackage();
  78.             wchar_t *package_name = package -> PackageName();
  79.             if (package -> PackageNameLength() > 0 && wcscmp(package_name, StringConstant::US__DO) != 0)
  80.             {
  81.                 while (*package_name)
  82.                 {
  83.                     *s++ = (*package_name == U_SLASH ? (wchar_t) U_DOT : *package_name);
  84.                     package_name++;
  85.                 }
  86.                 *s++ = U_DOT;
  87.             }
  88.  
  89.             for (wchar_t *s2 = this -> Type() -> ExternalName(); *s2; s2++)
  90.                  *s++ = *s2;
  91.             *s++ = U_SPACE;
  92.             for (wchar_t *s3 = Name(); *s3; s3++)
  93.                  *s++ = *s3;
  94.         }
  95.         *s++ = U_LEFT_PARENTHESIS;
  96.         if (NumFormalParameters() > 0)
  97.         {
  98.             for (int k = 0; k < NumFormalParameters(); k++)
  99.             {
  100.                 VariableSymbol *formal = FormalParameter(k);
  101.  
  102.                 PackageSymbol *package = formal -> Type() -> ContainingPackage();
  103.                 wchar_t *package_name = package -> PackageName();
  104.                 if (package -> PackageNameLength() > 0 && wcscmp(package_name, StringConstant::US__DO) != 0)
  105.                 {
  106.                     while (*package_name)
  107.                     {
  108.                         *s++ = (*package_name == U_SLASH ? (wchar_t) U_DOT : *package_name);
  109.                         package_name++;
  110.                     }
  111.                     *s++ = U_DOT;
  112.                 }
  113.  
  114.                 for (wchar_t *s2 = formal -> Type() -> ExternalName(); *s2; s2++)
  115.                     *s++ = *s2;
  116.                 *s++ = U_SPACE;
  117.                 for (wchar_t *s3 = formal -> Name(); *s3; s3++)
  118.                      *s++ = *s3;
  119.                 *s++ = U_COMMA;
  120.                 *s++ = U_SPACE;
  121.             }
  122.  
  123.             s -= 2; // remove the last ',' and ' '
  124.         }
  125.         *s++ = U_RIGHT_PARENTHESIS;
  126.         *s++ = U_SEMICOLON;
  127.         *s = U_NULL;
  128.  
  129.         assert((s - header) <= length);
  130.     }
  131.  
  132.     return header;
  133. }
  134.  
  135.  
  136. MethodSymbol *SymbolTable::FindOverloadMethod(MethodSymbol *base_method, AstMethodDeclarator *method_declarator)
  137. {
  138.     for (MethodSymbol *method = base_method; method; method = method -> next_method)
  139.     {
  140.         assert(method -> IsTyped());
  141.  
  142.         if (method -> NumFormalParameters() == method_declarator -> NumFormalParameters())
  143.         {
  144.             int i;
  145.             for (i = method -> NumFormalParameters() - 1; i >= 0; i--)
  146.             {
  147.                 AstFormalParameter *parameter = method_declarator -> FormalParameter(i);
  148.                 if (method -> FormalParameter(i) -> Type() != parameter -> formal_declarator -> symbol -> Type())
  149.                     break;
  150.             }
  151.             if (i < 0)
  152.                 return method;
  153.         }
  154.     }
  155.  
  156.     return(MethodSymbol *)  NULL;
  157. }
  158.  
  159.  
  160. void TypeSymbol::ProcessTypeHeaders()
  161. {
  162.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  163.  
  164.     if (class_declaration)
  165.          semantic_environment -> sem -> ProcessTypeHeaders(class_declaration);
  166.     else semantic_environment -> sem -> ProcessTypeHeaders((AstInterfaceDeclaration *) declaration);
  167. }
  168.  
  169. void TypeSymbol::ProcessMembers()
  170. {
  171.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  172.  
  173.     if (class_declaration)
  174.          semantic_environment -> sem -> ProcessMembers(class_declaration -> semantic_environment, class_declaration -> class_body);
  175.     else semantic_environment -> sem -> ProcessMembers((AstInterfaceDeclaration *) declaration);
  176. }
  177.  
  178. void TypeSymbol::CompleteSymbolTable()
  179. {
  180.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  181.  
  182.     if (class_declaration)
  183.          semantic_environment -> sem -> CompleteSymbolTable(class_declaration -> semantic_environment,
  184.                                                             class_declaration -> identifier_token, class_declaration -> class_body);
  185.     else semantic_environment -> sem -> CompleteSymbolTable((AstInterfaceDeclaration *) declaration);
  186. }
  187.  
  188.  
  189. void TypeSymbol::ProcessExecutableBodies()
  190. {
  191.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  192.  
  193.     if (class_declaration)
  194.          semantic_environment -> sem -> ProcessExecutableBodies(class_declaration -> semantic_environment,
  195.                                                                 class_declaration -> class_body);
  196.     else semantic_environment -> sem -> ProcessExecutableBodies((AstInterfaceDeclaration *) declaration);
  197. }
  198.  
  199.  
  200. void TypeSymbol::RemoveCompilationReferences()
  201. {
  202.     if (semantic_environment)
  203.     {
  204.         semantic_environment = NULL;
  205.         declaration = NULL;
  206.  
  207.         //
  208.         // TODO: What else needs to be reset?
  209.         //
  210.         if (table)
  211.         {
  212.             for (int i = 0; i < table -> NumVariableSymbols(); i++)
  213.                 table -> VariableSym(i) -> declarator = NULL;
  214.  
  215.             for (int j = 0; j < table -> NumMethodSymbols(); j++)
  216.                 table -> MethodSym(j) -> method_or_constructor_declaration = NULL;
  217.  
  218.             for (int k = 0; k < table -> NumTypeSymbols(); k++)
  219.                 table -> TypeSym(k) -> declaration = NULL;
  220.  
  221.             for (int l = 0; l < table -> NumAnonymousSymbols(); l++)
  222.                 table -> AnonymousSym(l) -> declaration = NULL;
  223.         }
  224.     }
  225.  
  226.     return;
  227. }
  228.  
  229.  
  230. TypeSymbol *TypeSymbol::GetArrayType(Semantic *sem, int num_dimensions_)
  231. {
  232.     if (num_dimensions_ == 0)
  233.         return this;
  234.     if (num_dimensions_ < NumArrays())
  235.         return Array(num_dimensions_);
  236.  
  237.     if (NumArrays() == 0)
  238.         AddArrayType(this);
  239.  
  240.     TypeSymbol *previous_array_type = Array(array -> Length() - 1);
  241.     wchar_t *name = new wchar_t[this -> ExternalNameLength() + (num_dimensions_ * 2) + 1];
  242.     wcscpy(name, previous_array_type -> ExternalName());
  243.  
  244.     for (int num = array -> Length(), len = previous_array_type -> ExternalNameLength() + 2;
  245.          num <= num_dimensions_;
  246.          num++, len = len + 2)
  247.     {
  248.         wcscat(name, StringConstant::US__LB__RB);
  249.         NameSymbol *name_sym = sem -> control.FindOrInsertName(name, len);
  250.  
  251.         TypeSymbol *type = new TypeSymbol(name_sym);
  252.  
  253.         type -> MarkHeaderProcessed();
  254.         type -> MarkConstructorMembersProcessed();
  255.         type -> MarkMethodMembersProcessed();
  256.         type -> MarkFieldMembersProcessed();
  257.         type -> MarkLocalClassProcessingCompleted();
  258.         type -> MarkSourceNoLongerPending();
  259.         type -> outermost_type = type;
  260.  
  261.         type -> SetACC_PUBLIC();
  262.         type -> SetACC_FINAL();
  263.  
  264.         type -> super = sem -> control.Object();
  265.         //
  266.         // All arrays implement the interfaces java.io.Serializable and
  267.         // java.io.Cloneable
  268.         //
  269.         type -> AddInterface(sem -> control.Serializable());
  270.         type -> AddInterface(sem -> control.Cloneable());
  271.         type -> base_type = this;
  272.         type -> num_dimensions = num;
  273.         type -> SetOwner(this -> ContainingPackage());
  274.         type -> table = new SymbolTable(3); // only 2 elements will be added to this table
  275.         type -> SetSignature(sem -> control);
  276.  
  277.         MethodSymbol *method = type -> InsertMethodSymbol(sem -> control.clone_name_symbol);
  278.         method -> SetType(sem -> control.Object());
  279.         method -> SetContainingType(type);
  280.         method -> SetACC_PUBLIC();
  281.         method -> SetACC_FINAL();
  282.         method -> SetBlockSymbol(new BlockSymbol(1)); // the associated symbol table will remain empty
  283.         method -> SetSignature(sem -> control);
  284.  
  285.         VariableSymbol *symbol = type -> InsertVariableSymbol(sem -> control.length_name_symbol);
  286.         symbol -> SetACC_PUBLIC();
  287.         symbol -> SetACC_FINAL();
  288.         symbol -> SetOwner(type);
  289.         symbol -> SetType(sem -> control.int_type);
  290.  
  291.         type -> CompressSpace(); // space optimization
  292.  
  293.         AddArrayType(type);
  294.     }
  295.  
  296.     delete [] name;
  297.     return Array(num_dimensions_);
  298. }
  299.  
  300. void TypeSymbol::SetLocation()
  301. {
  302.     if (! declaration)
  303.         file_location = new FileLocation(file_symbol);
  304.     else
  305.     {
  306.         AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  307.         AstInterfaceDeclaration *interface_declaration = declaration -> InterfaceDeclarationCast();
  308.  
  309.         file_location = new FileLocation(semantic_environment -> sem -> lex_stream,
  310.                                          (class_declaration
  311.                                                ? class_declaration -> identifier_token
  312.                                                : (interface_declaration
  313.                                                            ? interface_declaration -> identifier_token
  314.                                                            : ((AstClassInstanceCreationExpression *) declaration)
  315.                                                                                            -> class_body_opt -> left_brace_token)));
  316.     }
  317.  
  318.     return;
  319. }
  320.  
  321.  
  322. void TypeSymbol::SetSignature(Control &control)
  323. {
  324.     if (this -> num_dimensions > 0)
  325.     {
  326.         char *type_signature;
  327.         TypeSymbol *subtype = this -> ArraySubtype();
  328.         int signature_len = strlen(subtype -> SignatureString()) + 1; // +1 for '['
  329.         type_signature = new char[signature_len + 1];                  // +1 for '\0'
  330.         type_signature[0] = U_LEFT_BRACKET;
  331.         strcpy(type_signature + 1, subtype -> SignatureString());
  332.         this -> signature = control.Utf8_pool.FindOrInsert(type_signature, signature_len);
  333.         this -> fully_qualified_name = this -> signature;
  334.         delete [] type_signature;
  335.     }
  336.     else
  337.     {
  338.         wchar_t *package_name = this -> ContainingPackage() -> PackageName();
  339.         wchar_t *type_name = this -> ExternalName();
  340.  
  341.         int len = this -> ContainingPackage() -> PackageNameLength() +
  342.                   this -> ExternalNameLength() + 4; // +1 for 'L' +1 for '/' +1 for ';' +1 for '\0'
  343.         wchar_t *type_signature = new wchar_t[len];
  344.         wcscpy(type_signature, StringConstant::US_L);
  345.         if (this -> ContainingPackage() -> PackageNameLength() > 0 && wcscmp(package_name, StringConstant::US__DO) != 0)
  346.         {
  347.             wcscat(type_signature, package_name);
  348.             wcscat(type_signature, StringConstant::US__SL);
  349.         }
  350.         wcscat(type_signature, type_name);
  351.         this -> fully_qualified_name = control.ConvertUnicodeToUtf8(type_signature + 1); // +1 to skip the initial L'L'
  352.  
  353.         wcscat(type_signature, StringConstant::US__SC);
  354.         this -> signature = control.ConvertUnicodeToUtf8(type_signature);
  355.  
  356.         delete [] type_signature;
  357.  
  358.         if (! (this -> Anonymous() || this -> IsLocal()))
  359.             control.type_table.InsertType((TypeSymbol *) this);
  360.     }
  361.  
  362.     return;
  363. }
  364.  
  365.  
  366. int SymbolTable::primes[] = {DEFAULT_HASH_SIZE, 101, 401, MAX_HASH_SIZE};
  367.  
  368. void SymbolTable::Rehash()
  369. {
  370.     hash_size = primes[++prime_index];
  371.  
  372.     delete [] base;
  373.     base = (Symbol **) memset(new Symbol *[hash_size], 0, hash_size * sizeof(Symbol *));
  374.  
  375.     int k;
  376.     for (k = 0; k < NumTypeSymbols(); k++)
  377.     {
  378.         TypeSymbol *symbol = TypeSym(k);
  379.         int i = symbol -> name_symbol -> index % hash_size;
  380.         symbol -> next = base[i];
  381.         base[i] = symbol;
  382.     }
  383.  
  384.     for (k = 0; k < NumMethodSymbols(); k++)
  385.     {
  386.         MethodSymbol *symbol = MethodSym(k);
  387.         if (symbol -> next != symbol) // not an overload
  388.         {
  389.             int i = symbol -> name_symbol -> index % hash_size;
  390.             symbol -> next = base[i];
  391.             base[i] = symbol;
  392.         }
  393.     }
  394.  
  395.     for (k = 0; k < NumVariableSymbols(); k++)
  396.     {
  397.         VariableSymbol *symbol = VariableSym(k);
  398.         int i = symbol -> name_symbol -> index % hash_size;
  399.         symbol -> next = base[i];
  400.         base[i] = symbol;
  401.     }
  402.  
  403.     for (k = 0; k < NumOtherSymbols(); k++)
  404.     {
  405.         Symbol *symbol = OtherSym(k);
  406.  
  407.         if (! symbol -> BlockCast())
  408.         {
  409.             int i = symbol -> Identity() -> index % hash_size;
  410.             symbol -> next = base[i];
  411.             base[i] = symbol;
  412.         }
  413.     }
  414.  
  415.     return;
  416. }
  417.  
  418.  
  419. SymbolTable::SymbolTable(int hash_size_) : type_symbol_pool(NULL),
  420.                                            anonymous_symbol_pool(NULL),
  421.                                            method_symbol_pool(NULL),
  422.                                            variable_symbol_pool(NULL),
  423.                                            other_symbol_pool(NULL),
  424.                                            constructor(NULL)
  425. {
  426.     hash_size = (hash_size_ <= 0 ? 1 : hash_size_);
  427.  
  428.     prime_index = -1;
  429.     do
  430.     {
  431.         if (hash_size < primes[prime_index + 1])
  432.             break;
  433.         prime_index++;
  434.     } while (primes[prime_index] < MAX_HASH_SIZE);
  435.  
  436.     base = (Symbol **) memset(new Symbol *[hash_size], 0, hash_size * sizeof(Symbol *));
  437. }
  438.  
  439. SymbolTable::~SymbolTable()
  440. {
  441. /*
  442. int n;
  443. int num_slots = 0;
  444. int total = 0;
  445. for (n = 0; n < hash_size; n++)
  446. {
  447. int num = 0;
  448. for (Symbol *s = base[n]; s; s = s -> next)
  449.     num++;
  450. if (num > 0)
  451. {
  452. num_slots++;
  453. total += num;
  454. }
  455. }
  456.  
  457. if (num_slots > 0)
  458. {
  459. cout << "\nDestroying a symbol table with base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  460. for (n = 0; n < hash_size; n++)
  461. {
  462. int num = 0;
  463. for (Symbol *s = base[n]; s; s = s -> next)
  464.     num++;
  465. if (num > 0)
  466. cout << "    slot " << n << " contains " << num << " element(s)\n";
  467. }
  468. }
  469. if (hash_size < total)
  470.     total = total;
  471. */
  472.     for (int i = 0; i < NumAnonymousSymbols(); i++)
  473.         delete AnonymousSym(i);
  474.     delete anonymous_symbol_pool;
  475.     for (int j = 0; j < NumTypeSymbols(); j++)
  476.         delete TypeSym(j);
  477.     delete type_symbol_pool;
  478.     for (int k = 0; k < NumMethodSymbols(); k++)
  479.         delete MethodSym(k);
  480.     delete method_symbol_pool;
  481.     for (int l = 0; l < NumVariableSymbols(); l++)
  482.         delete VariableSym(l);
  483.     delete variable_symbol_pool;
  484.     for (int m = 0; m < NumOtherSymbols(); m++)
  485.         delete OtherSym(m);
  486.     delete other_symbol_pool;
  487.     delete [] base;
  488.  
  489.     return;
  490. }
  491.  
  492.  
  493. PackageSymbol::~PackageSymbol()
  494. {
  495.     delete [] package_name;
  496.     delete table;
  497. }
  498.  
  499.  
  500. void PackageSymbol::SetPackageName()
  501. {
  502.     this -> package_name_length = (owner ? owner -> PackageNameLength() + 1 : 0) + NameLength(); // +1 for '/'
  503.     this -> package_name = new wchar_t[package_name_length + 1]; // +1 for '\0'
  504.  
  505.     if (owner)
  506.     {
  507.         wcscpy(this -> package_name, owner -> PackageName());
  508.         wcscat(this -> package_name, StringConstant::US__SL);
  509.     }
  510.     else this -> package_name[0] = U_NULL;
  511.     wcscat(this -> package_name, this -> Name());
  512.  
  513.     assert(wcslen(this -> package_name) == this -> package_name_length);
  514.  
  515.     return;
  516. }
  517.  
  518.  
  519. TypeSymbol::TypeSymbol(NameSymbol *name_symbol_) : semantic_environment(NULL),
  520.                                                    declaration(NULL),
  521.                                                    file_symbol(NULL),
  522.                                                    file_location(NULL),
  523.                                                    name_symbol(name_symbol_),
  524.                                                    owner(NULL),
  525.                                                    outermost_type(NULL),
  526.                                                    super(NULL),
  527.                                                    base_type(NULL),
  528.                                                    index(CycleChecker::OMEGA),
  529.                                                    unit_index(CycleChecker::OMEGA),
  530.                                                    incremental_index(CycleChecker::OMEGA),
  531.                                                    local(NULL),
  532.                                                    non_local(NULL),
  533.                                                    supertypes_closure(NULL),
  534.                                                    subtypes(NULL),
  535.                                                    subtypes_closure(NULL),
  536.                                                    innertypes_closure(NULL),
  537.                                                    dependents(new SymbolSet()),
  538.                                                    parents(new SymbolSet()),
  539.                                                    static_parents(new SymbolSet()),
  540.                                                    dependents_closure(NULL),
  541.                                                    parents_closure(NULL),
  542.                                                    signature(NULL),
  543.                                                    fully_qualified_name(NULL),
  544.                                                    expanded_type_table(NULL),
  545.                                                    expanded_field_table(NULL),
  546.                                                    expanded_method_table(NULL),
  547.                                                    num_dimensions(0),
  548.                                                    static_initializer_method(NULL),
  549.                                                    block_initializer_method(NULL),
  550.                                                    external_name_symbol(NULL),
  551.                                                    table(NULL),
  552.                                                    local_shadow_map(NULL),
  553.                                                    status(0),
  554.                                                    package(NULL),
  555.                                                    class_name(NULL),
  556.                                                    class_literal_class(NULL),
  557.                                                    class_literal_method(NULL),
  558.                                                    class_literal_name(NULL),
  559.                                                    local_constructor_call_environments(NULL),
  560.                                                    private_access_methods(NULL),
  561.                                                    private_access_constructors(NULL),
  562.                                                    read_method(NULL),
  563.                                                    write_method(NULL),
  564.                                                    constructor_parameters(NULL),
  565.                                                    generated_constructors(NULL),
  566.                                                    enclosing_instances(NULL),
  567.                                                    class_literals(NULL),
  568.                                                    nested_type_signatures(NULL),
  569.                                                    nested_types(NULL),
  570.                                                    interfaces(NULL),
  571.                                                    anonymous_types(NULL),
  572.                                                    array(NULL)
  573. {
  574.     Symbol::_kind = TYPE;
  575. }
  576.  
  577.  
  578. TypeSymbol::~TypeSymbol()
  579. {
  580.     if (read_method) delete read_method;
  581.     if (write_method) delete write_method;
  582.     delete semantic_environment;
  583.     delete local;
  584.     delete non_local;
  585.     delete supertypes_closure;
  586.     delete subtypes;
  587.     delete subtypes_closure;
  588.     delete innertypes_closure;
  589.     delete dependents;
  590.     delete parents;
  591.     delete static_parents;
  592.     delete table;
  593.     delete local_shadow_map;
  594.     delete expanded_type_table;
  595.     delete expanded_field_table;
  596.     delete expanded_method_table;
  597.     delete file_location;
  598.     delete [] class_name;
  599.     for (int i = 1; i < NumArrays(); i++)
  600.         delete Array(i);
  601.     for (int k = 0; k < NumNestedTypeSignatures(); k++)
  602.         delete [] NestedTypeSignature(k);
  603.     delete nested_type_signatures;
  604.  
  605.     delete local_constructor_call_environments;
  606.     delete private_access_methods;
  607.     delete private_access_constructors;
  608.     delete constructor_parameters;
  609.     delete generated_constructors;
  610.     delete enclosing_instances;
  611.     delete class_literals;
  612.     delete nested_types;
  613.     delete interfaces;
  614.     delete anonymous_types;
  615.     delete array;
  616. }
  617.  
  618. MethodSymbol::~MethodSymbol()
  619. {
  620.     for (int i = 0; i < NumThrowsSignatures(); i++)
  621.         delete [] ThrowsSignature(i);
  622.     delete throws_signatures;
  623.     delete formal_parameters;
  624.     delete throws;
  625.     delete initializer_constructors;
  626.  
  627.     delete block_symbol; // overload(s)
  628.     delete [] header;
  629. }
  630.  
  631.  
  632. BlockSymbol::BlockSymbol(int hash_size) : max_variable_index(-1),
  633.                                           try_or_synchronized_variable_index(0),
  634.                                           table(hash_size > 0 ? new SymbolTable(hash_size) : (SymbolTable *) NULL)
  635. {
  636.     Symbol::_kind = BLOCK;
  637. }
  638.  
  639. BlockSymbol::~BlockSymbol()
  640. {
  641.     delete table;
  642. }
  643.  
  644. PathSymbol::PathSymbol(NameSymbol *name_symbol_) : name_symbol(name_symbol_),
  645.                                                    zipfile(NULL)
  646. {
  647.     Symbol::_kind = PATH;
  648. }
  649.  
  650. PathSymbol::~PathSymbol()
  651. {
  652.     if (zipfile)
  653.         delete zipfile;
  654. }
  655.  
  656.  
  657. DirectorySymbol::DirectorySymbol(NameSymbol *name_symbol_, Symbol *owner_) : owner(owner_),
  658.                                                                              name_symbol(name_symbol_),
  659.                                                                              mtime(0),
  660.                                                                              table(NULL),
  661.                                                                              entries(NULL),
  662.                                                                              directory_name(NULL)
  663. {
  664.     Symbol::_kind = _DIRECTORY;
  665. }
  666.  
  667.  
  668. DirectorySymbol::~DirectorySymbol()
  669. {
  670.     delete [] directory_name;
  671.     delete entries;
  672.     delete table;
  673. }
  674.  
  675. void DirectorySymbol::SetDirectoryName()
  676. {
  677.     PathSymbol *path_symbol = owner -> PathCast();
  678.     if (path_symbol)
  679.     {
  680.         if (strcmp(path_symbol -> Utf8Name(), StringConstant::U8S__DO) == 0)
  681.         {
  682.             this -> directory_name_length = this -> Utf8NameLength();
  683.             this -> directory_name = new char[this -> directory_name_length + 1]; // +1 for '\0'
  684.  
  685.             strcpy(this -> directory_name, this -> Utf8Name());
  686.         }
  687.         else
  688.         {
  689.             this -> directory_name_length = path_symbol -> Utf8NameLength();
  690.             this -> directory_name = new char[this -> directory_name_length + 1]; // +1 for '\0'
  691.  
  692.             strcpy(this -> directory_name, path_symbol -> Utf8Name());
  693.         }
  694.     }
  695.     else
  696.     {
  697.         DirectorySymbol *owner_directory = owner -> DirectoryCast();
  698.         if (this -> Name()[this -> NameLength() - 1] == U_SLASH ||                     // An absolute file name ?
  699.             strcmp(owner_directory -> DirectoryName(), StringConstant::U8S__DO) == 0) // or is the owner "." ?
  700.         {
  701.             this -> directory_name_length = this -> Utf8NameLength();
  702.             this -> directory_name = new char[this -> directory_name_length + 1];  // +1 for '\0'
  703.             strcpy(this -> directory_name, this -> Utf8Name());
  704.         }
  705.         else
  706.         {
  707.             int owner_length = owner_directory -> DirectoryNameLength();
  708.             char *owner_name = owner_directory -> DirectoryName();
  709.             this -> directory_name_length = owner_length +
  710.                                             this -> Utf8NameLength() +
  711.                                             (owner_name[owner_length - 1] != U_SLASH ? 1 : 0); // +1 for '/'
  712.  
  713.             this -> directory_name = new char[this -> directory_name_length + 1]; // +1 for '\0'
  714.  
  715.             strcpy(this -> directory_name, owner_directory -> DirectoryName());
  716.             if (owner_name[owner_length - 1] != U_SLASH)
  717.                 strcat(this -> directory_name, StringConstant::U8S__SL);
  718.             strcat(this -> directory_name, this -> Utf8Name());
  719.         }
  720.     }
  721.  
  722.     assert(strlen(this -> directory_name) == this -> directory_name_length);
  723.  
  724.     return;
  725. }
  726.  
  727.  
  728. void DirectorySymbol::ResetDirectory()
  729. {
  730.     //
  731.     // TODO: the stat function does not work for directories in that the "modified" time stamp associated
  732.     // with a directory is not updated when a file contained in the directory is changed.
  733.     // For now, we always reread the directory.
  734.     //
  735.     //    struct stat status;
  736.     //    if ((SystemStat(this -> DirectoryName(), &status) == 0) && status.st_mtime > mtime)
  737.     //    {
  738.     //        this -> mtime = status.st_mtime;
  739.     //
  740.     //        delete this -> entries;
  741.     //        this -> entries = NULL;
  742.     //    }
  743.     //
  744.     //    ReadDirectory();
  745.     //
  746.  
  747.     delete this -> entries;
  748.     this -> entries = NULL;
  749.  
  750.     ReadDirectory();
  751.  
  752.     return;
  753. }
  754.  
  755.  
  756. void DirectorySymbol::ReadDirectory()
  757. {
  758.     assert(! this -> IsZip());
  759.  
  760.     if (! entries)
  761.     {
  762.         entries = new DirectoryTable();
  763.     
  764. //FIXME: these need to go into platform.cpp
  765. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  766.         DIR *directory = opendir(this -> DirectoryName());
  767.         if (directory)
  768.         {
  769.             for (dirent *entry = readdir(directory); entry; entry = readdir(directory))
  770.             {
  771.                 int length = strlen(entry -> d_name);
  772.  
  773.                 //
  774.                 // Check if the file is a java source, a java class file or a subdirectory.
  775.                 // Since packages cannot start with '.', we skip all files that start with
  776.                 // a dot. That includes this directory "." and its parent ".."
  777.                 //
  778.                 if ((length > FileSymbol::java_suffix_length &&
  779.                      FileSymbol::IsJavaSuffix(&entry -> d_name[length - FileSymbol::java_suffix_length]))  ||
  780.                     (length > FileSymbol::class_suffix_length &&
  781.                      FileSymbol::IsClassSuffix(&entry -> d_name[length - FileSymbol::class_suffix_length])) ||
  782.                     ((Case::Index(entry -> d_name, U_DOT) < 0) && SystemIsDirectory(entry -> d_name)))
  783.                     entries -> InsertEntry((DirectorySymbol *) this, entry -> d_name, length);
  784.             }
  785.             closedir(directory);
  786.         }
  787.  
  788. #elif defined(WIN32_FILE_SYSTEM)
  789.  
  790.         char *directory_name = new char[this -> DirectoryNameLength() + 3]; // +2 for "/*" +1 for '\0'
  791.         strcpy(directory_name, this -> DirectoryName());
  792.         if (directory_name[this -> DirectoryNameLength() - 1] != U_SLASH)
  793.             strcat(directory_name, StringConstant::U8S__SL);
  794.         strcat(directory_name, StringConstant::U8S__ST);
  795.  
  796.         WIN32_FIND_DATA entry;
  797.         HANDLE file_handle = FindFirstFile(directory_name, &entry);
  798.         if (file_handle != INVALID_HANDLE_VALUE)
  799.         {
  800.             do
  801.             {
  802.                 int length = strlen(entry.cFileName);
  803.  
  804.                 //
  805.                 // Check if the file is a java source, a java class file or a subdirectory.
  806.                 // Since packages cannot start with '.', we skip all files that start with
  807.                 // a dot. That includes this directory "." and its parent ".."
  808.                 //
  809.                 bool is_java  = (length > FileSymbol::java_suffix_length &&
  810.                                  FileSymbol::IsJavaSuffix(&entry.cFileName[length - FileSymbol::java_suffix_length])),
  811.                      is_class = (length > FileSymbol::class_suffix_length &&
  812.                                  FileSymbol::IsClassSuffix(&entry.cFileName[length - FileSymbol::class_suffix_length]));
  813.  
  814.                 if (is_java ||
  815.                     is_class ||
  816.                     (entry.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && Case::Index(entry.cFileName, U_DOT) < 0))
  817.                 {
  818.                     char *clean_name = new char[length + 1];
  819.                     for (int i = 0; i < length; i++)
  820.                         clean_name[i] = (entry.cFileName[i] == U_BACKSLASH ? U_SLASH : entry.cFileName[i]);
  821.                     if (is_java)
  822.                          strcpy(&clean_name[length - FileSymbol::java_suffix_length], FileSymbol::java_suffix);
  823.                     else if (is_class)
  824.                          strcpy(&clean_name[length - FileSymbol::class_suffix_length], FileSymbol::class_suffix);
  825.                     DirectoryEntry *entry = entries -> InsertEntry((DirectorySymbol *) this, clean_name, length);
  826.                     if (! is_java)
  827.                         entries -> InsertCaseInsensitiveEntry(entry);
  828.                     delete [] clean_name;
  829.                 }
  830.             } while (FindNextFile(file_handle, &entry));
  831.             FindClose(file_handle);
  832.         }
  833.  
  834.         delete [] directory_name;
  835. #endif
  836.     }
  837.  
  838.     return;
  839. }
  840.  
  841.  
  842. DirectorySymbol *FileSymbol::OutputDirectory()
  843. {
  844.     return (output_directory ? output_directory : output_directory = Control::GetOutputDirectory(this));
  845. }
  846.  
  847.  
  848. void FileSymbol::SetFileName()
  849. {
  850.     PathSymbol *path_symbol = this -> PathSym();
  851.     char *directory_name = directory_symbol -> DirectoryName();
  852.     size_t directory_name_length = directory_symbol -> DirectoryNameLength();
  853.     bool dot_directory = (strcmp(directory_name, StringConstant::U8S__DO) == 0);
  854.     this -> file_name_length = (dot_directory ? 0 : directory_name_length) +
  855.                                this -> Utf8NameLength()   +
  856.                                (path_symbol -> IsZip() // For zip files, we need "()"; for regular directory, we need 1 '/'
  857.                                              ? 2
  858.                                              : (dot_directory || directory_name[directory_name_length - 1] == U_SLASH ? 0 : 1)) +
  859.                                (kind == JAVA ? java_suffix_length : class_suffix_length);
  860.  
  861.     file_name = new char[file_name_length + 1]; // +1 for '\0'
  862.     if (dot_directory)
  863.          file_name[0] = U_NULL;
  864.     else
  865.     {
  866.         strcpy(file_name, directory_symbol -> DirectoryName());
  867.         if (path_symbol -> IsZip())
  868.              strcat(file_name, StringConstant::U8S__LP);
  869.         else if (directory_name[directory_name_length - 1] != U_SLASH)
  870.              strcat(file_name, StringConstant::U8S__SL);
  871.     }
  872.     strcat(file_name, this -> Utf8Name());
  873.     strcat(file_name, kind == JAVA ? FileSymbol::java_suffix : FileSymbol::class_suffix);
  874.     if (path_symbol -> IsZip())
  875.         strcat(file_name, StringConstant::U8S__RP);
  876.  
  877.     assert(strlen(this -> file_name) == this -> file_name_length);
  878.  
  879.     return;
  880. }
  881.  
  882.  
  883. void FileSymbol::SetFileNameLiteral(Control *control)
  884. {
  885.     if (! file_name_literal)
  886.     {
  887.         char *file_name = FileName();
  888.  
  889.         int i;
  890.         for (i = FileNameLength() - 1; i >= 0; i--)
  891.         {
  892.             if (file_name[i] == U_SLASH)
  893.                 break;
  894.         }
  895.  
  896.         int file_name_start = i + 1,
  897.             file_name_length = FileNameLength() - file_name_start;
  898.         file_name_literal = control -> Utf8_pool.FindOrInsert(file_name + file_name_start, file_name_length);
  899.     }
  900.  
  901.     return;
  902. }
  903.  
  904.  
  905. void FileSymbol::CleanUp()
  906. {
  907.     delete lex_stream;
  908.     lex_stream = NULL;
  909.  
  910.     if (compilation_unit)
  911.     {
  912.         delete compilation_unit -> ast_pool;
  913.         compilation_unit = NULL;
  914.     }
  915.  
  916.     delete semantic;
  917.     semantic = NULL;
  918.  
  919.     return;
  920. }
  921.  
  922.  
  923. void TypeSymbol::SetClassName()
  924. {
  925.     size_t length;
  926.  
  927.     if (semantic_environment -> sem -> control.option.directory)
  928.     {
  929.         DirectorySymbol *output_directory = file_symbol -> OutputDirectory();
  930.         int directory_length = output_directory -> DirectoryNameLength();
  931.         char *directory_name = output_directory -> DirectoryName();
  932.         length = directory_length + this -> ExternalUtf8NameLength() + FileSymbol::class_suffix_length + 1; // +1 for /
  933.         class_name = new char[length + 1]; // +1 for '\0'
  934.  
  935.         strcpy(class_name, directory_name);
  936.  
  937.         if (directory_name[directory_length - 1] != U_SLASH)
  938.             strcat(class_name, StringConstant::U8S__SL);
  939.     }
  940.     else
  941.     {
  942.         char *file_name = semantic_environment -> sem -> lex_stream -> FileName();
  943.         int n;
  944.         for (n = semantic_environment -> sem -> lex_stream -> FileNameLength() - 1; n >= 0; n--)
  945.         {
  946.             if (file_name[n] == U_SLASH)
  947.                 break;
  948.         }
  949.         n++;
  950.  
  951.         length = n + this -> ExternalUtf8NameLength() + FileSymbol::class_suffix_length;
  952.         class_name = new char[length + 1]; // +1 for '\0'
  953.         strncpy(class_name, file_name, n);
  954.         class_name[n] = U_NULL;
  955.     }
  956.  
  957.     strcat(class_name, ExternalUtf8Name());
  958.     strcat(class_name, FileSymbol::class_suffix);
  959.  
  960.     assert(strlen(this -> class_name) <= length);
  961.  
  962.     return;
  963. }
  964.  
  965.  
  966. void TypeSymbol::ProcessNestedTypeSignatures(Semantic *sem, LexStream::TokenIndex tok)
  967. {
  968.     for (int i = 0; i < NumNestedTypeSignatures(); i++)
  969.     {
  970.         NameSymbol *name_symbol = sem -> control.ConvertUtf8ToUnicode(NestedTypeSignature(i), strlen(NestedTypeSignature(i)));
  971.         delete [] NestedTypeSignature(i);
  972.         sem -> ProcessNestedType(this, name_symbol, tok);
  973.     }
  974.  
  975.     delete nested_type_signatures;
  976.     nested_type_signatures = NULL;
  977.  
  978.     return;
  979. }
  980.  
  981.  
  982. void MethodSymbol::ProcessMethodThrows(Semantic *sem, LexStream::TokenIndex tok)
  983. {
  984.     if (throws_signatures)
  985.     {
  986.         assert(sem);
  987.  
  988.         //
  989.         // Process throws clause
  990.         //
  991.         for (int i = 0; i < NumThrowsSignatures(); i++)
  992.         {
  993.             TypeSymbol *type = sem -> ReadTypeFromSignature(this -> containing_type,
  994.                                                             ThrowsSignature(i),
  995.                                                             strlen(ThrowsSignature(i)),
  996.                                                             tok);
  997.             this -> AddThrows(type);
  998.             delete [] ThrowsSignature(i);
  999.         }
  1000.  
  1001.         delete throws_signatures;
  1002.         throws_signatures = NULL;
  1003.     }
  1004.  
  1005.     return;
  1006. }
  1007.  
  1008.  
  1009. void MethodSymbol::SetSignature(Control &control, VariableSymbol *this0_variable)
  1010. {
  1011.     int len = 2 + strlen(this -> Type() -> SignatureString()); // +1 for '(' +1 for ')'
  1012.  
  1013.     if (this0_variable)
  1014.         len += strlen(this0_variable -> Type() -> SignatureString());
  1015.     for (int i = 0; i < this -> NumFormalParameters(); i++)
  1016.     {
  1017.         TypeSymbol *formal_type = this -> FormalParameter(i) -> Type();
  1018.         len += strlen(formal_type -> SignatureString());
  1019.     }
  1020.  
  1021.     char *method_signature = new char[len + 1]; // +1 for '\0'
  1022.     method_signature[0] = U_LEFT_PARENTHESIS;
  1023.     int k = 1;
  1024.     if (this0_variable)
  1025.     {
  1026.         for (char *str = this0_variable -> Type() -> SignatureString(); *str; str++, k++)
  1027.             method_signature[k] = *str;
  1028.     }
  1029.     for (int j = 0; j < this -> NumFormalParameters(); j++)
  1030.     {
  1031.         TypeSymbol *formal_type = this -> FormalParameter(j) -> Type();
  1032.         for (char *str = formal_type -> SignatureString(); *str; str++, k++)
  1033.             method_signature[k] = *str;
  1034.     }
  1035.     method_signature[k++] = U_RIGHT_PARENTHESIS;
  1036.     for (char *str = this -> Type() -> SignatureString(); *str; str++, k++)
  1037.          method_signature[k] = *str;
  1038.     method_signature[k] = U_NULL;
  1039.  
  1040.     this -> signature = control.Utf8_pool.FindOrInsert(method_signature, len);
  1041.  
  1042.     delete [] method_signature;
  1043.  
  1044.     return;
  1045. }
  1046.  
  1047.  
  1048. void MethodSymbol::ProcessMethodSignature(Semantic *sem, LexStream::TokenIndex token_location)
  1049. {
  1050.     if (! this -> type_)
  1051.     {
  1052.         assert(sem);
  1053.  
  1054.         int num_parameters = 0;
  1055.         char *signature = this -> SignatureString();
  1056.         signature++; // +1 to skip initial '('
  1057.  
  1058.         //
  1059.         // For the constructor of an inner type, skip the "this$0" argument.
  1060.         //
  1061.         if (this -> containing_type -> IsInner() && this -> Identity() == sem -> control.init_name_symbol)
  1062.         {
  1063.             if (*signature != U_RIGHT_PARENTHESIS)
  1064.             {
  1065.                 //
  1066.                 // Move to next signature
  1067.                 //
  1068.                 char *str;
  1069.                 for (str = signature; *str == U_LEFT_BRACKET; str++)
  1070.                     ;
  1071.                 if (*str == U_L)
  1072.                 {
  1073.                     for (str++; *str != U_SEMICOLON; str++)
  1074.                         ;
  1075.                 }
  1076.  
  1077.                 int len = str - signature + 1;
  1078.                 signature += len; // make signature point to next type
  1079.             }
  1080.         }
  1081.  
  1082.         while (*signature != U_RIGHT_PARENTHESIS)
  1083.         {
  1084.             //
  1085.             // Make up a name for each parameter... Recall that for an inner class we need to skip the this$0 parameter
  1086.             //
  1087.             NameSymbol *name_symbol = sem -> control.MakeParameter(++num_parameters);
  1088.             VariableSymbol *symbol = new VariableSymbol(name_symbol);
  1089.             symbol -> SetType(sem -> ProcessSignature(this -> containing_type, signature, token_location));
  1090.             symbol -> MarkComplete();
  1091.             this -> AddFormalParameter(symbol);
  1092.  
  1093.             //
  1094.             // Move to next signature
  1095.             //
  1096.             char *str;
  1097.             for (str = signature; *str == U_LEFT_BRACKET; str++)
  1098.                 ;
  1099.             if (*str == U_L)
  1100.             {
  1101.                 for (str++; *str != U_SEMICOLON; str++)
  1102.                     ;
  1103.             }
  1104.  
  1105.             int len = str - signature + 1;
  1106.             signature += len; // make signature point to next type
  1107.         }
  1108.         signature++; // skip L')'
  1109.  
  1110.         //
  1111.         // Now set the type of the method.
  1112.         //
  1113.         this -> SetType(sem -> ProcessSignature(this -> containing_type, signature, token_location));
  1114.  
  1115.         //
  1116.         // Create a symbol table for this method for consistency... and in order
  1117.         // to release the space used by the variable paramaters later.
  1118.         //
  1119.         BlockSymbol *block_symbol = new BlockSymbol(num_parameters);
  1120.         for (int k = 0; k < num_parameters; k++)
  1121.             block_symbol -> InsertVariableSymbol((*this -> formal_parameters)[k]);
  1122.         block_symbol -> CompressSpace(); // space optimization
  1123.         this -> SetBlockSymbol(block_symbol);
  1124.     }
  1125.  
  1126.     return;
  1127. }
  1128.  
  1129.  
  1130. void MethodSymbol::CleanUp()
  1131. {
  1132.     BlockSymbol *block_symbol = new BlockSymbol(this -> NumFormalParameters());
  1133.  
  1134.     //
  1135.     // Make a copy of each parameter into the new pared-down symbol table and
  1136.     // fix the FormalParameter information to identify the new symbol.
  1137.     //
  1138.     for (int k = 0; k < this -> NumFormalParameters(); k++)
  1139.     {
  1140.         VariableSymbol *formal_parameter = (*formal_parameters)[k],
  1141.                        *symbol = block_symbol -> InsertVariableSymbol(formal_parameter -> Identity());
  1142.         symbol -> SetType(formal_parameter -> Type());
  1143.         symbol -> MarkComplete();
  1144.         (*formal_parameters)[k] = symbol;
  1145.     }
  1146.  
  1147.     //
  1148.     // Destroy the old symbol and replace it by the new one.
  1149.     //
  1150.     delete this -> block_symbol;
  1151.     block_symbol -> CompressSpace(); // space optimization
  1152.     this -> SetBlockSymbol(block_symbol);
  1153.  
  1154.     this -> method_or_constructor_declaration = NULL; // remove reference to Ast structure
  1155.  
  1156.     return;
  1157. }
  1158.  
  1159.  
  1160. void VariableSymbol::ProcessVariableSignature(Semantic *sem, LexStream::TokenIndex token_location)
  1161. {
  1162.     if (! this -> type_)
  1163.     {
  1164.         assert(sem);
  1165.  
  1166.         this -> SetType(sem -> ProcessSignature((TypeSymbol *) owner, signature_string, token_location));
  1167.     }
  1168.  
  1169.     return;
  1170. }
  1171.  
  1172.  
  1173. bool TypeSymbol::IsNestedIn(TypeSymbol *type)
  1174. {
  1175.     for (SemanticEnvironment *env = this -> semantic_environment; env != NULL; env = env -> previous)
  1176.     {
  1177.         if (env -> Type() == type)
  1178.              return true;
  1179.     }
  1180.  
  1181.     return false;
  1182. }
  1183.  
  1184.  
  1185. bool TypeSymbol::CanAccess(TypeSymbol *type)
  1186. {
  1187.     assert(semantic_environment);
  1188.  
  1189.     SemanticEnvironment *env = this -> semantic_environment;
  1190.     //
  1191.     // Note that this case is only possible in the current environment (i.e., it is not recursively applicable)
  1192.     // as it is not possible to declare an inner class (even an anonymous one) within an explicit
  1193.     // constructor invocation. This is the case precisely because of the unavailability of the "this"
  1194.     // which one would need to pass to the inner class in question. See comment below...
  1195.     //
  1196.     if (env -> explicit_constructor_invocation && env -> explicit_constructor_invocation -> SuperCallCast())
  1197.     {
  1198.         //
  1199.         // If we are processing a super call statement in the constructor of an inner class then
  1200.         // we have access to the this$0 (passed to the constructor of the inner class as parameter) but
  1201.         // not to the "this" of the inner class in question, unless it is static.
  1202.         //
  1203.         if (this -> IsSubclass(type))
  1204.             return this -> ACC_STATIC(); // "this" class is accessible only if it is static.
  1205.         if (this -> IsInner())
  1206.         {
  1207.             if (this -> ContainingType() -> IsSubclass(type))
  1208.                 return true;
  1209.             env = env -> previous; // skip "this" type.
  1210.         }
  1211.     }
  1212.  
  1213.     for (; env != NULL; env = env -> previous)
  1214.     {
  1215.         if (env -> StaticRegion()) // are we in a static environment?
  1216.              break;
  1217.         else if (env -> Type() -> IsSubclass(type)) // then, check if we reached the type in question or one of its superclasses;
  1218.              return true;
  1219.         else if (env -> Type() -> ACC_STATIC())     // next, check whether or not the current type is static...
  1220.              break;
  1221.     }
  1222.  
  1223.     return false;
  1224. }
  1225.  
  1226.  
  1227. //
  1228. // Given two types T and T2 in different packages, the type T has protected
  1229. // access to T2 iff T or any class in which T is lexically enclosed is a subclass
  1230. // of T2 or of some other type T3 that lexically encloses T2.
  1231. //
  1232. // Of course, T2 and all its enclosing classes, if any, must have been declared
  1233. // either public or protected, otherwise they could not be eligible as a superclass
  1234. // candidate. We do not (and need not) check for that condition here.
  1235. //
  1236. bool TypeSymbol::HasProtectedAccessTo(TypeSymbol *target_type)
  1237. {
  1238.     assert(semantic_environment);
  1239.  
  1240.     for (SemanticEnvironment *env = this -> semantic_environment; env != NULL; env = env -> previous)
  1241.     {
  1242.         TypeSymbol *main_type = env -> Type();
  1243.         for (TypeSymbol *type = target_type; type; type = type -> owner -> TypeCast())
  1244.         {
  1245.             if (main_type -> IsSubclass(type)) // then, check if we reached the type in question or one of its superclasses;
  1246.                 return true;
  1247.         }
  1248.     }
  1249.  
  1250.     return false;
  1251. }
  1252.  
  1253.  
  1254. inline NameSymbol *TypeSymbol::GetThisName(Control &control, int n)
  1255. {
  1256.     IntToWstring value(n);
  1257.  
  1258.     int length = wcslen(StringConstant::US__this_DOLLAR) + value.Length();
  1259.     wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1260.     wcscpy(name, StringConstant::US__this_DOLLAR);
  1261.     wcscat(name, value.String());
  1262.     NameSymbol *name_symbol = control.FindOrInsertName(name, length);
  1263.  
  1264.     delete [] name;
  1265.  
  1266.     return name_symbol;
  1267. }
  1268.  
  1269.  
  1270. VariableSymbol *TypeSymbol::InsertThis(int n)
  1271. {
  1272.     assert(IsInner());
  1273.  
  1274.     Control &control = semantic_environment -> sem -> control;
  1275.     VariableSymbol *variable_symbol = NULL;
  1276.  
  1277.     if (n == 0)
  1278.     {
  1279.         assert(NumConstructorParameters() == 0); // no local shadows and no this$0 !!!
  1280.         assert(NumEnclosingInstances() == 0);
  1281.  
  1282.         //
  1283.         // Create a this0 pointer for an inner class.
  1284.         //
  1285.         variable_symbol = InsertVariableSymbol(control.this0_name_symbol);
  1286.         variable_symbol -> MarkSynthetic();
  1287.         variable_symbol -> SetType(ContainingType());
  1288.         variable_symbol -> SetACC_PRIVATE();
  1289. //        variable_symbol -> SetACC_FINAL();
  1290.         variable_symbol -> SetOwner((TypeSymbol *) this);
  1291.         variable_symbol -> MarkComplete();
  1292.  
  1293.         AddConstructorParameter(variable_symbol);
  1294.         AddEnclosingInstance(variable_symbol); // must at least have this$0
  1295.     }
  1296.     else
  1297.     {
  1298.         assert(NumEnclosingInstances() == n);
  1299.  
  1300.         //
  1301.         // Create a this$n pointer.
  1302.         //
  1303.         variable_symbol = InsertVariableSymbol(GetThisName(control, n));
  1304.         variable_symbol -> MarkSynthetic();
  1305.         variable_symbol -> SetType(EnclosingInstance(n - 1) -> Type() -> ContainingType());
  1306.         variable_symbol -> SetACC_PRIVATE();
  1307. //        variable_symbol -> SetACC_FINAL();
  1308.         variable_symbol -> SetOwner((TypeSymbol *) this);
  1309.         variable_symbol -> MarkComplete();
  1310.  
  1311.         AddEnclosingInstance(variable_symbol);
  1312.     }
  1313.  
  1314.     return variable_symbol;
  1315. }
  1316.  
  1317.  
  1318. TypeSymbol *TypeSymbol::FindOrInsertClassLiteralClass(LexStream::TokenIndex tok)
  1319. {
  1320.     Semantic *sem = semantic_environment -> sem;
  1321.     AstCompilationUnit *compilation_unit = sem -> compilation_unit;
  1322.     Control &control = sem -> control;
  1323.  
  1324.     assert(this == outermost_type && this -> ACC_INTERFACE());
  1325.  
  1326.     if (! this -> class_literal_class)
  1327.     {
  1328.         AstClassInstanceCreationExpression *class_creation = compilation_unit -> ast_pool -> GenClassInstanceCreationExpression();
  1329.         class_creation -> base_opt      = NULL;
  1330.         class_creation -> dot_token_opt = 0;
  1331.         class_creation -> new_token = tok;
  1332.  
  1333.              AstSimpleName *ast_type = compilation_unit -> ast_pool -> GenSimpleName(tok);
  1334.  
  1335.         class_creation -> class_type = compilation_unit -> ast_pool -> GenTypeExpression(ast_type);
  1336.         class_creation -> left_parenthesis_token  = tok;
  1337.         class_creation -> right_parenthesis_token = tok;
  1338.  
  1339.             AstClassBody *class_body = compilation_unit -> ast_pool -> GenClassBody();
  1340.             class_body -> left_brace_token = tok;
  1341.             class_body -> right_brace_token = tok;
  1342.  
  1343.         class_creation -> class_body_opt = class_body;
  1344.  
  1345.         TypeSymbol *class_literal_type = sem -> GetAnonymousType(class_creation, control.Object());
  1346.         (void) class_literal_type -> FindOrInsertClassLiteralMethod(control);
  1347.  
  1348.         sem -> AddDependence(class_literal_type, control.Class(), tok);
  1349.  
  1350.         this -> class_literal_class = class_literal_type;
  1351.     }
  1352.  
  1353.     return this -> class_literal_class;
  1354. }
  1355.  
  1356.  
  1357. MethodSymbol *TypeSymbol::FindOrInsertClassLiteralMethod(Control &control)
  1358. {
  1359.     if (! class_literal_method)
  1360.     {
  1361.         //
  1362.         // Note that max_variable_index is initialized to 1 (instead of 0),
  1363.         // even though the class literal method is static. The reason is that
  1364.         // in generating code for this method, a try statement with a catch
  1365.         // will be used. Therefore, an extra "local" slot is required for the
  1366.         // local Exception parameter of the catch clause.
  1367.         //
  1368.         BlockSymbol *block_symbol = new BlockSymbol(1); // the associated symbol table will contain 1 element
  1369.         block_symbol -> max_variable_index = 1;
  1370.  
  1371.         class_literal_method = InsertMethodSymbol(control.class_name_symbol);
  1372.         class_literal_method -> MarkSynthetic();
  1373.         class_literal_method -> SetType(control.Class());
  1374.         class_literal_method -> SetACC_STATIC();
  1375.         class_literal_method -> SetContainingType((TypeSymbol *) this);
  1376.         class_literal_method -> SetBlockSymbol(block_symbol);
  1377.  
  1378.             VariableSymbol *variable_symbol = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1379.             variable_symbol -> MarkSynthetic();
  1380.             variable_symbol -> SetType(control.String());
  1381.             variable_symbol -> SetOwner(class_literal_method);
  1382.             variable_symbol -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1383.  
  1384.         class_literal_method -> AddFormalParameter(variable_symbol);
  1385.         class_literal_method -> SetSignature(control);
  1386.     }
  1387.  
  1388.     return class_literal_method;
  1389. }
  1390.  
  1391.  
  1392. Utf8LiteralValue *TypeSymbol::FindOrInsertClassLiteralName(Control &control)
  1393. {
  1394.     if (! class_literal_name)
  1395.     {
  1396.         int length = fully_qualified_name -> length;
  1397.         char *slashed_name = fully_qualified_name -> value;
  1398.         char *name = new char[length + 1];
  1399.         for (int i = 0; i < length; i++)
  1400.             name[i] = (slashed_name[i] == U_SLASH ? (wchar_t) U_DOT : slashed_name[i]);
  1401.         name[length] = U_NULL;
  1402.         class_literal_name = control.Utf8_pool.FindOrInsert(name, length);
  1403.         delete [] name;
  1404.     }
  1405.  
  1406.     return class_literal_name;
  1407. }
  1408.  
  1409.  
  1410. VariableSymbol *TypeSymbol::FindOrInsertClassLiteral(TypeSymbol *type)
  1411. {
  1412.     assert(IsTopLevel() && (! type -> Primitive()));
  1413.  
  1414.     Semantic *sem = semantic_environment -> sem;
  1415.     Control &control = sem -> control;
  1416.  
  1417.     (void) this -> FindOrInsertClassLiteralMethod(control);
  1418.  
  1419.     (void) type -> FindOrInsertClassLiteralName(control);
  1420.  
  1421.     NameSymbol *name_symbol = NULL;
  1422.     char *signature = type -> SignatureString();
  1423.     if (signature[0] == U_LEFT_BRACKET) // an array?
  1424.     {
  1425.         int array_length = wcslen(StringConstant::US__array),
  1426.             length = strlen(signature) + array_length;
  1427.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1428.         wcscpy(name, StringConstant::US__array);
  1429.         int i,
  1430.             k;
  1431.         for (i = 0, k = array_length; signature[i] == U_LEFT_BRACKET; i++, k++)
  1432.             name[k] = U_DOLLAR;
  1433.         for (wchar_t ch = signature[i++]; ch && ch != U_SEMICOLON; ch = signature[i++])
  1434.             name[k++] = (ch == U_SLASH ? (wchar_t) U_DOLLAR : ch);
  1435.         name[k] = U_NULL;
  1436.         name_symbol = control.FindOrInsertName(name, k);
  1437.  
  1438.         delete [] name;
  1439.     }
  1440.     else if (signature[0] == U_L) // a reference type ?
  1441.     {
  1442.         int class_length = wcslen(StringConstant::US__class_DOLLAR),
  1443.             length = strlen(signature) + class_length;
  1444.  
  1445.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1446.         wcscpy(name, StringConstant::US__class_DOLLAR);
  1447.         int i = 0,
  1448.             k = class_length;
  1449.         for (wchar_t ch = signature[i++]; ch && ch != U_SEMICOLON; ch = signature[i++])
  1450.             name[k++] = (ch == U_SLASH ? (wchar_t) U_DOLLAR : ch);
  1451.         name[k] = U_NULL;
  1452.         name_symbol = control.FindOrInsertName(name, k);
  1453.  
  1454.         delete [] name;
  1455.     }
  1456.  
  1457.     VariableSymbol *variable_symbol = FindVariableSymbol(name_symbol);
  1458.     if (! variable_symbol)
  1459.     {
  1460.         variable_symbol = InsertVariableSymbol(name_symbol);
  1461.         variable_symbol -> MarkSynthetic();
  1462.         variable_symbol -> SetType(control.Class());
  1463.         variable_symbol -> SetACC_PRIVATE();
  1464.         variable_symbol -> SetACC_STATIC();
  1465.         variable_symbol -> SetOwner((TypeSymbol *) this);
  1466.         variable_symbol -> MarkComplete();
  1467.  
  1468.         AddClassLiteral(variable_symbol);
  1469.     }
  1470.  
  1471.     return variable_symbol;
  1472. }
  1473.  
  1474.  
  1475. VariableSymbol *TypeSymbol::FindOrInsertLocalShadow(VariableSymbol *local)
  1476. {
  1477.     assert(this -> IsLocal());
  1478.  
  1479.     Control &control = semantic_environment -> sem -> control;
  1480.     VariableSymbol *variable = (VariableSymbol *) (local_shadow_map ? local_shadow_map -> Image(local) : NULL);
  1481.  
  1482.     //
  1483.     // For a local class, if it does not yet have a shadow for a local variable
  1484.     // that it needs access to, create one.
  1485.     //
  1486.     // Note that since this function is always invoked after the symbol
  1487.     // table for the type in question has been extended, the local shadow will
  1488.     // not appear in the expanded_field_table. Creating a shadow in the
  1489.     // expanded_field_table as well would cut down on the number of calls to
  1490.     // this function. However, the reason why we don't create such a shadow is
  1491.     // that since the new symbol is assigned a new name on the fly, its
  1492.     // name_symbol will fall outside the range of the expanded field table in
  1493.     // question.
  1494.     //
  1495.     if (! variable)
  1496.     {
  1497.         int length = 4 + local -> NameLength(); // +4 for val$
  1498.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1499.         wcscpy(name, StringConstant::US__val_DOLLAR);
  1500.         wcscat(name, local -> Name());
  1501.         NameSymbol *name_symbol = control.FindOrInsertName(name, length);
  1502.  
  1503.         variable = InsertVariableSymbol(name_symbol);
  1504.         variable -> MarkSynthetic();
  1505.         variable -> accessed_local = local;
  1506.         variable -> SetType(local -> Type());
  1507.         variable -> SetACC_PRIVATE();
  1508. //        variable -> SetACC_FINAL();
  1509.         variable -> SetOwner((TypeSymbol *) this);
  1510.         variable -> MarkComplete();
  1511.  
  1512.         AddConstructorParameter(variable);
  1513.  
  1514.         delete [] name;
  1515.  
  1516.         for (int i = 0; i < NumGeneratedConstructors(); i++)
  1517.         {
  1518.             MethodSymbol *constructor = GeneratedConstructor(i);
  1519.  
  1520.             VariableSymbol *symbol = constructor -> block_symbol -> InsertVariableSymbol(name_symbol);
  1521.             symbol -> MarkSynthetic();
  1522.             symbol -> SetType(variable -> Type());
  1523.             symbol -> SetOwner(constructor);
  1524.             symbol -> SetLocalVariableIndex(constructor -> block_symbol -> max_variable_index++);
  1525.             if (control.IsDoubleWordType(symbol -> Type()))
  1526.                 constructor -> block_symbol -> max_variable_index++;
  1527.             constructor -> AddFormalParameter(symbol);
  1528.         }
  1529.  
  1530.         if (! local_shadow_map)
  1531.             local_shadow_map = new SymbolMap();
  1532.         local_shadow_map -> Map(local, variable);
  1533.     }
  1534.  
  1535. assert(variable -> accessed_local == local);
  1536.  
  1537.     return variable;
  1538. }
  1539.  
  1540.  
  1541. inline void TypeSymbol::MapSymbolToReadMethod(Symbol *symbol, MethodSymbol *method)
  1542. {
  1543.     if (! read_method)
  1544.         read_method = new SymbolMap();
  1545.     read_method -> Map(symbol, method);
  1546.  
  1547.     return;
  1548. }
  1549.  
  1550. inline MethodSymbol *TypeSymbol::ReadMethod(Symbol *symbol)
  1551. {
  1552.     return (MethodSymbol *) (read_method ? read_method -> Image(symbol) : NULL);
  1553. }
  1554.  
  1555. inline void TypeSymbol::MapSymbolToWriteMethod(VariableSymbol *symbol, MethodSymbol *method)
  1556. {
  1557.     if (! write_method)
  1558.         write_method = new SymbolMap();
  1559.     write_method -> Map(symbol, method);
  1560.  
  1561.     return;
  1562. }
  1563.  
  1564. inline MethodSymbol *TypeSymbol::WriteMethod(VariableSymbol *symbol)
  1565. {
  1566.     return (MethodSymbol *) (write_method ? write_method -> Image(symbol) : NULL);
  1567. }
  1568.  
  1569. MethodSymbol *TypeSymbol::GetReadAccessMethod(MethodSymbol *member)
  1570. {
  1571.     TypeSymbol *this_type = (TypeSymbol *) this,
  1572.                *containing_type = member -> containing_type;
  1573.  
  1574.     assert((member -> ACC_PRIVATE() && this_type == containing_type) || (member -> ACC_PROTECTED() && this_type != containing_type));
  1575.  
  1576.     MethodSymbol *read_method = this_type -> ReadMethod(member);
  1577.  
  1578.     if (! read_method)
  1579.     {
  1580.         Semantic *sem = this_type -> semantic_environment -> sem;
  1581.  
  1582.         assert(sem);
  1583.  
  1584.         Control &control = sem -> control;
  1585.         StoragePool *ast_pool = sem -> compilation_unit -> ast_pool;
  1586.  
  1587.         IntToWstring value(member -> Identity() == control.init_name_symbol ? this_type -> NumPrivateAccessConstructors()
  1588.                                                                             : this_type -> NumPrivateAccessMethods());
  1589.  
  1590.         int length = 7 + value.Length(); // +7 for access$
  1591.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1592.         wcscpy(name, StringConstant::US__access_DOLLAR);
  1593.         wcscat(name, value.String());
  1594.  
  1595.         BlockSymbol *block_symbol = new BlockSymbol(member -> NumFormalParameters() + 3);
  1596.  
  1597.         read_method = this_type -> InsertMethodSymbol(control.FindOrInsertName(name, length));
  1598.         read_method -> MarkSynthetic();
  1599.         read_method -> SetType(member -> Type());
  1600.         read_method -> SetContainingType(this_type);
  1601.         read_method -> SetBlockSymbol(block_symbol);
  1602.  
  1603.         for (int i = 0; i < member -> NumThrows(); i++)
  1604.             read_method -> AddThrows(member -> Throws(i));
  1605.  
  1606.         //
  1607.         //
  1608.         //
  1609.         if (member -> Identity() != control.init_name_symbol) // not a constructor
  1610.         {
  1611.             read_method -> SetACC_STATIC();
  1612.             block_symbol -> max_variable_index = 0;
  1613.  
  1614.             if (! member -> ACC_STATIC())
  1615.             {
  1616.                 VariableSymbol *instance = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1617.                 instance -> MarkSynthetic();
  1618.                 instance -> SetType(this_type);
  1619.                 instance -> SetOwner(read_method);
  1620.                 instance -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1621.                 read_method -> AddFormalParameter(instance);
  1622.             }
  1623.  
  1624.             for (int i = 0; i < member -> NumFormalParameters(); i++)
  1625.             {
  1626.                 VariableSymbol *parm = block_symbol -> InsertVariableSymbol(member -> FormalParameter(i) -> Identity());
  1627.                 parm -> MarkSynthetic();
  1628.                 parm -> SetType(member -> FormalParameter(i) -> Type());
  1629.                 parm -> SetOwner(read_method);
  1630.                 parm -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1631.                 if (control.IsDoubleWordType(parm -> Type()))
  1632.                     block_symbol -> max_variable_index++;
  1633.                 read_method -> AddFormalParameter(parm);
  1634.             }
  1635.             read_method -> SetSignature(control);
  1636.             // A read access method has no throws clause !
  1637.  
  1638.             this_type -> AddPrivateAccessMethod(read_method);
  1639.         }
  1640.         else
  1641.         {
  1642.             //
  1643.             // A constructor in a local class already has a "LocalConstructor()" associated
  1644.             // with it that can be used as a read access method.
  1645.             //
  1646.             assert(! this_type -> IsLocal());
  1647.  
  1648.             //
  1649.             //
  1650.             //
  1651.             block_symbol -> max_variable_index = 1;
  1652.             read_method -> SetExternalIdentity(member -> Identity());
  1653.  
  1654.             Ast *declaration = member -> method_or_constructor_declaration;
  1655.             AstMethodDeclaration *method_declaration = declaration -> MethodDeclarationCast();
  1656.             AstMethodDeclarator *declarator = (method_declaration
  1657.                                                      ? method_declaration -> method_declarator
  1658.                                                      : ((AstConstructorDeclaration *) declaration) -> constructor_declarator);
  1659.             LexStream::TokenIndex loc = declarator -> identifier_token;
  1660.  
  1661.             //
  1662.             // Create a new anonymous type in order to create a unique substitute constructor.
  1663.             //
  1664.             AstClassInstanceCreationExpression *class_creation = ast_pool -> GenClassInstanceCreationExpression();
  1665.             class_creation -> base_opt      = NULL;
  1666.             class_creation -> dot_token_opt = 0;
  1667.             class_creation -> new_token = loc;
  1668.  
  1669.                 AstSimpleName *ast_type = ast_pool -> GenSimpleName(loc);
  1670.  
  1671.             class_creation -> class_type = ast_pool -> GenTypeExpression(ast_type);
  1672.             class_creation -> left_parenthesis_token  = loc;
  1673.             class_creation -> right_parenthesis_token = loc;
  1674.  
  1675.                 AstClassBody *class_body = ast_pool -> GenClassBody();
  1676.                 class_body -> left_brace_token = loc;
  1677.                 class_body -> right_brace_token = loc;
  1678.  
  1679.             class_creation -> class_body_opt = class_body;
  1680.  
  1681.             TypeSymbol *anonymous_type = sem -> GetAnonymousType(class_creation, control.Object());
  1682.  
  1683.             //
  1684.             //
  1685.             //
  1686.             AstMethodDeclarator *method_declarator       = ast_pool -> GenMethodDeclarator();
  1687.             method_declarator -> identifier_token        = loc;
  1688.             method_declarator -> left_parenthesis_token  = declarator -> LeftToken();
  1689.             method_declarator -> right_parenthesis_token = declarator -> RightToken();
  1690.  
  1691.             AstThisCall *this_call = ast_pool -> GenThisCall();
  1692.             this_call -> base_opt                = NULL;
  1693.             this_call -> this_token              = loc;
  1694.             this_call -> left_parenthesis_token  = loc;
  1695.             this_call -> right_parenthesis_token = loc;
  1696.             this_call -> semicolon_token         = loc;
  1697.             this_call -> symbol = member;
  1698.  
  1699.             VariableSymbol *this0_variable = NULL;
  1700.             if (this_type -> IsInner())
  1701.             {
  1702.                 this0_variable = block_symbol -> InsertVariableSymbol(control.this0_name_symbol);
  1703.                 this0_variable -> MarkSynthetic();
  1704.                 this0_variable -> SetType(this_type -> ContainingType());
  1705.                 this0_variable -> SetOwner(read_method);
  1706.                 this0_variable -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1707.             }
  1708.  
  1709.             //
  1710.             // Add extra parameter with anonymous type...
  1711.             //
  1712.             VariableSymbol *parm = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1713.             parm -> MarkSynthetic();
  1714.             parm -> SetType(anonymous_type);
  1715.             parm -> SetOwner(read_method);
  1716.             parm -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1717.             read_method -> AddFormalParameter(parm);
  1718.  
  1719.             //
  1720.             // Since private_access_constructors will be compiled (see body.cpp), we must create
  1721.             // valid ast_simple_names for its parameters.
  1722.             //
  1723.             for (int i = 0; i < member -> NumFormalParameters(); i++)
  1724.             {
  1725.                 parm = block_symbol -> InsertVariableSymbol(member -> FormalParameter(i) -> Identity());
  1726.                 parm -> MarkSynthetic();
  1727.                 parm -> SetType(member -> FormalParameter(i) -> Type());
  1728.                 parm -> SetOwner(read_method);
  1729.                 parm -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1730.                 if (control.IsDoubleWordType(parm -> Type()))
  1731.                     block_symbol -> max_variable_index++;
  1732.                 read_method -> AddFormalParameter(parm);
  1733.  
  1734.                 //
  1735.                 // Since private_access_constructors will be compiled (see body.cpp), we must create
  1736.                 // valid ast_simple_names for its parameters.
  1737.                 //
  1738.                 AstVariableDeclaratorId *variable_declarator_name = declarator -> FormalParameter(i)
  1739.                                                                                -> formal_declarator -> variable_declarator_name;
  1740.                 AstSimpleName *simple_name = ast_pool -> GenSimpleName(variable_declarator_name -> identifier_token);
  1741.                 simple_name -> symbol = parm;
  1742.                 this_call -> AddArgument(simple_name);
  1743.             }
  1744.             read_method -> SetSignature(control, this0_variable);
  1745.             // A read access method has no throws clause !
  1746.  
  1747.             AstReturnStatement *return_statement = ast_pool -> GenReturnStatement();
  1748.             return_statement -> return_token = loc;
  1749.             return_statement -> expression_opt = NULL;
  1750.             return_statement -> semicolon_token = loc;
  1751.             return_statement -> is_reachable = true;
  1752.  
  1753.             AstBlock *block = ast_pool -> GenBlock();
  1754.             block -> AllocateBlockStatements(1); // this block contains one statement
  1755.             block -> left_brace_token  = loc;
  1756.             block -> right_brace_token = loc;
  1757.  
  1758.             block -> block_symbol = new BlockSymbol(0); // the symbol table associated with this block will contain no element
  1759.             block -> is_reachable = true;
  1760.             block -> can_complete_normally = false;
  1761.             block -> AddStatement(return_statement);
  1762.  
  1763.             AstConstructorBlock *constructor_block                   = ast_pool -> GenConstructorBlock();
  1764.             constructor_block -> left_brace_token                    = loc;
  1765.             constructor_block -> explicit_constructor_invocation_opt = this_call;
  1766.             constructor_block -> block                               = block;
  1767.             constructor_block -> right_brace_token                   = loc;
  1768.  
  1769.             AstConstructorDeclaration *constructor_declaration  = ast_pool -> GenConstructorDeclaration();
  1770.             constructor_declaration -> constructor_declarator   = method_declarator;
  1771.             constructor_declaration -> constructor_body         = constructor_block;
  1772.  
  1773.             constructor_declaration -> constructor_symbol = read_method;
  1774.             read_method -> method_or_constructor_declaration = constructor_declaration;
  1775.  
  1776.             this_type -> AddPrivateAccessConstructor(read_method);
  1777.         }
  1778.  
  1779.         read_method -> accessed_member = member;
  1780.         this_type -> MapSymbolToReadMethod(member, read_method);
  1781.  
  1782.         delete [] name;
  1783.     }
  1784.  
  1785.     return read_method;
  1786. }
  1787.  
  1788.  
  1789. MethodSymbol *TypeSymbol::GetReadAccessMethod(VariableSymbol *member)
  1790. {
  1791.     TypeSymbol *this_type = (TypeSymbol *) this,
  1792.                *containing_type = member -> owner -> TypeCast();
  1793.  
  1794.     assert((member -> ACC_PRIVATE() && this_type == containing_type) || (member -> ACC_PROTECTED() && this_type != containing_type));
  1795.  
  1796.  
  1797.     MethodSymbol *read_method = this_type -> ReadMethod(member);
  1798.  
  1799.     if (! read_method)
  1800.     {
  1801.         Semantic *sem = this_type -> semantic_environment -> sem;
  1802.  
  1803.         assert(sem);
  1804.  
  1805.         Control &control = sem -> control;
  1806.  
  1807.         IntToWstring value(this_type -> NumPrivateAccessMethods());
  1808.  
  1809.         int length = 7 + value.Length(); // +7 for access$
  1810.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1811.         wcscpy(name, StringConstant::US__access_DOLLAR);
  1812.         wcscat(name, value.String());
  1813.  
  1814.         read_method = this_type -> InsertMethodSymbol(control.FindOrInsertName(name, length));
  1815.         read_method -> MarkSynthetic();
  1816.         read_method -> SetType(member -> Type());
  1817.         read_method -> SetACC_STATIC();
  1818.         read_method -> SetContainingType(this_type);
  1819.  
  1820.         //
  1821.         // A read access method for a field has 1 formal parameter if the member in question is not static
  1822.         //
  1823.         BlockSymbol *block_symbol = new BlockSymbol(3);
  1824.         block_symbol -> max_variable_index = 0;
  1825.         read_method -> SetBlockSymbol(block_symbol);
  1826.  
  1827.         if (! member -> ACC_STATIC())
  1828.         {
  1829.             VariableSymbol *instance = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1830.             instance -> MarkSynthetic();
  1831.             instance -> SetType(this_type);
  1832.             instance -> SetOwner(read_method);
  1833.             instance -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1834.             read_method -> AddFormalParameter(instance);
  1835.         }
  1836.  
  1837.         read_method -> SetSignature(control);
  1838.         // A read access method has no throws clause !
  1839.  
  1840.         read_method -> accessed_member = member;
  1841.         this_type -> MapSymbolToReadMethod(member, read_method);
  1842.         this_type -> AddPrivateAccessMethod(read_method);
  1843.  
  1844.         delete [] name;
  1845.     }
  1846.  
  1847.     return read_method;
  1848. }
  1849.  
  1850.  
  1851. MethodSymbol *TypeSymbol::GetWriteAccessMethod(VariableSymbol *member)
  1852. {
  1853.     TypeSymbol *this_type = (TypeSymbol *) this,
  1854.                *containing_type = member -> owner -> TypeCast();
  1855.  
  1856.     assert((member -> ACC_PRIVATE() && this_type == containing_type) || (member -> ACC_PROTECTED() && this_type != containing_type));
  1857.  
  1858.     MethodSymbol *write_method = this_type -> WriteMethod(member);
  1859.  
  1860.     if (! write_method)
  1861.     {
  1862.         Semantic *sem = this_type -> semantic_environment -> sem;
  1863.  
  1864.         assert(sem);
  1865.  
  1866.         Control &control = sem -> control;
  1867.  
  1868.         IntToWstring value(this_type -> NumPrivateAccessMethods());
  1869.  
  1870.         int length = 7 + value.Length(); // +7 for access$
  1871.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1872.         wcscpy(name, StringConstant::US__access_DOLLAR);
  1873.         wcscat(name, value.String());
  1874.  
  1875.         write_method = this_type -> InsertMethodSymbol(control.FindOrInsertName(name, length));
  1876.         write_method -> MarkSynthetic();
  1877.         write_method -> SetType(sem -> control.void_type);
  1878.         write_method -> SetACC_STATIC();
  1879.         write_method -> SetContainingType(this_type);
  1880.  
  1881.         BlockSymbol *block_symbol = new BlockSymbol(3);
  1882.         block_symbol -> max_variable_index = 0;
  1883.         write_method -> SetBlockSymbol(block_symbol);
  1884.  
  1885.         //
  1886.         // A write access method takes one or two arguments. The first is the instance, $1,
  1887.         // of the object in which to do the writing if the member in question is not static.
  1888.         // The second is a parameter of the same type as the member. For a member named "m",
  1889.         // the body of the write access method will consist of the single statement:
  1890.         //
  1891.         //    $1.m = m;
  1892.         //
  1893.         if (! member -> ACC_STATIC())
  1894.         {
  1895.             VariableSymbol *instance = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1896.             instance -> MarkSynthetic();
  1897.             instance -> SetType(this_type);
  1898.             instance -> SetOwner(write_method);
  1899.             instance -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1900.             write_method -> AddFormalParameter(instance);
  1901.         }
  1902.  
  1903.         VariableSymbol *symbol = block_symbol -> InsertVariableSymbol(member -> Identity());
  1904.         symbol -> MarkSynthetic();
  1905.         symbol -> SetType(member -> Type());
  1906.         symbol -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1907.         if (control.IsDoubleWordType(member -> Type()))
  1908.             block_symbol -> max_variable_index++;
  1909.         write_method -> AddFormalParameter(symbol);
  1910.  
  1911.         write_method -> SetSignature(control);
  1912.         // A write access method has no throws clause !
  1913.  
  1914.         write_method -> accessed_member = member;
  1915.         this_type -> MapSymbolToWriteMethod(member, write_method);
  1916.         this_type -> AddPrivateAccessMethod(write_method);
  1917.  
  1918.         delete [] name;
  1919.     }
  1920.  
  1921.     return write_method;
  1922. }
  1923.  
  1924. #ifdef    HAVE_JIKES_NAMESPACE
  1925. }            // Close namespace Jikes block
  1926. #endif
  1927.  
  1928.