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

  1. // $Id: getclass.cpp,v 1.24 2001/01/10 16:49:45 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.  
  11. #include "getclass.h"
  12. #include "control.h"
  13. #include "semantic.h"
  14. #include "access.h"
  15. #include "zip.h"
  16. #include "jikesapi.h"
  17.  
  18. #ifdef    HAVE_JIKES_NAMESPACE
  19. namespace Jikes {    // Open namespace Jikes block
  20. #endif
  21.  
  22. inline u1 Semantic::GetU1(const char *buffer)
  23. {
  24.     return *buffer;
  25. }
  26.  
  27. inline u2 Semantic::GetU2(const char *buffer)
  28. {
  29.     u2 i = (u1) *buffer++;
  30.     return (i << 8) + (u1) *buffer;
  31. }
  32.  
  33. inline u4 Semantic::GetU4(const char *buffer)
  34. {
  35.     u4 i = (u1) *buffer++;
  36.     i = (i << 8) + (u1) *buffer++;
  37.     i = (i << 8) + (u1) *buffer++;
  38.     return (i << 8) + (u1) *buffer;
  39. }
  40.  
  41. inline u1 Semantic::GetAndSkipU1(const char *&buffer)
  42. {
  43.     return (u1) *buffer++;
  44. }
  45.  
  46. inline u2 Semantic::GetAndSkipU2(const char *&buffer)
  47. {
  48.     u2 i = (u1) *buffer++;
  49.     return (i << 8) + (u1) *buffer++;
  50. }
  51.  
  52. inline u4 Semantic::GetAndSkipU4(const char *&buffer)
  53. {
  54.     u4 i = (u1) *buffer++;
  55.     i = (i << 8) + (u1) *buffer++;
  56.     i = (i << 8) + (u1) *buffer++;
  57.     return (i << 8) + (u1) *buffer++;
  58. }
  59.  
  60. inline void Semantic::Skip(const char *&buffer, int n)
  61. {
  62.     buffer += n;
  63. }
  64.  
  65.  
  66. TypeSymbol *Semantic::ProcessNestedType(TypeSymbol *base_type, NameSymbol *name_symbol, LexStream::TokenIndex tok)
  67. {
  68.     TypeSymbol *inner_type = base_type -> FindTypeSymbol(name_symbol);
  69.     if (! inner_type)
  70.     {
  71.         int length = base_type -> ExternalNameLength() + 1 + name_symbol -> NameLength(); // +1 for $,... +1 for $
  72.         wchar_t *external_name = new wchar_t[length + 1]; // +1 for '\0';
  73.         wcscpy(external_name, base_type -> ExternalName());
  74.         wcscat(external_name, StringConstant::US__DS);
  75.         wcscat(external_name, name_symbol -> Name());
  76.         NameSymbol *external_name_symbol = control.FindOrInsertName(external_name, length);
  77.  
  78.         delete [] external_name;
  79.  
  80.         inner_type = base_type -> InsertNestedTypeSymbol(name_symbol);
  81.         inner_type -> outermost_type = base_type -> outermost_type;
  82.         inner_type -> supertypes_closure = new SymbolSet;
  83.         inner_type -> subtypes = new SymbolSet;
  84.         inner_type -> SetExternalIdentity(external_name_symbol);
  85.         inner_type -> SetOwner(base_type);
  86.         inner_type -> SetSignature(control);
  87.  
  88.         FileSymbol *file_symbol = Control::GetFile(control, base_type -> ContainingPackage(), external_name_symbol);
  89.         if (file_symbol)
  90.         {
  91.             inner_type -> file_symbol = file_symbol;
  92.             inner_type -> SetLocation();
  93.  
  94.             ReadClassFile(inner_type, tok);
  95.         }
  96.         else
  97.         {
  98.             inner_type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  99.             inner_type -> super = control.Object();
  100.             inner_type -> MarkBad();
  101.             AddDefaultConstructor(inner_type);
  102.             ReportSemError(SemanticError::TYPE_NOT_FOUND,
  103.                            tok,
  104.                            tok,
  105.                            inner_type -> ContainingPackage() -> PackageName(),
  106.                            inner_type -> ExternalName());
  107.         }
  108.     }
  109.  
  110.     return inner_type;
  111. }
  112.  
  113.  
  114. TypeSymbol *Semantic::RetrieveNestedTypes(TypeSymbol *base_type, wchar_t *signature, LexStream::TokenIndex tok)
  115. {
  116.     int len;
  117.     for (len = 0; signature[len] != U_NULL && signature[len] != U_DOLLAR; len++)
  118.         ;
  119.     NameSymbol *name_symbol = control.FindOrInsertName(signature, len);
  120.     TypeSymbol *inner_type = ProcessNestedType(base_type, name_symbol, tok);
  121.  
  122.     return (signature[len] == U_DOLLAR ? RetrieveNestedTypes(inner_type, &signature[len + 1], tok) : inner_type);
  123. }
  124.  
  125.  
  126. TypeSymbol *Semantic::ReadTypeFromSignature(TypeSymbol *base_type, const char *utf8_signature, int length, LexStream::TokenIndex tok)
  127. {
  128.     TypeSymbol *type = control.type_table.FindType(utf8_signature, length);
  129.  
  130.     if (type)
  131.     {
  132.         if (type -> SourcePending())
  133.             control.ProcessHeaders(type -> file_symbol);
  134.     }
  135.     else
  136.     {
  137.         wchar_t *signature = new wchar_t[length + 1];
  138.         (void) Control::ConvertUtf8ToUnicode(signature, utf8_signature, length);
  139.  
  140.         int total_length;
  141.         for (total_length = 0; signature[total_length] != U_NULL && signature[total_length] != U_DOLLAR; total_length++)
  142.             ;
  143.  
  144.         if (signature[total_length] != U_NULL && Code::IsDigit(signature[total_length + 1])) // an anonymous or a local type?
  145.         {
  146.             for (total_length += 2; Code::IsDigit(signature[total_length]); total_length++) // will stop at next '$' or '\0' !!!
  147.                 ;
  148.             if (signature[total_length] != U_NULL) // not an anonymous type ?  then, it's a local type: scan local name
  149.             {
  150.                 for (total_length++; signature[total_length] != U_NULL && signature[total_length] != U_DOLLAR; total_length++)
  151.                     ;
  152.             }
  153.         }
  154.  
  155.         int len;
  156.         for (len = total_length - 1; len >= 0 && signature[len] != U_SLASH; len--)
  157.             ;
  158.  
  159.         wchar_t *name = &(signature[len + 1]);
  160.  
  161.         //
  162.         // When a package name is specified in the signature, we look for the type in question
  163.         // in that package, i.e., we redefine package. Otherwise, we search for the type in the
  164.         // unnamed package.
  165.         //
  166.         PackageSymbol *package = NULL;
  167.  
  168.         //
  169.         // Which package?
  170.         //
  171.         if (len >= 0)
  172.         {
  173.             wchar_t *package_name = new wchar_t[len + 1];
  174.             for (int i = 0; i < len; i++)
  175.                 package_name[i] = signature[i];
  176.             package_name[len] = U_NULL;
  177.             package = control.ProcessPackage(package_name);
  178.  
  179.             if (package -> directory.Length() == 0)
  180.             {
  181.                 ReportSemError(SemanticError::PACKAGE_NOT_FOUND,
  182.                                tok,
  183.                                tok,
  184.                                package -> PackageName());
  185.             }
  186.             delete [] package_name;
  187.         }
  188.         else package = control.unnamed_package;
  189.  
  190.         //
  191.         // Process type
  192.         //
  193.         NameSymbol *name_symbol = control.FindOrInsertName(name, total_length - (len + 1));
  194.         type = package -> FindTypeSymbol(name_symbol);
  195.         if (type)
  196.         {
  197.             if (type -> SourcePending())
  198.                 control.ProcessHeaders(type -> file_symbol);
  199.         }
  200.         else
  201.         {
  202.             FileSymbol *file_symbol = Control::GetFile(control, package, name_symbol);
  203.  
  204.             //
  205.             // If we are dealing with the unnamed package, ...
  206.             //
  207.             if ((! file_symbol) && package == control.unnamed_package)
  208.                 file_symbol = Control::GetFile(control, control.unnamed_package, name_symbol);
  209.  
  210.             //
  211.             // If a file_symbol was not found, ReadType will issue an error message
  212.             //
  213.             type = ReadType(file_symbol, package, name_symbol, tok);
  214.  
  215.             //
  216.             // If we have to do a full check and we have a case where a ".class" file
  217.             // depends on a ".java" file then we should signal that the ".java" file
  218.             // associated with the ".class" file should be recompiled.
  219.             //
  220.             if (control.option.full_check && (! control.option.depend) &&
  221.                 file_symbol && file_symbol -> IsJava() && (! file_symbol -> IsZip()))
  222.             {
  223.                 control.recompilation_file_set.AddElement(file_symbol);
  224.                 if (! control.option.incremental && control.option.pedantic)
  225.                 {
  226.                     ReportSemError(SemanticError::RECOMPILATION,
  227.                                    tok,
  228.                                    tok,
  229.                                    base_type -> ContainingPackage() -> Name(),
  230.                                    base_type -> ExternalName(),
  231.                                    type -> ContainingPackage() -> Name(),
  232.                                    type -> ExternalName());
  233.                 }
  234.             }
  235.         }
  236.  
  237.         if (signature[total_length] == U_DOLLAR)
  238.             type = RetrieveNestedTypes(type, &signature[total_length + 1], tok);
  239.  
  240.         delete [] signature;
  241.     }
  242.  
  243.     //
  244.     // Establish a dependence from base_type (read from a class file) to type.
  245.     //
  246.     AddDependence(base_type, type, tok);
  247.  
  248.     return type;
  249. }
  250.  
  251.  
  252. TypeSymbol *Semantic::ProcessSignature(TypeSymbol *base_type, const char *signature, LexStream::TokenIndex tok)
  253. {
  254.     TypeSymbol *type;
  255.     int num_dimensions = 0;
  256.  
  257.     for (; *signature == U_LEFT_BRACKET; signature++)
  258.         num_dimensions++;
  259.  
  260.     switch(*signature)
  261.     {
  262.         case U_B:
  263.              type = control.byte_type;
  264.              break;
  265.         case U_C:
  266.              type = control.char_type;
  267.              break;
  268.         case U_D:
  269.              type = control.double_type;
  270.              break;
  271.         case U_F:
  272.              type = control.float_type;
  273.              break;
  274.         case U_I:
  275.              type = control.int_type;
  276.              break;
  277.         case U_J:
  278.              type = control.long_type;
  279.              break;
  280.         case U_L:
  281.              {
  282.                  //
  283.                  // The signature is of the form: "L<filename>;" - So, +1 to skip the 'L'
  284.                  // ReadTypeFromSignature considers a semicolon to be a terminator.
  285.                  //
  286.                  const char *str = ++signature;
  287.                  while (*str != U_SEMICOLON)
  288.                      str++;
  289.                  type = ReadTypeFromSignature(base_type, signature, str - signature, tok);
  290.              }
  291.              break;
  292.         case U_S:
  293.              type = control.short_type;
  294.              break;
  295.         case U_Z:
  296.              type = control.boolean_type;
  297.              break;
  298.         case U_V:
  299.              type = control.void_type;
  300.              break;
  301.         default:
  302.             assert(! "KNOW WHAT TO DO WITH SIGNATURE");
  303.             break;
  304.     }
  305.  
  306.     return (num_dimensions == 0 ? type : type -> GetArrayType((Semantic *)this, num_dimensions));
  307. }
  308.  
  309.  
  310. inline TypeSymbol *Semantic::GetClassPool(TypeSymbol *base_type,
  311.                                           TypeSymbol **class_pool,
  312.                                           const char **constant_pool,
  313.                                           int index,
  314.                                           LexStream::TokenIndex tok)
  315. {
  316.     if (! class_pool[index])
  317.     {
  318.         u2 name_index = Constant_Class_info::NameIndex(constant_pool[index]);
  319.         const char *str = Constant_Utf8_info::Bytes(constant_pool[name_index]);
  320.  
  321.         if (*str == U_LEFT_BRACKET)
  322.             class_pool[index] = ProcessSignature(base_type, str, tok);
  323.         else
  324.         {
  325.             u2 length = Constant_Utf8_info::Length(constant_pool[name_index]);
  326.             const char *p;
  327.             for (p = &str[length - 1]; Code::IsDigit(*p); p--)
  328.                 ;
  329.             if (*p != U_DOLLAR) // not an anonymous class
  330.                 class_pool[index] = ReadTypeFromSignature(base_type, str, length, tok);
  331.         }
  332.     }
  333.  
  334.     return class_pool[index];
  335. }
  336.  
  337.  
  338. void Semantic::ReadClassFile(TypeSymbol *type, LexStream::TokenIndex tok)
  339. {
  340. #ifdef JIKES_DEBUG
  341.     control.class_files_read++;
  342. #endif
  343.  
  344.     FileSymbol *file_symbol = type -> file_symbol;
  345.  
  346.     if (control.option.verbose)  {
  347.         Coutput << "[read "
  348.                 << file_symbol -> FileName()
  349.                 << "]\n";
  350.     }
  351.  
  352.     if (file_symbol -> IsZip())
  353.     {
  354.         ZipFile *zipfile = new ZipFile(file_symbol);
  355.  
  356.         if (zipfile -> Buffer() == NULL)
  357.         {
  358.             type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  359.             if (type != control.Object())
  360.                 type -> super = (type == control.Throwable() ? control.Object() : control.Throwable());
  361.             type -> MarkBad();
  362.             AddDefaultConstructor(type);
  363.  
  364.             ReportSemError(SemanticError::COMPRESSED_ZIP_FILE,
  365.                            tok,
  366.                            tok,
  367.                            file_symbol -> PathSym() -> Name(),
  368.                            type -> ContainingPackage() -> PackageName(),
  369.                            type -> ExternalName());
  370.         }
  371.         else if (! ProcessClassFile(type, zipfile -> Buffer(), file_symbol -> uncompressed_size, tok))
  372.             ProcessBadClass(type, tok);
  373.  
  374.         delete zipfile;
  375.     }
  376.     else
  377.     {
  378.         // Get a ReadObject from the API that contains the filew data.
  379.         JikesAPI::FileReader  *classFile   = JikesAPI::getInstance()->read(file_symbol->FileName());
  380.         if (classFile == NULL)
  381.         {
  382.             type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  383.             if (type != control.Object())
  384.                 type -> super = (type == control.Throwable() ? control.Object() : control.Throwable());
  385.             type -> MarkBad();
  386.             AddDefaultConstructor(type);
  387.  
  388.             ReportSemError(SemanticError::CANNOT_OPEN_CLASS_FILE,
  389.                            tok,
  390.                            tok,
  391.                            type -> ContainingPackage() -> PackageName(),
  392.                            type -> ExternalName());
  393.         }
  394.  
  395.         else
  396.         {
  397.             // Process the file data.
  398.             size_t   size  = classFile->getBufferSize();
  399.  
  400. #if defined(WIN32_FILE_SYSTEM)
  401.             size = ((0xFFFFFFFF && GetLastError()) != NO_ERROR) ? 0 : size;
  402. #endif
  403.             if (! ProcessClassFile(type, classFile->getBuffer(),size, tok))
  404.                 ProcessBadClass(type, tok);
  405.  
  406.             delete classFile;
  407.         }
  408.     }
  409.  
  410.     return;
  411. }
  412.  
  413.  
  414. void Semantic::ProcessBadClass(TypeSymbol *type, LexStream::TokenIndex tok)
  415. {
  416.     if (! type -> Table()) // if there is no symbol table, add one
  417.         type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  418.     if ((! type -> super) && type != control.Object()) // if there is no super type, add one
  419.         type -> super = (type == control.Throwable() ? control.Object() : control.Throwable());
  420.     type -> MarkBad();
  421.     if (! type -> FindConstructorSymbol()) // if there are no constructors, add a default one
  422.         AddDefaultConstructor(type);
  423.  
  424.     ReportSemError(SemanticError::INVALID_CLASS_FILE,
  425.                    tok,
  426.                    tok,
  427.                    type -> ContainingPackage() -> PackageName(),
  428.                    type -> ExternalName());
  429.  
  430.     return;
  431. }
  432.  
  433.  
  434. bool Semantic::ProcessClassFile(TypeSymbol *type,const char *buffer, int buffer_size, LexStream::TokenIndex tok)
  435. {
  436.     const char *buffer_tail = &buffer[buffer_size];
  437.  
  438.     type -> MarkHeaderProcessed();
  439.     type -> MarkConstructorMembersProcessed();
  440.     type -> MarkMethodMembersProcessed();
  441.     type -> MarkFieldMembersProcessed();
  442.     type -> MarkLocalClassProcessingCompleted();
  443.     type -> MarkSourceNoLongerPending();
  444.  
  445.     Skip(buffer, 8); // u4 magic;
  446.                      // u2 minor_version;
  447.                      // u2 major_version;
  448.  
  449.     if (! InRange(buffer, buffer_tail, 2))
  450.         return false;
  451.     u2 constant_pool_count = GetAndSkipU2(buffer);
  452.     const char **constant_pool = new const char*[constant_pool_count];
  453.     TypeSymbol **class_pool = (TypeSymbol **)
  454.                               memset(new TypeSymbol*[constant_pool_count], 0, constant_pool_count * sizeof(TypeSymbol *));
  455.  
  456.     constant_pool[0] = NULL;
  457.     int *next_pool_index = new int[constant_pool_count],
  458.         Class_root = 0,
  459.         NameAndType_root = 0;
  460.  
  461.     for (int i = 1; i < constant_pool_count; i++)
  462.     {
  463.         constant_pool[i] = buffer;
  464.         if (! InRange(buffer, buffer_tail, 1))
  465.             return false;
  466.         u1 tag = GetAndSkipU1(buffer);
  467.         if (tag == Cp_Info::CONSTANT_Long || tag == Cp_Info::CONSTANT_Double)
  468.             ++i; // skip the next entry for eight-byte constants
  469.  
  470.         u2 length;
  471.         switch(tag)
  472.         {
  473.             case Cp_Info::CONSTANT_Utf8:
  474.                  if (! InRange(buffer, buffer_tail, 2))
  475.                      return false;
  476.                  length = GetAndSkipU2(buffer);
  477.                  break;
  478.             case Cp_Info::CONSTANT_Class:
  479.                  length = 2;                      // set_NameIndex(GetU2(classfile));
  480.                  next_pool_index[i] = Class_root; // save index of class constant
  481.                  Class_root = i;
  482.                  break;
  483.             case Cp_Info::CONSTANT_String:
  484.                  length = 2; // set_NameIndex(GetU2(classfile));
  485.                  break;
  486.             case Cp_Info::CONSTANT_NameAndType:
  487.                  length = 4; // set_class_index(GetU2(classfile)); set_name_and_type_index(GetU2(classfile));
  488.                              //                                     or
  489.                              // set_NameIndex(GetU2(classfile)); set_DescriptorIndex(GetU2(classfile));
  490.                              //                                     or
  491.                              // SetBytes(GetU4(classfile));
  492.                  next_pool_index[i] = NameAndType_root; // save index of class constant
  493.                  NameAndType_root = i;
  494.                  break;
  495.             case Cp_Info::CONSTANT_Fieldref:
  496.             case Cp_Info::CONSTANT_Methodref:
  497.             case Cp_Info::CONSTANT_InterfaceMethodref:
  498.             case Cp_Info::CONSTANT_Integer:
  499.             case Cp_Info::CONSTANT_Float:
  500.                  length = 4; // set_class_index(GetU2(classfile)); set_name_and_type_index(GetU2(classfile));
  501.                              //                                     or
  502.                              // set_NameIndex(GetU2(classfile)); set_DescriptorIndex(GetU2(classfile));
  503.                              //                                     or
  504.                              // SetBytes(GetU4(classfile));
  505.                  break;
  506.             case Cp_Info::CONSTANT_Long:
  507.             case Cp_Info::CONSTANT_Double:
  508.                  length = 8; // set_HighBytes(GetU4(classfile));
  509.                              // set_LowBytes(GetU4(classfile));
  510.  
  511.                  break;
  512.             default:
  513. fprintf(stderr, "%s%d%s", "chaos: CODE \"", (int) tag, "\" is an invalid tag !!!\n");
  514. fflush(stderr);
  515.                  break;
  516.         }
  517.  
  518.         Skip(buffer, length);
  519.     }
  520.  
  521.     //
  522.     // We are now ready to process this class file. If type is a nested
  523.     // class, we will set its untransformed access flags properly later...
  524.     //
  525.     if (! InRange(buffer, buffer_tail, 2))
  526.         return false;
  527.     type -> SetFlags(GetAndSkipU2(buffer));
  528.  
  529.     if (! InRange(buffer, buffer_tail, 2))
  530.         return false;
  531.     u2 this_class_index = GetAndSkipU2(buffer); // The index of this class
  532.     u2 name_index = Constant_Class_info::NameIndex(constant_pool[this_class_index]);
  533.     const char *type_name = Constant_Utf8_info::Bytes(constant_pool[name_index]);
  534.     u2 type_name_length = Constant_Utf8_info::Length(constant_pool[name_index]);
  535.  
  536.     int n;
  537.     for (n = type_name_length; n >= 0 && type_name[n] != U_SLASH; n--)
  538.         ;
  539.  
  540.     bool matched_package_names;
  541.     if (type -> ContainingPackage() -> PackageNameLength() == n)
  542.     {
  543.         wchar_t *package_name = type -> ContainingPackage() -> PackageName();
  544.         int i;
  545.         for (i = 0; i < n && package_name[i] == type_name[i]; i++)
  546.             ;
  547.         matched_package_names = (i == n);
  548.     }
  549.     else matched_package_names = (n < 0 && type -> ContainingPackage() == control.unnamed_package);
  550.  
  551.     if (! matched_package_names)
  552.     {
  553.         type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
  554.         if (type != control.Object())
  555.             type -> super = (type == control.Throwable() ? control.Object() : control.Throwable());
  556.         type -> MarkBad();
  557.         AddDefaultConstructor(type);
  558.  
  559.         if (n < 0)
  560.             n = 0;
  561.         wchar_t *package_name = new wchar_t[n + 1];
  562.         for (int i = 0; i < n; i++)
  563.             package_name[i] = type_name[i];
  564.         package_name[n] = U_NULL;
  565.  
  566.         if (type -> ContainingPackage() == control.unnamed_package)
  567.              ReportSemError(SemanticError::TYPE_NOT_IN_UNNAMED_PACKAGE,
  568.                             tok,
  569.                             tok,
  570.                             type -> ExternalName(),
  571.                             type -> file_symbol -> directory_symbol -> PathSym() -> Name(),
  572.                             package_name);
  573.         else ReportSemError(SemanticError::TYPE_IN_WRONG_PACKAGE,
  574.                             tok,
  575.                             tok,
  576.                             type -> ExternalName(),
  577.                             type -> ContainingPackage() -> PackageName(),
  578.                             package_name);
  579.  
  580.         delete [] package_name;
  581.     }
  582.     else
  583.     {
  584.         if ((! type -> IsNested()) && (n < 0)) // An outermost type contained in the unnamed package?
  585.         {
  586.             TypeSymbol *old_type = (TypeSymbol *) control.unnamed_package_types.Image(type -> Identity());
  587.             if (! old_type)
  588.                 control.unnamed_package_types.AddElement(type);
  589.             else
  590.             {
  591.                 ReportSemError(SemanticError::DUPLICATE_TYPE_DECLARATION,
  592.                                tok,
  593.                                tok,
  594.                                type -> Name(),
  595.                                old_type -> FileLoc());
  596.             }
  597.         }
  598.  
  599.         //
  600.         // On systems such as NT and Win-95 that are not case-sensitive,
  601.         // we need to confirm that the type name specified matches the name
  602.         // in the class file.
  603.         //
  604.         assert(type_name_length - (n + 1) == type -> ExternalNameLength());
  605.  
  606.         int i;
  607.         for (i = 0; i < type -> ExternalNameLength(); i++)
  608.         {
  609.             if (type_name[(n + 1) + i] != type -> ExternalName()[i])
  610.                 break;
  611.         }
  612.         if (i < type -> ExternalNameLength())
  613.         {
  614.             wchar_t *name = new wchar_t[type_name_length + 1];
  615.             for (int k = 0; k < type_name_length; k++)
  616.                 name[k] = type_name[k];
  617.             name[type_name_length] = U_NULL;
  618.             ReportSemError(SemanticError::TYPE_NAME_MISMATCH,
  619.                            tok,
  620.                            tok,
  621.                            type -> ContainingPackage() -> PackageName(),
  622.                            type -> ExternalName(),
  623.                            name);
  624.             delete [] name;
  625.         }
  626.  
  627.         //
  628.         // ... Start doing real work !!!
  629.         //
  630.         if (! InRange(buffer, buffer_tail, 2))
  631.             return false;
  632.         u2 super_class = GetAndSkipU2(buffer);
  633.         if (super_class)
  634.         {
  635.             type -> super = GetClassPool(type, class_pool, constant_pool, super_class, tok);
  636.  
  637.             type -> outermost_type -> supertypes_closure -> AddElement(type -> super -> outermost_type);
  638.             type -> outermost_type -> supertypes_closure -> Union(*type -> super -> outermost_type -> supertypes_closure);
  639.         }
  640.  
  641.         if (! InRange(buffer, buffer_tail, 2))
  642.             return false;
  643.         for (int j = GetAndSkipU2(buffer); j > 0; j--)
  644.         {
  645.             if (! InRange(buffer, buffer_tail, 2))
  646.                 return false;
  647.             u2 interface_index = GetAndSkipU2(buffer);
  648.             type -> AddInterface(GetClassPool(type, class_pool, constant_pool, interface_index, tok));
  649.  
  650.             type -> outermost_type -> supertypes_closure -> AddElement(type -> super -> outermost_type);
  651.             type -> outermost_type -> supertypes_closure -> Union(*type -> super -> outermost_type -> supertypes_closure);
  652.         }
  653.  
  654.         //
  655.         // Read all the fields
  656.         //
  657.         if (! InRange(buffer, buffer_tail, 2))
  658.             return false;
  659.         u2 fields_count = GetAndSkipU2(buffer);
  660.         VariableSymbol **fields = new VariableSymbol*[fields_count];
  661.         for (int k = 0; k < fields_count; k++)
  662.         {
  663.             if (! InRange(buffer, buffer_tail, 6))
  664.                 return false;
  665.             u2 access_flags = GetAndSkipU2(buffer);
  666.             u2 name_index = GetAndSkipU2(buffer);
  667.             u2 descriptor_index = GetAndSkipU2(buffer);
  668.  
  669.             NameSymbol *name_symbol = control.ConvertUtf8ToUnicode(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  670.                                                                    Constant_Utf8_info::Length(constant_pool[name_index]));
  671.  
  672.             VariableSymbol *symbol = new VariableSymbol(name_symbol);
  673.             fields[k] = symbol;
  674.  
  675.             symbol -> SetOwner(type);
  676.             symbol -> MarkComplete();
  677.             symbol -> SetFlags(access_flags);
  678.             symbol -> SetSignatureString(Constant_Utf8_info::Bytes(constant_pool[descriptor_index]),
  679.                                          Constant_Utf8_info::Length(constant_pool[descriptor_index]));
  680.  
  681.             if (! InRange(buffer, buffer_tail, 2))
  682.                 return false;
  683.             int j = GetAndSkipU2(buffer);
  684.             for (; j > 0; j--)
  685.             {
  686.                 if (! InRange(buffer, buffer_tail, 2))
  687.                     return false;
  688.                 u2 name_index = GetAndSkipU2(buffer);
  689.  
  690.                 if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_Synthetic_length &&
  691.                     memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  692.                            StringConstant::U8S_Synthetic, StringConstant::U8S_Synthetic_length * sizeof(char)) == 0)
  693.                 {
  694.                     symbol -> MarkSynthetic();
  695.                     if (! InRange(buffer, buffer_tail, 4))
  696.                         return false;
  697.                     Skip(buffer, 4); // u4 attribute_length() { return attribute_length_; }
  698.                                      // there is no info associated with a Synthetic attribute
  699.                     break; // If the field is synthetic, remaining attributes don't matter...
  700.                 }
  701.                 else if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_Deprecated_length &&
  702.                          memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  703.                                 StringConstant::U8S_Deprecated, StringConstant::U8S_Deprecated_length * sizeof(char)) == 0)
  704.                 {
  705.                     symbol -> MarkDeprecated();
  706.                     if (! InRange(buffer, buffer_tail, 4))
  707.                         return false;
  708.                     Skip(buffer, 4); // u4 attribute_length() { return attribute_length_; }
  709.                                      // there is no info associated with a Deprecated attribute
  710.                 }
  711.                 else if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_ConstantValue_length &&
  712.                          memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  713.                                 StringConstant::U8S_ConstantValue, StringConstant::U8S_ConstantValue_length * sizeof(char)) == 0)
  714.                 {
  715.                     Skip(buffer, 4); // u4 attribute_length;
  716.                     if (! InRange(buffer, buffer_tail, 2))
  717.                         return false;
  718.                     u2 constantvalue_index = GetAndSkipU2(buffer);
  719.  
  720.                     u1 tag = Cp_Info::Tag(constant_pool[constantvalue_index]);
  721.                     if (tag == Cp_Info::CONSTANT_Integer)
  722.                     {
  723.                         int value = Constant_Integer_info::Value(constant_pool[constantvalue_index]);
  724.                         symbol -> initial_value = control.int_pool.FindOrInsert(value);
  725.                     }
  726.                     else if (tag == Cp_Info::CONSTANT_Long)
  727.                     {
  728.                         LongInt value = Constant_Long_info::Value(constant_pool[constantvalue_index]);
  729.                         symbol -> initial_value = control.long_pool.FindOrInsert(value);
  730.                     }
  731.                     else if (tag == Cp_Info::CONSTANT_Float)
  732.                     {
  733.                         IEEEfloat value = Constant_Float_info::Value(constant_pool[constantvalue_index]);
  734.                         symbol -> initial_value = control.float_pool.FindOrInsert(value);
  735.                     }
  736.                     else if (tag == Cp_Info::CONSTANT_Double)
  737.                     {
  738.                         IEEEdouble value = Constant_Double_info::Value(constant_pool[constantvalue_index]);
  739.                         symbol -> initial_value = control.double_pool.FindOrInsert(value);
  740.                     }
  741.                     else if (tag == Cp_Info::CONSTANT_String)
  742.                     {
  743.                         u2 string_index = Constant_String_info::StringIndex(constant_pool[constantvalue_index]);
  744.                         u2 length = Constant_Utf8_info::Length(constant_pool[string_index]);
  745.                         const char *value = Constant_Utf8_info::Bytes(constant_pool[string_index]);
  746.                         symbol -> initial_value = control.Utf8_pool.FindOrInsert(value, length);
  747.                     }
  748.                     else if (tag == Cp_Info::CONSTANT_Utf8)
  749.                     {
  750.                         u2 length = Constant_Utf8_info::Length(constant_pool[constantvalue_index]);
  751.                         const char *value = Constant_Utf8_info::Bytes(constant_pool[constantvalue_index]);
  752.                         symbol -> initial_value = control.Utf8_pool.FindOrInsert(value, length);
  753.                     }
  754. else
  755. {
  756. fprintf(stderr, "%s%d%s", "chaos: Constant tag \"", (int) tag, "\" is an invalid tag !!!\n");
  757. fflush(stderr);
  758. }
  759.                 }
  760.                 else
  761.                 {
  762.                     if (! InRange(buffer, buffer_tail, 4))
  763.                         return false;
  764.                     Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  765.                                                         // u1 *info; /* info[attribute_length] */
  766.                 }
  767.             }
  768.  
  769.             //
  770.             // Skip remaining attributes
  771.             //
  772.             while (--j > 0)
  773.             {
  774.                 Skip(buffer, 2);                    // u2 name_index
  775.                 if (! InRange(buffer, buffer_tail, 4))
  776.                     return false;
  777.                 Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  778.                                                     // u1 *info; /* info[attribute_length] */
  779.             }
  780.         }
  781.  
  782.         //
  783.         // Read all the methods
  784.         //
  785.         if (! InRange(buffer, buffer_tail, 2))
  786.             return false;
  787.         u2 methods_count = GetAndSkipU2(buffer);
  788.         MethodSymbol **methods = new MethodSymbol*[methods_count];
  789.         for (int l = 0; l < methods_count; l++)
  790.         {
  791.             if (! InRange(buffer, buffer_tail, 6))
  792.                 return false;
  793.             u2 access_flags = GetAndSkipU2(buffer);
  794.             u2 name_index = GetAndSkipU2(buffer);
  795.             u2 descriptor_index = GetAndSkipU2(buffer);
  796.  
  797.             NameSymbol *name_symbol = control.ConvertUtf8ToUnicode(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  798.                                                                Constant_Utf8_info::Length(constant_pool[name_index]));
  799.  
  800.             if (! InRange(buffer, buffer_tail, 2))
  801.                 return false;
  802.             int j = GetAndSkipU2(buffer); // number of attributes
  803.  
  804.             if (name_symbol == control.clinit_name_symbol)
  805.             {
  806.                 methods[l] = NULL;
  807.                 j++; // see the loop (way) below that skips the remaining attributes
  808.             }
  809.             else
  810.             {
  811.                 MethodSymbol *method = new MethodSymbol(name_symbol);
  812.                 methods[l] = method;
  813.  
  814.                 method -> SetContainingType(type);
  815.                 method -> SetFlags(access_flags);
  816.  
  817.                 const char *signature = Constant_Utf8_info::Bytes(constant_pool[descriptor_index]);
  818.                 int length = Constant_Utf8_info::Length(constant_pool[descriptor_index]);
  819.  
  820.                 method -> SetSignature(control.Utf8_pool.FindOrInsert(signature, length));
  821.  
  822.                 //
  823.                 // Read the exception that can be thrown by this method
  824.                 //
  825.                 for (; j > 0; j--)
  826.                 {
  827.                     if (! InRange(buffer, buffer_tail, 2))
  828.                         return false;
  829.                     u2 name_index = GetAndSkipU2(buffer);
  830.  
  831.                     if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_Synthetic_length &&
  832.                         memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  833.                                StringConstant::U8S_Synthetic, StringConstant::U8S_Synthetic_length * sizeof(char)) == 0)
  834.                     {
  835.                         method -> MarkSynthetic();
  836.                         if (! InRange(buffer, buffer_tail, 4))
  837.                             return false;
  838.                         Skip(buffer, 4); // u4 attribute_length() { return attribute_length_; }
  839.                                          // there is no info associated with a Synthetic attribute
  840.                         break; // If the field is synthetic, remaining attributes don't matter...
  841.                     }
  842.                     else if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_Deprecated_length &&
  843.                              memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  844.                                     StringConstant::U8S_Deprecated, StringConstant::U8S_Deprecated_length * sizeof(char)) == 0)
  845.                     {
  846.                         method -> MarkDeprecated();
  847.                         if (! InRange(buffer, buffer_tail, 4))
  848.                             return false;
  849.                         Skip(buffer, 4); // u4 attribute_length() { return attribute_length_; }
  850.                                          // there is no info associated with a Deprecated attribute
  851.                     }
  852.                     else if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_Exceptions_length &&
  853.                              memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  854.                                     StringConstant::U8S_Exceptions, StringConstant::U8S_Exceptions_length * sizeof(char)) == 0)
  855.                     {
  856.                         Skip(buffer, 4); // attribute_length = GetAndSkipU4(buffer);
  857.                         if (! InRange(buffer, buffer_tail, 2))
  858.                             return false;
  859.                         for (int k = GetAndSkipU2(buffer); k > 0; k--)
  860.                         {
  861.                             if (! InRange(buffer, buffer_tail, 2))
  862.                                 return false;
  863.                             int index = GetAndSkipU2(buffer);
  864.                             u2 name_index = Constant_Class_info::NameIndex(constant_pool[index]);
  865.                             method -> AddThrowsSignature(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  866.                                                          Constant_Utf8_info::Length(constant_pool[name_index]));
  867.                         }
  868.                     }
  869.                     else
  870.                     {
  871.                         if (! InRange(buffer, buffer_tail, 4))
  872.                             return false;
  873.                         Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  874.                                                             // u1 *info; /* info[attribute_length] */
  875.                     }
  876.                 }
  877.             }
  878.  
  879.             //
  880.             // Skip remaining attributes
  881.             //
  882.             while (--j > 0)
  883.             {
  884.                 Skip(buffer, 2);                     // u2 name_index
  885.                 if (! InRange(buffer, buffer_tail, 4))
  886.                     return false;
  887.                 Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  888.                                                     // u1 *info; /* info[attribute_length] */
  889.             }
  890.         }
  891.  
  892.         //
  893.         // Process InnerClasses attributes
  894.         //
  895.         if (! InRange(buffer, buffer_tail, 2))
  896.             return false;
  897.         u2 attributes_count = GetAndSkipU2(buffer);
  898.         Tuple<u2> inner_name_indexes(8);
  899.         for (int a = 0; a < attributes_count; a++)
  900.         {
  901.             if (! InRange(buffer, buffer_tail, 2))
  902.                 return false;
  903.             u2 name_index = GetAndSkipU2(buffer);
  904.  
  905.             if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_InnerClasses_length &&
  906.                 memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  907.                        StringConstant::U8S_InnerClasses, StringConstant::U8S_InnerClasses_length * sizeof(char)) == 0)
  908.             {
  909.                 Skip(buffer, 4); // attribute_length = GetAndSkipU4(buffer);
  910.                 if (! InRange(buffer, buffer_tail, 2))
  911.                     return false;
  912.                 for (int k = GetAndSkipU2(buffer); k > 0; k--)
  913.                 {
  914.                     if (! InRange(buffer, buffer_tail, 8))
  915.                         return false;
  916.                     u2 inner_class_info_index   = GetAndSkipU2(buffer);
  917.                     u2 outer_class_info_index   = GetAndSkipU2(buffer);
  918.                     u2 inner_name_index         = GetAndSkipU2(buffer);
  919.                     u2 inner_class_access_flags = GetAndSkipU2(buffer);
  920.  
  921.                     //
  922.                     // Recall that the untransformed access flag is the one specified
  923.                     // in the inner_class attribute. (See 1.1 document)
  924.                     //
  925.                     if (inner_class_info_index == this_class_index)
  926.                         type -> SetFlags(inner_class_access_flags);
  927.                     //
  928.                     // This guard statement is used to identify only inner classes that are
  929.                     // not anonymous classes and are immediately contained within this class.
  930.                     // Recall that an inner class may not be enclosed (directly on indirectly)
  931.                     // in another class with the same name. Therefore when outer_class_info_index
  932.                     // matches this_class_index they both refer to "this" class (that we are currently processing).
  933.                     //
  934.                     else if ((outer_class_info_index == this_class_index) &&
  935.                              (inner_class_info_index != 0) &&                  // an inner class
  936.                              (inner_name_index != 0))                          // not an anonymous class
  937.                     {
  938.                         //
  939.                         // When length is 0, the inner class in question is "this" class ?
  940.                         // the one we are currently reading ?
  941.                         //
  942.                         u2 length = Constant_Utf8_info::Length(constant_pool[inner_name_index]);
  943.                         if (length > 0)
  944.                             inner_name_indexes.Next() = inner_name_index;
  945.                     }
  946.                 }
  947.             }
  948.             else if (Constant_Utf8_info::Length(constant_pool[name_index]) == StringConstant::U8S_Deprecated_length &&
  949.                      memcmp(Constant_Utf8_info::Bytes(constant_pool[name_index]),
  950.                             StringConstant::U8S_Deprecated, StringConstant::U8S_Deprecated_length * sizeof(char)) == 0)
  951.             {
  952.                 type -> MarkDeprecated();
  953.                 if (! InRange(buffer, buffer_tail, 4))
  954.                     return false;
  955.                 Skip(buffer, 4); // u4 attribute_length() { return attribute_length_; }
  956.                                  // there is no info associated with a Deprecated attribute
  957.             }
  958.             else
  959.             {
  960.                 if (! InRange(buffer, buffer_tail, 4))
  961.                     return false;
  962.                 Skip(buffer, GetAndSkipU4(buffer)); // u4 attribute_length() { return attribute_length_; }
  963.                                                     // u1 *info; /* info[attribute_length] */
  964.             }
  965.         }
  966.  
  967.         //
  968.         // We now have enough information to make a good estimate for the size of the
  969.         // symbol table we need for this class.
  970.         //
  971.         type -> SetSymbolTable(fields_count + methods_count + inner_name_indexes.Length());
  972.  
  973.         //
  974.         //   . Read in all class files that are referenced in CONSTANT_Class
  975.         //     structures in this class file.
  976.         //
  977.         //   . Read in all class files that are referenced in CONSTANT_NameAndType
  978.         //     structures in this class file.
  979.         //
  980.         if (control.option.full_check && (control.option.unzip || (! type -> file_symbol -> IsZip())))
  981.         {
  982.             for (int h = Class_root; h != 0; h = next_pool_index[h])
  983.                 GetClassPool(type, class_pool, constant_pool, h, tok);
  984.  
  985.             for (int j = NameAndType_root; j != 0; j = next_pool_index[j])
  986.             {
  987.                 u2 descriptor_index = Constant_NameAndType_info::DescriptorIndex(constant_pool[j]);
  988.                 const char *signature = Constant_Utf8_info::Bytes(constant_pool[descriptor_index]);
  989.  
  990.                 if (! class_pool[descriptor_index])
  991.                 {
  992.                     if (*signature != U_LEFT_PARENTHESIS)  // ')' indicates a field descriptor
  993.                         class_pool[descriptor_index] = ProcessSignature(type,
  994.                                                                         Constant_Utf8_info::Bytes(constant_pool[descriptor_index]),
  995.                                                                         tok);
  996.                     else // a method descriptor
  997.                     {
  998.                         signature++; // +1 to skip initial '('
  999.                         while (*signature != U_RIGHT_PARENTHESIS)
  1000.                         {
  1001.                             const char *str;
  1002.                             for (str = signature; *str == U_LEFT_BRACKET; str++)
  1003.                                 ;
  1004.  
  1005.                             if (*str == U_L)
  1006.                             {
  1007.                                 for (str++; *str != U_SEMICOLON; str++)
  1008.                                     ;
  1009.                             }
  1010.  
  1011.                             int len = str - signature + 1;
  1012.                             signature += len; // make signature point to next type
  1013.                         }
  1014.                         signature++; // skip L')'
  1015.  
  1016.                         class_pool[descriptor_index] = ProcessSignature(type, signature, tok); // save the return type in first spot
  1017.                     }
  1018.                 }
  1019.             }
  1020.  
  1021.             //
  1022.             // Process all the fields, then the methods, then the inner types.
  1023.             // Read in all the types associated with the signatures.
  1024.             //
  1025.             for (int k = 0; k < fields_count; k++)
  1026.             {
  1027.                 type -> InsertVariableSymbol(fields[k]);
  1028.                 fields[k] -> ProcessVariableSignature((Semantic *) this, tok);
  1029.             }
  1030.  
  1031.             for (int l = 0; l < methods_count; l++)
  1032.             {
  1033.                 if (methods[l])
  1034.                 {
  1035.                     MethodSymbol *method = type -> FindMethodSymbol(methods[l] -> name_symbol);
  1036.  
  1037.                     if (! method)
  1038.                     {
  1039.                          if (methods[l] -> name_symbol == control.init_name_symbol)
  1040.                               type -> InsertConstructorSymbol(methods[l]);
  1041.                          else type -> InsertMethodSymbol(methods[l]);
  1042.                     }
  1043.                     else type -> Overload(method, methods[l]);
  1044.                     methods[l] -> ProcessMethodSignature((Semantic *) this, tok);
  1045.                 }
  1046.             }
  1047.  
  1048.             for (int m = 0; m < inner_name_indexes.Length(); m++)
  1049.             {
  1050.                 u2 inner_name_index = inner_name_indexes[m];
  1051.                 type -> AddNestedTypeSignature(Constant_Utf8_info::Bytes(constant_pool[inner_name_index]),
  1052.                                                Constant_Utf8_info::Length(constant_pool[inner_name_index]));
  1053.             }
  1054.             type -> ProcessNestedTypeSignatures((Semantic *) this, tok);
  1055.         }
  1056.         else
  1057.         {
  1058.             //
  1059.             // Process all the fields, then the methods, then the inner types.
  1060.             //
  1061.             for (int k = 0; k < fields_count; k++)
  1062.                 type -> InsertVariableSymbol(fields[k]);
  1063.  
  1064.             for (int l = 0; l < methods_count; l++)
  1065.             {
  1066.                 if (methods[l])
  1067.                 {
  1068.                     MethodSymbol *method = type -> FindMethodSymbol(methods[l] -> name_symbol);
  1069.  
  1070.                     if (! method)
  1071.                     {
  1072.                          if (methods[l] -> name_symbol == control.init_name_symbol)
  1073.                               type -> InsertConstructorSymbol(methods[l]);
  1074.                          else type -> InsertMethodSymbol(methods[l]);
  1075.                     }
  1076.                     else type -> Overload(method, methods[l]);
  1077.                 }
  1078.             }
  1079.  
  1080.             for (int m = 0; m < inner_name_indexes.Length(); m++)
  1081.             {
  1082.                 u2 inner_name_index = inner_name_indexes[m];
  1083.                 type -> AddNestedTypeSignature(Constant_Utf8_info::Bytes(constant_pool[inner_name_index]),
  1084.                                                Constant_Utf8_info::Length(constant_pool[inner_name_index]));
  1085.             }
  1086.         }
  1087.  
  1088.         delete [] fields;
  1089.         delete [] methods;
  1090.  
  1091.         //
  1092.         // Release extra space. This is an optimization.
  1093.         //
  1094.         type -> CompressSpace();
  1095.     }
  1096.  
  1097.     delete [] next_pool_index;
  1098.     delete [] class_pool;
  1099.     delete [] constant_pool;
  1100.  
  1101.     return true;
  1102. }
  1103.  
  1104. #ifdef    HAVE_JIKES_NAMESPACE
  1105. }            // Close namespace Jikes block
  1106. #endif
  1107.  
  1108.