Logo Search packages:      
Sourcecode: jikes version File versions

decl.cpp

// $Id: decl.cpp,v 1.145 2004/10/09 18:04:50 elliott-oss Exp $
//
// This software is subject to the terms of the IBM Jikes Compiler
// License Agreement available at the following URL:
// http://ibm.com/developerworks/opensource/jikes.
// Copyright (C) 1996, 2004 IBM Corporation and others.  All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
#include "platform.h"
#include "semantic.h"
#include "control.h"
#include "depend.h"
#include "table.h"
#include "tuple.h"
#include "spell.h"
#include "option.h"
#include "stream.h"

#ifdef HAVE_JIKES_NAMESPACE
namespace Jikes { // Open namespace Jikes block
#endif

//
// If this compilation unit contains a package declaration, make sure
// the package is not also associated with a type. We used to also
// require that the package exist at compile time, but this was
// changed so that we are compatible with other Java compilers.
//
inline void Semantic::CheckPackage()
{
    if (! compilation_unit -> package_declaration_opt)
        return;
    AstPackageDeclaration* package_decl =
        compilation_unit -> package_declaration_opt;
    //
    // Make sure that the package or any of its parents does not match the
    // name of a type.
    //
    for (PackageSymbol* subpackage = this_package,
             *package = subpackage -> owner;
         package; subpackage = package, package = package -> owner)
    {
        FileSymbol* file_symbol =
            Control::GetFile(control, package, subpackage -> Identity());
        if (file_symbol)
        {
            char* file_name = file_symbol -> FileName();
            int length = file_symbol -> FileNameLength();
            wchar_t* error_name = new wchar_t[length + 1];
            for (int i = 0; i < length; i++)
                error_name[i] = file_name[i];
            error_name[length] = U_NULL;

            ReportSemError(SemanticError::PACKAGE_TYPE_CONFLICT,
                           compilation_unit -> package_declaration_opt -> name,
                           package -> PackageName(), subpackage -> Name(),
                           error_name);
            delete [] error_name;
        }
    }
    // TODO: Warn about package annotations outside of package-info.java.
    ProcessPackageModifiers(package_decl);
}


//
// Pass 1: Introduce the main package, the current package and all types
// specified into their proper scope
//
void Semantic::ProcessTypeNames()
{
    import_on_demand_packages.Next() = control.LangPackage();
    compilation_unit = source_file_symbol -> compilation_unit;

    //
    // If we are supposed to be verbose, report empty declarations...
    //
    if (control.option.pedantic)
    {
        if (compilation_unit -> EmptyCompilationUnitCast())
            ReportSemError(SemanticError::NO_TYPES, compilation_unit);
        for (unsigned i = 0;
             i < compilation_unit -> NumTypeDeclarations(); i++)
        {
            AstDeclaredType* type_declaration =
                compilation_unit -> TypeDeclaration(i);
            if (type_declaration -> EmptyDeclarationCast())
            {
                ReportSemError(SemanticError::EMPTY_DECLARATION,
                               type_declaration);
            }
        }
    }

    //
    // If we have a bad compilation unit insert its types as "bad types"
    //
    if (compilation_unit -> BadCompilationUnitCast())
    {
        for (unsigned i = 0; i < lex_stream -> NumTypes(); i++)
        {
            TokenIndex identifier_token =
                lex_stream -> Next(lex_stream -> Type(i));
            NameSymbol* name_symbol =
                lex_stream -> NameSymbol(identifier_token);
            if (name_symbol)
            {
                TypeSymbol* type = this_package -> FindTypeSymbol(name_symbol);
                assert(type);

                type -> MarkBad();
                type -> MarkSourceNoLongerPending();
                type -> supertypes_closure = new SymbolSet;
                type -> subtypes = new SymbolSet;
                type -> semantic_environment =
                    new SemanticEnvironment(this, type, NULL);
                if (type != control.Object())
                    type -> super = control.no_type;
                if (! type -> FindMethodSymbol(control.init_name_symbol))
                    AddDefaultConstructor(type);
                source_file_symbol -> types.Next() = type;
            }
        }
        return;
    }

    //
    // Use this tuple to compute the list of valid types encountered in this
    // compilation unit.
    //
    Tuple<TypeSymbol*> type_list;

    //
    // Process each type in this compilation unit, in turn
    //
    for (unsigned k = 0; k < compilation_unit -> NumTypeDeclarations(); k++)
    {
        TokenIndex identifier_token = BAD_TOKEN;
        TypeSymbol* type = NULL;
        AstDeclaredType* declaration = compilation_unit -> TypeDeclaration(k);
        if (! declaration -> EmptyDeclarationCast())
        {
            identifier_token = declaration -> class_body -> identifier_token;
            NameSymbol* name_symbol =
                lex_stream -> NameSymbol(identifier_token);
            //
            // Warn against unconventional names.
            //
            if (name_symbol -> IsBadStyleForClass())
            {
                ReportSemError(SemanticError::UNCONVENTIONAL_CLASS_NAME,
                               identifier_token, name_symbol -> Name());
            }
            type = this_package -> FindTypeSymbol(name_symbol);
            // type was already created in Control::ProcessPackageDeclaration
            assert(type);
            if (! type -> SourcePending())
            {
                ReportSemError(SemanticError::DUPLICATE_TYPE_DECLARATION,
                               identifier_token, name_symbol -> Name(),
                               type -> FileLoc());
                type = NULL;
            }
            else
            {
                if (type -> ContainingPackage() == control.UnnamedPackage())
                {
                    TypeSymbol* old_type = (TypeSymbol*) control.
                        unnamed_package_types.Image(name_symbol);
                    if (old_type != type)
                    {
                        ReportSemError(SemanticError::DUPLICATE_TYPE_DECLARATION,
                                       identifier_token, name_symbol -> Name(),
                                       old_type -> FileLoc());
                    }
                }
                // Save valid type for later processing. See below.
                type_list.Next() = type;
                type -> MarkSourceNoLongerPending();
                type -> semantic_environment =
                    new SemanticEnvironment(this, type, NULL);
                type -> declaration = declaration -> class_body;
                type -> SetFlags(ProcessTopLevelTypeModifiers(declaration));
                //
                // Add 3 extra elements for padding. May need a default
                // constructor and other support elements.
                //
                type -> SetSymbolTable(declaration -> class_body ->
                                       NumClassBodyDeclarations() + 3);
                type -> SetLocation();

                if (lex_stream -> IsDeprecated(declaration -> LeftToken()))
                    type -> MarkDeprecated();
                source_file_symbol -> types.Next() = type;
                declaration -> class_body -> semantic_environment =
                    type -> semantic_environment;
                CheckNestedMembers(type, declaration -> class_body);
            }
        }

        //
        // If we successfully processed this type, check that
        //     . its name does not conflict with a subpackage
        //     . if it is contained in a file with a different name
        //       than its own name that there does not also exist a
        //       (java or class) file with its name.
        //
        if (type)
        {
            NameSymbol* name_symbol =
                lex_stream -> NameSymbol(identifier_token);
            for (unsigned i = 0; i < this_package -> directory.Length(); i++)
            {
                //
                // The unnamed package cannot contain subpackages, as
                // subpackages require a named top-level package. In other
                // words, java.lang is not a subpackage of the unnamed one.
                //
                if ((this_package -> directory[i] ->
                     FindDirectorySymbol(name_symbol)) &&
                    this_package != control.UnnamedPackage())
                {
                    char* file_name = type -> file_symbol -> FileName();
                    int length = type -> file_symbol -> FileNameLength();
                    wchar_t* error_name = new wchar_t[length + 1];
                    for (int j = 0; j < length; j++)
                        error_name[j] = file_name[j];
                    error_name[length] = U_NULL;

                    ReportSemError(SemanticError::PACKAGE_TYPE_CONFLICT,
                                   identifier_token,
                                   this_package -> PackageName(),
                                   name_symbol -> Name(), error_name);
                    delete [] error_name;
                }
            }

            if (type -> Identity() != source_file_symbol -> Identity())
            {
                PackageSymbol* package = this_package;
                FileSymbol* file_symbol =
                    Control::GetJavaFile(package, type -> Identity());

                if (file_symbol)
                {
                    ReportSemError(SemanticError::TYPE_IN_MULTIPLE_FILES,
                                   identifier_token,
                                   this_package -> PackageName(),
                                   source_file_symbol -> Name(),
                                   package -> PackageName(), type -> Name());
                }
            }
        }
    }

    CheckPackage();
    ProcessImports();

    //
    // Make sure that compilation unit contains exactly one public type, and
    // that it matches the file name.
    //
    TypeSymbol* public_type = NULL;
    for (unsigned i = 0; i < type_list.Length(); i++)
    {
        TypeSymbol* type = type_list[i];
        if (type && type -> ACC_PUBLIC())
        {
            if (! public_type)
            {
                public_type = type;
                if (source_file_symbol -> Identity() !=
                    public_type -> Identity())
                {
                    ReportSemError(SemanticError::MISMATCHED_TYPE_AND_FILE_NAMES,
                                   type -> declaration -> identifier_token,
                                   public_type -> Name());
                }
            }
            else
            {
                ReportSemError(SemanticError::MULTIPLE_PUBLIC_TYPES,
                               type -> declaration -> identifier_token,
                               type -> Name(),
                               public_type -> Name());
            }
        }
    }
}


void Semantic::CheckNestedMembers(TypeSymbol* containing_type,
                                  AstClassBody* class_body)
{
    unsigned i;
    for (i = 0; i < class_body -> NumNestedClasses(); i++)
    {
        AstClassDeclaration* decl = class_body -> NestedClass(i);
        ProcessNestedTypeName(containing_type, decl);
    }
    for (i = 0; i < class_body -> NumNestedEnums(); i++)
    {
        AstEnumDeclaration* decl = class_body -> NestedEnum(i);
        ProcessNestedTypeName(containing_type, decl);
    }
    for (i = 0; i < class_body -> NumNestedInterfaces(); i++)
    {
        AstInterfaceDeclaration* decl = class_body -> NestedInterface(i);
        ProcessNestedTypeName(containing_type, decl);
    }
    for (i = 0; i < class_body -> NumNestedAnnotations(); i++)
    {
        AstAnnotationDeclaration* decl = class_body -> NestedAnnotation(i);
        ProcessNestedTypeName(containing_type, decl);
    }
    for (i = 0; i < class_body -> NumEmptyDeclarations(); i++)
    {
        if (control.option.pedantic)
            ReportSemError(SemanticError::EMPTY_DECLARATION,
                           class_body -> EmptyDeclaration(i));
    }
}


//
// Given a type shadow symbol, returns the first accessible type, and reports
// an error for any other accessible types.
//
inline TypeSymbol* Semantic::FindTypeInShadow(TypeShadowSymbol* type_shadow_symbol,
                                              TokenIndex identifier_token)
{
    TypeSymbol* type = type_shadow_symbol -> type_symbol;
    unsigned i = 0;
    if (! TypeAccessCheck(type))
    {
        if (type_shadow_symbol -> NumConflicts())
        {
            //
            // The conflicts are necessarily accessible, because they are
            // public types inherited from interfaces.
            //
            type = type_shadow_symbol -> Conflict(0);
            i = 1;
        }
        else type = NULL;
    }
    for ( ; i < type_shadow_symbol -> NumConflicts(); i++)
    {
        ReportSemError(SemanticError::AMBIGUOUS_TYPE,
                       identifier_token, type -> Name(),
                       type -> owner -> TypeCast() -> ContainingPackageName(),
                       type -> owner -> TypeCast() -> ExternalName(),
                       type_shadow_symbol -> Conflict(i) -> owner -> TypeCast() -> ContainingPackageName(),
                       type_shadow_symbol -> Conflict(i) -> owner -> TypeCast() -> ExternalName());
    }
    return type;
}


void Semantic::CheckNestedTypeDuplication(SemanticEnvironment* env,
                                          TokenIndex identifier_token)
{
    NameSymbol* name_symbol = lex_stream -> NameSymbol(identifier_token);

    //
    // First check to see if we have a duplication at the same level...
    //
    TypeSymbol* old_type = NULL;
    if (env -> symbol_table.Size())
    {
        for (int i = env -> symbol_table.Size(); --i >= 0; )
        {
            old_type = env -> symbol_table[i] -> FindTypeSymbol(name_symbol);
            if (old_type)
                break;
        }
    }
    else old_type = env -> Type() -> FindTypeSymbol(name_symbol);
    if (old_type)
    {
        ReportSemError(SemanticError::DUPLICATE_TYPE_DECLARATION,
                       identifier_token, name_symbol -> Name(),
                       old_type -> FileLoc());
    }
    else
    {
        //
        // ... Then check the enclosing environments...
        //
        for (; env; env = env -> previous)
        {
            if (env -> Type() -> Identity() == name_symbol)
            {
                ReportSemError(SemanticError::DUPLICATE_INNER_TYPE_NAME,
                               identifier_token, name_symbol -> Name(),
                               env -> Type() -> FileLoc());
                break;
            }
        }
    }
}


TypeSymbol* Semantic::ProcessNestedTypeName(TypeSymbol* containing_type,
                                            AstDeclaredType* declaration)
{
    AstClassBody* class_body = declaration -> class_body;
    NameSymbol* name_symbol =
        lex_stream -> NameSymbol(class_body -> identifier_token);
    TypeSymbol* outermost_type = containing_type -> outermost_type;

    CheckNestedTypeDuplication(containing_type -> semantic_environment,
                               class_body -> identifier_token);
    int length = containing_type -> ExternalNameLength() + 1 +
        name_symbol -> NameLength(); // +1 for $,... +1 for $
    wchar_t* external_name = new wchar_t[length + 1]; // +1 for '\0';
    wcscpy(external_name, containing_type -> ExternalName());
    wcscat(external_name, StringConstant::US_DS);
    wcscat(external_name, name_symbol -> Name());

    TypeSymbol* inner_type =
        containing_type -> InsertNestedTypeSymbol(name_symbol);
    inner_type -> outermost_type = outermost_type;
    inner_type -> supertypes_closure = new SymbolSet;
    inner_type -> subtypes = new SymbolSet;
    inner_type -> SetExternalIdentity(control.FindOrInsertName(external_name,
                                                               length));
    inner_type -> semantic_environment =
        new SemanticEnvironment(this, inner_type,
                                containing_type -> semantic_environment);
    inner_type -> declaration = declaration -> class_body;
    inner_type -> file_symbol = source_file_symbol;
    inner_type -> SetFlags(ProcessNestedTypeModifiers(containing_type,
                                                      declaration));
    inner_type -> SetOwner(containing_type);
    //
    // Add 3 extra elements for padding. May need a default constructor and
    // other support elements.
    //
    inner_type -> SetSymbolTable(class_body -> NumClassBodyDeclarations() + 3);
    inner_type -> SetLocation();
    inner_type -> SetSignature(control);

    delete [] external_name;

    if (lex_stream -> IsDeprecated(declaration -> LeftToken()))
        inner_type -> MarkDeprecated();

    //
    // If not a top-level type, then add pointer to enclosing type.
    //
    if (! inner_type -> ACC_STATIC())
        inner_type -> InsertThis0();
    else if (containing_type -> IsInner())
    {
        ReportSemError(SemanticError::STATIC_TYPE_IN_INNER_CLASS,
                       class_body -> identifier_token, name_symbol -> Name(),
                       containing_type -> Name(),
                       containing_type -> FileLoc());
        // Change its status so we can continue compiling...
        inner_type -> ResetACC_STATIC();
    }

    if (inner_type -> IsLocal())
    {
        if (! outermost_type -> local)
            outermost_type -> local = new SymbolSet;
        outermost_type -> local -> AddElement(inner_type);
    }
    else
    {
        if (! outermost_type -> non_local)
            outermost_type -> non_local = new SymbolSet;
        outermost_type -> non_local -> AddElement(inner_type);
    }

    //
    // Warn against unconventional names.
    //
    if (name_symbol -> IsBadStyleForClass())
    {
        ReportSemError(SemanticError::UNCONVENTIONAL_CLASS_NAME,
                       class_body -> identifier_token, name_symbol -> Name());
    }

    declaration -> class_body -> semantic_environment =
        inner_type -> semantic_environment;
    CheckNestedMembers(inner_type, class_body);
    return inner_type;
}


//
// Pass 1.2: Process all import statements
//
void Semantic::ProcessImports()
{
    for (unsigned i = 0; i < compilation_unit -> NumImportDeclarations(); i++)
    {
        AstImportDeclaration* import_declaration =
            compilation_unit -> ImportDeclaration(i);
        if (import_declaration -> static_token_opt)
        {
            // TODO: Add static import support for 1.5.
            //      if (control.option.source < JikesOption::SDK1_5)
            {
                ReportSemError(SemanticError::STATIC_IMPORT_UNSUPPORTED,
                               import_declaration -> static_token_opt);
            }
        }
        if (import_declaration -> star_token_opt)
            ProcessTypeImportOnDemandDeclaration(import_declaration);
        else ProcessSingleTypeImportDeclaration(import_declaration);
    }
}


//
// Pass 2: Process "extends" and "implements" clauses associated with the
// types.
//
void Semantic::ProcessTypeHeader(AstClassDeclaration* declaration)
{
    TypeSymbol* type =
        declaration -> class_body -> semantic_environment -> Type();
    assert(! type -> HeaderProcessed() || type -> Bad());
    type -> MarkHeaderProcessed();
    if (type -> Bad())
        return;

    //
    // Special case certain classes in java.lang.  We can't use the
    // control.Classname() accessor method here, because that causes problems
    // with recursion or non-existant classes.
    //
    if (this_package == control.LangPackage() && ! type -> IsNested())
    {
        // java.lang.Object is the only class with no supertype.
        if (type -> Identity() == control.Object_name_symbol)
        {
            if (declaration -> super_opt || declaration -> NumInterfaces())
            {
                ReportSemError(SemanticError::OBJECT_WITH_SUPER_TYPE,
                               declaration -> LeftToken(),
                               declaration -> class_body -> left_brace_token - 1);
            }
            if (declaration -> type_parameters_opt)
            {
                ReportSemError(SemanticError::TYPE_MAY_NOT_HAVE_PARAMETERS,
                               declaration -> LeftToken(),
                               declaration -> class_body -> left_brace_token - 1,
                               type -> ContainingPackageName(),
                               type -> ExternalName());
            }
            type -> MarkHeaderProcessed();
            return;
        }
        //
        // java.lang.Enum didn't exist before 1.5.
        //
        else if (type -> Identity() == control.Enum_name_symbol)
            type -> MarkEnum();
    }

    if (declaration -> type_parameters_opt)
        ProcessTypeParameters(type, declaration -> type_parameters_opt);

    //
    // Process the supertypes.
    //
    if (declaration -> super_opt)
    {
        ProcessType(declaration -> super_opt);
        TypeSymbol* super_type = declaration -> super_opt -> symbol;
        assert(! super_type -> SourcePending());
        if (! super_type -> HeaderProcessed())
            super_type -> ProcessTypeHeaders();
        if (control.option.deprecation && state_stack.Size() == 0 &&
            super_type -> IsDeprecated() && ! type -> IsDeprecated())
        {
            ReportSemError(SemanticError::DEPRECATED_TYPE,
                           declaration -> super_opt,
                           super_type -> ContainingPackageName(),
                           super_type -> ExternalName());
        }
        if (super_type -> IsEnum())
        {
            ReportSemError(SemanticError::SUPER_IS_ENUM,
                           declaration -> super_opt,
                           super_type -> ContainingPackageName(),
                           super_type -> ExternalName());
        }
        else if (super_type -> ACC_INTERFACE())
        {
            ReportSemError(SemanticError::NOT_A_CLASS,
                           declaration -> super_opt,
                           super_type -> ContainingPackageName(),
                           super_type -> ExternalName());
        }
        else if (super_type -> ACC_FINAL())
        {
            ReportSemError(SemanticError::SUPER_IS_FINAL,
                           declaration -> super_opt,
                           super_type -> ContainingPackageName(),
                           super_type -> ExternalName());
        }
        else if (super_type -> Bad())
            ; // ignore
        else
        {
            super_type -> subtypes -> AddElement(type);
            type -> super = super_type;
            while (super_type)
            {
                type -> supertypes_closure -> AddElement(super_type);
                type -> supertypes_closure -> Union(*super_type ->
                                                    supertypes_closure);
                if (super_type -> owner -> TypeCast())
                    super_type = super_type -> ContainingType();
                else super_type = NULL;
            }
        }
    }
    if (! type -> super)
    {
        type -> super = control.Object();
        type -> supertypes_closure -> AddElement(control.Object());
        control.Object() -> subtypes -> AddElement(type);
    }
    AddDependence(type, type -> super);

    for (unsigned i = 0; i < declaration -> NumInterfaces(); i++)
        ProcessSuperinterface(type, declaration -> Interface(i));

    // if there is a cycle, break it and issue an error message
    if (type -> supertypes_closure -> IsElement(type))
    {
        type -> super = control.Object();
        type -> ResetInterfaces();
        type -> MarkCircular();
        ReportSemError(SemanticError::CIRCULAR_CLASS,
                       declaration -> class_body -> identifier_token,
                       declaration -> class_body -> left_brace_token - 1,
                       type -> ContainingPackageName(),
                       type -> ExternalName());
    }
    else if (declaration -> type_parameters_opt &&
             type -> IsSubclass(control.Throwable()))
    {
        ReportSemError(SemanticError::TYPE_MAY_NOT_HAVE_PARAMETERS,
                       declaration -> LeftToken(),
                       declaration -> class_body -> left_brace_token - 1,
                       type -> ContainingPackageName(),
                       type -> ExternalName());
    }
}


void Semantic::ProcessTypeHeader(AstEnumDeclaration* declaration)
{
    TypeSymbol* type =
        declaration -> class_body -> semantic_environment -> Type();
    assert(! type -> HeaderProcessed() || type -> Bad());
    type -> MarkHeaderProcessed();
    // TODO: Add enum support for 1.5.
//      if (control.option.source < JikesOption::SDK1_5)
    {
        ReportSemError(SemanticError::ENUM_TYPE_UNSUPPORTED,
                       declaration -> enum_token);
        type -> super = control.Object();
        type -> MarkBad();
    }
    if (type -> Bad())
        return;

    //
    // Process the supertypes.
    //
    type -> super = control.Enum();
    type -> supertypes_closure -> AddElement(control.Enum());
    type -> MarkEnum(); // Since ACC_ENUM is only for enum constants.
    control.Enum() -> subtypes -> AddElement(type);
    AddDependence(type, type -> super);
    for (unsigned i = 0; i < declaration -> NumInterfaces(); i++)
        ProcessSuperinterface(type, declaration -> Interface(i));
    // there will not be a cycle
    assert(! type -> supertypes_closure -> IsElement(type));
}


void Semantic::ProcessTypeHeader(AstInterfaceDeclaration* declaration)
{
    TypeSymbol* type =
        declaration -> class_body -> semantic_environment -> Type();
    assert(! type -> HeaderProcessed() || type -> Bad());
    type -> MarkHeaderProcessed();
    if (declaration -> type_parameters_opt)
        ProcessTypeParameters(type, declaration -> type_parameters_opt);

    //
    // Although interfaces do not have a superclass in source code, in
    // bytecode they are treated as subclasses of Object.
    //
    type -> super = control.Object();
    AddDependence(type, control.Object());
    for (unsigned k = 0; k < declaration -> NumInterfaces(); k++)
        ProcessSuperinterface(type, declaration -> Interface(k));

    if (type -> supertypes_closure -> IsElement(type))
    {
        //
        // Remove all the interfaces if a loop is detected.
        //
        type -> ResetInterfaces();
        type -> MarkCircular();
        ReportSemError(SemanticError::CIRCULAR_INTERFACE,
                       declaration -> class_body -> identifier_token,
                       declaration -> class_body -> left_brace_token - 1,
                       type -> ContainingPackageName(),
                       type -> ExternalName());
    }
}


void Semantic::ProcessTypeHeader(AstAnnotationDeclaration* declaration)
{
    TypeSymbol* type =
        declaration -> class_body -> semantic_environment -> Type();
    assert(! type -> HeaderProcessed() || type -> Bad());
    type -> MarkHeaderProcessed();
    // TODO: Add annotation support for 1.5.
//      if (control.option.source < JikesOption::SDK1_5)
    {
        ReportSemError(SemanticError::ANNOTATION_TYPE_UNSUPPORTED,
                       declaration -> interface_token - 1,
                       declaration -> interface_token);
        type -> MarkBad();
    }
    //
    // All annotations are treated as subclasses of Object and Annotation.
    //
    type -> super = control.Object();
    AddDependence(type, control.Object());
    type -> AddInterface(control.Annotation());
    AddDependence(type, control.Annotation());
}


void Semantic::ProcessSuperinterface(TypeSymbol* base_type, AstTypeName* name)
{
    ProcessType(name);
    TypeSymbol* interf = name -> symbol;

    assert(! interf -> SourcePending());
    if (! interf -> HeaderProcessed())
        interf -> ProcessTypeHeaders();
    if (control.option.deprecation && state_stack.Size() == 0 &&
        interf -> IsDeprecated() && ! base_type -> IsDeprecated())
    {
        ReportSemError(SemanticError::DEPRECATED_TYPE, name,
                       interf -> ContainingPackageName(),
                       interf -> ExternalName());
    }
    if (! interf -> ACC_INTERFACE())
    {
        if (! interf -> Bad())
        {
            ReportSemError(SemanticError::NOT_AN_INTERFACE, name,
                           interf -> ContainingPackageName(),
                           interf -> ExternalName());
        }
        name -> symbol = NULL;
    }
    else
    {
        for (unsigned k = 0; k < base_type -> NumInterfaces(); k++)
        {
            if (base_type -> Interface(k) == interf)
            {
                ReportSemError(SemanticError::DUPLICATE_INTERFACE, name,
                               interf -> ContainingPackageName(),
                               interf -> ExternalName(),
                               base_type -> ExternalName());
                name -> symbol = NULL;
                return;
            }
        }
        name -> symbol = interf; // save type name in ast.
        base_type -> AddInterface(interf);
        interf -> subtypes -> AddElement(base_type);
        AddDependence(base_type, interf);
        while (interf)
        {
            base_type -> supertypes_closure -> AddElement(interf);
            base_type -> supertypes_closure -> Union(*interf ->
                                                     supertypes_closure);
            if (interf -> owner -> TypeCast())
                interf = interf -> ContainingType();
            else interf = NULL;
        }
    }
}


//
// Processes the type parameters of a class or interface.
//
void Semantic::ProcessTypeParameters(TypeSymbol* /*type*/,
                                     AstTypeParameters* parameters)
{
    // TODO: Add generics support for 1.5.
    ReportSemError(SemanticError::TYPE_PARAMETERS_UNSUPPORTED, parameters);
}


//
// Process the type headers of the owner of body.  Anonymous types have no
// owner, so anon_type must be non-null only in that case.
//
TypeSymbol* Semantic::ProcessTypeHeaders(AstClassBody* body,
                                         TypeSymbol* anon_type)
{
    assert(! body -> owner ^ ! anon_type);
    SemanticEnvironment* sem = anon_type ? anon_type -> semantic_environment
        : body -> semantic_environment;
    TypeSymbol* type = anon_type ? anon_type : sem -> Type();
    if (type -> HeaderProcessed())
        return type; // Possible if a subclass was declared in the same file.
    if (anon_type)
        anon_type -> MarkHeaderProcessed();
    else if (body -> owner -> ClassDeclarationCast())
        ProcessTypeHeader((AstClassDeclaration*) body -> owner);
    else if (body -> owner -> EnumDeclarationCast())
        ProcessTypeHeader((AstEnumDeclaration*) body -> owner);
    else if (body -> owner -> InterfaceDeclarationCast())
        ProcessTypeHeader((AstInterfaceDeclaration*) body -> owner);
    else
    {
        assert(body -> owner -> AnnotationDeclarationCast());
        ProcessTypeHeader((AstAnnotationDeclaration*) body -> owner);
    }
    state_stack.Push(sem);
    unsigned i;
    for (i = 0; i < body -> NumNestedClasses(); i++)
    {
        AstClassDeclaration* nested_class = body -> NestedClass(i);
        type -> AddNestedType(ProcessTypeHeaders(nested_class -> class_body));
    }
    for (i = 0; i < body -> NumNestedEnums(); i++)
    {
        AstEnumDeclaration* nested_enum = body -> NestedEnum(i);
        type -> AddNestedType(ProcessTypeHeaders(nested_enum -> class_body));
    }
    for (i = 0; i < body -> NumNestedInterfaces(); i++)
    {
        AstInterfaceDeclaration* nested = body -> NestedInterface(i);
        type -> AddNestedType(ProcessTypeHeaders(nested -> class_body));
    }
    for (i = 0; i < body -> NumNestedAnnotations(); i++)
    {
        AstAnnotationDeclaration* nested = body -> NestedAnnotation(i);
        type -> AddNestedType(ProcessTypeHeaders(nested -> class_body));
    }
    state_stack.Pop();
    return type;
}


void Semantic::ReportTypeInaccessible(TokenIndex left_tok,
                                      TokenIndex right_tok,
                                      TypeSymbol* type)
{
    ReportSemError(SemanticError::TYPE_NOT_ACCESSIBLE, left_tok, right_tok,
                   type -> ContainingPackageName(),
                   type -> ExternalName(), type -> AccessString());
}


//
// Finds an accessible member type named identifier_token within type, or
// returns NULL. Issues an error if there are multiple ambiguous types. The
// caller is responsible for searching for inaccessible member types.
//
TypeSymbol* Semantic::FindNestedType(TypeSymbol* type,
                                     TokenIndex identifier_token)
{
    if (type == control.null_type || type -> Bad() || type -> Primitive())
    {
        return NULL;
    }

    NameSymbol* name_symbol = lex_stream -> NameSymbol(identifier_token);

    if (! type -> expanded_type_table)
        ComputeTypesClosure(type, identifier_token);
    TypeShadowSymbol* type_shadow_symbol =
        type -> expanded_type_table -> FindTypeShadowSymbol(name_symbol);

    return (type_shadow_symbol
            ? FindTypeInShadow(type_shadow_symbol, identifier_token)
            : (TypeSymbol*) NULL);
}


//
// Finds a nested type named name within the enclosing type, and establishes
// a dependence relation. This also searches for inaccessible types, and
// reports an error before returning the inaccessible type. For any other
// error, the return is control.no_type.
//
TypeSymbol* Semantic::MustFindNestedType(TypeSymbol* type, AstName* name)
{
    if (type -> Bad())
        return control.no_type;
    if (name -> base_opt && ! name -> base_opt -> symbol)
        type = MustFindNestedType(type, name -> base_opt);
    TypeSymbol* inner_type = FindNestedType(type, name -> identifier_token);
    if (! inner_type)
    {
        //
        // Before failing completely, check whether or not the user is trying
        // to access an inaccessible nested type.
        //
        NameSymbol* name_symbol =
            lex_stream -> NameSymbol(name -> identifier_token);
        for (TypeSymbol* super_type = type -> super;
             super_type && ! super_type -> Bad();
             super_type = super_type -> super)
        {
            assert(super_type -> expanded_type_table);

            TypeShadowSymbol* type_shadow_symbol = super_type ->
                expanded_type_table -> FindTypeShadowSymbol(name_symbol);
            if (type_shadow_symbol)
            {
                inner_type = FindTypeInShadow(type_shadow_symbol,
                                              name -> identifier_token);
                break;
            }
        }

        if (inner_type)
            ReportTypeInaccessible(name, inner_type);
        else inner_type = GetBadNestedType(type, name -> identifier_token);
    }
    return inner_type -> Bad() ? control.no_type : inner_type;
}


//
// Pass 3: Process all method and constructor declarations within the
// compilation unit so that any field initialization enclosed in the
// compilation unit can invoke any constructor or method within the unit.
//
inline void Semantic::ProcessConstructorMembers(AstClassBody* class_body)
{
    TypeSymbol* this_type = ThisType();
    assert(this_type -> HeaderProcessed());
    if (class_body -> NumConstructors())
    {
        for (unsigned i = 0; i < class_body -> NumConstructors(); i++)
            ProcessConstructorDeclaration(class_body -> Constructor(i));
    }
    else if (! this_type -> Anonymous() && ! this_type -> ACC_INTERFACE())
        AddDefaultConstructor(this_type);
    this_type -> MarkConstructorMembersProcessed();
}


inline void Semantic::ProcessMethodMembers(AstClassBody* class_body)
{
    assert(ThisType() -> HeaderProcessed());
    for (unsigned i = 0; i < class_body -> NumMethods(); i++)
        ProcessMethodDeclaration(class_body -> Method(i));
    ThisType() -> MarkMethodMembersProcessed();
}


inline void Semantic::ProcessFieldMembers(AstClassBody* class_body)
{
    assert(ThisType() -> HeaderProcessed());
    unsigned i;
    for (i = 0; i < class_body -> NumInstanceVariables(); i++)
        ProcessFieldDeclaration(class_body -> InstanceVariable(i));
    for (i = 0; i < class_body -> NumClassVariables(); i++)
        ProcessFieldDeclaration(class_body -> ClassVariable(i));
    ThisType() -> MarkFieldMembersProcessed();
}


void Semantic::ProcessClassBodyForEffectiveJavaChecks(AstClassBody* class_body)
{
    TypeSymbol* this_type = ThisType();
    assert(this_type -> HeaderProcessed());

    //
    // Find out about this class' constructors:
    // Does it have any non-default constructors?
    // Does it have a private constructor?
    //
    bool has_private_constructor = false;
    bool has_non_default_constructor = false;
    for (unsigned i = 0; i < class_body -> NumConstructors(); ++i)
    {
        AstConstructorDeclaration* constructor_declaration =
            class_body -> Constructor(i);
        if (! constructor_declaration -> IsValid())
            continue;
        MethodSymbol* constructor = constructor_declaration ->
            constructor_symbol;
        if (constructor -> ACC_PRIVATE())
        {
            has_private_constructor = true;
        }

        if (class_body -> default_constructor == NULL ||
            constructor != class_body -> default_constructor -> constructor_symbol)
        {
            has_non_default_constructor = true;
        }
    }

    //
    // Find out about equals and hashCode, and count how many instance methods
    // we have (the NumMethods member function returns the sum of both the
    // class and instance methods).
    //
    bool has_correct_equals_method = false;
    AstMethodDeclaration* equals_method = NULL;
    AstMethodDeclaration* hashCode_method = NULL;
    int instance_method_count = 0;

    for (unsigned i = 0; i < class_body -> NumMethods(); ++i)
    {
        AstMethodDeclaration* method_declaration = class_body -> Method(i);
        if (! method_declaration -> IsValid())
            continue;
        MethodSymbol* method = method_declaration -> method_symbol;
        if (! method -> ACC_STATIC())
        {
            ++instance_method_count;
        }
        if (! this_type -> ACC_INTERFACE() && ! method -> ACC_ABSTRACT())
        {
            //
            // Is it "boolean equals(T other)" for some type T?
            //
            if (method -> name_symbol == control.equals_name_symbol &&
                method -> Type() == control.boolean_type &&
                method -> NumFormalParameters() == 1 &&
                ! has_correct_equals_method)
            {
                equals_method = method_declaration;
                has_correct_equals_method = (method -> FormalParameter(0) ->
                                             Type() == control.Object());
            }

            //
            // Is it "int hashCode()"?
            //
            if (method -> name_symbol == control.hashCode_name_symbol &&
                method -> Type() == control.int_type &&
                method -> NumFormalParameters() == 0)
            {
                hashCode_method = method_declaration;
            }
        }
    }

    //
    // Warn about problems with equals and hashCode.
    //
    if (equals_method != NULL && ! has_correct_equals_method)
    {
        ReportSemError(SemanticError::EJ_AVOID_OVERLOADING_EQUALS,
                       equals_method -> method_declarator -> identifier_token,
                       this_type -> Name());
    }
    if (equals_method != NULL && hashCode_method == NULL)
    {
        ReportSemError(SemanticError::EJ_EQUALS_WITHOUT_HASH_CODE,
                       equals_method -> method_declarator -> identifier_token,
                       this_type -> Name());
    }
    if (equals_method == NULL && hashCode_method != NULL)
    {
        ReportSemError(SemanticError::EJ_HASH_CODE_WITHOUT_EQUALS,
                       hashCode_method -> method_declarator -> identifier_token,
                       this_type -> Name());
    }

    //
    // Warn against utility classes that don't have a private constructor.
    // Empty classes don't count. They're not very useful, but they do
    // exist. The jacks test suite uses one to check the compiler's
    // working, and Sun use them in the Swing Windows plaf, for example.
    //
    bool is_non_empty_class = (class_body -> NumClassVariables() > 0 ||
                               class_body -> NumInstanceVariables() > 0 ||
                               class_body -> NumMethods() > 0);
    bool has_instance_members = (class_body -> NumInstanceVariables() > 0 ||
                                 instance_method_count > 0);
    if (is_non_empty_class &&
        ! has_instance_members &&
        ! this_type -> ACC_INTERFACE() &&
        ! this_type -> ACC_ABSTRACT() &&
        ! this_type -> Anonymous() &&
        ! has_non_default_constructor &&
        ! has_private_constructor &&
        this_type -> super == control.Object())
    {
        ReportSemError(SemanticError::EJ_MISSING_PRIVATE_CONSTRUCTOR,
                       class_body -> identifier_token,
                       this_type -> Name());
    }

    //
    // Warn against interfaces that don't define any behavior.
    //
    if (this_type -> ACC_INTERFACE() &&
        this_type -> super == control.Object() &&
        class_body -> NumMethods() == 0)
    {
        //
        // Tag interfaces such as java.io.Serializable are okay, so we need
        // to check that there is actually something in this interface
        // before we complain about it.
        //
        int field_count = class_body -> NumClassVariables() +
                          class_body -> NumInstanceVariables();
        if (field_count != 0)
        {
            ReportSemError(SemanticError::EJ_INTERFACE_DOES_NOT_DEFINE_TYPE,
                           class_body -> identifier_token,
                           this_type -> Name());
        }
    }

    CheckForSerializationMistakes(class_body);
}


void Semantic::CheckForSerializationMistakes(AstClassBody* class_body)
{
    TypeSymbol* this_type = ThisType();

    if (! this_type -> Implements(control.Serializable()))
        return;

    if (this_type -> IsInner())
    {
        // FIXME: If the class implements the readObject and writeObject
        // methods, it should be okay. But would anyone really do that?
        ReportSemError(SemanticError::EJ_SERIALIZABLE_INNER_CLASS,
                       class_body -> identifier_token);
    }

    //
    // Warn against Serializable classes without an explicit serialVersionUID.
    //
    bool found_serialVersionUID = false;
    for (unsigned i = 0; i < class_body -> NumClassVariables(); ++i)
    {
        AstFieldDeclaration* fd = class_body -> ClassVariable(i);
        for (unsigned j = 0; j < fd -> NumVariableDeclarators(); ++j)
        {
            AstVariableDeclarator* vd = fd -> VariableDeclarator(j);
            NameSymbol* name_symbol = lex_stream -> NameSymbol(vd ->
                variable_declarator_name -> identifier_token);
            if (name_symbol == control.serialVersionUID_name_symbol)
            {
                found_serialVersionUID = true;
            }
        }
    }
    if (! found_serialVersionUID)
    {
        ReportSemError(SemanticError::MISSING_SERIAL_VERSION_UID,
                       class_body -> identifier_token);
    }
}


void Semantic::ProcessMembers(AstClassBody* class_body)
{
    state_stack.Push(class_body -> semantic_environment);
    TypeSymbol* this_type = ThisType();
    unsigned i;

    assert(! this_type -> ConstructorMembersProcessed() || this_type -> Bad());
    assert(! this_type -> MethodMembersProcessed() || this_type -> Bad());
    assert(! this_type -> FieldMembersProcessed() || this_type -> Bad());

    ProcessConstructorMembers(class_body);
    ProcessMethodMembers(class_body);
    ProcessFieldMembers(class_body);
    ProcessClassBodyForEffectiveJavaChecks(class_body);

    delete this_type -> innertypes_closure; // save some space !!!
    this_type -> innertypes_closure = NULL;

    if (this_type -> IsInner())
    {
        for (i = 0; i < class_body -> NumStaticInitializers(); i++)
        {
            ReportSemError(SemanticError::STATIC_INITIALIZER_IN_INNER_CLASS,
                           class_body -> StaticInitializer(i),
                           this_type -> Name(), this_type -> FileLoc());
        }
    }

    for (i = 0; i < this_type -> NumNestedTypes(); i++)
    {
        TypeSymbol* inner_type = this_type -> NestedType(i);
        ProcessMembers(inner_type -> declaration);
    }
    state_stack.Pop();
}


//
// Pass 4: Process the field declarations at the top level of the types
//
void Semantic::CompleteSymbolTable(AstClassBody* class_body)
{
    if (compilation_unit -> BadCompilationUnitCast())
        return;

    state_stack.Push(class_body -> semantic_environment);
    TypeSymbol* this_type = ThisType();
    TokenIndex identifier = class_body -> identifier_token;

    assert(this_type -> ConstructorMembersProcessed());
    assert(this_type -> MethodMembersProcessed());
    assert(this_type -> FieldMembersProcessed());

    if (! this_type -> expanded_method_table)
        ComputeMethodsClosure(this_type, identifier);

    if (this_type -> super && ! this_type -> Bad())
    {
        if (! this_type -> ACC_ABSTRACT())
        {
            //
            // We already checked that this class does not declare abstract
            // methods. Now see that there are no unimplemented abstract
            // methods in any of the superclasses or superinterfaces. Exploit
            // the fact that the method table is built with the first element
            // being from a superclass; all conflicts are inherited from
            // interfaces and are necessarily abstract.
            //
            ExpandedMethodTable* expanded_table =
                this_type -> expanded_method_table;
            for (unsigned i = 0;
                 i < expanded_table -> symbol_pool.Length(); i++)
            {
                MethodSymbol* method =
                    expanded_table -> symbol_pool[i] -> method_symbol;

                if (method -> ACC_ABSTRACT())
                {
                    TypeSymbol* containing_type = method -> containing_type;
                    if (containing_type != this_type)
                    {
                        if (! method -> IsTyped())
                            method -> ProcessMethodSignature(this, identifier);

                        ReportSemError(SemanticError::NON_ABSTRACT_TYPE_INHERITS_ABSTRACT_METHOD,
                                       identifier, method -> Header(),
                                       containing_type -> ContainingPackageName(),
                                       containing_type -> ExternalName(),
                                       this_type -> ContainingPackageName(),
                                       this_type -> ExternalName());
                    }
                }
            }
        }

        //
        // If any superclass of this_type is abstract and is contained in a
        // different package, check to see if its members include abstract
        // methods with default access. If so, this class must be abstract,
        // as it cannot override them. And if this class has a protected or
        // public method with a conflicting signature, then it is cannot be
        // implemented. However, this can be tricky: suppose abstract p1.A
        // declares abstract foo(), abstract p2.B extends p1.A, abstract p1.C
        // extends p2.B and implements foo(). Then, p2.B does not inherit foo()
        // and thus neither does p1.C, but p1.C DOES override foo() with a
        // valid implementation. And thus, p2.D extends p1.C may be concrete.
        //
        PackageSymbol* package = this_type -> ContainingPackage();
        for (TypeSymbol* super_type = this_type -> super;
             super_type && super_type -> ACC_ABSTRACT();
             super_type = super_type -> super)
        {
            if (super_type -> ContainingPackage() == package)
                continue;

            package = super_type -> ContainingPackage();
            ExpandedMethodTable* super_expanded_table =
                super_type -> expanded_method_table;
            for (unsigned i = 0;
                 i < super_expanded_table -> symbol_pool.Length(); i++)
            {
                MethodSymbol* method =
                    super_expanded_table -> symbol_pool[i] -> method_symbol;

                //
                // Remember that abstract methods cannot be private, and that
                // non-default methods were inherited.
                //
                if (! method -> ACC_ABSTRACT() || method -> ACC_PUBLIC() ||
                    method -> ACC_PROTECTED())
                {
                    continue;
                }
                TypeSymbol* containing_type = method -> containing_type;
                if (! method -> IsTyped())
                    method -> ProcessMethodSignature(this, identifier);

                //
                // Search all intermediate superclasses in the same package
                // as the current super_class for an override of the abstract
                // method in question. Also report any protected or public
                // methods outside super's package that cause this class
                // to be uninstantiable.
                //
                TypeSymbol* intermediate;
                MethodSymbol* method_clash = NULL;
                for (intermediate = this_type;
                     intermediate != super_type;
                     intermediate = intermediate -> super)
                {
                    MethodShadowSymbol* shadow = intermediate ->
                        expanded_method_table ->
                        FindOverloadMethodShadow(method, this, identifier);
                    if (! shadow)
                        continue;
                    if (intermediate -> ContainingPackage() != package)
                    {
                        if ((shadow -> method_symbol -> ACC_PUBLIC() ||
                             shadow -> method_symbol -> ACC_PROTECTED()) &&
                            (shadow -> method_symbol -> Type() !=
                             method -> Type()))
                        {
                            //
                            // No need to repeat the warning for subclasses of
                            // where the problem originally occurred.
                            //
                            if (method_clash == shadow -> method_symbol)
                                method_clash = NULL;
                            else method_clash = shadow -> method_symbol;
                        }
                    }
                    else if (shadow -> method_symbol -> containing_type ==
                             intermediate)
                    {
                        break;
                    }
                }

                if (intermediate == super_type &&
                    ! this_type -> ACC_ABSTRACT())
                {
                    ReportSemError((this_type -> Anonymous()
                                    ? SemanticError::ANONYMOUS_TYPE_CANNOT_OVERRIDE_DEFAULT_ABSTRACT_METHOD
                                    : SemanticError::NON_ABSTRACT_TYPE_CANNOT_OVERRIDE_DEFAULT_ABSTRACT_METHOD),
                                   identifier, method -> Header(),
                                   containing_type -> ContainingPackageName(),
                                   containing_type -> ExternalName(),
                                   this_type -> ContainingPackageName(),
                                   this_type -> ExternalName());
                }
                if (method_clash)
                {
                    TypeSymbol* base_type = method_clash -> containing_type;
                    ReportSemError(SemanticError::UNIMPLEMENTABLE_CLASS,
                                   identifier,
                                   this_type -> ContainingPackageName(),
                                   this_type -> ExternalName(),
                                   method_clash -> Header(),
                                   base_type -> ContainingPackageName(),
                                   base_type -> ExternalName(),
                                   method -> Header(),
                                   containing_type -> ContainingPackageName(),
                                   containing_type -> ExternalName());
                }
            }
        }
    }

    //
    // Compute the set of final variables declared by the user in this type.
    // Then process all variable initializers and initializer blocks.
    //
    DefiniteSetup();
    ProcessStaticInitializers(class_body);
    ProcessInstanceInitializers(class_body);

    //
    // Reset the this_variable and this_method may have been set in
    // ProcessStaticInitializers and/or ProcessInstanceInitializers.
    // Indicate that there is no method being currently compiled
    // in this environment.
    //
    ThisVariable() = NULL;
    ThisMethod() = NULL;

    //
    // Recursively process all inner types
    //
    for (unsigned l = 0; l < this_type -> NumNestedTypes(); l++)
    {
        TypeSymbol* inner_type = this_type -> NestedType(l);
        CompleteSymbolTable(inner_type -> declaration);
    }
    state_stack.Pop();
}


//
// Pass 5: Free up unneeded space.
//
void Semantic::CleanUp()
{
    if (control.option.nocleanup)
        return;

    for (unsigned i = 0; i < compilation_unit -> NumTypeDeclarations(); i++)
    {
        AstDeclaredType* type_declaration =
            compilation_unit -> TypeDeclaration(i);
        if (type_declaration -> class_body &&
            type_declaration -> class_body -> semantic_environment)
        {
            CleanUpType(type_declaration -> class_body ->
                        semantic_environment -> Type());
        }
    }
}


void Semantic::CleanUpType(TypeSymbol* type)
{
    type -> DeleteAnonymousTypes();
    for (unsigned i = 0; i < type -> NumNestedTypes(); i++)
        CleanUpType(type -> NestedType(i));

    type -> CompressSpace(); // space optimization

    for (unsigned j = 0; j < type -> NumMethodSymbols(); j++)
        type -> MethodSym(j) -> CleanUp();

    delete type -> local;

    type -> local = NULL;

    delete type -> non_local;
    type -> non_local = NULL;

    delete type -> semantic_environment;
    type -> semantic_environment = NULL;

    type -> declaration = NULL;
}


TypeSymbol* Semantic::ReadType(FileSymbol* file_symbol, PackageSymbol* package,
                               NameSymbol* name_symbol, TokenIndex tok)
{
    TypeSymbol* type;

    if (file_symbol && file_symbol -> IsJava())
    {
        if (! file_symbol -> semantic)
            control.ProcessHeaders(file_symbol);
        type = package -> FindTypeSymbol(name_symbol);
        if (! type)
        {
            type = package -> InsertOuterTypeSymbol(name_symbol);
            type -> MarkBad();
            type -> outermost_type = type;
            type -> supertypes_closure = new SymbolSet;
            type -> subtypes = new SymbolSet;
            type -> semantic_environment =
                new SemanticEnvironment(this, type, NULL);
            if (type != control.Object())
                type -> super = (type == control.Throwable()
                                 ? control.Object() : control.Throwable());
            type -> SetOwner(package);
            type -> SetSignature(control);
            AddDefaultConstructor(type);
            type -> file_symbol = file_symbol;
            file_symbol -> types.Next() = type;

            ReportSemError(SemanticError::TYPE_NOT_FOUND, tok,
                           type -> ContainingPackageName(),
                           type -> ExternalName());
        }
        else if (file_symbol -> semantic -> NumErrors())
        {
            ReportSemError(SemanticError::INVALID_TYPE_FOUND, tok,
                           name_symbol -> Name());
        }
    }
    else if (file_symbol)
    {
        // Read class file.
        type = package -> InsertOuterTypeSymbol(name_symbol);
        type -> outermost_type = type;
        type -> supertypes_closure = new SymbolSet;
        type -> subtypes = new SymbolSet;
        type -> SetOwner(package);
        type -> SetSignature(control);
        type -> file_symbol = file_symbol;
        type -> SetLocation();

        file_symbol -> package = package;
        file_symbol -> types.Next() = type;

        ReadClassFile(type, tok);
        assert (! type -> IsNested());
        control.input_class_file_set.AddElement(file_symbol);
    }
    else
    {
        //
        // No file found. See if a package by the same name exists, otherwise
        // create a placeholder type to avoid errors when the type name is
        // subsequently used.
        //
        PackageSymbol* subpackage = package -> FindPackageSymbol(name_symbol);
        if (! subpackage)
            subpackage = package -> InsertPackageSymbol(name_symbol);
        control.FindPathsToDirectory(subpackage);
        if (subpackage -> directory.Length())
        {
            if (package -> directory.Length())
                ReportSemError(SemanticError::PACKAGE_NOT_TYPE, tok,
                               subpackage -> PackageName());
            type = control.no_type;
        }
        else
        {
            type = package -> InsertOuterTypeSymbol(name_symbol);
            type -> outermost_type = type;
            type -> SetOwner(package);
            type -> SetSignature(control);
            control.ProcessBadType(type);
            type -> MarkBad();
            ReportSemError(SemanticError::TYPE_NOT_FOUND, tok,
                           type -> ContainingPackageName(),
                           type -> ExternalName());
        }
    }
    return type;
}


TypeSymbol* Semantic::GetBadNestedType(TypeSymbol* type,
                                       TokenIndex identifier_token)
{
    NameSymbol* name_symbol = lex_stream -> NameSymbol(identifier_token);

    TypeSymbol* outermost_type = type -> outermost_type;
    if (! outermost_type -> non_local)
        outermost_type -> non_local = new SymbolSet;
    if (! outermost_type -> local)
        outermost_type -> local = new SymbolSet;

    int length = type -> ExternalNameLength() + 1 +
        name_symbol -> NameLength(); // +1 for $,... +1 for $
    wchar_t* external_name = new wchar_t[length + 1]; // +1 for '\0';
    wcscpy(external_name, type -> ExternalName());
    wcscat(external_name, StringConstant::US_DS);
    wcscat(external_name, name_symbol -> Name());

    TypeSymbol* inner_type = type -> InsertNestedTypeSymbol(name_symbol);
    inner_type -> MarkBad();
    inner_type -> outermost_type = type -> outermost_type;
    inner_type -> supertypes_closure = new SymbolSet;
    inner_type -> subtypes = new SymbolSet;
    inner_type -> SetExternalIdentity(control.FindOrInsertName(external_name,
                                                               length));
    inner_type -> super = control.Object();
    inner_type -> SetOwner(type);
    if (! type -> Bad())
        ReportSemError(SemanticError::TYPE_NOT_FOUND, identifier_token,
                       inner_type -> ContainingPackageName(),
                       inner_type -> ExternalName());

    delete [] external_name;

    return inner_type;
}


void Semantic::ProcessImportQualifiedName(AstName* name)
{
    if (name -> base_opt)
    {
        ProcessImportQualifiedName(name -> base_opt);
        Symbol* symbol = name -> base_opt -> symbol;

        TypeSymbol* type = symbol -> TypeCast();
        NameSymbol* name_symbol =
            lex_stream -> NameSymbol(name -> identifier_token);
        if (type) // The base name is a type
        {
            if (type -> Bad()) // Avoid chain-reaction errors.
            {
                name -> symbol = control.no_type;
                return;
            }
            if (! type -> expanded_type_table)
                ComputeTypesClosure(type, name -> identifier_token);
            TypeSymbol* inner_type = NULL;
            TypeShadowSymbol* type_shadow_symbol = type ->
                expanded_type_table -> FindTypeShadowSymbol(name_symbol);
            //
            // Only canonical names may be used in import statements, so we
            // don't worry about ambiguous names (which are necessarily
            // inherited and hence non-canonical). But we do need an extra
            // filter on the containing type being correct.
            //
            if (type_shadow_symbol)
                inner_type = type_shadow_symbol -> type_symbol;
            if (! inner_type)
                inner_type = control.no_type;
            else if (type != inner_type -> owner)
            {
                ReportSemError(SemanticError::IMPORT_NOT_CANONICAL,
                               name, name_symbol -> Name(),
                               inner_type -> ContainingPackageName(),
                               inner_type -> ExternalName());
            }
            else if (inner_type -> ACC_PRIVATE() ||
                     (! inner_type -> ACC_PUBLIC() &&
                      inner_type -> ContainingPackage() != this_package))
            {
                ReportTypeInaccessible(name, inner_type);
            }
            name -> symbol = inner_type;
        }
        else
        {
            PackageSymbol* package = symbol -> PackageCast();
            type = package -> FindTypeSymbol(name_symbol);
            if (! type)
            {
                FileSymbol* file_symbol =
                    Control::GetFile(control, package, name_symbol);
                if (file_symbol)
                    type = ReadType(file_symbol, package, name_symbol,
                                    name -> identifier_token);
            }
            else if (type -> SourcePending())
                control.ProcessHeaders(type -> file_symbol);

            //
            // If the field_access was resolved to a type, save it later use.
            // Otherwise, assume the field_access is a package name.
            //
            if (type)
            {
                if (! type -> ACC_PUBLIC() &&
                    type -> ContainingPackage() != this_package)
                {
                    ReportTypeInaccessible(name, type);
                }
                name -> symbol = type;
            }
            else
            {
                PackageSymbol* subpackage =
                    package -> FindPackageSymbol(name_symbol);
                if (! subpackage)
                    subpackage = package -> InsertPackageSymbol(name_symbol);
                control.FindPathsToDirectory(subpackage);
                name -> symbol = subpackage;
            }
        }
    }
    else // unqualified name
    {
        //
        // JLS 6.3 The leading simple name of a type import must be a package
        // name, as class names are not in scope. JLS 7.5: Nested classes of
        // all sorts (top-level or inner) can be imported by either kind of
        // import statement. Class names in import statements must be the
        // canonical version.
        //
        TypeSymbol* type = FindSimpleNameType(control.UnnamedPackage(),
                                              name -> identifier_token);

        //
        // If the name is a type, detect the error. Otherwise, assume
        // it is a package, and legal.
        //
        if (type)
        {
            ReportSemError(SemanticError::IMPORT_FROM_UNNAMED_PACKAGE,
                           name -> identifier_token,
                           lex_stream -> NameString(name -> identifier_token));
            name -> symbol = control.no_type;
        }
        else
        {
            NameSymbol* name_symbol =
                lex_stream -> NameSymbol(name -> identifier_token);
            PackageSymbol* package =
                control.external_table.FindPackageSymbol(name_symbol);
            if (! package)
                package = control.external_table.
                    InsertPackageSymbol(name_symbol, NULL);
            control.FindPathsToDirectory(package);
            name -> symbol = package;
        }
    }
}


//
// Processes a package-or-type name. If an accessible type exists, it is
// chosen. Next, if a package exists, it is chosen. Then, an error is issued,
// but a check for an inaccessible type is made before inventing a package.
// The result is stored in name->symbol.
//
void Semantic::ProcessPackageOrType(AstName* name)
{
    if (name -> base_opt)
    {
        ProcessPackageOrType(name -> base_opt);
        Symbol* symbol = name -> base_opt -> symbol;

        TypeSymbol* type = symbol -> TypeCast();
        if (type) // The base name is a type
            name -> symbol = MustFindNestedType(type, name);
        else
        {
            // Base name is package. Search for type, then subpackage.
            PackageSymbol* package = symbol -> PackageCast();
            NameSymbol* name_symbol =
                lex_stream -> NameSymbol(name -> identifier_token);
            type = package -> FindTypeSymbol(name_symbol);
            if (! type)
            {
                FileSymbol* file_symbol =
                    Control::GetFile(control, package, name_symbol);
                if (file_symbol)
                    type = ReadType(file_symbol, package, name_symbol,
                                    name -> identifier_token);
            }
            else if (type -> SourcePending())
                control.ProcessHeaders(type -> file_symbol);

            //
            // If the field access was resolved into a type, then save it.
            // Otherwise, assume it is a package
            //
            if (type)
                // save the resolved type of this expression for later use...
                name -> symbol = type;
            else
            {
                NameSymbol* name_symbol =
                    lex_stream -> NameSymbol(name -> identifier_token);
                PackageSymbol* subpackage =
                    package -> FindPackageSymbol(name_symbol);
                if (! subpackage)
                    subpackage = package -> InsertPackageSymbol(name_symbol);
                control.FindPathsToDirectory(subpackage);
                name -> symbol = subpackage;
                if (subpackage -> directory.Length() == 0)
                {
                    ReportSemError(SemanticError::PACKAGE_NOT_FOUND,
                                   name -> identifier_token,
                                   subpackage -> PackageName());
                }
            }
        }
    }
    else // unqualified name
    {
        TypeSymbol* type = FindType(name -> identifier_token);
        if (type)
            name -> symbol = type;
        else
        {
            NameSymbol* name_symbol =
                lex_stream -> NameSymbol(name -> identifier_token);
            PackageSymbol* package =
                control.external_table.FindPackageSymbol(name_symbol);
            if (! package)
                package = control.external_table.
                    InsertPackageSymbol(name_symbol, NULL);
            control.FindPathsToDirectory(package);
            if (package -> directory.Length() == 0)
            {
                //
                // If there is no package, see if the user is trying to access
                // an inaccessible nested type before giving up.
                //
                if (state_stack.Size())
                {
                    NameSymbol* name_symbol = lex_stream ->
                        NameSymbol(name -> identifier_token);
                    for (TypeSymbol* super_type = ThisType() -> super;
                         super_type; super_type = super_type -> super)
                    {
                        assert(super_type -> expanded_type_table);

                        TypeShadowSymbol* type_shadow_symbol =
                            super_type -> expanded_type_table ->
                            FindTypeShadowSymbol(name_symbol);
                        if (type_shadow_symbol)
                        {
                            type = type_shadow_symbol -> type_symbol;
                            break;
                        }
                    }
                }
                if (type)
                {
                    ReportTypeInaccessible(name, type);
                    name -> symbol = type;
                }
                else
                {
                    ReportSemError(SemanticError::PACKAGE_NOT_FOUND,
                                   name -> identifier_token,
                                   package -> PackageName());
                    name -> symbol = package;
                }
            }
            else name -> symbol = package;
        }
    }
}


void Semantic::ProcessTypeImportOnDemandDeclaration(AstImportDeclaration* import_declaration)
{
    ProcessImportQualifiedName(import_declaration -> name);
    Symbol* symbol = import_declaration -> name -> symbol;

    PackageSymbol* package = symbol -> PackageCast();
    if (package && package -> directory.Length() == 0)
    {
        ReportSemError(SemanticError::PACKAGE_NOT_FOUND,
                       import_declaration -> name,
                       package -> PackageName());
    }

    //
    // Two or more type-import-on-demand may name the same package; the effect
    // is as if there were only one such declaration. Likewise, importing the
    // current package or java.lang.* is ok, although useless.
    // TODO: In pedantic mode, warn about duplicate imports of the same
    // package, of the current package, or of java.lang.*.
    //
    if (symbol == this_package)
        return;
    for (unsigned i = 0; i < import_on_demand_packages.Length(); i++)
    {
        if (symbol == import_on_demand_packages[i])
            return;
    }

    import_on_demand_packages.Next() = symbol;

    TypeSymbol* type = symbol -> TypeCast();
    if (control.option.deprecation && type &&
        type -> IsDeprecated() && type -> file_symbol != source_file_symbol)
    {
        ReportSemError(SemanticError::DEPRECATED_TYPE,
                       import_declaration -> name,
                       type -> ContainingPackageName(),
                       type -> ExternalName());
    }
}


TypeSymbol* Semantic::FindSimpleNameType(PackageSymbol* package,
                                         TokenIndex identifier_token)
{
    NameSymbol* name_symbol = lex_stream -> NameSymbol(identifier_token);
    TypeSymbol* type = package -> FindTypeSymbol(name_symbol);
    if (type)
    {
        if (type -> SourcePending())
            control.ProcessHeaders(type -> file_symbol);
    }
    else
    {
        //
        // Check whether or not the type was declared in another compilation
        // unit in the main package.
        //
        FileSymbol* file_symbol = Control::GetFile(control, package,
                                                   name_symbol);
        if (file_symbol)
            type = ReadType(file_symbol, package, name_symbol,
                            identifier_token);
    }

    return type;
}

void Semantic::ProcessSingleTypeImportDeclaration(AstImportDeclaration* import_declaration)
{
    ProcessImportQualifiedName(import_declaration -> name);
    Symbol* symbol = import_declaration -> name -> symbol;
    PackageSymbol* package = symbol -> PackageCast();
    TypeSymbol* type = symbol -> TypeCast();

    //
    // Technically, the JLS grammar forbids "import foo;". However, our
    // grammar parses it, and will either find or create the package foo, so
    // we can give a better message than "expected '.'". If a non-type is
    // imported, we create a place-holder type so that the use of the
    // unqualified type name won't cause cascading errors elsewhere.
    //
    if (package)
    {
        ReportSemError(SemanticError::UNKNOWN_ON_DEMAND_IMPORT,
                       import_declaration -> name,
                       package -> PackageName());
        NameSymbol* name_symbol = lex_stream ->
            NameSymbol(import_declaration -> name -> RightToken());
        type = package -> InsertOuterTypeSymbol(name_symbol);
        type -> MarkBad();
        type -> super = control.no_type;
        type -> outermost_type = control.no_type;
    }

    //
    // If two single-type-import declarations in the same compilation unit
    // attempt to import types with the same simple name, then a compile-time
    // error occurs, unless the two types are the same type, in which case the
    // duplicate declaration is ignored.
    // TODO: Give pedantic warnings about duplicate type declarations.
    //
    for (unsigned i = 0; i < single_type_imports.Length(); i++)
    {
        if (type == single_type_imports[i])
            return;
    }

    TypeSymbol* old_type = NULL;
    unsigned k;
    for (k = 0; k < compilation_unit -> NumTypeDeclarations(); k++)
    {
        AstDeclaredType* declaration = compilation_unit -> TypeDeclaration(k);
        if (declaration -> class_body &&
            declaration -> class_body -> semantic_environment)
        {
            old_type =
                declaration -> class_body -> semantic_environment -> Type();
            if (old_type -> Identity() == type -> Identity())
                break;
        }
    }

    if (k < compilation_unit -> NumTypeDeclarations())
    {
        AstName* name = import_declaration -> name;
        package = name -> base_opt
            ? name -> base_opt -> symbol -> PackageCast()
            : control.UnnamedPackage();

        //
        // It's ok to import a type that is being compiled...
        //
        if (type == old_type && package == this_package)
        {
            ReportSemError(SemanticError::UNNECESSARY_TYPE_IMPORT, name,
                           lex_stream -> NameString(name -> identifier_token),
                           old_type -> FileLoc());
        }
        else
        {
            ReportSemError(SemanticError::DUPLICATE_IMPORT_NAME, name,
                           lex_stream -> NameString(name -> identifier_token),
                           old_type -> FileLoc());
        }
    }
    else
    {
        unsigned i = 0;
        for (i = 0; i < compilation_unit -> NumImportDeclarations(); i++)
        {
            TypeSymbol* other_type =
                compilation_unit -> ImportDeclaration(i) -> name -> Type();
            if (compilation_unit -> ImportDeclaration(i) == import_declaration ||
                (other_type && other_type -> Identity() == type -> Identity()))
            {
                break;
            }
        }

        assert(i < compilation_unit -> NumImportDeclarations());

        if (compilation_unit -> ImportDeclaration(i) == import_declaration)
        {
            // No duplicate found
            import_declaration -> name -> symbol = type;
            single_type_imports.Next() = type;
        }
        else
        {
            AstName* name = compilation_unit -> ImportDeclaration(i) -> name;
            FileLocation file_location(lex_stream, name -> identifier_token);
            ReportSemError(SemanticError::DUPLICATE_IMPORT_NAME, name,
                           lex_stream -> NameString(name -> identifier_token),
                           file_location.location);
        }
    }

    if (control.option.deprecation && type -> IsDeprecated() &&
        type -> file_symbol != source_file_symbol)
    {
        ReportSemError(SemanticError::DEPRECATED_TYPE,
                       import_declaration -> name,
                       type -> ContainingPackageName(),
                       type -> ExternalName());
    }
}


void Semantic::ProcessFieldDeclaration(AstFieldDeclaration* field_declaration)
{
    TypeSymbol* this_type = ThisType();
    AccessFlags access_flags = this_type -> ACC_INTERFACE()
        ? ProcessInterfaceFieldModifiers(field_declaration)
        : ProcessFieldModifiers(field_declaration);

    //
    // JLS2 8.1.2 - Inner classes may not have static fields unless they are
    // final and initialized by a constant.  Hence, the type of the static
    // field may only be a primitive or String.  Here, we check that the
    // entire declaration is final, then that each variableDeclarator is
    // of the right type and is initialized.  Later, when processing the
    // initializer, we check that it is indeed a compile-time constant
    // (see init.cpp, Semantic::ProcessVariableInitializer)
    //
    bool must_be_constant = false;
    if (this_type -> IsInner() && access_flags.ACC_STATIC())
    {
        if (access_flags.ACC_FINAL())
            must_be_constant = true;
        else
        {
            assert(field_declaration -> modifiers_opt &&
                   field_declaration -> modifiers_opt -> static_token_opt);
            ReportSemError(SemanticError::STATIC_FIELD_IN_INNER_CLASS_NOT_FINAL,
                           field_declaration -> modifiers_opt -> static_token_opt,
                           this_type -> Name(),
                           this_type -> FileLoc());
        }
    }

    //
    // To avoid deprecated type warnings when processing a deprecated field
    // declaration, we must temporarily mark this type as deprecated, because
    // the field variable symbol(s) do not yet exist.
    //
    bool deprecated_declarations =
        lex_stream -> IsDeprecated(field_declaration -> LeftToken());
    bool deprecated_type = this_type -> IsDeprecated();
    if (deprecated_declarations)
        this_type -> MarkDeprecated();
    ProcessType(field_declaration -> type);
    TypeSymbol* field_type = field_declaration -> type -> symbol;
    if (! deprecated_type && deprecated_declarations)
        this_type -> ResetDeprecated();

    for (unsigned i = 0;
         i < field_declaration -> NumVariableDeclarators(); i++)
    {
        AstVariableDeclarator* variable_declarator =
            field_declaration -> VariableDeclarator(i);
        AstVariableDeclaratorId* name =
            variable_declarator -> variable_declarator_name;
        NameSymbol* name_symbol =
            lex_stream -> NameSymbol(name -> identifier_token);

        if (this_type -> FindVariableSymbol(name_symbol))
        {
            ReportSemError(SemanticError::DUPLICATE_FIELD,
                           name -> identifier_token, name_symbol -> Name(),
                           this_type -> Name(),
                           this_type -> FindVariableSymbol(name_symbol) -> FileLoc());
        }
        else
        {
            if (name_symbol != control.serialVersionUID_name_symbol)
            {
                WarnOfAccessibleFieldWithName(SemanticError::HIDDEN_FIELD,
                                              name, name_symbol, access_flags.ACC_STATIC());
            }

            VariableSymbol* variable =
                this_type -> InsertVariableSymbol(name_symbol);
            unsigned dims =
                field_type -> num_dimensions + name -> NumBrackets();
            variable -> SetType(field_type -> GetArrayType(this, dims));
            variable -> SetFlags(access_flags);
            variable -> SetOwner(this_type);
            variable -> declarator = variable_declarator;
            if (must_be_constant &&
                (dims || ! variable_declarator -> variable_initializer_opt ||
                 (! field_type -> Primitive() &&
                  field_type != control.String())))
            {
                ReportSemError(SemanticError::STATIC_FIELD_IN_INNER_CLASS_NOT_CONSTANT,
                               name -> identifier_token, name_symbol -> Name(),
                               this_type -> Name(), this_type -> FileLoc());
            }
            variable_declarator -> symbol = variable;
            variable -> SetLocation();
            if (deprecated_declarations)
                variable -> MarkDeprecated();
        }

        CheckFieldDeclaration(field_declaration, name, access_flags);
    }
}


void Semantic::CheckFieldDeclaration(AstFieldDeclaration* field_declaration,
                                     AstVariableDeclaratorId* name,
                                     const AccessFlags& access_flags)
{
    TypeSymbol* field_type = field_declaration -> type -> symbol;
    NameSymbol* name_symbol = lex_stream ->
        NameSymbol(name -> identifier_token);

    //
    // Warn against public static final array fields.
    //
    bool is_constant_field = (access_flags.ACC_FINAL() &&
                              access_flags.ACC_STATIC());
    if (access_flags.ACC_PUBLIC() &&
        is_constant_field &&
        field_type -> IsArray())
    {
        // FIXME: shouldn't warn if it's a zero-length array.
        ReportSemError(SemanticError::EJ_PUBLIC_STATIC_FINAL_ARRAY_FIELD,
                       name, name_symbol -> Name());
    }

    if (name_symbol == control.serialVersionUID_name_symbol)
    {
        //
        // Warn about serialVersionUID mistakes.
        //
        TypeSymbol* this_type = ThisType();
        bool is_serializable = this_type -> Implements(control.Serializable());
        if (! is_serializable)
        {
            ReportSemError(SemanticError::UNNEEDED_SERIAL_VERSION_UID,
                           name);
        }
        else if (field_type != control.long_type ||
                 is_constant_field == false ||
                 access_flags.ACC_PUBLIC() ||
                 access_flags.ACC_PROTECTED())
        {
            ReportSemError(SemanticError::BAD_SERIAL_VERSION_UID,
                           field_declaration);
        }
    }
    else if (name_symbol == control.serialPersistentFields_name_symbol)
    {
        //
        // FIXME: Warn about serialPersistentFields mistakes; has anyone
        // ever seen this used in the wild?
        //
    }
    else
    {
        //
        // Warn against unconventional field names. This doesn't apply to
        // the serialization fields above, because their names are mandated
        // names that break conventions, and aren't likely to be fixed.
        //
        CheckFieldName(name, name_symbol, is_constant_field);
    }
}


void Semantic::CheckFieldName(AstVariableDeclaratorId* name,
                              NameSymbol* name_symbol,
                              bool is_constant_field)
{
    if (is_constant_field &&
        name_symbol -> IsBadStyleForConstantField())
    {
        ReportSemError(SemanticError::UNCONVENTIONAL_CONSTANT_FIELD_NAME,
                       name -> identifier_token, name_symbol -> Name());
    }
    else if (! is_constant_field &&
             name_symbol -> IsBadStyleForField())
    {
        ReportSemError(SemanticError::UNCONVENTIONAL_FIELD_NAME,
                       name -> identifier_token, name_symbol -> Name());
    }
}


void Semantic::ProcessConstructorDeclaration(AstConstructorDeclaration* constructor_declaration)
{
    TypeSymbol* this_type = ThisType();

    AccessFlags access_flags =
        ProcessConstructorModifiers(constructor_declaration);
    if (this_type -> ACC_STRICTFP())
        access_flags.SetACC_STRICTFP();

    if (constructor_declaration -> type_parameters_opt)
    {
        // TODO: Add generics support for 1.5.
        ReportSemError(SemanticError::TYPE_PARAMETERS_UNSUPPORTED,
                       constructor_declaration -> type_parameters_opt);
    }

    AstMethodDeclarator* constructor_declarator =
        constructor_declaration -> constructor_declarator;
    const wchar_t* constructor_name =
        lex_stream -> NameString(constructor_declarator -> identifier_token);

    //
    // A bad name indicates either a misspelling, or a method missing
    // a return type.  In an anonymous class, assume a missing return
    // type.  In all other classes, if the probability of misspelling
    // >= 50%, correct the name, otherwise treat it as a method with
    // bad return type.
    //
    bool treat_as_method = false;
    if (this_type -> Anonymous())
    {
        ReportSemError(SemanticError::CONSTRUCTOR_FOUND_IN_ANONYMOUS_CLASS,
                       constructor_declarator, constructor_name);
        treat_as_method = true;
    }
    else if (lex_stream -> NameSymbol(constructor_declarator -> identifier_token) != this_type -> Identity())
    {
        if (Spell::Index(constructor_name, this_type -> Name()) >= 5)
        {
            ReportSemError(SemanticError::MISSPELLED_CONSTRUCTOR_NAME,
                           constructor_declarator -> identifier_token,
                           constructor_name, this_type -> Name());
            constructor_name = this_type -> Name(); // correct the name
        }
        else
        {
            ReportSemError(SemanticError::MISMATCHED_CONSTRUCTOR_NAME,
                           constructor_declarator -> identifier_token,
                           constructor_name, this_type -> Name());
            treat_as_method = true;
        }
    }

    //
    // As the body of the constructor may not have been parsed yet, we estimate
    // a size for its symbol table based on the number of lines in the body + a
    // margin for one-liners.
    //
    BlockSymbol* block_symbol =
        new BlockSymbol(constructor_declarator -> NumFormalParameters() + 3);
    // All types need a spot for "this".
    block_symbol -> max_variable_index = 1;

    ProcessFormalParameters(block_symbol, constructor_declarator);

    //
    // Note that constructors are always named "<init>", but if this is a
    // method with missing return type, we use the method name.
    //
    NameSymbol* name_symbol = treat_as_method
        ? lex_stream -> NameSymbol(constructor_declarator -> identifier_token)
        : control.init_name_symbol;
    MethodSymbol* constructor = this_type -> FindMethodSymbol(name_symbol);
    if (constructor && this_type -> FindOverloadMethod(constructor,
                                                       constructor_declarator))
    {
        ReportSemError(SemanticError::DUPLICATE_CONSTRUCTOR,
                       constructor_declarator, this_type -> Name(),
                       constructor -> FileLoc());
        delete block_symbol;
        return;
    }

    constructor = this_type -> InsertMethodSymbol(name_symbol);
    TypeSymbol* ctor_type = this_type;
    if (treat_as_method)
        ctor_type = control.no_type;
    constructor -> SetType(ctor_type);
    constructor -> SetFlags(access_flags);
    constructor -> SetContainingType(this_type);
    constructor -> SetBlockSymbol(block_symbol);
    constructor -> declaration = constructor_declaration;
    constructor -> SetLocation();
    if (this_type -> EnclosingType())
    {
        VariableSymbol* this0_variable =
            block_symbol -> InsertVariableSymbol(control.this_name_symbol);
        this0_variable -> SetType(this_type -> ContainingType());
        this0_variable -> SetOwner(constructor);
        this0_variable -> SetLocalVariableIndex(block_symbol ->
                                                max_variable_index++);
        this0_variable -> MarkComplete();
        this0_variable -> SetACC_SYNTHETIC();
    }

    for (unsigned i = 0;
         i < constructor_declarator -> NumFormalParameters(); i++)
    {
        AstVariableDeclarator* formal_declarator =
            constructor_declarator -> FormalParameter(i) -> formal_declarator;
        VariableSymbol* symbol = formal_declarator -> symbol;

        symbol -> SetOwner(constructor);
        symbol -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
        symbol -> MarkComplete();
        if (control.IsDoubleWordType(symbol -> Type()))
            block_symbol -> max_variable_index++;
        symbol -> declarator = formal_declarator;
        symbol -> SetLocation();
        constructor -> AddFormalParameter(symbol);
    }
    constructor -> SetSignature(control);

    for (unsigned k = 0; k < constructor_declaration -> NumThrows(); k++)
    {
        AstTypeName* throw_expr = constructor_declaration -> Throw(k);
        ProcessType(throw_expr);
        constructor -> AddThrows(throw_expr -> symbol);
    }

    // save for processing bodies later.
    constructor_declaration -> constructor_symbol = constructor;

    if (lex_stream -> IsDeprecated(constructor_declaration -> LeftToken()))
        constructor -> MarkDeprecated();
}


void Semantic::AddDefaultConstructor(TypeSymbol* type)
{
    assert(! type -> ACC_INTERFACE());
    MethodSymbol* constructor =
        type -> InsertMethodSymbol(control.init_name_symbol);

    BlockSymbol* block_symbol = new BlockSymbol(1);
    block_symbol -> max_variable_index = 1; // All types need a spot for "this"

    constructor -> SetType(type);
    constructor -> SetContainingType(type);
    constructor -> SetBlockSymbol(block_symbol);
    if (type -> ACC_PUBLIC())
        constructor -> SetACC_PUBLIC();
    else if (type -> ACC_PROTECTED())
        constructor -> SetACC_PROTECTED();
    else if (type -> ACC_PRIVATE())
        constructor -> SetACC_PRIVATE();

    if (type -> ACC_STRICTFP())
        constructor -> SetACC_STRICTFP();

    if (type -> EnclosingType())
    {
        VariableSymbol* this0_variable =
            block_symbol -> InsertVariableSymbol(control.this_name_symbol);
        this0_variable -> SetType(type -> ContainingType());
        this0_variable -> SetOwner(constructor);
        this0_variable -> SetLocalVariableIndex(block_symbol ->
                                                max_variable_index++);
        this0_variable -> MarkComplete();
        this0_variable -> SetACC_SYNTHETIC();
    }
    constructor -> SetSignature(control);

    AstClassBody* class_body = type -> declaration;
    if (class_body)
    {
        TokenIndex left_loc = class_body -> identifier_token;
        TokenIndex right_loc = class_body -> left_brace_token - 1;

        AstMethodDeclarator* method_declarator =
            compilation_unit -> ast_pool -> GenMethodDeclarator();
        method_declarator -> identifier_token = left_loc;
        method_declarator -> left_parenthesis_token = left_loc;
        method_declarator -> right_parenthesis_token = right_loc;

        AstSuperCall* super_call = NULL;
        if (type != control.Object())
        {
            super_call = compilation_unit -> ast_pool -> GenSuperCall();
            super_call -> super_token = left_loc;
            super_call -> arguments = compilation_unit -> ast_pool ->
                GenArguments(left_loc, right_loc);
            super_call -> semicolon_token = right_loc;
        }

        AstReturnStatement* return_statement =
            compilation_unit -> ast_pool -> GenReturnStatement();
        return_statement -> return_token = left_loc;
        return_statement -> semicolon_token = left_loc;
        return_statement -> is_reachable = true;

        AstMethodBody* constructor_block =
            compilation_unit -> ast_pool -> GenMethodBody();
        // This symbol table will be empty.
        constructor_block -> block_symbol = new BlockSymbol(0);
        constructor_block -> left_brace_token  = left_loc;
        constructor_block -> right_brace_token = right_loc;
        constructor_block -> AllocateStatements(1);
        constructor_block -> AddStatement(return_statement);
        constructor_block -> explicit_constructor_opt = super_call;

        AstConstructorDeclaration* constructor_declaration =
            compilation_unit -> ast_pool -> GenConstructorDeclaration();
        constructor_declaration -> constructor_declarator = method_declarator;
        constructor_declaration -> constructor_body = constructor_block;

        constructor_declaration -> constructor_symbol = constructor;
        constructor -> declaration = constructor_declaration;
        class_body -> default_constructor = constructor_declaration;
    }
}


//
// This is called by AddInheritedMethods in two conditions: First, method
// belongs to base_type, so it must successfully override hidden_method,
// including a compatible throws clause. Second, method belongs to a supertype
// of base_type, in which case base_type is inheriting two declarations, one
// of which is necessarily abstract. If one is non-abstract, it must
// successfully override the abstract version, including the throws clause;
// but if both are abstract the throws clauses are inconsequential. It is
// possible that both method and hidden_method were declared in the same
// class, and inherited through two paths, in which case we do nothing.
// See JLS 8.4.6.4, and 9.4.1.
//
void Semantic::CheckMethodOverride(MethodSymbol* method,
                                   MethodSymbol* hidden_method,
                                   TypeSymbol* base_type)
{
    assert(! hidden_method -> ACC_PRIVATE());

    //
    // If we inherit the same method from multiple paths (including methods
    // of Object via interfaces), we already know the result.
    //
    if (hidden_method == method ||
        (method -> containing_type -> ACC_INTERFACE() &&
         method -> containing_type != base_type &&
         hidden_method -> containing_type == control.Object()))
    {
        return;
    }

    TokenIndex left_tok;
    TokenIndex right_tok;

    if (method -> containing_type == base_type && ThisType() == base_type)
    {
        AstMethodDeclaration* method_declaration =
            (AstMethodDeclaration*) method -> declaration;
        assert(method_declaration);
        AstMethodDeclarator* method_declarator =
            method_declaration -> method_declarator;

        left_tok = method_declarator -> LeftToken();
        right_tok = method_declarator -> RightToken();
    }
    else
    {
        left_tok = ThisType() -> declaration -> identifier_token;
        right_tok = ThisType() -> declaration -> left_brace_token - 1;
    }

    //
    // Return types must match.
    //
    if (hidden_method -> Type() != method -> Type())
    {
        //
        // We support covariant return types when loading from .class files,
        // even though this is not strictly legal in JLS2 (according to binary
        // compatibility, changing the return type need not be supported).
        // This is done in anticipation of JDK 1.5, when covariance is likely
        // to be introduced. The resultant effect is that the subclass must
        // conform to the narrower return type. Note that we currently only
        // support Object->Object covariance (and not primitive->primitive,
        // void->primitive, or void->Object). When loading from .java files,
        // however, we enforce exact return type matching.
        //
        if (hidden_method -> Type() -> IsSubtype(control.Object()) &&
            method -> Type() -> IsSubtype(hidden_method -> Type()))
        {
            // Silent acceptance for .class files only.
            // They must work, because the 1.5 library is covariant,
            // even for -source 1.4!
            if (control.option.source < JikesOption::SDK1_5 &&
                ! hidden_method -> containing_type ->
                  file_symbol -> IsClassOnly())
            {
                ReportSemError(SemanticError::COVARIANCE_UNSUPPORTED,
                               left_tok, right_tok, method -> Header(),
                               hidden_method -> Header());
            }
        }
        else if (method -> containing_type == base_type)
        {
            if (base_type -> ACC_INTERFACE() &&
                hidden_method -> containing_type == control.Object())
            {
                //
                // TODO: Review this when JLS3 is published.  See Sun bug
                // 4479715, which explains our current stance of allowing
                // int clone() throws MyException; or Object finalize();.
                //
                if (hidden_method -> ACC_PUBLIC())
                {
                    ReportSemError(SemanticError::MISMATCHED_IMPLICIT_METHOD,
                                   left_tok, right_tok, method -> Header(),
                                   hidden_method -> Header());
                    base_type -> MarkBad();
                }
                else
                {
                    ReportSemError(SemanticError::UNIMPLEMENTABLE_INTERFACE,
                                   left_tok, right_tok,
                                   base_type -> ContainingPackageName(),
                                   base_type -> ExternalName(),
                                   method -> Header(),
                                   hidden_method -> Header());
                }
            }
            else
            {
                ReportSemError(SemanticError::MISMATCHED_INHERITED_METHOD,
                               left_tok, right_tok, method -> Header(),
                               hidden_method -> Header(),
                               hidden_method -> containing_type -> ContainingPackageName(),
                               hidden_method -> containing_type -> ExternalName());
                base_type -> MarkBad();
            }
        }
        else
        {
            ReportSemError(SemanticError::MISMATCHED_INHERITED_METHOD_EXTERNALLY,
                           left_tok, right_tok, base_type -> ExternalName(),
                           method -> Header(),
                           method -> containing_type -> ContainingPackageName(),
                           method -> containing_type -> ExternalName(),
                           hidden_method -> Header(),
                           hidden_method -> containing_type -> ContainingPackageName(),
                           hidden_method -> containing_type -> ExternalName());
            base_type -> MarkBad();
        }
    }


    //
    // If base_type declared method, hidden_method must not be final. On the
    // other hand, if a type inherits a final method from a superclass and
    // an abstract method from an interface, it is legal.
    //
    if (method -> containing_type == base_type &&
        (hidden_method -> ACC_FINAL() ||
         hidden_method -> containing_type -> ACC_FINAL()))
    {
        if (base_type -> ACC_INTERFACE())
        {
            ReportSemError(SemanticError::FINAL_IMPLICIT_METHOD_OVERRIDE,
                           left_tok, right_tok, method -> Header(),
                           hidden_method -> Header());
        }
        else
        {
            ReportSemError(SemanticError::FINAL_METHOD_OVERRIDE,
                           left_tok, right_tok, method -> Header(),
                           hidden_method -> Header(),
                           hidden_method -> containing_type -> ContainingPackageName(),
                           hidden_method -> containing_type -> ExternalName());
        }
        base_type -> MarkBad();
    }

    //
    // Warn if a method we have source for is overriding a deprecated method.
    //
    if (control.option.deprecation &&
        hidden_method -> IsDeprecated() &&
        ! method -> containing_type -> file_symbol -> IsClassOnly() &&
        ! method -> IsDeprecated() &&
        ! InDeprecatedContext())
    {
        ReportSemError(SemanticError::DEPRECATED_METHOD_OVERRIDE,
                       left_tok, right_tok, method -> Header(),
                       hidden_method -> containing_type -> ContainingPackageName(),
                       hidden_method -> containing_type -> ExternalName());
    }

    //
    // Both or neither versions must be static.
    //
    if (method -> ACC_STATIC() != hidden_method -> ACC_STATIC())
    {
        if (method -> containing_type == base_type)
        {
            ReportSemError((method -> ACC_STATIC()
                            ? SemanticError::INSTANCE_METHOD_OVERRIDE
                            : SemanticError::CLASS_METHOD_OVERRIDE),
                           left_tok, right_tok, method -> Header(),
                           hidden_method -> Header(),
                           hidden_method -> containing_type -> ContainingPackageName(),
                           hidden_method -> containing_type -> ExternalName());
        }
        else
        {
            assert(method -> ACC_STATIC());
            ReportSemError(SemanticError::INSTANCE_METHOD_OVERRIDE_EXTERNALLY,
                           left_tok, right_tok, base_type -> ExternalName(),
                           method -> Header(),
                           method -> containing_type -> ContainingPackageName(),
                           method -> containing_type -> ExternalName(),
                           hidden_method -> Header(),
                           hidden_method -> containing_type -> ContainingPackageName(),
                           hidden_method -> containing_type -> ExternalName());
        }
        base_type -> MarkBad();
    }

    //
    // An overriding method cannot be less accessible. On the other hand, it
    // is legal to inherit two abstract methods when one is not public.
    //
    if (hidden_method -> ACC_PUBLIC())
    {
        if (! method -> ACC_PUBLIC())
        {
            if (method -> containing_type == base_type)
            {
                ReportSemError(SemanticError::BAD_ACCESS_METHOD_OVERRIDE,
                               left_tok, right_tok, method -> Header(),
                               method -> AccessString(),
                               hidden_method -> Header(),
                               StringConstant::US_public,
                               hidden_method -> containing_type -> ContainingPackageName(),
                               hidden_method -> containing_type -> ExternalName());
                base_type -> MarkBad();
            }
            else if (! method -> ACC_ABSTRACT())
            {
                ReportSemError(SemanticError::BAD_ACCESS_METHOD_OVERRIDE_EXTERNALLY,
                               left_tok, right_tok,
                               base_type -> ExternalName(),
                               method -> Header(),
                               method -> AccessString(),
                               method -> containing_type -> ContainingPackageName(),
                               method -> containing_type -> ExternalName(),
                               hidden_method -> Header(),
                               StringConstant::US_public,
                               hidden_method -> containing_type -> ContainingPackageName(),
                               hidden_method -> containing_type -> ExternalName());
                base_type -> MarkBad();
            }
        }
    }
    else if (hidden_method -> ACC_PROTECTED())
    {
        if (! method -> ACC_PROTECTED() &&
            ! method -> ACC_PUBLIC())
        {
            ReportSemError(SemanticError::BAD_ACCESS_METHOD_OVERRIDE,
                           left_tok, right_tok, method -> Header(),
                           method -> AccessString(),
                           hidden_method -> Header(),
                           StringConstant::US_protected,
                           hidden_method -> containing_type -> ContainingPackageName(),
                           hidden_method -> containing_type -> ExternalName());
            base_type -> MarkBad();
        }
    }
    else if (method -> ACC_PRIVATE())
    {
        ReportSemError(SemanticError::BAD_ACCESS_METHOD_OVERRIDE,
                       left_tok, right_tok, method -> Header(),
                       StringConstant::US_private,
                       hidden_method -> Header(),
                       StringConstant::US_default,
                       hidden_method -> containing_type -> ContainingPackageName(),
                       hidden_method -> containing_type -> ExternalName());
        base_type -> MarkBad();
    }

    //
    // Check the throws clause, unless base_type is inheriting two abstract
    // methods.
    //
    if (method -> containing_type != base_type && method -> ACC_ABSTRACT())
        return;

    method -> ProcessMethodThrows(this, left_tok);
    hidden_method -> ProcessMethodThrows(this, left_tok);

    for (int i = method -> NumThrows() - 1; i >= 0; i--)
    {
        TypeSymbol* exception = method -> Throws(i);

        if (! CheckedException(exception))
            continue;

        int k;
        for (k = hidden_method -> NumThrows() - 1; k >= 0; k--)
        {
            if (exception -> IsSubclass(hidden_method -> Throws(k)))
                break;
        }

        if (k < 0)
        {
            if (method -> containing_type == base_type)
            {
                if (base_type -> ACC_INTERFACE() &&
                    hidden_method -> containing_type == control.Object())
                {
                    //
                    // TODO: Review this when JLS3 is published.  See Sun bug
                    // 4479715, which explains our current stance of allowing
                    // int clone() throws MyException; or Object finalize();.
                    //
                    if (hidden_method -> ACC_PUBLIC())
                    {
                        ReportSemError(SemanticError::MISMATCHED_IMPLICIT_OVERRIDDEN_EXCEPTION,
                                       left_tok, right_tok,
                                       exception -> Name(),
                                       method -> Header());
                        base_type -> MarkBad();
                    }
                }
                else
                {
                    ReportSemError(SemanticError::MISMATCHED_OVERRIDDEN_EXCEPTION,
                                   left_tok, right_tok,
                                   exception -> Name(),
                                   hidden_method -> Header(),
                                   hidden_method -> containing_type -> ContainingPackageName(),
                                   hidden_method -> containing_type -> ExternalName());
                    base_type -> MarkBad();
                }
            }
            else
            {
                ReportSemError(SemanticError::MISMATCHED_OVERRIDDEN_EXCEPTION_EXTERNALLY,
                               left_tok, right_tok,
                               base_type -> ExternalName(),
                               exception -> Name(), method -> Header(),
                               method -> containing_type -> ContainingPackageName(),
                               method -> containing_type -> ExternalName(),
                               hidden_method -> Header(),
                               hidden_method -> containing_type -> ContainingPackageName(),
                               hidden_method -> containing_type -> ExternalName());
                base_type -> MarkBad();
            }
        }
    }
}


void Semantic::AddInheritedTypes(TypeSymbol* base_type, TypeSymbol* super_type)
{
    if (super_type -> Bad())
    {
        base_type -> MarkBad();
        return;
    }

    ExpandedTypeTable& base_expanded_table =
        *(base_type -> expanded_type_table);
    ExpandedTypeTable& super_expanded_table =
        *(super_type -> expanded_type_table);

    for (unsigned i = 0; i < super_expanded_table.symbol_pool.Length(); i++)
    {
        TypeShadowSymbol* type_shadow_symbol =
            super_expanded_table.symbol_pool[i];
        TypeSymbol* type = type_shadow_symbol -> type_symbol;

        //
        // Note that since all types in an interface are implicitly public,
        // all other types encountered here are enclosed in a type that is a
        // super class of base_type.
        //
        if (type -> ACC_PUBLIC() ||
            type -> ACC_PROTECTED() ||
            (! type -> ACC_PRIVATE() &&
             super_type -> ContainingPackage() == base_type -> ContainingPackage()))
        {
            TypeShadowSymbol* shadow =
                base_expanded_table.FindTypeShadowSymbol(type -> Identity());

            if (! shadow || shadow -> type_symbol -> owner != base_type)
            {
                if (! shadow)
                    shadow = base_expanded_table.InsertTypeShadowSymbol(type);
                else shadow -> AddConflict(type);

                assert(type -> owner != super_type ||
                       type_shadow_symbol -> NumConflicts() == 0);
                for (unsigned j = 0;
                     j < type_shadow_symbol -> NumConflicts(); j++)
                {
                    shadow -> AddConflict(type_shadow_symbol -> Conflict(j));
                }
            }
        }
        //
        // The main type was not accessible. But it may have been inherited
        // from yet another class, in which case any conflicts (which are
        // necessarily public types from interfaces) are still inherited in
        // the base_type.
        //
        else if (! type -> ACC_PRIVATE() &&
                 type_shadow_symbol -> NumConflicts())
        {
            assert(type -> owner != super_type);
            TypeShadowSymbol* shadow =
                base_expanded_table.FindTypeShadowSymbol(type -> Identity());

            if (shadow)
                assert(shadow -> type_symbol -> owner == base_type);
            else
            {
                shadow = base_expanded_table.
                    InsertTypeShadowSymbol(type_shadow_symbol -> Conflict(0));
                for (unsigned k = 1;
                     k < type_shadow_symbol -> NumConflicts(); k++)
                {
                    shadow -> AddConflict(type_shadow_symbol -> Conflict(k));
                }
            }
        }
    }
}


void Semantic::AddInheritedFields(TypeSymbol* base_type,
                                  TypeSymbol* super_type)
{
    if (super_type -> Bad())
    {
        base_type -> MarkBad();
        return;
    }

    ExpandedFieldTable& base_expanded_table =
        *(base_type -> expanded_field_table);
    ExpandedFieldTable& super_expanded_table =
        *(super_type -> expanded_field_table);

    for (unsigned i = 0; i < super_expanded_table.symbol_pool.Length(); i++)
    {
        VariableShadowSymbol* variable_shadow_symbol =
            super_expanded_table.symbol_pool[i];
        VariableSymbol* variable = variable_shadow_symbol -> variable_symbol;
        //
        // Note that since all fields in an interface are implicitly public,
        // all other fields encountered here are enclosed in a type that is a
        // super class of base_type.
        //
        if (variable -> ACC_PUBLIC() ||
            variable -> ACC_PROTECTED() ||
            (! variable -> ACC_PRIVATE() &&
             super_type -> ContainingPackage() == base_type -> ContainingPackage()))
        {
            VariableShadowSymbol* shadow = base_expanded_table.
                FindVariableShadowSymbol(variable -> Identity());

            if (! shadow || shadow -> variable_symbol -> owner != base_type)
            {
                if (! shadow)
                    shadow = base_expanded_table.
                        InsertVariableShadowSymbol(variable);
                else shadow -> AddConflict(variable);

                assert(variable -> owner != super_type ||
                       variable_shadow_symbol -> NumConflicts() == 0);
                for (unsigned j = 0;
                     j < variable_shadow_symbol -> NumConflicts(); j++)
                {
                    shadow -> AddConflict(variable_shadow_symbol ->
                                          Conflict(j));
                }
            }
        }
        //
        // The main field was not accessible. But it may have been inherited
        // from yet another class, in which case any conflicts (which are
        // necessarily public fields from interfaces) are still inherited in
        // the base_type.
        //
        else if (! variable -> ACC_PRIVATE() &&
                 ! variable -> ACC_SYNTHETIC() &&
                 variable_shadow_symbol -> NumConflicts())
        {
            assert(variable -> owner != super_type);
            VariableShadowSymbol* shadow = base_expanded_table.
                FindVariableShadowSymbol(variable -> Identity());

            if (shadow)
                assert(shadow -> variable_symbol -> owner == base_type);
            else
            {
                shadow = base_expanded_table.
                    InsertVariableShadowSymbol(variable_shadow_symbol ->
                                               Conflict(0));

                for (unsigned k = 1;
                     k < variable_shadow_symbol -> NumConflicts(); k++)
                {
                    shadow -> AddConflict(variable_shadow_symbol ->
                                          Conflict(k));
                }
            }
        }
    }
}


void Semantic::AddInheritedMethods(TypeSymbol* base_type,
                                   TypeSymbol* super_type, TokenIndex tok)
{
    if (super_type -> Bad())
    {
        base_type -> MarkBad();
        return;
    }

    ExpandedMethodTable* base_expanded_table =
        base_type -> expanded_method_table;
    ExpandedMethodTable* super_expanded_table =
        super_type -> expanded_method_table;
    PackageSymbol* base_package = base_type -> ContainingPackage();
    unsigned i;

    for (i = 0; i < super_expanded_table -> symbol_pool.Length(); i++)
    {
        MethodShadowSymbol* method_shadow_symbol =
            super_expanded_table -> symbol_pool[i];
        MethodSymbol* method = method_shadow_symbol -> method_symbol;

        //
        // We have to special case interfaces, since they implicitly declare
        // the public methods of Object. In ComputeMethodsClosure, we add all
        // methods from Object after adding those from interfaces. Also, since
        // user code cannot invoke synthetic methods, we ignore those.
        //
        if ((base_type -> ACC_INTERFACE() &&
             super_type -> ACC_INTERFACE() &&
             method -> containing_type == control.Object()) ||
            method -> ACC_SYNTHETIC())
        {
            continue;
        }

        //
        // Note that since all methods in an interface are implicitly
        // public, all other methods encountered here are enclosed in a
        // type that is a super class of base_type.
        //
        if (method -> ACC_PUBLIC() || method -> ACC_PROTECTED() ||
            (! method -> ACC_PRIVATE() &&
             super_type -> ContainingPackage() == base_package))
        {
            //
            // Check that method is compatible with every method it
            // overrides.
            //
            MethodShadowSymbol* shadow = base_expanded_table ->
                FindOverloadMethodShadow(method, this, tok);
            if (shadow)
            {
                CheckMethodOverride(shadow -> method_symbol, method,
                                    base_type);
                for (unsigned m = 0;
                     m < method_shadow_symbol -> NumConflicts(); m++)
                {
                    CheckMethodOverride(shadow -> method_symbol,
                                        method_shadow_symbol -> Conflict(m),
                                        base_type);
                }
            }

            if (! shadow ||
                shadow -> method_symbol -> containing_type != base_type)
            {
                if (! shadow)
                    shadow = base_expanded_table -> Overload(method);
                else shadow -> AddConflict(method);

                assert(method -> containing_type != super_type ||
                       method_shadow_symbol -> NumConflicts() == 0);
                for (unsigned j = 0;
                     j < method_shadow_symbol -> NumConflicts(); j++)
                {
                    shadow -> AddConflict(method_shadow_symbol -> Conflict(j));
                }
            }
        }
        //
        // The main method was not accessible. But it may have been inherited
        // from yet another class, in which case any conflicts (which are
        // necessarily public methods from interfaces) are still inherited in
        // the base_type.
        //
        else if (! method -> ACC_PRIVATE())
        {
            MethodShadowSymbol* shadow = base_expanded_table ->
                FindOverloadMethodShadow(method, this, tok);
            if (method_shadow_symbol -> NumConflicts())
            {
                assert(method -> containing_type != super_type);

                if (shadow)
                {
                    assert(shadow -> method_symbol -> containing_type == base_type);
                    for (unsigned k = 0;
                         k < method_shadow_symbol -> NumConflicts(); k++)
                    {
                        CheckMethodOverride(shadow -> method_symbol,
                                            method_shadow_symbol -> Conflict(k),
                                            base_type);
                    }
                }
                else
                {
                    shadow = base_expanded_table ->
                        Overload(method_shadow_symbol -> Conflict(0));

                    for (unsigned l = 1;
                         l < method_shadow_symbol -> NumConflicts(); l++)
                    {
                        shadow -> AddConflict(method_shadow_symbol ->
                                              Conflict(l));
                    }
                }
            }
            else if (shadow && control.option.pedantic)
            {
                //
                // The base_type declares a method by the same name as a
                // method in the superclass, but the new method does not
                // override or hide the old. Warn the user about this fact,
                // although it is usually not an error.
                //
                assert(shadow -> method_symbol -> containing_type ==
                       base_type);
                TokenIndex left_tok;
                TokenIndex right_tok;

                if (ThisType() == base_type)
                {
                    AstMethodDeclaration* method_declaration =
                        (AstMethodDeclaration*) shadow -> method_symbol -> declaration;
                    AstMethodDeclarator* method_declarator =
                        method_declaration -> method_declarator;

                    left_tok = method_declarator -> LeftToken();
                    right_tok = method_declarator -> RightToken();
                }
                else
                {
                    left_tok = ThisType() -> declaration -> identifier_token;
                    right_tok =
                        ThisType() -> declaration -> right_brace_token - 1;
                }

                if (! method -> IsTyped())
                    method -> ProcessMethodSignature(this, tok);

                //
                // We filter here, because CompleteSymbolTable gives a
                // different warning for unimplementable abstract classes.
                //
                if (! method -> ACC_ABSTRACT() ||
                    method -> Type() == shadow -> method_symbol -> Type() ||
                    (! shadow -> method_symbol -> ACC_PUBLIC() &&
                     ! shadow -> method_symbol -> ACC_PROTECTED()))
                {
                    ReportSemError(SemanticError::DEFAULT_METHOD_NOT_OVERRIDDEN,
                                   left_tok, right_tok, method -> Header(),
                                   base_type -> ContainingPackageName(),
                                   base_type -> ExternalName(),
                                   super_type -> ContainingPackageName(),
                                   super_type -> ExternalName());
                }
            }
        }
    }
    //
    // Now, we must ensure that any time the inheritance tree left and
    // reentered the package, the non-inherited default methods were
    // correctly overridden or hidden if redeclared in this class. A method
    // is non-inherited only if a class C is in the package, it's subclass
    // is not, and there is no interface method also inherited into C.
    //
    while (super_type -> super)
    {
        TypeSymbol* prev = super_type;
        super_type = super_type -> super;
        if (prev -> ContainingPackage() == base_package ||
            super_type -> ContainingPackage() != base_package)
        {
            continue;
        }
        super_expanded_table = super_type -> expanded_method_table;
        for (i = 0; i < super_expanded_table -> symbol_pool.Length(); i++)
        {
            MethodShadowSymbol* method_shadow_symbol =
                super_expanded_table -> symbol_pool[i];
            MethodSymbol* method = method_shadow_symbol -> method_symbol;
            if (! method -> ACC_PUBLIC() && ! method -> ACC_PROTECTED() &&
                ! method -> ACC_PRIVATE() && ! method -> ACC_SYNTHETIC() &&
                method_shadow_symbol -> NumConflicts() == 0)
            {
                // found a non-inherited package scope method
                MethodShadowSymbol* shadow = base_expanded_table ->
                    FindOverloadMethodShadow(method, this, tok);
                if (shadow &&
                    shadow -> method_symbol -> containing_type == base_type)
                {
                    CheckMethodOverride(shadow -> method_symbol, method,
                                        base_type);
                }
            }
        }
    }
}


void Semantic::ComputeTypesClosure(TypeSymbol* type, TokenIndex tok)
{
    if (! type -> HeaderProcessed())
        type -> ProcessTypeHeaders();
    type -> expanded_type_table = new ExpandedTypeTable();

    TypeSymbol* super_class = type -> super;
    if (super_class)
    {
        if (! super_class -> expanded_type_table)
            ComputeTypesClosure(super_class, tok);
    }

    for (unsigned j = 0; j < type -> NumInterfaces(); j++)
    {
        TypeSymbol* interf = type -> Interface(j);
        if (! interf -> expanded_type_table)
            ComputeTypesClosure(interf, tok);
    }

    if (! type -> NestedTypesProcessed())
        type -> ProcessNestedTypeSignatures(this, tok);
    for (unsigned i = 0; i < type -> NumTypeSymbols(); i++)
    {
        if (! type -> TypeSym(i) -> Bad())
        {
            type -> expanded_type_table ->
                InsertTypeShadowSymbol(type -> TypeSym(i));
        }
    }
    if (super_class)
        AddInheritedTypes(type, super_class);
    for (unsigned k = 0; k < type -> NumInterfaces(); k++)
        AddInheritedTypes(type, type -> Interface(k));
    type -> expanded_type_table -> CompressSpace();
}


void Semantic::ComputeFieldsClosure(TypeSymbol* type, TokenIndex tok)
{
    type -> expanded_field_table = new ExpandedFieldTable();

    TypeSymbol* super_class = type -> super;
    if (super_class)
    {
        if (! super_class -> expanded_field_table)
            ComputeFieldsClosure(super_class, tok);
    }

    for (unsigned j = 0; j < type -> NumInterfaces(); j++)
    {
        TypeSymbol* interf = type -> Interface(j);
        if (! interf -> expanded_field_table)
            ComputeFieldsClosure(interf, tok);
    }

    assert(type -> FieldMembersProcessed());

    for (unsigned i = 0; i < type -> NumVariableSymbols(); i++)
    {
        VariableSymbol* variable = type -> VariableSym(i);
        type -> expanded_field_table -> InsertVariableShadowSymbol(variable);
    }

    //
    // As the type Object which is the super type of all interfaces does
    // not contain any field declarations, we don't have to do any special
    // check here as we have to when computing method closures.
    //
    if (super_class)
        AddInheritedFields(type, super_class);
    for (unsigned k = 0; k < type -> NumInterfaces(); k++)
        AddInheritedFields(type, type -> Interface(k));
    type -> expanded_field_table -> CompressSpace();
}


void Semantic::ComputeMethodsClosure(TypeSymbol* type, TokenIndex tok)
{
    type -> expanded_method_table = new ExpandedMethodTable();

    TypeSymbol* super_class = type -> super;
    if (super_class)
    {
        if (! super_class -> expanded_method_table)
            ComputeMethodsClosure(super_class, tok);
    }

    for (unsigned j = 0; j < type -> NumInterfaces(); j++)
    {
        TypeSymbol* interf = type -> Interface(j);

        if (! interf -> expanded_method_table)
            ComputeMethodsClosure(interf, tok);
    }

    assert(type -> MethodMembersProcessed());

    for (unsigned i = 0; i < type -> NumMethodSymbols(); i++)
    {
        MethodSymbol* method = type -> MethodSym(i);
        //
        // If the method in question is neither a constructor nor an
        // initializer, then ...
        //
        if (*(method -> Name()) != U_LESS)
        {
            type -> expanded_method_table -> Overload(method);
        }
    }

    //
    // We build in this order to guarantee that the first method listed in
    // the table will be declared in a class.  Conflicts, if any, are from
    // interfaces and are necessarily abstract; but if the first method
    // is not abstract, it implements all the conflicts.
    //
    if (super_class && ! type -> ACC_INTERFACE())
        AddInheritedMethods(type, super_class, tok);
    for (unsigned k = 0; k < type -> NumInterfaces(); k++)
        AddInheritedMethods(type, type -> Interface(k), tok);
    if (type -> ACC_INTERFACE()) // the super class is Object
        AddInheritedMethods(type, control.Object(), tok);
    type -> expanded_method_table -> CompressSpace();
}


void Semantic::ProcessFormalParameters(BlockSymbol* block,
                                       AstMethodDeclarator* method_declarator)
{
    for (unsigned i = 0; i < method_declarator -> NumFormalParameters(); i++)
    {
        AstFormalParameter* parameter =
            method_declarator -> FormalParameter(i);
        AccessFlags access_flags = ProcessFormalModifiers(parameter);
        ProcessType(parameter -> type);
        TypeSymbol* parm_type = parameter -> type -> symbol;

        AstVariableDeclaratorId* name =
            parameter -> formal_declarator -> variable_declarator_name;
        NameSymbol* name_symbol =
            lex_stream -> NameSymbol(name -> identifier_token);
        VariableSymbol* symbol = block -> FindVariableSymbol(name_symbol);
        if (symbol)
        {
            ReportSemError(SemanticError::DUPLICATE_FORMAL_PARAMETER,
                           name -> identifier_token, name_symbol -> Name());
        }
        else symbol = block -> InsertVariableSymbol(name_symbol);

        unsigned dims = parm_type -> num_dimensions + name -> NumBrackets();
        if (parameter -> ellipsis_token_opt)
        {
            assert(i == method_declarator -> NumFormalParameters() - 1);
            dims++;
            access_flags.SetACC_VARARGS();
            // TODO: Add varargs support for 1.5.
            //            if (control.option.source < JikesOption::SDK1_5)
            {
                ReportSemError(SemanticError::VARARGS_UNSUPPORTED,
                               parameter -> ellipsis_token_opt);
            }
        }
        symbol -> SetType(parm_type -> GetArrayType(this, dims));
        symbol -> SetFlags(access_flags);
        symbol -> MarkComplete();
        symbol -> MarkInitialized();

        parameter -> formal_declarator -> symbol = symbol;
    }
}


void Semantic::ProcessMethodDeclaration(AstMethodDeclaration* method_declaration)
{
    TypeSymbol* this_type = ThisType();
    AccessFlags access_flags = this_type -> ACC_INTERFACE()
        ? ProcessInterfaceMethodModifiers(method_declaration)
        : ProcessMethodModifiers(method_declaration);
    //
    // By JLS2 8.4.3.3, a private method and all methods declared in a
    // final class are implicitly final. Also, all methods in a strictfp
    // class are strictfp.
    //
    if (access_flags.ACC_PRIVATE() || this_type -> ACC_FINAL())
        access_flags.SetACC_FINAL();
    if (this_type -> ACC_STRICTFP())
        access_flags.SetACC_STRICTFP();

    if (method_declaration -> type_parameters_opt)
    {
        // TODO: Add generics support for 1.5.
        ReportSemError(SemanticError::TYPE_PARAMETERS_UNSUPPORTED,
                       method_declaration -> type_parameters_opt);
    }
    //
    // A method enclosed in an inner type may not be declared static.
    //
    if (access_flags.ACC_STATIC() && this_type -> IsInner())
    {
        assert(method_declaration -> modifiers_opt &&
               method_declaration -> modifiers_opt -> static_token_opt);
        ReportSemError(SemanticError::STATIC_METHOD_IN_INNER_CLASS,
                       method_declaration -> modifiers_opt -> static_token_opt,
                       lex_stream -> NameString(method_declaration -> method_declarator -> identifier_token),
                       this_type -> Name(),
                       this_type -> FileLoc());
    }

    //
    // To avoid deprecated type warnings when processing a deprecated method
    // declaration, we must temporarily mark this type as deprecated, because
    // the method symbol does not yet exist. We fix it after formal parameter
    // processing.
    //
    bool deprecated_method =
        lex_stream -> IsDeprecated(method_declaration -> LeftToken());
    bool deprecated_type = this_type -> IsDeprecated();
    if (deprecated_method)
        this_type -> MarkDeprecated();
    ProcessType(method_declaration -> type);
    TypeSymbol* method_type = method_declaration -> type -> symbol;

    AstMethodDeclarator* method_declarator =
        method_declaration -> method_declarator;
    if (method_declarator -> NumBrackets())
    {
        if (method_type == control.void_type)
        {
            ReportSemError(SemanticError::VOID_ARRAY,
                           method_declaration -> type -> LeftToken(),
                           method_declarator -> RightToken());
            method_type = control.no_type;
        }
        else ReportSemError(SemanticError::OBSOLESCENT_BRACKETS,
                            method_declarator);
    }

    NameSymbol* name_symbol =
        lex_stream -> NameSymbol(method_declarator -> identifier_token);

    if (name_symbol == this_type -> Identity())
    {
        ReportSemError(SemanticError::METHOD_WITH_CONSTRUCTOR_NAME,
                       method_declaration -> type -> LeftToken(),
                       method_declarator -> identifier_token,
                       name_symbol -> Name());
    }

    //
    // Warn against unconventional names.
    //
    if (name_symbol -> IsBadStyleForMethod())
    {
        ReportSemError(SemanticError::UNCONVENTIONAL_METHOD_NAME,
                       method_declarator -> identifier_token,
                       name_symbol -> Name());
    }

    //
    // As the body of the method may not have been parsed yet, we estimate a
    // size for its symbol table based on the number of lines in the body + a
    // margin for one-liners.
    //
    BlockSymbol* block_symbol =
        new BlockSymbol(method_declarator -> NumFormalParameters());
    block_symbol -> max_variable_index = (access_flags.ACC_STATIC() ? 0 : 1);
    ProcessFormalParameters(block_symbol, method_declarator);
    if (! deprecated_type && deprecated_method)
        this_type -> ResetDeprecated();

    MethodSymbol* method = this_type -> FindMethodSymbol(name_symbol);
    if (method && this_type -> FindOverloadMethod(method, method_declarator))
    {
        ReportSemError(SemanticError::DUPLICATE_METHOD,
                       method_declarator, name_symbol -> Name(),
                       this_type -> Name(), method -> FileLoc());
        delete block_symbol;
        return;
    }

    method = this_type -> InsertMethodSymbol(name_symbol);
    unsigned dims =
        method_type -> num_dimensions + method_declarator -> NumBrackets();
    method -> SetType(method_type -> GetArrayType(this, dims));

    //
    // if the method is not static, leave a slot for the "this" pointer.
    //
    method -> SetFlags(access_flags);
    method -> SetContainingType(this_type);
    method -> SetBlockSymbol(block_symbol);
    method -> declaration = method_declaration;
    method -> SetLocation();
    for (unsigned i = 0; i < method_declarator -> NumFormalParameters(); i++)
    {
        AstVariableDeclarator* formal_declarator =
            method_declarator -> FormalParameter(i) -> formal_declarator;
        VariableSymbol* symbol = formal_declarator -> symbol;

        symbol -> SetOwner(method);
        symbol -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
        symbol -> MarkComplete();
        if (control.IsDoubleWordType(symbol -> Type()))
            block_symbol -> max_variable_index++;
        symbol -> declarator = formal_declarator;
        symbol -> SetLocation();
        method -> AddFormalParameter(symbol);
    }
    method -> SetSignature(control);

    for (unsigned k = 0; k < method_declaration -> NumThrows(); k++)
    {
        AstTypeName* throw_expr = method_declaration -> Throw(k);
        ProcessType(throw_expr);
        method -> AddThrows(throw_expr -> symbol);
    }

    // save for processing bodies later.
    method_declaration -> method_symbol = method;

    if (method -> ACC_ABSTRACT() && ! this_type -> ACC_ABSTRACT())
    {
        ReportSemError(SemanticError::NON_ABSTRACT_TYPE_CONTAINS_ABSTRACT_METHOD,
                       method_declaration -> LeftToken(),
                       method_declarator -> identifier_token,
                       name_symbol -> Name(),
                       this_type -> Name());
    }

    if (deprecated_method)
        method -> MarkDeprecated();
}


//
// Return the type corresponding to a primitive type keyword.
//
TypeSymbol* Semantic::FindPrimitiveType(AstPrimitiveType* primitive_type)
{
    switch (primitive_type -> kind)
    {
    case Ast::INT:
        return control.int_type;
    case Ast::DOUBLE:
        return control.double_type;
    case Ast::CHAR:
        return control.char_type;
    case Ast::LONG:
        return control.long_type;
    case Ast::FLOAT:
        return control.float_type;
    case Ast::BYTE:
        return control.byte_type;
    case Ast::SHORT:
        return control.short_type;
    case Ast::BOOLEAN:
        return control.boolean_type;
    default:
        break;
    }

    return control.void_type;
}


//
// Search the import-on-demand locations for a type with the given name. This
// returns inaccessible types if found, with no error message, but favors
// accessible ones. It will issue an error if the only way an accessible type
// was found is non-canonical. If no type is found, NULL is returned.
//
TypeSymbol* Semantic::ImportType(TokenIndex identifier_token,
                                 NameSymbol* name_symbol)
{
    //
    // To keep track of inaccessible types, we note the first one we find,
    // while leaving the location as NULL. Once we find an accessible type, we
    // set location, so that we know that future types are duplicates. We
    // pre-filtered duplicate import-on-demands, as well as adding java.lang.*.
    //
    TypeSymbol* type = NULL;
    PackageSymbol* location = NULL;

    for (unsigned i = 0; i < import_on_demand_packages.Length(); i++)
    {
        PackageSymbol* import_package =
            import_on_demand_packages[i] -> PackageCast();
        TypeSymbol* possible_type = NULL;

        if (import_package)
        {
            possible_type = import_package -> FindTypeSymbol(name_symbol);
            if (! possible_type)
            {
                FileSymbol* file_symbol =
                    Control::GetFile(control, import_package, name_symbol);
                if (file_symbol)
                    possible_type = ReadType(file_symbol, import_package,
                                             name_symbol, identifier_token);
            }
            else if (possible_type -> SourcePending())
                control.ProcessHeaders(possible_type -> file_symbol);
        }
        else
        {
            TypeSymbol* import_type =
                (TypeSymbol*) import_on_demand_packages[i];
            if (! import_type -> expanded_type_table)
                ComputeTypesClosure(import_type, identifier_token);
            TypeShadowSymbol* type_shadow_symbol = import_type ->
                expanded_type_table -> FindTypeShadowSymbol(name_symbol);
            if (type_shadow_symbol)
            {
                //
                // Only canonical names may be used in import statements, hence
                // the extra filter on the containing type being correct. If
                // we encounter conflicts, they are necessarily accessible
                // inherited types from interfaces (and hence non-canonical).
                //
                possible_type = (type_shadow_symbol -> NumConflicts()
                                 ? type_shadow_symbol -> Conflict(0)
                                 : type_shadow_symbol -> type_symbol);
                if (! possible_type -> ACC_PRIVATE() &&
                    import_type == possible_type -> owner)
                {
                    import_package = import_type -> ContainingPackage();
                }
            }
        }
        if (possible_type)
        {
            if (location && import_package &&
                (possible_type -> ACC_PUBLIC() ||
                 import_package == this_package))
            {
                ReportSemError(SemanticError::DUPLICATE_ON_DEMAND_IMPORT,
                               identifier_token, name_symbol -> Name(),
                               location -> PackageName(),
                               import_package -> PackageName());
            }
            else
            {
                type = possible_type;
                if (type -> ACC_PUBLIC() || import_package == this_package)
                    location = import_package; // may be NULL
            }
        }
    }

    if (type && ! location && ! type -> ACC_PRIVATE() &&
        (type -> ACC_PUBLIC() || type -> ContainingPackage() == this_package))
    {
        ReportSemError(SemanticError::IMPORT_NOT_CANONICAL,
                       identifier_token, type -> Name(),
                       type -> ContainingPackageName(),
                       type -> ExternalName());
    }

    // Keep track of referenced types.
    if (type && location)
        referenced_package_imports.AddElement(location);

    return type;
}


//
// Finds an accessible type by the name located at identifier_token, or returns
// NULL. If there are ambiguous accessible types, this issues an error in the
// process. Note that inaccessible types are skipped - if the caller wishes
// to use an inaccessible type, they must search for it.
//
TypeSymbol* Semantic::FindType(TokenIndex identifier_token)
{
    TypeSymbol* type;
    NameSymbol* name_symbol = lex_stream -> NameSymbol(identifier_token);

    SemanticEnvironment* env = NULL;
    if (state_stack.Size())
        env = state_stack.Top();
    for ( ; env; env = env -> previous)
    {
        // Search for local types, which are always accessible.
        type = env -> symbol_table.FindTypeSymbol(name_symbol);
        if (type)
            break;
        // Search for declared or inherited member types.
        type = env -> Type();
        if (! type -> expanded_type_table)
            ComputeTypesClosure(type, identifier_token);
        TypeShadowSymbol* type_shadow_symbol =
            type -> expanded_type_table -> FindTypeShadowSymbol(name_symbol);
        if (type_shadow_symbol)
        {
            type = FindTypeInShadow(type_shadow_symbol, identifier_token);
            if (type)
                break;
        }
    }

    if (env) // The type was found in some enclosing environment?
    {
        //
        // A static type cannot access a non-static member type of an enclosing
        // class by simple name.
        //
        TypeSymbol* this_type = ThisType();
        assert(this_type);
        if (this_type -> ACC_STATIC() && ! type -> ACC_STATIC() &&
            ! this_type -> IsSubclass(type -> ContainingType()))
        {
            ReportSemError(SemanticError::STATIC_TYPE_ACCESSING_MEMBER_TYPE,
                           identifier_token,
                           this_type -> ContainingPackageName(),
                           this_type -> ExternalName(),
                           type -> ContainingPackageName(),
                           type -> ExternalName(),
                           env -> Type() -> ContainingPackageName(),
                           env -> Type() -> ExternalName());
        }
        //
        // If the type was inherited, give a warning if it shadowed another
        // type of the same name within an enclosing lexical scope.
        //
        if (type -> owner -> TypeCast() && type -> owner != env -> Type())
        {
            TypeSymbol* supertype = (TypeSymbol*) type -> owner;
            for ( ; env; env = env -> previous)
            {
                //
                // First, check the enclosing type name - this is a caution,
                // because this behavior is opposite C++ when a type inherits
                // a membertype with the same name.
                //
                if (name_symbol == env -> Type() -> Identity() &&
                    env -> Type() != type)
                {
                    ReportSemError(SemanticError::INHERITANCE_AND_LEXICAL_SCOPING_CONFLICT_WITH_TYPE,
                                   identifier_token,
                                   lex_stream -> NameString(identifier_token),
                                   type -> ContainingPackageName(),
                                   type -> ExternalName(),
                                   env -> Type() -> ContainingPackageName(),
                                   env -> Type() -> ExternalName());
                    break;
                }
                if (env -> previous && control.option.pedantic)
                {
                    // Next, in pedantic mode, check local type
                    SemanticEnvironment* env2 = env -> previous;
                    TypeSymbol* outer_type =
                        env2 -> symbol_table.FindTypeSymbol(name_symbol);
                    if (outer_type)
                    {
                        assert(outer_type -> owner -> MethodCast());
                        ReportSemError(SemanticError::INHERITANCE_AND_LEXICAL_SCOPING_CONFLICT_WITH_LOCAL,
                                       identifier_token,
                                       lex_stream -> NameString(identifier_token),
                                       supertype -> ContainingPackageName(),
                                       supertype -> ExternalName(),
                                       ((MethodSymbol*) outer_type -> owner) -> Name());
                        break;
                    }
                    // If local type not found, check inner type.
                    if (! env2 -> Type() -> expanded_type_table)
                        ComputeTypesClosure(env2 -> Type(), identifier_token);
                    TypeShadowSymbol* type_shadow_symbol =
                        env2 -> Type() -> expanded_type_table ->
                        FindTypeShadowSymbol(name_symbol);
                    if (type_shadow_symbol)
                        outer_type = FindTypeInShadow(type_shadow_symbol,
                                                      identifier_token);
                    if (outer_type && outer_type != type &&
                        outer_type -> owner == env2 -> Type())
                    {
                        ReportSemError(SemanticError::INHERITANCE_AND_LEXICAL_SCOPING_CONFLICT_WITH_MEMBER,
                                       identifier_token,
                                       lex_stream -> NameString(identifier_token),
                                       supertype -> ContainingPackageName(),
                                       supertype -> ExternalName(),
                                       env2 -> Type() -> ContainingPackageName(),
                                       env2 -> Type() -> ExternalName());
                        break;
                    }
                }
            }
        }

        return type;
    }

    //
    // Search for the type in the current compilation unit if it was declared
    // as a class or interface or imported by a single-type-import declaration.
    //
    for (unsigned i = 0; i < single_type_imports.Length(); i++)
    {
        type = single_type_imports[i];
        if (name_symbol == type -> Identity())
        {
            // Keep track of referenced types.
            referenced_type_imports.AddElement(type);
            return type;
        }
    }

    //
    // Search for another file in the current package, and if that fails, check
    // for an accessible import-on-demand.
    //
    type = FindSimpleNameType(this_package, identifier_token);
    TypeSymbol* imported_type = (! type || type -> Bad()
                                 ? ImportType(identifier_token, name_symbol)
                                 : (TypeSymbol*) NULL);

    //
    // If a valid type can be imported on demand, choose that type.
    // Otherwise, if a type was found at all, do some final checks on it.
    //
    // Note that a type T contained in a package P is always accessible to all
    // other types contained in P. I.e., we do not need to perform access check
    // for type...
    //
    if (imported_type && TypeAccessCheck(imported_type))
        type = imported_type;
    else if (type)
    {
        //
        // If a type T was specified in a source file that is not called T.java
        // but X.java (where X != T) and we are not currently compiling file X,
        // issue a warning to alert the user that in some circumstances, this
        // may not be visible. (i.e., if the file X has not yet been compiled,
        // then T is invisile as the compiler will only look for T in T.java.)
        //
        FileSymbol* file_symbol = type -> file_symbol;
        if (file_symbol && type -> Identity() != file_symbol -> Identity() &&
            file_symbol != this -> source_file_symbol)
        {
            ReportSemError(SemanticError::REFERENCE_TO_TYPE_IN_MISMATCHED_FILE,
                           identifier_token, type -> Name(),
                           file_symbol -> Name());
        }
    }

    return type;
}


//
// Returns an inaccessible type of the given name, or 0 if there is none.
// No errors are reported by this method.
//
TypeSymbol* Semantic::FindInaccessibleType(AstName* name)
{
    assert(! name -> base_opt);
    NameSymbol* name_symbol =
        lex_stream -> NameSymbol(name -> identifier_token);

    // Check for inaccessible member type.
    if (state_stack.Size())
    {
        for (TypeSymbol* super_type = ThisType() -> super;
             super_type; super_type = super_type -> super)
        {
            assert(super_type -> expanded_type_table);
            TypeShadowSymbol* type_shadow_symbol = super_type ->
                expanded_type_table -> FindTypeShadowSymbol(name_symbol);
            if (type_shadow_symbol)
            {
                return type_shadow_symbol -> type_symbol;
            }
        }
    }
    // Check for an inaccessible import.
    return ImportType(name -> identifier_token, name_symbol);
}


//
// Finds a type by the given name, and add the dependence information. If one
// exists, but is not accessible, it is returned after an error. After other
// errors, control.no_type is returned.
//
TypeSymbol* Semantic::MustFindType(AstName* name)
{
    TypeSymbol* type;
    NameSymbol* name_symbol =
        lex_stream -> NameSymbol(name -> identifier_token);
    if (! name -> base_opt)
    {
        type = FindType(name -> identifier_token);
        //
        // If the type was not found, generate an appropriate error message.
        //
        if (! type)
        {
            type = FindInaccessibleType(name);
            if (type)
                ReportTypeInaccessible(name, type);
            else
            {
                // Try reading the file again, to force an error.
                NameSymbol* name_symbol =
                    lex_stream -> NameSymbol(name -> identifier_token);
                FileSymbol* file_symbol =
                    Control::GetFile(control, this_package, name_symbol);
                type = ReadType(file_symbol, this_package, name_symbol,
                                name -> identifier_token);
            }
        }
    }
    else // qualified name
    {
        ProcessPackageOrType(name -> base_opt);
        Symbol* symbol = name -> base_opt -> symbol;
        type = symbol -> TypeCast();
        if (type)
            type = MustFindNestedType(type, name);
        else
        {
            PackageSymbol* package = symbol -> PackageCast();
            type = package -> FindTypeSymbol(name_symbol);
            if (! type)
            {
                FileSymbol* file_symbol =
                    Control::GetFile(control, package, name_symbol);
                type = ReadType(file_symbol, package, name_symbol,
                                name -> identifier_token);
            }
            else if (type -> SourcePending())
                control.ProcessHeaders(type -> file_symbol);
            if (! TypeAccessCheck(type))
                ReportTypeInaccessible(name, type);
        }
    }

    //
    // Establish a dependence from the base_type to a type that it "must find".
    // Note that the only time an environment is not available is when were are
    // processing the type header of an outermost type.
    //
    if (state_stack.Size())
    {
        AddDependence(ThisType(), type);
        if (control.option.deprecation && type -> IsDeprecated() &&
            ! InDeprecatedContext())
        {
            ReportSemError(SemanticError::DEPRECATED_TYPE, name,
                           type -> ContainingPackageName(),
                           type -> ExternalName());
        }
    }
    if (type -> Anonymous() && ! type -> Bad())
    {
        ReportSemError(SemanticError::UNNAMED_TYPE_ACCESS, name,
                       type -> ContainingPackageName(),
                       type -> ExternalName());
    }
    if (type -> ACC_SYNTHETIC() && ! type -> Bad())
    {
        ReportSemError(SemanticError::SYNTHETIC_TYPE_ACCESS, name,
                       type -> ContainingPackageName(),
                       type -> ExternalName());
    }
    return type -> Bad() ? control.no_type : type;
}


void Semantic::ProcessType(AstType* type_expr)
{
    if (type_expr -> symbol)
        return; // already processed
    AstArrayType* array_type = type_expr -> ArrayTypeCast();
    AstType* actual_type = array_type ? array_type -> type : type_expr;
    AstTypeName* name = actual_type -> TypeNameCast();
    AstPrimitiveType* primitive_type = actual_type -> PrimitiveTypeCast();
    AstWildcard* wildcard_type = actual_type -> WildcardCast();
    if (wildcard_type)
    {
        ReportSemError(SemanticError::WILDCARD_UNSUPPORTED, type_expr);
        type_expr -> symbol = control.no_type;
        return;
    }
    assert(name || primitive_type);
    //
    // Occaisionally, MustFindType finds a bad type (for example, if we
    // reference Other.java which has syntax errors), but does not know to
    // report the error.
    //
    unsigned error_count = NumErrors();
    TypeSymbol* type;
    if (primitive_type)
        type = FindPrimitiveType(primitive_type);
    else
    {
        if (name -> base_opt)
        {
            ProcessType(name -> base_opt);
            type = MustFindNestedType(name -> base_opt -> symbol,
                                      name -> name);
        }
        else type = MustFindType(name -> name);
        if (name -> type_arguments_opt)
        {
            // TODO: Add generics support for 1.5.
            ReportSemError(SemanticError::TYPE_ARGUMENTS_UNSUPPORTED,
                           name -> type_arguments_opt,
                           type -> ContainingPackageName(),
                           type -> ExternalName());
        }
    }
    if (type -> Bad() && NumErrors() == error_count)
    {
        if (type == control.no_type)
        {
            ReportSemError(SemanticError::TYPE_NOT_FOUND, actual_type,
                           NULL,
                           lex_stream -> NameString(type_expr ->
                                                    IdentifierToken()));
        }
        else
        {
            ReportSemError(SemanticError::INVALID_TYPE_FOUND, actual_type,
                           lex_stream -> NameString(type_expr ->
                                                    IdentifierToken()));
        }
    }
    if (array_type)
        type = type -> GetArrayType(this, array_type -> NumBrackets());
    type_expr -> symbol = type;
}


//
// Initializes a static or instance field. In addition to checking the
// semantics, the initialization is added as a statement in the init_method,
// for easy bytecode emission, if it has an initializer and is not a constant.
//
void Semantic::InitializeVariable(AstFieldDeclaration* field_declaration,
                                  MethodSymbol* init_method)
{
    ThisMethod() = NULL;
    AstMethodDeclaration* declaration =
        (AstMethodDeclaration*) init_method -> declaration;
    assert(declaration -> method_body_opt);

    for (unsigned i = 0;
         i < field_declaration -> NumVariableDeclarators(); i++)
    {
        AstVariableDeclarator* variable_declarator =
            field_declaration -> VariableDeclarator(i);
        VariableSymbol* variable = variable_declarator -> symbol;

        if (variable)
        {
            ThisVariable() = variable;
            if (variable_declarator -> variable_initializer_opt)
            {
                variable_declarator -> pending = true;

                unsigned start_num_errors = NumErrors();
                ProcessVariableInitializer(variable_declarator);
                if (NumErrors() == start_num_errors)
                {
                    DefiniteFieldInitializer(variable_declarator);
                    if (! variable -> initial_value)
                    {
                        declaration -> method_body_opt ->
                            AddStatement(variable_declarator);
                    }
                }
                else if (variable -> ACC_FINAL())
                {
                    // Suppress further error messages.
                    DefinitelyAssignedVariables() ->
                        AssignElement(variable -> LocalVariableIndex());
                }

                variable_declarator -> pending = false;
            }
            variable -> MarkComplete();
        }
    }
}


//
// Adds an initializer block to the init_method, after checking its semantics,
// for easier bytecode emission.
//
inline void Semantic::ProcessInitializer(AstInitializerDeclaration* initializer,
                                         MethodSymbol* init_method)
{
    ThisVariable() = NULL;
    ThisMethod() = init_method;
    AstMethodDeclaration* declaration =
        (AstMethodDeclaration*) init_method -> declaration;

    LocalBlockStack().Push(declaration -> method_body_opt);
    LocalSymbolTable().Push(init_method -> block_symbol -> Table());

    //
    // Initializer blocks are always reachable, as prior blocks must be able
    // to complete normally.
    //
    initializer -> block -> is_reachable = true;

    if (initializer -> block -> explicit_constructor_opt)
    {
        AstStatement* explicit_ctor =
            initializer -> block -> explicit_constructor_opt;
        ReportSemError(SemanticError::MISPLACED_EXPLICIT_CONSTRUCTOR,
                       explicit_ctor);
    }
    ProcessInitializerModifiers(initializer);
    ProcessBlock(initializer -> block);
    DefiniteBlockInitializer(initializer -> block, LocalBlockStack().max_size);

    declaration -> method_body_opt -> AddStatement(initializer -> block);

    //
    // If the initializer has a higher max_variable_index than the overall
    // block, update max_variable_index in the method_body, accordingly.
    //
    if (init_method -> block_symbol -> max_variable_index <
        LocalBlockStack().TopMaxEnclosedVariableIndex())
    {
        init_method -> block_symbol -> max_variable_index =
            LocalBlockStack().TopMaxEnclosedVariableIndex();
    }

    if (! initializer -> block -> can_complete_normally)
        ReportSemError(SemanticError::ABRUPT_INITIALIZER, initializer);

    LocalBlockStack().Pop();
    LocalSymbolTable().Pop();
}


//
// Lazily create and return the static initializer for this type. The estimate
// is for the number of initializers that will be grouped into this method.
// This is called both when processing static initializers, and any time an
// assert statement is encountered (since assertions require an initialized
// static variable to operate).
//
MethodSymbol* Semantic::GetStaticInitializerMethod(unsigned estimate)
{
    TypeSymbol* this_type = ThisType();
    if (this_type -> static_initializer_method)
        return this_type -> static_initializer_method;

    StoragePool* ast_pool = compilation_unit -> ast_pool;
    TokenIndex loc = this_type -> declaration -> identifier_token;

    // The symbol table associated with this block has no elements.
    BlockSymbol* block_symbol = new BlockSymbol(0);
    block_symbol -> max_variable_index = 0;

    // The body of the static initializer. This will contain each initializer
    // block in sequence.
    AstMethodBody* block = ast_pool -> GenMethodBody();
    block -> left_brace_token = loc;
    block -> right_brace_token = loc;
    block -> block_symbol = block_symbol;
    block -> AllocateStatements(estimate);

    // The return type (void).
    AstType* return_type = ast_pool -> GenPrimitiveType(Ast::VOID_TYPE, loc);
    return_type -> symbol = control.void_type;

    // The method declaration. We leave some fields uninitialized, because
    // they are not needed in bytecode.cpp.
    AstMethodDeclaration* declaration = ast_pool -> GenMethodDeclaration();
    MethodSymbol* init_method =
        this_type -> InsertMethodSymbol(control.clinit_name_symbol);
    declaration -> type = return_type;
    declaration -> method_symbol = init_method;
    declaration -> method_body_opt = block;

    // The method symbol.
    init_method -> SetType(control.void_type);
    init_method -> SetFlags(AccessFlags::ACCESS_PRIVATE |
                            AccessFlags::ACCESS_FINAL |
                            AccessFlags::ACCESS_STATIC);
    if (this_type -> ACC_STRICTFP())
        init_method -> SetACC_STRICTFP();
    init_method -> SetContainingType(this_type);
    init_method -> SetBlockSymbol(block_symbol);
    init_method -> SetSignature(control);
    init_method -> declaration = declaration;

    this_type -> static_initializer_method = init_method;
    return init_method;
}


void Semantic::ProcessStaticInitializers(AstClassBody* class_body)
{
    //
    // Notice that the bodies of methods have not been processed yet when this
    // is called.  If any method contains an assert, it will generate a static
    // initializer for the $noassert variable as needed.  On the other hand, if
    // we already encountered an assert statement in an instance initializer,
    // the static initializer already exists.  The assert variable initializer
    // is magically implemented by bytecode.cpp, rather than adding all the AST
    // structure to the block of the static initializer.
    //
    if (class_body -> NumStaticInitializers() == 0 &&
        class_body -> NumClassVariables() == 0)
    {
        return;
    }

    TypeSymbol* this_type = ThisType();
    LocalBlockStack().max_size = 1;
    assert(FinalFields());

    //
    // Work out how many statements we'll need.
    //
    unsigned estimate = class_body -> NumStaticInitializers();
    for (unsigned i = 0; i < class_body -> NumClassVariables(); ++i)
    {
        estimate += class_body -> ClassVariable(i) -> NumVariableDeclarators();
    }
    MethodSymbol* init_method = GetStaticInitializerMethod(estimate);

    //
    // The static initializers and class variable initializers are executed
    // in textual order, with the exception that assignments may occur before
    // declaration. See JLS 8.5.
    //
    unsigned j = 0;
    unsigned k = 0;
    while (j < class_body -> NumClassVariables() &&
           k < class_body -> NumStaticInitializers())
    {
        if (class_body -> ClassVariable(j) -> semicolon_token <
            class_body -> StaticInitializer(k) -> block -> right_brace_token)
        {
            InitializeVariable(class_body -> ClassVariable(j++), init_method);
        }
        else
        {
            ProcessInitializer(class_body -> StaticInitializer(k++),
                               init_method);
        }
    }
    while (j < class_body -> NumClassVariables())
    {
        InitializeVariable(class_body -> ClassVariable(j++), init_method);
    }
    while (k < class_body -> NumStaticInitializers())
    {
        ProcessInitializer(class_body -> StaticInitializer(k++),
                           init_method);
    }

    //
    // Check that each static final variable has been initialized by now.
    // If not, issue an error and assume it is.  Notice that for inner
    // classes, we have already reported that a non-constant static
    // field is illegal, so we only need an error here for top-level
    // and static classes.
    //
    for (unsigned l = 0; l < FinalFields() -> Length(); l++)
    {
        VariableSymbol* final_var = (*FinalFields())[l];
        if (final_var -> ACC_STATIC() &&
            ! DefinitelyAssignedVariables() -> da_set[l])
        {
            if (! this_type -> IsInner())
            {
                ReportSemError(SemanticError::UNINITIALIZED_STATIC_FINAL_VARIABLE,
                               final_var -> declarator, final_var -> Name());
            }
            DefinitelyAssignedVariables() -> AssignElement(l);
        }
    }

    //
    // If an initialization method has been defined, update its
    // max_block_depth.
    //
    if (this_type -> static_initializer_method)
    {
        MethodSymbol* init_method = this_type -> static_initializer_method;
        init_method -> max_block_depth = LocalBlockStack().max_size;
        init_method -> block_symbol -> CompressSpace(); // space optimization
    }
}


void Semantic::ProcessInstanceInitializers(AstClassBody* class_body)
{
    //
    // For instance initializers, we create a method to do all the
    // initialization. We name the method 'this', which is legal in VM's
    // but an illegal user name, to avoid name clashes. Constructors which
    // do not invoke another constructor via the this() statement will call
    // the instance initializer method after calling super(). We rely on the
    // fact that VM's allow assignment of final instance variables in an
    // instance method, rather than requiring it to be in a constructor.
    //
    if (class_body -> NumInstanceInitializers() == 0 &&
        class_body -> NumInstanceVariables() == 0)
    {
        return;
    }

    TypeSymbol* this_type = ThisType();
    LocalBlockStack().max_size = 1;
    StoragePool* ast_pool = compilation_unit -> ast_pool;
    TokenIndex loc = this_type -> declaration -> identifier_token;

    // The symbol table associated with this block has one element, the
    // current instance 'this'.
    BlockSymbol* block_symbol = new BlockSymbol(1);
    block_symbol -> max_variable_index = 1;

    // The combined block of the instance initializations. This will contain
    // each initializer block in sequence, and be inlined into constructors.
    AstMethodBody* block = ast_pool -> GenMethodBody();
    block -> left_brace_token = loc;
    block -> right_brace_token = loc;
    block -> block_symbol = block_symbol;

    // The return type (void).
    AstType* return_type = ast_pool -> GenPrimitiveType(Ast::VOID_TYPE, loc);
    return_type -> symbol = control.void_type;

    // The method declaration. We leave some fields uninitialized, because
    // they are not needed in bytecode.cpp.
    AstMethodDeclaration* declaration = ast_pool -> GenMethodDeclaration();
    MethodSymbol* init_method =
        this_type -> InsertMethodSymbol(control.block_init_name_symbol);
    declaration -> type = return_type;
    declaration -> method_symbol = init_method;
    declaration -> method_body_opt = block;

    // The method symbol.
    init_method -> SetType(control.void_type);
    init_method -> SetFlags(AccessFlags::ACCESS_PRIVATE |
                            AccessFlags::ACCESS_FINAL |
                            AccessFlags::ACCESS_SYNTHETIC);
    if (this_type -> ACC_STRICTFP())
        init_method -> SetACC_STRICTFP();
    init_method -> SetContainingType(this_type);
    init_method -> SetBlockSymbol(block_symbol);
    init_method -> SetSignature(control);
    init_method -> declaration = declaration;

    assert(this_type -> instance_initializer_method == NULL);
    this_type -> instance_initializer_method = init_method;

    //
    // Make sure the instance final fields are properly set.
    //
    assert(FinalFields());
    for (unsigned i = 0; i < FinalFields() -> Length(); i++)
    {
        VariableSymbol* variable_symbol = (*FinalFields())[i];
        if (variable_symbol -> ACC_STATIC())
        {
            DefinitelyAssignedVariables() -> AssignElement(i);
            BlankFinals() -> RemoveElement(i);
        }
        else
            DefinitelyAssignedVariables() -> ReclaimElement(i);
    }

    //
    // Work out how many statements we'll need.
    //
    unsigned estimate = class_body -> NumInstanceInitializers();
    for (unsigned i = 0; i < class_body -> NumInstanceVariables(); ++i)
    {
        estimate += class_body -> InstanceVariable(i) ->
            NumVariableDeclarators();
    }
    block -> AllocateStatements(estimate);

    //
    // Initialization code is executed by every constructor that does not call
    // this(), just after the superclass constructor is called, in textual
    // order along with any instance variable initializations.
    //
    unsigned j = 0;
    unsigned k = 0;
    while (j < class_body -> NumInstanceVariables() &&
           k < class_body -> NumInstanceInitializers())
    {
        if (class_body -> InstanceVariable(j) -> semicolon_token <
            class_body -> InstanceInitializer(k) -> block -> right_brace_token)
        {
            InitializeVariable(class_body -> InstanceVariable(j++),
                               init_method);
        }
        else
        {
            ProcessInitializer(class_body -> InstanceInitializer(k++),
                               init_method);
        }
    }
    while (j < class_body -> NumInstanceVariables())
    {
        InitializeVariable(class_body -> InstanceVariable(j++), init_method);
    }
    while (k < class_body -> NumInstanceInitializers())
    {
        ProcessInitializer(class_body -> InstanceInitializer(k++),
                           init_method);
    }

    //
    // Note that unlike the case of static fields, we do not ensure here that
    // each final instance variable has been initialized at this point. This
    // is because the user may choose instead to initialize such a final
    // variable in every constructor instead. See body.cpp
    //
    init_method -> max_block_depth = LocalBlockStack().max_size;
    init_method -> block_symbol -> CompressSpace(); // space optimization
}

#ifdef HAVE_JIKES_NAMESPACE
} // Close namespace Jikes block
#endif


Generated by  Doxygen 1.6.0   Back to index