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

  1. // $Id: control.cpp,v 1.39 2001/01/10 16:49:44 mdejong Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // 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 "control.h"
  11. #include "scanner.h"
  12. #include "parser.h"
  13. #include "semantic.h"
  14. #include "error.h"
  15. #include "bytecode.h"
  16. #include "case.h"
  17.  
  18. #ifdef    HAVE_JIKES_NAMESPACE
  19. namespace Jikes {    // Open namespace Jikes block
  20. #endif
  21.  
  22. Control::Control(char **arguments, Option &option_) : return_code(0),
  23.                                                                  option(option_),
  24.                                                                  dot_classpath_index(0),
  25.                                                                  system_table(NULL),
  26.                                                                  system_semantic(NULL),
  27.                                                                  semantic(1024),
  28.                                                                  needs_body_work(1024),
  29.                                                                  type_trash_bin(1024),
  30.                                                                  input_java_file_set(1021),
  31.                                                                  input_class_file_set(1021),
  32.                                                                  expired_file_set(),
  33.                                                                  recompilation_file_set(1021),
  34.                                                                  int_pool(&bad_value),
  35.                                                                  long_pool(&bad_value),
  36.                                                                  float_pool(&bad_value),
  37.                                                                  double_pool(&bad_value),
  38.                                                                  Utf8_pool(&bad_value),
  39. #ifdef JIKES_DEBUG
  40.                                                                  input_files_processed(0),
  41.                                                                  class_files_read(0),
  42.                                                                  class_files_written(0),
  43.                                                                  line_count(0),
  44. #endif
  45.                                                                  Serializable_type(NULL),
  46.                                                                  Object_type(NULL),
  47.                                                                  Cloneable_type(NULL),
  48.                                                                  String_type(NULL),
  49.                                                                  Void_type(NULL),
  50.                                                                  Boolean_type(NULL),
  51.                                                                  Byte_type(NULL),
  52.                                                                  Short_type(NULL),
  53.                                                                  Character_type(NULL),
  54.                                                                  Integer_type(NULL),
  55.                                                                  Long_type(NULL),
  56.                                                                  Float_type(NULL),
  57.                                                                  Double_type(NULL),
  58.                                                                  Class_type(NULL),
  59.                                                                  Throwable_type(NULL),
  60.                                                                  Exception_type(NULL),
  61.                                                                  RuntimeException_type(NULL),
  62.                                                                  ClassNotFoundException_type(NULL),
  63.                                                                  Error_type(NULL),
  64.                                                                  NoClassDefFoundError_type(NULL),
  65.                                                                  StringBuffer_type(NULL),
  66.  
  67.                                                                  Class_forName_method(NULL),
  68.  
  69.                                                                  Throwable_getMessage_method(NULL),
  70.  
  71.                                                                  NoClassDefFoundError_InitWithString_method(NULL),
  72.  
  73.                                                                  StringBuffer_Init_method(NULL),
  74.                                                                  StringBuffer_InitWithString_method(NULL),
  75.                                                                  StringBuffer_toString_method(NULL),
  76.                                                                  StringBuffer_append_char_array_method(NULL),
  77.                                                                  StringBuffer_append_char_method(NULL),
  78.                                                                  StringBuffer_append_boolean_method(NULL),
  79.                                                                  StringBuffer_append_int_method(NULL),
  80.                                                                  StringBuffer_append_long_method(NULL),
  81.                                                                  StringBuffer_append_float_method(NULL),
  82.                                                                  StringBuffer_append_double_method(NULL),
  83.                                                                  StringBuffer_append_string_method(NULL),
  84.                                                                  StringBuffer_append_object_method(NULL)
  85. {
  86.     ProcessGlobals();
  87.  
  88.     ProcessUnnamedPackage();
  89.  
  90.     ProcessPath();
  91.  
  92.     ProcessSystemInformation();
  93.  
  94.     //
  95.     // Instantiate a scanner and a parser and initialize the static members for the semantic processors.
  96.     //
  97.     scanner = new Scanner(*this);
  98.     parser = new Parser();
  99.     SemanticError::StaticInitializer();
  100.  
  101.     //
  102.     // Process all file names specified in command line
  103.     //
  104.     ProcessNewInputFiles(input_java_file_set, arguments, option.first_file_index);
  105.  
  106.     //
  107.     // For each input file, copy it into the input_files array and process its package declaration.
  108.     //
  109.     StoragePool *ast_pool = new StoragePool(64); // how much space do we need? estimate 64 tokens.
  110.     FileSymbol **input_files = new FileSymbol*[input_java_file_set.Size() + 1];
  111.     int num_files = 0;
  112.     for (FileSymbol *file_symbol = (FileSymbol *) input_java_file_set.FirstElement();
  113.                      file_symbol;
  114.                      file_symbol = (FileSymbol *) input_java_file_set.NextElement())
  115.     {
  116.         input_files[num_files++] = file_symbol;
  117.         scanner -> Scan(file_symbol);
  118.         if (file_symbol -> lex_stream) // did we have a successful scan!
  119.         {
  120.             AstPackageDeclaration *package_declaration = parser -> PackageHeaderParse(file_symbol -> lex_stream, ast_pool);
  121.             ProcessPackageDeclaration(file_symbol, package_declaration);
  122.             ast_pool -> Reset();
  123.         }
  124.     }
  125.  
  126.     //
  127.     //
  128.     //
  129.     FileSymbol *main_file_clone;
  130.     if (num_files > 0)
  131.         main_file_clone = input_files[0] -> Clone();
  132.     else
  133.     {
  134.         //
  135.         // Some name, any name !!! We use dot_name_symbol as a bad file name because
  136.         // no file can be named ".".
  137.         //
  138.         FileSymbol *file_symbol = classpath[dot_classpath_index] -> RootDirectory() -> InsertFileSymbol(dot_name_symbol);
  139.         file_symbol -> directory_symbol = classpath[dot_classpath_index] -> RootDirectory();
  140.         file_symbol -> SetJava();
  141.  
  142.         main_file_clone = file_symbol -> Clone();
  143.     }
  144.  
  145.     main_file_clone -> semantic = new Semantic(*this, main_file_clone);
  146.     system_semantic = main_file_clone -> semantic;
  147.     scanner -> SetUp(main_file_clone);
  148.  
  149. #ifdef WIN32_FILE_SYSTEM
  150.     //
  151.     //
  152.     //
  153.     if (option.BadMainDisk())
  154.     {
  155.         system_semantic -> ReportSemError(SemanticError::NO_CURRENT_DIRECTORY,
  156.                                           0,
  157.                                           0);
  158.     }
  159. #endif
  160.  
  161.     //
  162.     //
  163.     //
  164.     for (int o = 0; o < option.bad_options.Length(); o++)
  165.     {
  166.         system_semantic -> ReportSemError((SemanticError::SemanticErrorKind) option.bad_options[o] -> kind,
  167.                                           0,
  168.                                           0,
  169.                                           option.bad_options[o] -> name);
  170.     }
  171.  
  172.     if (java_util_package -> directory.Length() == 0)
  173.     {
  174.         system_semantic -> ReportSemError(SemanticError::PACKAGE_NOT_FOUND,
  175.                                           0,
  176.                                           0,
  177.                                           StringConstant::US_java_SL_util);
  178.     }
  179.  
  180.     //
  181.     //
  182.     //
  183.     for (int l = 0; l < bad_zip_filenames.Length(); l++)
  184.     {
  185.         wchar_t *tail = &bad_zip_filenames[l][wcslen(bad_zip_filenames[l]) - 3];
  186.  
  187.         system_semantic -> ReportSemError(Case::StringSegmentEqual(tail, StringConstant::US__zip, 3) ||
  188.                                           Case::StringSegmentEqual(tail, StringConstant::US__jar, 3)
  189.                                                ? SemanticError::CANNOT_OPEN_ZIP_FILE
  190.                                                : SemanticError::CANNOT_OPEN_PATH_DIRECTORY,
  191.                                           0,
  192.                                           0,
  193.                                           bad_zip_filenames[l]);
  194.     }
  195.  
  196.     //
  197.     //
  198.     //
  199.     if (system_package -> directory.Length() == 0)
  200.     {
  201.         system_semantic -> ReportSemError(SemanticError::PACKAGE_NOT_FOUND,
  202.                                           0,
  203.                                           0,
  204.                                           StringConstant::US_java_SL_lang);
  205.     }
  206.  
  207.     //
  208.     // When the -d option is specified, create the relevant
  209.     // directories if they don't already exist.
  210.     //
  211.     if (option.directory)
  212.     {
  213.         if (! SystemIsDirectory(option.directory))
  214.         {
  215.             for (char *ptr = option.directory; *ptr; ptr++)
  216.             {
  217.                 char delimiter = *ptr;
  218.                 if (delimiter == U_SLASH)
  219.                 {
  220.                     *ptr = U_NULL;
  221.  
  222.                     if (! SystemIsDirectory(option.directory))
  223.                         SystemMkdir(option.directory);
  224.  
  225.                     *ptr = delimiter;
  226.                 }
  227.             }
  228.  
  229.             SystemMkdir(option.directory);
  230.  
  231.             if (! SystemIsDirectory(option.directory))
  232.             {
  233.                 int length = strlen(option.directory);
  234.                 wchar_t *name = new wchar_t[length + 1];
  235.                 for (int i = 0; i < length; i++)
  236.                     name[i] = option.directory[i];
  237.                 name[length] = U_NULL;
  238.                 system_semantic -> ReportSemError(SemanticError::CANNOT_OPEN_DIRECTORY,
  239.                                                   0,
  240.                                                   0,
  241.                                                   name);
  242.                 delete [] name;
  243.             }
  244.         }
  245.     }
  246.  
  247.     //
  248.     //
  249.     //
  250.     for (int m = 0; m < bad_input_filenames.Length(); m++)
  251.     {
  252.         system_semantic -> ReportSemError(SemanticError::BAD_INPUT_FILE,
  253.                                           0,
  254.                                           0,
  255.                                           bad_input_filenames[m]);
  256.     }
  257.  
  258.     //
  259.     //
  260.     //
  261.     for (int n = 0; n < unreadable_input_filenames.Length(); n++)
  262.     {
  263.         system_semantic -> ReportSemError(SemanticError::UNREADABLE_INPUT_FILE,
  264.                                           0,
  265.                                           0,
  266.                                           unreadable_input_filenames[n]);
  267.     }
  268.  
  269.     //
  270.     //
  271.     //
  272.     if (system_semantic -> NumErrors() > 0)
  273.     {
  274.         system_semantic -> PrintMessages();
  275.         return_code = system_semantic -> return_code;
  276.     }
  277.     else
  278.     {
  279.         system_semantic -> PrintMessages(); // there might be some warnings we want to print...
  280.  
  281.         //
  282.         //
  283.         //
  284.         input_java_file_set.SetEmpty();
  285.         for (int i = 0; i < num_files; i++)
  286.         {
  287.             FileSymbol *file_symbol = input_files[i];
  288.             if (! input_java_file_set.IsElement(file_symbol))
  289.                 ProcessFile(file_symbol);
  290.         }
  291.  
  292.         //
  293.         // Clean up all the files that have just been compiled in this new batch.
  294.         //
  295.         for (FileSymbol *file_symbol = (FileSymbol *) input_java_file_set.FirstElement();
  296.                          file_symbol;
  297.                          file_symbol = (FileSymbol *) input_java_file_set.NextElement())
  298.         {
  299.             CleanUp(file_symbol);
  300.         }
  301.  
  302.         //
  303.         // If more messages were added to system_semantic, print them...
  304.         //
  305.         system_semantic -> PrintMessages();
  306.         if (system_semantic -> return_code > 0 || bad_input_filenames.Length() > 0 || unreadable_input_filenames.Length() > 0)
  307.             return_code = 1;
  308.  
  309.         //
  310.         // If the incremental flag is on, check to see if the user wants us to recompile.
  311.         //
  312.         if (option.incremental)
  313.         {
  314.             option.depend = false; // The depend flag should only be in effect in the first pass
  315.  
  316.             for (bool recompile = IncrementalRecompilation(); recompile; recompile = IncrementalRecompilation())
  317.             {
  318.                 return_code = 0; // reset the return code as we may compile clean in this pass
  319.                 system_semantic -> return_code = 0;
  320.  
  321.                 //
  322.                 //
  323.                 //
  324.                 for (int m = 0; m < bad_input_filenames.Length(); m++)
  325.                 {
  326.                     system_semantic -> ReportSemError(SemanticError::BAD_INPUT_FILE,
  327.                                                       0,
  328.                                                       0,
  329.                                                       bad_input_filenames[m]);
  330.                 }
  331.  
  332.                 //
  333.                 //
  334.                 //
  335.                 for (int n = 0; n < unreadable_input_filenames.Length(); n++)
  336.                 {
  337.                     system_semantic -> ReportSemError(SemanticError::UNREADABLE_INPUT_FILE,
  338.                                                       0,
  339.                                                       0,
  340.                                                       unreadable_input_filenames[n]);
  341.                 }
  342.  
  343.                 FileSymbol *file_symbol;
  344.  
  345.                 num_files = 0;
  346.                 delete [] input_files; // delete previous copy
  347.                 input_files = new FileSymbol*[recompilation_file_set.Size()];
  348.                 for (file_symbol = (FileSymbol *) recompilation_file_set.FirstElement();
  349.                      file_symbol;
  350.                      file_symbol = (FileSymbol *) recompilation_file_set.NextElement())
  351.                 {
  352.                     input_java_file_set.RemoveElement(file_symbol);
  353.                     input_files[num_files++] = file_symbol;
  354.  
  355.                     LexStream *lex_stream = file_symbol -> lex_stream;
  356.                     if (lex_stream)
  357.                     {
  358.                         AstPackageDeclaration *package_declaration = parser -> PackageHeaderParse(lex_stream, ast_pool);
  359.                         ProcessPackageDeclaration(file_symbol, package_declaration);
  360.                         ast_pool -> Reset();
  361.                     }
  362.                 }
  363.  
  364.                 //
  365.                 // If a file has been erased, remove it from the input file set.
  366.                 //
  367.                 for (file_symbol = (FileSymbol *) expired_file_set.FirstElement();
  368.                      file_symbol;
  369.                      file_symbol = (FileSymbol *) expired_file_set.NextElement())
  370.                 {
  371.                     input_java_file_set.RemoveElement(file_symbol);
  372.                 }
  373.  
  374.                 //
  375.                 // Reset the global objects before recompiling this new batch.
  376.                 //
  377.                 expired_file_set.SetEmpty();
  378.                 recompilation_file_set.SetEmpty();
  379.                 type_trash_bin.Reset();
  380.  
  381.                 //
  382.                 // For each file that should be recompiled, process it if it has not
  383.                 // already been dragged in by dependence.
  384.                 //
  385.                 for (int k = 0; k < num_files; k++)
  386.                 {
  387.                     FileSymbol *file_symbol = input_files[k];
  388.                     if (! input_java_file_set.IsElement(file_symbol))
  389.                         ProcessFile(file_symbol);
  390.                 }
  391.  
  392.                 //
  393.                 // Clean up all the files that have just been compiled in this new batch.
  394.                 //
  395.                 for (file_symbol = (FileSymbol *) input_java_file_set.FirstElement();
  396.                     // delete file_symbol
  397.                      file_symbol;
  398.                      file_symbol = (FileSymbol *) input_java_file_set.NextElement())
  399.                 {
  400.                     // delete file_symbol
  401.                     CleanUp(file_symbol);
  402.                 }
  403.  
  404.                 //
  405.                 // If any system error or warning was detected, print it...
  406.                 //
  407.                 system_semantic -> PrintMessages();
  408.                 if (system_semantic -> return_code > 0 || bad_input_filenames.Length() > 0 || unreadable_input_filenames.Length() > 0)
  409.                     return_code = 1;
  410.             }
  411.         }
  412.  
  413.         //
  414.         // Are we supposed to generate Makefiles?
  415.         //
  416.         if (option.makefile)
  417.         {
  418.             if (option.dependence_report)
  419.             {
  420.                 FILE *outfile = SystemFopen(option.dependence_report_name, "w");
  421.                 if (outfile == NULL)
  422.                     Coutput << "*** Cannot open file " << option.dependence_report_name << "\n";
  423.                 else
  424.                 {
  425.                     SymbolSet types_in_new_files;
  426.  
  427.                     for (FileSymbol *file_symbol = (FileSymbol *) input_java_file_set.FirstElement();
  428.                                      file_symbol;
  429.                                      file_symbol = (FileSymbol *) input_java_file_set.NextElement())
  430.                     {
  431.                         char *java_name = file_symbol -> FileName();
  432.  
  433.                         for (int j = 0; j < file_symbol -> types.Length(); j++)
  434.                         {
  435.                             TypeSymbol *type = file_symbol -> types[j];
  436. #ifdef EBCDIC
  437.                             for (char *p = java_name; *p; p++)
  438.                                  fprintf(outfile, "%c", Code::ToEBCDIC(*p));
  439.                             fprintf(outfile, " : ");
  440.                             for (char *q = type -> SignatureString(); *q; q++)
  441.                                  fprintf(outfile, "%c", Code::ToEBCDIC(*q));
  442.                             fprintf(outfile, "\n");
  443. #else
  444.                             fprintf(outfile, "%s : %s\n", java_name, type -> SignatureString());
  445. #endif
  446.  
  447.                             //
  448.                             //
  449.                             //
  450.                             for (TypeSymbol *static_parent = (TypeSymbol *) type -> static_parents -> FirstElement();
  451.                                              static_parent;
  452.                                              static_parent = (TypeSymbol *) type -> static_parents -> NextElement())
  453.                             {
  454.                                 if (! type -> parents -> IsElement(static_parent)) // Only a static reference to static_parent?
  455.                                 {
  456. #ifdef EBCDIC
  457.                                     fprintf(outfile, "   !");
  458.                                     for (char *q = static_parent -> SignatureString(); *q; q++)
  459.                                          fprintf(outfile, "%c", Code::ToEBCDIC(*q));
  460.                                     fprintf(outfile, "\n");
  461. #else
  462.                                     fprintf(outfile, "   !%s\n", static_parent -> SignatureString());
  463. #endif
  464.  
  465.                                     //
  466.                                     // If the type is contained in a type that is not one of the input files, save it
  467.                                     //
  468.                                     if (static_parent -> file_symbol -> IsClass())
  469.                                         types_in_new_files.AddElement(static_parent);
  470.                                 }
  471.                             }
  472.  
  473.                             //
  474.                             //
  475.                             //
  476.                             for (TypeSymbol *parent = (TypeSymbol *) type -> parents -> FirstElement();
  477.                                              parent;
  478.                                              parent = (TypeSymbol *) type -> parents -> NextElement())
  479.                             {
  480. #ifdef EBCDIC
  481.                                 fprintf(outfile, "    ");
  482.                                 for (char *q = parent -> SignatureString(); *q; q++)
  483.                                      fprintf(outfile, "%c", Code::ToEBCDIC(*q));
  484.                                 fprintf(outfile, "\n");
  485. #else
  486.                                 fprintf(outfile, "    %s\n", parent -> SignatureString());
  487. #endif
  488.  
  489.                                 //
  490.                                 // If the type is contained in a type that is not one of the input files, save it
  491.                                 //
  492.                                 if (parent -> file_symbol -> IsClass())
  493.                                     types_in_new_files.AddElement(parent);
  494.                             }
  495.                         }
  496.                     }
  497.  
  498.                     //
  499.                     // Print the list of class files that are referenced.
  500.                     //
  501.                     for (TypeSymbol *type = (TypeSymbol *) types_in_new_files.FirstElement();
  502.                                      type;
  503.                                      type = (TypeSymbol *) types_in_new_files.NextElement())
  504.                     {
  505.                         char *class_name = type -> file_symbol -> FileName();
  506. #ifdef EBCDIC
  507.                         for (char *p = class_name; *p; p++)
  508.                              fprintf(outfile, "%c", Code::ToEBCDIC(*p));
  509.                         fprintf(outfile, " : ");
  510.                         for (char *q = type -> SignatureString(); *q; q++)
  511.                              fprintf(outfile, "%c", Code::ToEBCDIC(*q));
  512.                         fprintf(outfile, "\n");
  513. #else
  514.                         fprintf(outfile, "%s : %s\n", class_name, type -> SignatureString());
  515. #endif
  516.                     }
  517.  
  518.                     fclose(outfile);
  519.                 }
  520.             }
  521.             else
  522.             {
  523.                 SymbolSet *candidates = new SymbolSet(input_java_file_set.Size() + input_class_file_set.Size());
  524.                 *candidates = input_java_file_set;
  525.                 candidates -> Union(input_class_file_set);
  526.  
  527.                 TypeDependenceChecker *dependence_checker = new TypeDependenceChecker((Control *) this, *candidates, type_trash_bin);
  528.                 dependence_checker -> PartialOrder();
  529.                 dependence_checker -> OutputDependences();
  530.                 delete dependence_checker;
  531.  
  532.                 delete candidates;
  533.             }
  534.         }
  535.     }
  536.  
  537.     delete ast_pool;
  538.  
  539.     delete main_file_clone; // delete the clone of the main source file...
  540.  
  541.     delete [] input_files;
  542.  
  543.     return;
  544. }
  545.  
  546.  
  547. Control::~Control()
  548. {
  549.     for (int i = 0; i < bad_zip_filenames.Length(); i++)
  550.         delete [] bad_zip_filenames[i];
  551.  
  552.     for (int j = 0; j < bad_input_filenames.Length(); j++)
  553.         delete [] bad_input_filenames[j];
  554.  
  555.     for (int k = 0; k < unreadable_input_filenames.Length(); k++)
  556.         delete [] unreadable_input_filenames[k];
  557.  
  558.     for (int l = 0; l < system_directories.Length(); l++)
  559.         delete system_directories[l];
  560.  
  561.     delete scanner;
  562.     delete parser;
  563.     delete system_semantic;
  564.     delete system_table;
  565.  
  566. #ifdef JIKES_DEBUG
  567.     if (option.debug_dump_lex || option.debug_dump_ast || option.debug_unparse_ast)
  568.     {
  569.         Coutput << line_count << " source lines read\n\n"
  570.                 << class_files_read << " \".class\" files read\n"
  571.                 << class_files_written << " \".class\" files written\n"
  572.                 << input_files_processed << " \".java\" files processed\n";
  573.     }
  574. #endif
  575. }
  576.  
  577.  
  578. PackageSymbol *Control::ProcessPackage(wchar_t *name)
  579. {
  580.     int name_length = wcslen(name);
  581.     wchar_t *package_name = new wchar_t[name_length];
  582.     int length;
  583.     for (length = 0; length < name_length && name[length] != U_SLASH; length++)
  584.          package_name[length] = name[length];
  585.     NameSymbol *name_symbol = FindOrInsertName(package_name, length);
  586.  
  587.     PackageSymbol *package_symbol = external_table.FindPackageSymbol(name_symbol);
  588.     if (! package_symbol)
  589.     {
  590.         package_symbol = external_table.InsertPackageSymbol(name_symbol, NULL);
  591.         FindPathsToDirectory(package_symbol);
  592.     }
  593.  
  594.     while(length < name_length)
  595.     {
  596.         int start = ++length;
  597.         for (int i = 0; length < name_length && name[length] != U_SLASH; i++, length++)
  598.              package_name[i] = name[length];
  599.         name_symbol = FindOrInsertName(package_name, length - start);
  600.         PackageSymbol *subpackage_symbol = package_symbol -> FindPackageSymbol(name_symbol);
  601.         if (! subpackage_symbol)
  602.         {
  603.             subpackage_symbol = package_symbol -> InsertPackageSymbol(name_symbol);
  604.             FindPathsToDirectory(subpackage_symbol);
  605.         }
  606.         package_symbol = subpackage_symbol;
  607.     }
  608.  
  609.     delete [] package_name;
  610.  
  611.     return package_symbol;
  612. }
  613.  
  614.  
  615. //
  616. // When searching for a subdirectory in a zipped file, it must already be present in the
  617. // hierarchy.
  618. //
  619. DirectorySymbol *Control::FindSubdirectory(PathSymbol *path_symbol, wchar_t *name, int name_length)
  620. {
  621.     wchar_t *directory_name = new wchar_t[name_length + 1];
  622.  
  623.     DirectorySymbol *directory_symbol = path_symbol -> RootDirectory();
  624.     for (int start = 0, end; directory_symbol && start < name_length; start = end + 1)
  625.     {
  626.         end = start;
  627.         for (int i = 0; end < name_length && name[end] != U_SLASH; i++, end++)
  628.              directory_name[i] = name[end];
  629.         NameSymbol *name_symbol = FindOrInsertName(directory_name, end - start);
  630.         directory_symbol = directory_symbol -> FindDirectorySymbol(name_symbol);
  631.     }
  632.  
  633.     delete [] directory_name;
  634.  
  635.     return directory_symbol;
  636. }
  637.  
  638.  
  639. //
  640. // When searching for a directory in the system, if it is not already present in the hierarchy
  641. // insert it and attempt to read it from the system...
  642. //
  643. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  644.     DirectorySymbol *Control::ProcessSubdirectories(wchar_t *source_name, int source_name_length)
  645.     {
  646.         int name_length = (source_name_length < 0 ? 0 : source_name_length);
  647.         char *input_name = new char[name_length + 1];
  648.         for (int i = 0; i < name_length; i++)
  649.             input_name[i] = source_name[i];
  650.         input_name[name_length] = U_NULL;
  651.  
  652.         DirectorySymbol *directory_symbol = NULL;
  653.         struct stat status;
  654.         if ((SystemStat(input_name, &status) == 0) && (status.st_mode & JIKES_STAT_S_IFDIR))
  655.             directory_symbol = system_table -> FindDirectorySymbol(status.st_dev, status.st_ino);
  656.  
  657.         if (! directory_symbol)
  658.         {
  659.             if (input_name[0] == U_SLASH) // file name starts with '/'
  660.             {
  661.                 directory_symbol = new DirectorySymbol(FindOrInsertName(source_name, name_length), classpath[dot_classpath_index]);
  662.                 directory_symbol -> ReadDirectory();
  663.                 system_directories.Next() = directory_symbol;
  664.                 system_table -> InsertDirectorySymbol(status.st_dev, status.st_ino, directory_symbol);
  665.             }
  666.             else
  667.             {
  668.                 wchar_t *name = new wchar_t[name_length + 1];
  669.                 for (int i = 0; i < name_length; i++)
  670.                     name[i] = source_name[i];
  671.                 name[name_length] = U_NULL;
  672.  
  673.                 directory_symbol = classpath[dot_classpath_index] -> RootDirectory(); // start at the dot directory.
  674.  
  675.                 //
  676.                 //
  677.                 //
  678.                 wchar_t *directory_name = new wchar_t[name_length];
  679.                 int end = 0;
  680.                 for (int start = end; start < name_length; start = end)
  681.                 {
  682.                     int length;
  683.                     for (length = 0; end < name_length && name[end] != U_SLASH; length++, end++)
  684.                         directory_name[length] = name[end];
  685.  
  686.                     if (length != 1 || directory_name[0] != U_DOT) // Not the current directory
  687.                     {
  688.                         if (length == 2 && directory_name[0] == U_DOT && directory_name[1] == U_DOT) // keep the current directory
  689.                         {
  690.                             if (directory_symbol -> Identity() == dot_name_symbol ||
  691.                                 directory_symbol -> Identity() == dot_dot_name_symbol)
  692.                             {
  693.                                 DirectorySymbol *subdirectory_symbol = directory_symbol -> FindDirectorySymbol(dot_dot_name_symbol);
  694.                                 if (! subdirectory_symbol)
  695.                                     subdirectory_symbol = directory_symbol -> InsertDirectorySymbol(dot_dot_name_symbol);
  696.                                 directory_symbol = subdirectory_symbol;
  697.                             }
  698.                             else directory_symbol = directory_symbol -> owner -> DirectoryCast();
  699.                         }
  700.                         else
  701.                         {
  702.                             NameSymbol *name_symbol = FindOrInsertName(directory_name, length);
  703.                             DirectorySymbol *subdirectory_symbol = directory_symbol -> FindDirectorySymbol(name_symbol);
  704.                             if (! subdirectory_symbol)
  705.                                 subdirectory_symbol = directory_symbol -> InsertDirectorySymbol(name_symbol);
  706.                             directory_symbol = subdirectory_symbol;
  707.                         }
  708.                     }
  709.  
  710.                     for (end++; end < name_length && name[end] == U_SLASH; end++) // skip all extra '/'
  711.                         ;
  712.                 }
  713.  
  714.                 //
  715.                 // Insert the new directory into the system table to avoid duplicates, in case
  716.                 // the same directory is specified with a different name.
  717.                 //
  718.                 if (directory_symbol != classpath[dot_classpath_index] -> RootDirectory()) // Not the dot directory.
  719.                 {
  720.                     system_table -> InsertDirectorySymbol(status.st_dev, status.st_ino, directory_symbol);
  721.                     directory_symbol -> ReadDirectory();
  722.                 }
  723.  
  724.                 delete [] directory_name;
  725.                 delete [] name;
  726.             }
  727.         }
  728.  
  729.         delete [] input_name;
  730.  
  731.         return directory_symbol;
  732.     }
  733. #elif defined(WIN32_FILE_SYSTEM)
  734.     DirectorySymbol *Control::ProcessSubdirectories(wchar_t *source_name, int source_name_length)
  735.     {
  736.         DirectorySymbol *directory_symbol = classpath[dot_classpath_index] -> RootDirectory();
  737.  
  738.         int name_length = (source_name_length < 0 ? 0 : source_name_length);
  739.         wchar_t *name = new wchar_t[name_length + 1];
  740.         char *input_name = new char[name_length + 1];
  741.         for (int i = 0; i < name_length; i++)
  742.             input_name[i] = name[i] = source_name[i];
  743.         input_name[name_length] = name[name_length] = U_NULL;
  744.  
  745.         if (name_length >= 2 && Case::IsAsciiAlpha(input_name[0]) && input_name[1] == U_COLON) // a disk was specified
  746.         {
  747.             char disk = input_name[0];
  748.             option.SaveCurrentDirectoryOnDisk(disk);
  749.             if (SetCurrentDirectory(input_name))
  750.             {
  751.                 DWORD directory_length = GetCurrentDirectory(0, input_name); // first, get the right size
  752.                 char *full_directory_name = new char[directory_length + 1];  // allocate the directory
  753.                 DWORD length = GetCurrentDirectory(directory_length, full_directory_name);
  754.                 if (length <= directory_length)
  755.                 {
  756.                     for (char *ptr = full_directory_name; *ptr; ptr++)
  757.                         *ptr = (*ptr != U_BACKSLASH ? *ptr : (char) U_SLASH); // turn '\' to '/'.
  758.  
  759.                     char *current_directory = option.GetMainCurrentDirectory();
  760.                     int prefix_length = strlen(current_directory);
  761.                     int start = (prefix_length <= (int) length &&
  762.                                  Case::StringSegmentEqual(current_directory, full_directory_name, prefix_length) &&
  763.                                  (full_directory_name[prefix_length] == U_SLASH || full_directory_name[prefix_length] == U_NULL)
  764.                                                 ? prefix_length + 1
  765.                                                 : 0);
  766.  
  767.                     if (start > (int) length)
  768.                          name_length = 0;
  769.                     else if (start <= (int) length) // note that we can assert that (start != length)
  770.                     {
  771.                         delete [] name;
  772.                         name_length = length - start;
  773.                         name = new wchar_t[name_length + 1];
  774.                         for (int k = 0, i = start; i < (int) length; i++, k++)
  775.                             name[k] = full_directory_name[i];
  776.                         name[name_length] = U_NULL;
  777.                     }
  778.                 }
  779.  
  780.                 delete [] full_directory_name;
  781.             }
  782.  
  783.             option.ResetCurrentDirectoryOnDisk(disk);  // reset the current directory on this disk
  784.             option.SetMainCurrentDirectory(); // reset the real current directory...
  785.         }
  786.  
  787.         //
  788.         //
  789.         //
  790.         int end;
  791.         if (name_length > 2 && Case::IsAsciiAlpha(name[0]) && name[1] == U_COLON && name[2] == U_SLASH)
  792.             end = 3;
  793.         else
  794.         {
  795.             for (end = 0; end < name_length && name[end] == U_SLASH; end++) // keep all extra leading '/'
  796.                 ;
  797.         }
  798.  
  799.         //
  800.         //
  801.         //
  802.         wchar_t *directory_name = new wchar_t[name_length];
  803.         int length;
  804.         if (end > 0)
  805.         {
  806.             for (length = 0; length < end; length++)
  807.                 directory_name[length] = name[length];
  808.             NameSymbol *name_symbol = FindOrInsertName(directory_name, length);
  809.             DirectorySymbol *subdirectory_symbol = directory_symbol -> FindDirectorySymbol(name_symbol);
  810.             if (! subdirectory_symbol)
  811.                 subdirectory_symbol = directory_symbol -> InsertDirectorySymbol(name_symbol);
  812.             directory_symbol = subdirectory_symbol;
  813.         }
  814.  
  815.         //
  816.         //
  817.         //
  818.         for (int start = end; start < name_length; start = end)
  819.         {
  820.             for (length = 0; end < name_length && name[end] != U_SLASH; length++, end++)
  821.                 directory_name[length] = name[end];
  822.  
  823.             if (length != 1 || directory_name[0] != U_DOT) // Not the current directory
  824.             {
  825.                 if (length == 2 && directory_name[0] == U_DOT && directory_name[1] == U_DOT) // keep the current directory
  826.                 {
  827.                     if (directory_symbol -> Identity() == dot_name_symbol || directory_symbol -> Identity() == dot_dot_name_symbol)
  828.                     {
  829.                         DirectorySymbol *subdirectory_symbol = directory_symbol -> FindDirectorySymbol(dot_dot_name_symbol);
  830.                         if (! subdirectory_symbol)
  831.                             subdirectory_symbol = directory_symbol -> InsertDirectorySymbol(dot_dot_name_symbol);
  832.                         directory_symbol = subdirectory_symbol;
  833.                     }
  834.                     else directory_symbol = directory_symbol -> owner -> DirectoryCast();
  835.                 }
  836.                 else
  837.                 {
  838.                     NameSymbol *name_symbol = FindOrInsertName(directory_name, length);
  839.                     DirectorySymbol *subdirectory_symbol = directory_symbol -> FindDirectorySymbol(name_symbol);
  840.                     if (! subdirectory_symbol)
  841.                         subdirectory_symbol = directory_symbol -> InsertDirectorySymbol(name_symbol);
  842.                     directory_symbol = subdirectory_symbol;
  843.                 }
  844.             }
  845.  
  846.             for (end++; end < name_length && name[end] == U_SLASH; end++) // skip all extra '/'
  847.                 ;
  848.         }
  849.  
  850.         directory_symbol -> ReadDirectory();
  851.  
  852.         delete [] directory_name;
  853.         delete [] name;
  854.         delete [] input_name;
  855.  
  856.         return directory_symbol;
  857.     }
  858. #endif
  859.  
  860.  
  861. void Control::ProcessNewInputFiles(SymbolSet &file_set, char **arguments, int first_index)
  862. {
  863.     for (int i = 0; i < bad_input_filenames.Length(); i++)
  864.         delete [] bad_input_filenames[i];
  865.     bad_input_filenames.Reset();
  866.  
  867.     for (int k = 0; k < unreadable_input_filenames.Length(); k++)
  868.         delete [] unreadable_input_filenames[k];
  869.     unreadable_input_filenames.Reset();
  870.  
  871.     //
  872.     // Process all file names specified in command line
  873.     //
  874.     if(arguments)
  875.     {
  876.         int j=0;
  877.         while(arguments[j])
  878.         {
  879.             char *file_name = arguments[j++];
  880.             int file_name_length = strlen(file_name);
  881.  
  882.             wchar_t *name = new wchar_t[file_name_length + 1];
  883.             for(int i = 0; i < file_name_length; i++)
  884.                 name[i] = (file_name[i] != U_BACKSLASH ? file_name[i] : (wchar_t) U_SLASH); // change backslash to forward slash.
  885.             name[file_name_length] = U_NULL;
  886.             
  887.             //
  888.             // File must be of the form xxx.java where xxx is a
  889.             // character string consisting of at least one character.
  890.             //
  891.             if (file_name_length < FileSymbol::java_suffix_length ||
  892.                 (! FileSymbol::IsJavaSuffix(&file_name[file_name_length - FileSymbol::java_suffix_length])))
  893.             {
  894.                 bad_input_filenames.Next() = name;
  895.             }
  896.             else
  897.             {
  898.                 FileSymbol *file_symbol = FindOrInsertJavaInputFile(name, file_name_length - FileSymbol::java_suffix_length);
  899.                 
  900.                 if (! file_symbol)
  901.                     unreadable_input_filenames.Next() = name;
  902.                 else
  903.                 {
  904.                     delete [] name;
  905.                     file_set.AddElement(file_symbol);
  906.                 }
  907.             }
  908.         }
  909.     }
  910.     
  911.     return;
  912. }
  913.  
  914.  
  915. FileSymbol *Control::FindOrInsertJavaInputFile(DirectorySymbol *directory_symbol, NameSymbol *file_name_symbol)
  916. {
  917.     FileSymbol *file_symbol = NULL;
  918.  
  919.     int length = file_name_symbol -> Utf8NameLength() + FileSymbol::java_suffix_length;
  920.     char *java_name = new char[length + 1]; // +1 for \0
  921.     strcpy(java_name, file_name_symbol -> Utf8Name());
  922.     strcat(java_name, FileSymbol::java_suffix);
  923.  
  924.     DirectoryEntry *entry = directory_symbol -> FindEntry(java_name, length);
  925.     if (entry)
  926.     {
  927.         file_symbol = directory_symbol -> FindFileSymbol(file_name_symbol);
  928.  
  929.         if (! file_symbol)
  930.         {
  931.             file_symbol = directory_symbol -> InsertFileSymbol(file_name_symbol);
  932.             file_symbol -> directory_symbol = directory_symbol;
  933.             file_symbol -> SetJava();
  934.         }
  935.  
  936.         file_symbol -> mtime = entry -> Mtime();
  937.     }
  938.  
  939.     delete [] java_name;
  940.  
  941.     return file_symbol;
  942. }
  943.  
  944.  
  945. FileSymbol *Control::FindOrInsertJavaInputFile(wchar_t *name, int name_length)
  946. {
  947.     FileSymbol *file_symbol = NULL;
  948.  
  949.     //
  950.     // The name has been preprocessed so that if it contains any
  951.     // slashes it is a forward slash. In the loop below we look
  952.     // for the occurrence of the first slash (if any) that separates
  953.     // the file name from its directory name.
  954.     //
  955.     DirectorySymbol *directory_symbol;
  956.     NameSymbol *file_name_symbol;
  957. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  958.     int len;
  959.     for (len = name_length - 1; len >= 0 && name[len] != U_SLASH; len--)
  960.         ;
  961.     directory_symbol = ProcessSubdirectories(name, len);
  962.     file_name_symbol = FindOrInsertName(&name[len + 1], name_length - (len + 1));
  963. #elif defined(WIN32_FILE_SYSTEM)
  964.     int len;
  965.     for (len = name_length - 1; len >= 0 && name[len] != U_SLASH && name[len] != U_COLON; len--)
  966.         ;
  967.     directory_symbol = ProcessSubdirectories(name, (name[len] == U_COLON ? len + 1 : len));
  968.     file_name_symbol = FindOrInsertName(&name[len + 1], name_length - (len + 1));
  969. #endif
  970.  
  971.     for (int i = 1; i < classpath.Length(); i++)
  972.     {
  973.         if (i == dot_classpath_index) // the current directory (.).
  974.         {
  975.             file_symbol = FindOrInsertJavaInputFile(directory_symbol, file_name_symbol);
  976.             if (file_symbol)
  977.                 break;
  978.         }
  979.         else if (classpath[i] -> IsZip())
  980.         {
  981.             DirectorySymbol *directory_symbol = FindSubdirectory(classpath[i], name, len);
  982.             if (directory_symbol)
  983.             {
  984.                 file_symbol = directory_symbol -> FindFileSymbol(file_name_symbol);
  985.                 if (file_symbol && file_symbol -> IsJava())
  986.                      break;
  987.                 else file_symbol = NULL;
  988.             }
  989.         }
  990.     }
  991.  
  992.     //
  993.     // If the file was found, return it; otherwise, in case the (.) directory was not specified in the
  994.     // classpath, search for the file in it...
  995.     //
  996.     return (file_symbol ? file_symbol : FindOrInsertJavaInputFile(directory_symbol, file_name_symbol));
  997. }
  998.  
  999.  
  1000. PackageSymbol *Control::FindOrInsertPackage(LexStream *lex_stream, AstExpression *name)
  1001. {
  1002.     PackageSymbol *package;
  1003.  
  1004.     AstFieldAccess* field_access = name -> FieldAccessCast();
  1005.     if (field_access)
  1006.     {
  1007.         package = FindOrInsertPackage(lex_stream, field_access -> base);
  1008.         NameSymbol *name_symbol = lex_stream -> NameSymbol(field_access -> identifier_token);
  1009.         PackageSymbol *subpackage = package -> FindPackageSymbol(name_symbol);
  1010.         if (! subpackage)
  1011.             subpackage = package -> InsertPackageSymbol(name_symbol);
  1012.         package = subpackage;
  1013.     }
  1014.     else
  1015.     {
  1016.         AstSimpleName *simple_name = (AstSimpleName *) name;
  1017.         NameSymbol *name_symbol = lex_stream -> NameSymbol(simple_name -> identifier_token);
  1018.         package = external_table.FindPackageSymbol(name_symbol);
  1019.         if (! package)
  1020.             package = external_table.InsertPackageSymbol(name_symbol, NULL);
  1021.     }
  1022.  
  1023.     FindPathsToDirectory(package);
  1024.  
  1025.     return package;
  1026. }
  1027.  
  1028.  
  1029. void Control::ProcessFile(FileSymbol *file_symbol)
  1030. {
  1031.     ProcessHeaders(file_symbol);
  1032.  
  1033.     //
  1034.     // As long as there are new bodies, ...
  1035.     //
  1036.     for (int i = 0; i < needs_body_work.Length(); i++)
  1037.     {
  1038.         assert(semantic.Length() == 0);
  1039.  
  1040.         ProcessBodies(needs_body_work[i]);
  1041.     }
  1042.     needs_body_work.Reset();
  1043.  
  1044.     return;
  1045. }
  1046.  
  1047.  
  1048. void Control::ProcessHeaders(FileSymbol *file_symbol)
  1049. {
  1050.     input_java_file_set.AddElement(file_symbol);
  1051.  
  1052.     bool initial_invocation = (semantic.Length() == 0);
  1053.  
  1054.     if (option.verbose)
  1055.     {
  1056.         Coutput << "[read "
  1057.                 << file_symbol -> FileName()
  1058.                 << "]\n";
  1059.     }
  1060.  
  1061.     if (! file_symbol -> lex_stream)
  1062.          scanner -> Scan(file_symbol);
  1063.     else file_symbol -> lex_stream -> Reset();
  1064.  
  1065.     if (file_symbol -> lex_stream) // do we have a successful scan!
  1066.     {
  1067.         if (! file_symbol -> compilation_unit)
  1068.             file_symbol -> compilation_unit = parser -> HeaderParse(file_symbol -> lex_stream);
  1069.         //
  1070.         // If we have a compilation unit, analyze it, process its types.
  1071.         //
  1072.         if (file_symbol -> compilation_unit)
  1073.         {
  1074.             assert(! file_symbol -> semantic);
  1075.  
  1076.             if (! file_symbol -> package)
  1077.                 ProcessPackageDeclaration(file_symbol, file_symbol -> compilation_unit -> package_declaration_opt);
  1078.             file_symbol -> semantic = new Semantic(*this, file_symbol);
  1079.             semantic.Next() = file_symbol -> semantic;
  1080.             file_symbol -> semantic -> ProcessTypeNames();
  1081.         }
  1082.     }
  1083.  
  1084.     if (initial_invocation)
  1085.         ProcessMembers();
  1086.  
  1087.     return;
  1088. }
  1089.  
  1090.  
  1091. void Control::ProcessMembers()
  1092. {
  1093.     Tuple<TypeSymbol *> partially_ordered_types(1024);
  1094.     SymbolSet needs_member_work(101);
  1095.     TypeCycleChecker cycle_checker(partially_ordered_types);
  1096.     TopologicalSort topological_sorter(needs_member_work, partially_ordered_types);
  1097.  
  1098.     int start = 0;
  1099.     while (start < semantic.Length())
  1100.     {
  1101.         needs_member_work.SetEmpty();
  1102.  
  1103.         do
  1104.         {
  1105.             //
  1106.             // Check whether or not there are cycles in this new batch of types.
  1107.             // Create a partial order of the types (cycles are ordered arbitrarily)
  1108.             // and place the result in partially_ordered_types.
  1109.             //
  1110.             cycle_checker.PartialOrder(semantic, start);
  1111.             start = semantic.Length(); // next starting point
  1112.  
  1113.             //
  1114.             // Process the extends and implements clauses.
  1115.             //
  1116.             for (int j = 0; j < partially_ordered_types.Length(); j++)
  1117.             {
  1118.                 TypeSymbol *type = partially_ordered_types[j];
  1119.                 needs_member_work.AddElement(type);
  1120.                 type -> ProcessTypeHeaders();
  1121.                 type -> semantic_environment -> sem -> types_to_be_processed.AddElement(type);
  1122.             }
  1123.         } while (start < semantic.Length());
  1124.  
  1125.         //
  1126.         // Patially order the collection of types in needs_member_work and place the result
  1127.         // in partially_ordered_types. This reordering is based on the complete "supertype"
  1128.         // information computed in ProcessTypeHeaders.
  1129.         //
  1130.         topological_sorter.Sort();
  1131.         for (int i = 0; i < partially_ordered_types.Length(); i++)
  1132.         {
  1133.             TypeSymbol *type = partially_ordered_types[i];
  1134.             needs_body_work.Next() = type;
  1135.             type -> ProcessMembers();
  1136.         }
  1137.     }
  1138.  
  1139.     semantic.Reset();
  1140.  
  1141.     return;
  1142. }
  1143.  
  1144.  
  1145.  
  1146. void Control::ProcessBodies(TypeSymbol *type)
  1147. {
  1148.     Semantic *sem = type -> semantic_environment -> sem;
  1149.  
  1150.     if (type -> declaration && (! sem -> compilation_unit -> BadCompilationUnitCast()))
  1151.     {
  1152.         AstInterfaceDeclaration *interface_declaration = type -> declaration -> InterfaceDeclarationCast();
  1153.         AstClassDeclaration *class_declaration = type -> declaration -> ClassDeclarationCast();
  1154.  
  1155. #ifdef WIN32_FILE_SYSTEM
  1156.         if (! type -> file_symbol -> IsZip())
  1157.         {
  1158.             int length = type -> Utf8NameLength() + FileSymbol::class_suffix_length;
  1159.             char *classfile_name = new char[length + 1]; // +1 for "\0"
  1160.             strcpy(classfile_name, type -> Utf8Name());
  1161.             strcat(classfile_name, FileSymbol::class_suffix);
  1162.  
  1163.             DirectorySymbol *directory = type -> file_symbol -> OutputDirectory();
  1164.             DirectoryEntry *entry = directory -> FindCaseInsensitiveEntry(classfile_name, length);
  1165.  
  1166.             //
  1167.             // If no entry exists for the classfile name, add it as we are about to create
  1168.             // such a file. If an entry is found and it is not identical (in a case-sensitive test)
  1169.             // to the name of the type, issue an appropriate message.
  1170.             //
  1171.             if (! entry)
  1172.                 directory -> InsertEntry(classfile_name, length);
  1173.             else if (strcmp(classfile_name, entry -> name) != 0)
  1174.             {
  1175.                 wchar_t *entry_name = new wchar_t[entry -> length + 1];
  1176.                 for (int i = 0; i < length; i++)
  1177.                     entry_name[i] = entry -> name[i];
  1178.                 entry_name[entry -> length] = U_NULL;
  1179.                 LexStream::TokenIndex identifier_token = (interface_declaration ? interface_declaration -> identifier_token
  1180.                                                                                 : class_declaration -> identifier_token);
  1181.  
  1182.                 sem -> ReportSemError(SemanticError::FILE_FILE_CONFLICT,
  1183.                                       identifier_token,
  1184.                                       identifier_token,
  1185.                                       type -> Name(),
  1186.                                       entry_name,
  1187.                                       directory -> Name());
  1188.  
  1189.                 delete [] entry_name;
  1190.             }
  1191.  
  1192.             delete [] classfile_name;
  1193.         }
  1194. #endif
  1195.  
  1196.         if (interface_declaration)
  1197.         {
  1198.             if (! parser -> InitializerParse(sem -> lex_stream, interface_declaration))
  1199.                 sem -> compilation_unit -> kind = Ast::BAD_COMPILATION; // recall that syntax errors were detected
  1200.             else
  1201.             {
  1202.                 type -> CompleteSymbolTable();
  1203.                 if (! parser -> BodyParse(sem -> lex_stream, interface_declaration))
  1204.                      sem -> compilation_unit -> kind = Ast::BAD_COMPILATION; // mark that syntax errors were detected
  1205.                 else type -> ProcessExecutableBodies();
  1206.             }
  1207.         }
  1208.         else
  1209.         {
  1210.             if (! parser -> InitializerParse(sem -> lex_stream, class_declaration -> class_body))
  1211.                 sem -> compilation_unit -> kind = Ast::BAD_COMPILATION; // recall that syntax errors were detected
  1212.             else
  1213.             {
  1214.                 type -> CompleteSymbolTable();
  1215.                 if (! parser -> BodyParse(sem -> lex_stream, class_declaration -> class_body))
  1216.                      sem -> compilation_unit -> kind = Ast::BAD_COMPILATION; // mark that syntax errors were detected.
  1217.                 else type -> ProcessExecutableBodies();
  1218.             }
  1219.         }
  1220.  
  1221.         if ((sem -> NumErrors() == 0) && (! sem -> compilation_unit -> BadCompilationUnitCast()))
  1222.         {
  1223.             Tuple<TypeSymbol *> *types = new Tuple<TypeSymbol *>(1024);
  1224.             types -> Next() = type;
  1225.  
  1226.             for (int j = 0; j < type -> num_anonymous_types(); j++)
  1227.             {
  1228.                 types -> Next() = type -> AnonymousType(j);
  1229.             }
  1230.  
  1231.             if (type -> local)
  1232.             {
  1233.                 for (TypeSymbol *local_type = (TypeSymbol *) type -> local -> FirstElement();
  1234.                                  local_type;
  1235.                                  local_type = (TypeSymbol *) type -> local -> NextElement())
  1236.                 {
  1237.                     types -> Next() = local_type;
  1238.                 }
  1239.             }
  1240.  
  1241.             if (type -> non_local)
  1242.             {
  1243.                 for (TypeSymbol *non_local_type = (TypeSymbol *) type -> non_local -> FirstElement();
  1244.                                  non_local_type;
  1245.                                  non_local_type = (TypeSymbol *) type -> non_local -> NextElement())
  1246.                 {
  1247.                     types -> Next() = non_local_type;
  1248.                 }
  1249.             }
  1250.  
  1251.             //
  1252.             // If we are supposed to generate code, do so now !!!
  1253.             //
  1254.             if (option.bytecode)
  1255.             {
  1256.                 for (int k = 0; k < types -> Length(); k++)
  1257.                 {
  1258.                     TypeSymbol *type = (*types)[k];
  1259.  
  1260.                     type -> file_symbol -> SetFileNameLiteral((Control *) this); // make sure the literal is available for bytecode
  1261.  
  1262.                     ByteCode *code = new ByteCode(type);
  1263.                     code -> GenerateCode();
  1264.  
  1265.                     delete code;
  1266.                 }
  1267.             }
  1268.  
  1269.             //
  1270.             // If no error was detected while generating code, then
  1271.             // start cleaning up.
  1272.             //
  1273.             if (! option.nocleanup)
  1274.             {
  1275.             if (sem -> NumErrors() == 0)
  1276.             {
  1277.                 for (int k = 0; k < types -> Length(); k++)
  1278.                 {
  1279.                     TypeSymbol *type = (*types)[k];
  1280.  
  1281.                     delete type -> semantic_environment;
  1282.                     type -> semantic_environment = NULL;
  1283.  
  1284.                     if (type -> ACC_INTERFACE())
  1285.                     {
  1286.                         AstInterfaceDeclaration *interface_declaration = (AstInterfaceDeclaration *) type -> declaration;
  1287.                         interface_declaration -> semantic_environment = NULL;
  1288.                     }
  1289.                     else
  1290.                     {
  1291.                         AstClassDeclaration *class_declaration = type -> declaration -> ClassDeclarationCast();
  1292.  
  1293.                         if (class_declaration)
  1294.                             class_declaration -> semantic_environment = NULL;
  1295.                     }
  1296.                 }
  1297.             }
  1298.  
  1299.             delete types;
  1300.         }
  1301.     }
  1302.     }
  1303.  
  1304.     sem -> types_to_be_processed.RemoveElement(type);
  1305.     if (! option.nocleanup)
  1306.     if (sem -> types_to_be_processed.Size() == 0) // all types belonging to this compilation unit have been processed.
  1307.         CleanUp(sem -> source_file_symbol);
  1308.  
  1309.     return;
  1310. }
  1311.  
  1312.  
  1313. //
  1314. // Introduce the main package and the current package.
  1315. // This procedure is invoked directly only while doing
  1316. // an incremental compilation.
  1317. //
  1318. void Control::ProcessPackageDeclaration(FileSymbol *file_symbol, AstPackageDeclaration *package_declaration)
  1319. {
  1320.     file_symbol -> package = (package_declaration
  1321.                                      ? FindOrInsertPackage(file_symbol -> lex_stream, package_declaration -> name)
  1322.                                      : unnamed_package);
  1323.  
  1324.     for (int i = 0; i < file_symbol -> lex_stream -> NumTypes(); i++)
  1325.     {
  1326.         LexStream::TokenIndex identifier_token = file_symbol -> lex_stream -> Next(file_symbol -> lex_stream -> Type(i));
  1327.         if (file_symbol -> lex_stream -> Kind(identifier_token) == TK_Identifier)
  1328.         {
  1329.             NameSymbol *name_symbol = file_symbol -> lex_stream -> NameSymbol(identifier_token);
  1330.             if (! file_symbol -> package -> FindTypeSymbol(name_symbol))
  1331.             {
  1332.                 TypeSymbol *type = file_symbol -> package -> InsertOuterTypeSymbol(name_symbol);
  1333.                 type -> file_symbol = file_symbol;
  1334.                 type -> outermost_type = type;
  1335.                 type -> supertypes_closure = new SymbolSet;
  1336.                 type -> subtypes = new SymbolSet;
  1337.                 type -> SetOwner(file_symbol -> package);
  1338.                 type -> SetSignature(*this);
  1339.                 type -> MarkSourcePending();
  1340.  
  1341.                 //
  1342.                 // If this type is contained in the unnamed package add it to the set
  1343.                 // unnamed_package_types if a type of similar name was not already there.
  1344.                 //
  1345.                 if ((! package_declaration) && (unnamed_package_types.Image(type -> Identity()) == NULL))
  1346.                     unnamed_package_types.AddElement(type);
  1347.             }
  1348.         }
  1349.     }
  1350.  
  1351.     return;
  1352. }
  1353.  
  1354.  
  1355. void Control::CleanUp(FileSymbol *file_symbol)
  1356. {
  1357.     Semantic *sem = file_symbol -> semantic;
  1358.  
  1359.     if (sem)
  1360.     {
  1361. #ifdef JIKES_DEBUG
  1362.         if (option.debug_dump_lex)
  1363.         {
  1364.             sem -> lex_stream -> Reset(); // rewind input and ...
  1365.             sem -> lex_stream -> Dump();  // dump it!
  1366.         }
  1367.         if (option.debug_dump_ast)
  1368.             sem -> compilation_unit -> Print(*sem -> lex_stream);
  1369.         if (option.debug_unparse_ast)
  1370.         {
  1371.             if (option.debug_unparse_ast_debug)
  1372.               {
  1373.                 // which of these is correct?
  1374.                 sem -> compilation_unit -> debug_unparse = true;
  1375.                 Ast::debug_unparse = true;
  1376.               }
  1377.             sem -> compilation_unit -> Unparse(*sem -> lex_stream,
  1378.                                                "unparsed/");
  1379.         }
  1380. #endif
  1381.         sem -> PrintMessages();
  1382.         if (sem -> return_code > 0)
  1383.             return_code = 1;
  1384.  
  1385.         file_symbol -> CleanUp();
  1386.     }
  1387.  
  1388.     return;
  1389. }
  1390.  
  1391. #ifdef    HAVE_JIKES_NAMESPACE
  1392. }            // Close namespace Jikes block
  1393. #endif
  1394.  
  1395.