// $Id: semantic.h,v 1.10 1999/03/10 19:59:21 shields Exp $ copyright notice #ifndef semantic_INCLUDED #define semantic_INCLUDED #include "config.h" #include <wchar.h> #include "ast.h" #include "diagnose.h" #include "error.h" #include "symbol.h" #include "control.h" #include "tuple.h" #include "set.h" class cp_info; class TypeShadowSymbol; // // // class SymbolTableStack { public: void Push(SymbolTable *symtab) { table.Next() = symtab; } void Pop() { if (table.Length() > 0) table.Reset(table.Length() - 1); } int Size() { return table.Length(); } SymbolTable *Top() { return (SymbolTable *) (table.Length() > 0 ? table[table.Length() - 1] : NULL); } SymbolTable *operator[](const int i) { return table[i]; } /* */ // // Search for a variable in a stack of symbol tables starting at the current symbol table // and ending with the symbol table of the method from which this call originates. // VariableSymbol *FindVariableSymbol(NameSymbol *name_symbol) { for (int i = table.Length() - 1; i >= 0; i--) { VariableSymbol *symbol = table[i] -> FindVariableSymbol(name_symbol); if (symbol) return symbol; } return (VariableSymbol *) NULL; } // // Search for a type in a stack of symbol tables starting at the current symbol table // and ending with the symbol table of the method from which this call originates. // TypeSymbol* FindTypeSymbol(NameSymbol *name_symbol) { for (int i = table.Length() - 1; i >= 0; i--) { TypeSymbol *symbol = table[i] -> FindTypeSymbol(name_symbol); if (symbol) return symbol; } return (TypeSymbol *) NULL; } // // Search for a label in a stack of symbol tables starting at the current symbol table // and ending with the symbol table of the method from which this call originates. // LabelSymbol* FindLabelSymbol(NameSymbol *name_symbol) { for (int i = table.Length() - 1; i >= 0; i--) { LabelSymbol *label = table[i] -> FindLabelSymbol(name_symbol); if (label) return label; } return (LabelSymbol *) NULL; } private: Tuple<SymbolTable *> table; }; // // // class ExceptionTableStack { public: void Push(SymbolSet *set) { table.Next() = set; } void Pop() { if (table.Length() > 0) table.Reset(table.Length() - 1); } int Size() { return table.Length(); } SymbolSet *Top() { return (SymbolSet *) (table.Length() > 0 ? table[table.Length() - 1] : NULL); } private: Tuple<SymbolSet *> table; }; // // // class StatementStack { public: void Push(Ast *stmt) { info.Next() = stmt; } void Pop() { if (info.Length() > 0) info.Reset(info.Length() - 1); } int Size() { return info.Length(); } Ast *Top() { return (Ast *) (info.Length() > 0 ? info[info.Length() - 1] : NULL); } Ast *operator[](const int i) { return info[i]; } private: Tuple<Ast *> info; }; // // // class BlockStack { public: int max_size; void Push(AstBlock *block_) { block.Next() = block_; index.Next() = 0; if (block.Length() > max_size) max_size = block.Length(); } void Pop() { int len = block.Length() - 1; if (len >= 0) { block.Reset(len); index.Reset(len); } } int Size() { return block.Length(); } AstBlock *TopBlock() { return (AstBlock *) (block.Length() > 0 ? block[block.Length() - 1] : NULL); } AstBlock *operator[](const int i) { return block[i]; } int &TopMaxEnclosedVariableIndex() { if (index.Length() <= 0) assert(0); return index[index.Length() - 1]; } BlockStack() : max_size(0) {} private: Tuple<AstBlock *> block; Tuple<int> index; }; // // // class DefiniteFinalAssignmentStack { public: void Push() { info.Next().Reset(); } void Pop() { if (info.Length() > 0) info.Reset(info.Length() - 1); } int Size() { return info.Length(); } Tuple <AstExpression *> &Top() { if (info.Length() == 0) assert(0); return info[info.Length() - 1]; } private: Tuple< Tuple<AstExpression *> > info; }; // // // class DefiniteSets { public: DefiniteSets(int set_size) : break_set(set_size), continue_set(set_size), return_set(set_size), throw_set(set_size) {} BitSet break_set, continue_set, return_set, throw_set; void UniverseInit() { break_set.SetUniverse(); continue_set.SetUniverse(); return_set.SetUniverse(); throw_set.SetUniverse(); } void EmptyInit() { break_set.SetEmpty(); continue_set.SetEmpty(); return_set.SetEmpty(); throw_set.SetEmpty(); } }; // // // class DefiniteBlockStack { public: void Push(AstBlock *block_) { definite_sets[top_index] -> UniverseInit(); final_sets[top_index] -> EmptyInit(); block[top_index] = block_; top_index++; } void Pop() { if (top_index > 0) top_index--; else assert(0); } int Size() { return top_index; } AstBlock *Block(int i) { return block[i]; } AstBlock *TopBlock() { assert(top_index > 0); return block[top_index - 1]; } BitSet &BreakSet(int i) { return definite_sets[i] -> break_set; } BitSet &ContinueSet(int i) { return definite_sets[i] -> continue_set; } BitSet &ReturnSet(int i) { return definite_sets[i] -> return_set; } BitSet &ThrowSet(int i) { return definite_sets[i] -> throw_set; } BitSet &TopBreakSet() { assert(top_index > 0); return definite_sets[top_index - 1] -> break_set; } BitSet &TopContinueSet() { assert(top_index > 0); return definite_sets[top_index - 1] -> continue_set; } BitSet &TopReturnSet() { assert(top_index > 0); return definite_sets[top_index - 1] -> return_set; } BitSet &TopThrowSet() { assert(top_index > 0); return definite_sets[top_index - 1] -> throw_set; } BitSet &TopExitSet(BitSet &start_set) { assert(top_index > 0); exit_set = start_set; exit_set *= TopBreakSet(); exit_set *= TopContinueSet(); exit_set *= TopReturnSet(); exit_set *= TopThrowSet(); return exit_set; } BitSet &FinalBreakSet(int i) { return final_sets[i] -> break_set; } BitSet &FinalContinueSet(int i) { return final_sets[i] -> continue_set; } BitSet &FinalReturnSet(int i) { return final_sets[i] -> return_set; } BitSet &FinalThrowSet(int i) { return final_sets[i] -> throw_set; } BitSet &TopFinalBreakSet() { assert(top_index > 0); return final_sets[top_index - 1] -> break_set; } BitSet &TopFinalContinueSet() { assert(top_index > 0); return final_sets[top_index - 1] -> continue_set; } BitSet &TopFinalReturnSet() { assert(top_index > 0); return final_sets[top_index - 1] -> return_set; } BitSet &TopFinalThrowSet() { assert(top_index > 0); return final_sets[top_index - 1] -> throw_set; } BitSet &TopFinalExitSet(BitSet &start_set) { assert(top_index > 0); exit_set = start_set; exit_set += TopFinalBreakSet(); exit_set += TopFinalContinueSet(); exit_set += TopFinalReturnSet(); exit_set += TopFinalThrowSet(); return exit_set; } DefiniteBlockStack(int stack_size_, int set_size) : stack_size(stack_size_), top_index(0), exit_set(set_size) { block = new AstBlock*[stack_size]; definite_sets = new DefiniteSets*[stack_size]; final_sets = new DefiniteSets*[stack_size]; for (int i = 0; i < stack_size; i++) { definite_sets[i] = new DefiniteSets(set_size); final_sets[i] = new DefiniteSets(set_size); } } ~DefiniteBlockStack() { delete [] block; for (int i = 0; i < stack_size; i++) { delete definite_sets[i]; delete final_sets[i]; } delete [] definite_sets; delete [] final_sets; } private: int stack_size, top_index; AstBlock **block; DefiniteSets **definite_sets, **final_sets; BitSet exit_set; }; // // // class DefiniteTryStack { public: void Push(AstTryStatement *try_statement_) { this -> try_statement[top_index] = try_statement_; top_index++; } void Pop() { if (top_index > 0) top_index--; else assert(0); } int Size() { return top_index; } AstTryStatement *TryStatement(int i) { return try_statement[i]; } AstBlock *Block(int i) { return block[i]; } AstBlock *TopBlock() { assert(top_index > 0); return block[top_index - 1]; } void SetTopBlock(AstBlock *block_) { assert(top_index > 0); block[top_index - 1] = block_; } DefiniteTryStack(int stack_size_) : stack_size(stack_size_), top_index(0) { block = new AstBlock*[stack_size]; try_statement = new AstTryStatement*[stack_size]; } ~DefiniteTryStack() { delete [] block; delete [] try_statement; } private: int stack_size, top_index; AstBlock **block; AstTryStatement **try_statement; }; // // // class SemanticEnvironment { public: Semantic *sem; SemanticEnvironment *previous; MethodSymbol *this_method; VariableSymbol *this_variable; Ast *explicit_constructor_invocation; Ast *ast_construct; SymbolTableStack symbol_table; // Points to symbol table on top of stack ExceptionTableStack try_exception_table_stack; StatementStack try_statement_stack, breakable_statement_stack, continuable_statement_stack; BlockStack block_stack; SemanticEnvironment(Semantic *sem_, TypeSymbol *type_, SemanticEnvironment *previous_ = NULL) : sem(sem_), _type(type_), previous(previous_), next(NULL), this_method(NULL), this_variable(NULL), explicit_constructor_invocation(NULL), ast_construct(NULL) {} ~SemanticEnvironment() { delete next; // if there was any clone, get rid of it } // // Clone the immediate environment of "this" Semantic environment. // The immediate environment consists primarily of the stack of symbol // tables that are necessary for looking up local variables in the immediate // environment. // SemanticEnvironment *GetEnvironment(Ast *ast) { SemanticEnvironment *clone = new SemanticEnvironment(sem, _type, NULL); clone -> this_method = this -> this_method; clone -> this_variable = this -> this_variable; clone -> ast_construct = ast; for (int i = 0; i < this -> symbol_table.Size(); i++) clone -> symbol_table.Push(this -> symbol_table[i]); clone -> next = this -> next; this -> next = clone; return clone; } TypeSymbol *Type() { return _type; } // // Are we in a static area ? // inline bool StaticRegion() { return (this_variable && this_variable -> ACC_STATIC()) || (this_method && this_method -> ACC_STATIC()) || (_type -> ACC_INTERFACE()); } private: TypeSymbol *_type; SemanticEnvironment *next; // use to link an environment to its clones. }; // // // class SemanticEnvironmentStack { public: void Push(SemanticEnvironment *env) { info.Next() = env; } void Pop() { if (info.Length() > 0) info.Reset(info.Length() - 1); return; } int Size() { return info.Length(); } SemanticEnvironment *Top() { return (SemanticEnvironment *) (info.Length() > 0 ? info[info.Length() - 1] : NULL); } SemanticEnvironment *operator[](const int i) { return info[i]; } private: Tuple<SemanticEnvironment *> info; }; class Semantic { public: // // // Control &control; FileSymbol *source_file_symbol; LexStream *lex_stream; AstCompilationUnit *compilation_unit; DirectorySymbol *directory_symbol; SymbolSet types_to_be_processed; int return_code; PackageSymbol *Package() { return this_package; } void CheckPackage(); void ProcessTypeNames(); void ProcessImports(); void ProcessSuperTypes(); LiteralValue *ComputeFinalValue(AstVariableDeclarator *); Semantic(Control &control_, FileSymbol *file_symbol_) : control(control_), source_file_symbol(file_symbol_), compilation_unit(file_symbol_ -> compilation_unit), lex_stream(file_symbol_ -> lex_stream), directory_symbol(file_symbol_ -> directory_symbol), this_package(file_symbol_ -> package), return_code(0), error(NULL), definitely_assigned_variables(NULL), universe(NULL), definite_block_stack(NULL), definite_try_stack(NULL), definite_final_assignment_stack(NULL), definite_visible_variables(NULL), possibly_assigned_finals(NULL) { ProcessExprOrStmt[Ast::LOCAL_VARIABLE_DECLARATION] = &Semantic::ProcessLocalVariableDeclarationStatement; ProcessExprOrStmt[Ast::BLOCK] = &Semantic::ProcessBlock; ProcessExprOrStmt[Ast::EXPRESSION_STATEMENT] = &Semantic::ProcessExpressionStatement; ProcessExprOrStmt[Ast::SYNCHRONIZED_STATEMENT] = &Semantic::ProcessSynchronizedStatement; ProcessExprOrStmt[Ast::IF] = &Semantic::ProcessIfStatement; ProcessExprOrStmt[Ast::WHILE] = &Semantic::ProcessWhileStatement; ProcessExprOrStmt[Ast::FOR] = &Semantic::ProcessForStatement; ProcessExprOrStmt[Ast::SWITCH] = &Semantic::ProcessSwitchStatement; ProcessExprOrStmt[Ast::DO] = &Semantic::ProcessDoStatement; ProcessExprOrStmt[Ast::BREAK] = &Semantic::ProcessBreakStatement; ProcessExprOrStmt[Ast::CONTINUE] = &Semantic::ProcessContinueStatement; ProcessExprOrStmt[Ast::RETURN] = &Semantic::ProcessReturnStatement; ProcessExprOrStmt[Ast::THROW] = &Semantic::ProcessThrowStatement; ProcessExprOrStmt[Ast::TRY] = &Semantic::ProcessTryStatement; ProcessExprOrStmt[Ast::EMPTY_STATEMENT] = &Semantic::ProcessEmptyStatement; ProcessExprOrStmt[Ast::CLASS] = &Semantic::ProcessClassDeclaration; ProcessExprOrStmt[Ast::IDENTIFIER] = &Semantic::ProcessSimpleName; ProcessExprOrStmt[Ast::DOT] = &Semantic::ProcessFieldAccess; ProcessExprOrStmt[Ast::INTEGER_LITERAL] = &Semantic::ProcessIntegerLiteral; ProcessExprOrStmt[Ast::LONG_LITERAL] = &Semantic::ProcessLongLiteral; ProcessExprOrStmt[Ast::FLOATING_POINT_LITERAL] = &Semantic::ProcessFloatingPointLiteral; ProcessExprOrStmt[Ast::DOUBLE_LITERAL] = &Semantic::ProcessDoubleLiteral; ProcessExprOrStmt[Ast::TRUE_LITERAL] = &Semantic::ProcessTrueLiteral; ProcessExprOrStmt[Ast::FALSE_LITERAL] = &Semantic::ProcessFalseLiteral; ProcessExprOrStmt[Ast::STRING_LITERAL] = &Semantic::ProcessStringLiteral; ProcessExprOrStmt[Ast::CHARACTER_LITERAL] = &Semantic::ProcessCharacterLiteral; ProcessExprOrStmt[Ast::NULL_LITERAL] = &Semantic::ProcessNullLiteral; ProcessExprOrStmt[Ast::ARRAY_ACCESS] = &Semantic::ProcessArrayAccess; ProcessExprOrStmt[Ast::CALL] = &Semantic::ProcessMethodInvocation; ProcessExprOrStmt[Ast::THIS_EXPRESSION] = &Semantic::ProcessThisExpression; ProcessExprOrStmt[Ast::SUPER_EXPRESSION] = &Semantic::ProcessSuperExpression; ProcessExprOrStmt[Ast::PARENTHESIZED_EXPRESSION] = &Semantic::ProcessParenthesizedExpression; ProcessExprOrStmt[Ast::CLASS_CREATION] = &Semantic::ProcessClassInstanceCreationExpression; ProcessExprOrStmt[Ast::ARRAY_CREATION] = &Semantic::ProcessArrayCreationExpression; ProcessExprOrStmt[Ast::POST_UNARY] = &Semantic::ProcessPostUnaryExpression; ProcessExprOrStmt[Ast::PRE_UNARY] = &Semantic::ProcessPreUnaryExpression; ProcessExprOrStmt[Ast::CAST] = &Semantic::ProcessCastExpression; ProcessExprOrStmt[Ast::BINARY] = &Semantic::ProcessBinaryExpression; ProcessExprOrStmt[Ast::TYPE] = &Semantic::ProcessTypeExpression; ProcessExprOrStmt[Ast::CONDITIONAL] = &Semantic::ProcessConditionalExpression; ProcessExprOrStmt[Ast::ASSIGNMENT] = &Semantic::ProcessAssignmentExpression; DefiniteStmt[Ast::LOCAL_VARIABLE_DECLARATION] = &Semantic::DefiniteLocalVariableDeclarationStatement; DefiniteStmt[Ast::BLOCK] = &Semantic::DefiniteBlock; DefiniteStmt[Ast::EXPRESSION_STATEMENT] = &Semantic::DefiniteExpressionStatement; DefiniteStmt[Ast::SYNCHRONIZED_STATEMENT] = &Semantic::DefiniteSynchronizedStatement; DefiniteStmt[Ast::IF] = &Semantic::DefiniteIfStatement; DefiniteStmt[Ast::WHILE] = &Semantic::DefiniteWhileStatement; DefiniteStmt[Ast::FOR] = &Semantic::DefiniteForStatement; DefiniteStmt[Ast::SWITCH] = &Semantic::DefiniteSwitchStatement; DefiniteStmt[Ast::DO] = &Semantic::DefiniteDoStatement; DefiniteStmt[Ast::BREAK] = &Semantic::DefiniteBreakStatement; DefiniteStmt[Ast::CONTINUE] = &Semantic::DefiniteContinueStatement; DefiniteStmt[Ast::RETURN] = &Semantic::DefiniteReturnStatement; DefiniteStmt[Ast::THROW] = &Semantic::DefiniteThrowStatement; DefiniteStmt[Ast::TRY] = &Semantic::DefiniteTryStatement; DefiniteStmt[Ast::EMPTY_STATEMENT] = &Semantic::DefiniteEmptyStatement; DefiniteStmt[Ast::CLASS] = &Semantic::DefiniteClassDeclaration; DefiniteExpr[Ast::IDENTIFIER] = &Semantic::DefiniteSimpleName; DefiniteExpr[Ast::DOT] = &Semantic::DefiniteFieldAccess; DefiniteExpr[Ast::ARRAY_ACCESS] = &Semantic::DefiniteArrayAccess; DefiniteExpr[Ast::CALL] = &Semantic::DefiniteMethodInvocation; DefiniteExpr[Ast::PARENTHESIZED_EXPRESSION] = &Semantic::DefiniteParenthesizedExpression; DefiniteExpr[Ast::CLASS_CREATION] = &Semantic::DefiniteClassInstanceCreationExpression; DefiniteExpr[Ast::ARRAY_CREATION] = &Semantic::DefiniteArrayCreationExpression; DefiniteExpr[Ast::POST_UNARY] = &Semantic::DefinitePostUnaryExpression; DefiniteExpr[Ast::PRE_UNARY] = &Semantic::DefinitePreUnaryExpression; DefiniteExpr[Ast::CAST] = &Semantic::DefiniteCastExpression; DefiniteExpr[Ast::CHECK_AND_CAST] = &Semantic::DefiniteCastExpression; DefiniteExpr[Ast::BINARY] = &Semantic::DefiniteBinaryExpression; DefiniteExpr[Ast::CONDITIONAL] = &Semantic::DefiniteConditionalExpression; DefiniteExpr[Ast::ASSIGNMENT] = &Semantic::DefiniteAssignmentExpression; DefiniteExpr[Ast::INTEGER_LITERAL] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::LONG_LITERAL] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::FLOATING_POINT_LITERAL] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::DOUBLE_LITERAL] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::TRUE_LITERAL] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::FALSE_LITERAL] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::STRING_LITERAL] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::CHARACTER_LITERAL] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::NULL_LITERAL] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::THIS_EXPRESSION] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::SUPER_EXPRESSION] = &Semantic::DefiniteDefaultExpression; DefiniteExpr[Ast::TYPE] = &Semantic::DefiniteDefaultExpression; DefiniteBinaryExpr[AstBinaryExpression::PLUS] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::LEFT_SHIFT] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::RIGHT_SHIFT] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::UNSIGNED_RIGHT_SHIFT] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::LESS] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::GREATER] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::LESS_EQUAL] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::GREATER_EQUAL] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::AND] = &Semantic::DefiniteAND; DefiniteBinaryExpr[AstBinaryExpression::XOR] = &Semantic::DefiniteXOR; DefiniteBinaryExpr[AstBinaryExpression::IOR] = &Semantic::DefiniteIOR; DefiniteBinaryExpr[AstBinaryExpression::AND_AND] = &Semantic::DefiniteAND_AND; DefiniteBinaryExpr[AstBinaryExpression::OR_OR] = &Semantic::DefiniteOR_OR; DefiniteBinaryExpr[AstBinaryExpression::EQUAL_EQUAL] = &Semantic::DefiniteEQUAL_EQUAL; DefiniteBinaryExpr[AstBinaryExpression::NOT_EQUAL] = &Semantic::DefiniteNOT_EQUAL; DefiniteBinaryExpr[AstBinaryExpression::STAR] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::MINUS] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::SLASH] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::MOD] = &Semantic::DefiniteDefaultBinaryExpression; DefiniteBinaryExpr[AstBinaryExpression::INSTANCEOF] = &Semantic::DefiniteDefaultBinaryExpression; DefinitePreUnaryExpr[AstPreUnaryExpression::PLUS] = &Semantic::DefiniteDefaultPreUnaryExpression; DefinitePreUnaryExpr[AstPreUnaryExpression::MINUS] = &Semantic::DefiniteDefaultPreUnaryExpression; DefinitePreUnaryExpr[AstPreUnaryExpression::TWIDDLE] = &Semantic::DefiniteDefaultPreUnaryExpression; DefinitePreUnaryExpr[AstPreUnaryExpression::NOT] = &Semantic::DefiniteNOT; DefinitePreUnaryExpr[AstPreUnaryExpression::PLUSPLUS] = &Semantic::DefinitePLUSPLUSOrMINUSMINUS; DefinitePreUnaryExpr[AstPreUnaryExpression::MINUSMINUS] = &Semantic::DefinitePLUSPLUSOrMINUSMINUS; ProcessBinaryExpr[AstBinaryExpression::PLUS] = &Semantic::ProcessPLUS; ProcessBinaryExpr[AstBinaryExpression::LEFT_SHIFT] = &Semantic::ProcessLEFT_SHIFT; ProcessBinaryExpr[AstBinaryExpression::RIGHT_SHIFT] = &Semantic::ProcessRIGHT_SHIFT; ProcessBinaryExpr[AstBinaryExpression::UNSIGNED_RIGHT_SHIFT] = &Semantic::ProcessUNSIGNED_RIGHT_SHIFT; ProcessBinaryExpr[AstBinaryExpression::LESS] = &Semantic::ProcessLESS; ProcessBinaryExpr[AstBinaryExpression::GREATER] = &Semantic::ProcessGREATER; ProcessBinaryExpr[AstBinaryExpression::LESS_EQUAL] = &Semantic::ProcessLESS_EQUAL; ProcessBinaryExpr[AstBinaryExpression::GREATER_EQUAL] = &Semantic::ProcessGREATER_EQUAL; ProcessBinaryExpr[AstBinaryExpression::AND] = &Semantic::ProcessAND; ProcessBinaryExpr[AstBinaryExpression::XOR] = &Semantic::ProcessXOR; ProcessBinaryExpr[AstBinaryExpression::IOR] = &Semantic::ProcessIOR; ProcessBinaryExpr[AstBinaryExpression::AND_AND] = &Semantic::ProcessAND_AND; ProcessBinaryExpr[AstBinaryExpression::OR_OR] = &Semantic::ProcessOR_OR; ProcessBinaryExpr[AstBinaryExpression::EQUAL_EQUAL] = &Semantic::ProcessEQUAL_EQUAL; ProcessBinaryExpr[AstBinaryExpression::NOT_EQUAL] = &Semantic::ProcessNOT_EQUAL; ProcessBinaryExpr[AstBinaryExpression::STAR] = &Semantic::ProcessSTAR; ProcessBinaryExpr[AstBinaryExpression::MINUS] = &Semantic::ProcessMINUS; ProcessBinaryExpr[AstBinaryExpression::SLASH] = &Semantic::ProcessSLASH; ProcessBinaryExpr[AstBinaryExpression::MOD] = &Semantic::ProcessMOD; ProcessBinaryExpr[AstBinaryExpression::INSTANCEOF] = &Semantic::ProcessINSTANCEOF; ProcessPreUnaryExpr[AstPreUnaryExpression::PLUS] = &Semantic::ProcessPLUS; ProcessPreUnaryExpr[AstPreUnaryExpression::MINUS] = &Semantic::ProcessMINUS; ProcessPreUnaryExpr[AstPreUnaryExpression::TWIDDLE] = &Semantic::ProcessTWIDDLE; ProcessPreUnaryExpr[AstPreUnaryExpression::NOT] = &Semantic::ProcessNOT; ProcessPreUnaryExpr[AstPreUnaryExpression::PLUSPLUS] = &Semantic::ProcessPLUSPLUSOrMINUSMINUS; ProcessPreUnaryExpr[AstPreUnaryExpression::MINUSMINUS] = &Semantic::ProcessPLUSPLUSOrMINUSMINUS; } ~Semantic() { delete error; } void ReportSemError(SemanticError::SemanticErrorKind kind, LexStream::TokenIndex ltok, LexStream::TokenIndex rtok, wchar_t *s1 = NULL, wchar_t *s2 = NULL, wchar_t *s3 = NULL, wchar_t *s4 = NULL, wchar_t *s5 = NULL, wchar_t *s6 = NULL, wchar_t *s7 = NULL, wchar_t *s8 = NULL, wchar_t *s9 = NULL) { if (! error) error = new SemanticError(control, source_file_symbol); error -> Report(kind, ltok, rtok, s1, s2, s3, s4, s5, s6, s7, s8, s9); } int NumErrors() { return (error ? error -> num_errors : 0); } // // If we had a bad compilation unit, print the parser messages. // If semantic errors were detected print them too. // Set the return code. // void PrintMessages() { if (this != control.system_semantic) { if (lex_stream -> NumBadTokens() > 0) { lex_stream -> PrintMessages(); return_code = 1; } if ((! compilation_unit) || compilation_unit -> BadCompilationUnitCast()) { DiagnoseParser *diagnose_parser = new DiagnoseParser(control, lex_stream); return_code = 1; delete diagnose_parser; } if (compilation_unit) CleanUp(); } if (error && error -> error.Length() > 0 && error -> PrintMessages() > return_code) return_code = 1; // // Once we have processed the errors, reset the error object // delete error; error = NULL; return; } TypeSymbol *ProcessSignature(TypeSymbol *, char *, LexStream::TokenIndex); void ConvertUtf8ToUnicode(wchar_t *, char *, int); TypeSymbol *ReadType(FileSymbol *, PackageSymbol *, NameSymbol *, LexStream::TokenIndex); TypeSymbol *ReadType(TypeSymbol *, wchar_t *, LexStream::TokenIndex); TypeSymbol *ProcessNestedType(TypeSymbol *, NameSymbol *, LexStream::TokenIndex); private: SemanticError *error; void CleanUp(); void CleanUpType(TypeSymbol *); void ProcessOuterType(AstClassDeclaration *); void ProcessOuterType(AstInterfaceDeclaration *); void ProcessTypeHeader(AstClassDeclaration *); void MarkCircularNest(TypeSymbol *); void ProcessSuperTypesOfOuterType(TypeSymbol *); void ProcessSuperTypesOfInnerType(TypeSymbol *, Tuple<TypeSymbol *> &); void ProcessTypeHeaders(AstClassDeclaration *); TypeSymbol *FindTypeInLayer(Ast *, SymbolSet &); void ProcessNestedSuperTypes(TypeSymbol *); void ProcessNestedTypeHeaders(TypeSymbol *, AstClassBody *); void ProcessTypeHeader(AstInterfaceDeclaration *); void ProcessTypeHeaders(AstInterfaceDeclaration *); void ProcessNestedTypeHeaders(AstInterfaceDeclaration *); void ProcessConstructorMembers(AstClassBody *); void ProcessMethodMembers(AstClassBody *); void ProcessFieldMembers(AstClassBody *); void ProcessMembers(SemanticEnvironment *, AstClassBody *); void CompleteSymbolTable(SemanticEnvironment *, LexStream::TokenIndex, AstClassBody *); void ProcessExecutableBodies(SemanticEnvironment *, AstClassBody *); void ProcessExecutableBodies(AstInterfaceDeclaration *); void ProcessMethodMembers(AstInterfaceDeclaration *); void ProcessFieldMembers(AstInterfaceDeclaration *); void ProcessMembers(AstInterfaceDeclaration *); void CompleteSymbolTable(AstInterfaceDeclaration *); friend class TypeSymbol; Tuple<Symbol *> import_on_demand_packages; Tuple<TypeSymbol *> single_type_imports; // // Where am I? // PackageSymbol *this_package; TypeSymbol *ThisType() { return state_stack.Top() -> Type(); } MethodSymbol *&ThisMethod() { return state_stack.Top() -> this_method; } VariableSymbol *&ThisVariable() { return state_stack.Top() -> this_variable; } Ast *&ExplicitConstructorInvocation() { return state_stack.Top() -> explicit_constructor_invocation; } SymbolTableStack &LocalSymbolTable() { return state_stack.Top() -> symbol_table; } ExceptionTableStack &TryExceptionTableStack() { return state_stack.Top() -> try_exception_table_stack; } StatementStack &TryStatementStack() { return state_stack.Top() -> try_statement_stack; } StatementStack &BreakableStatementStack() { return state_stack.Top() -> breakable_statement_stack; } StatementStack &ContinuableStatementStack() { return state_stack.Top() -> continuable_statement_stack; } BlockStack &LocalBlockStack() { return state_stack.Top() -> block_stack; } SemanticEnvironment *GetEnvironment(Ast *ast) { return state_stack.Top() -> GetEnvironment(ast); } bool StaticRegion() { return state_stack.Top() -> StaticRegion(); } SemanticEnvironmentStack state_stack; BitSet *definitely_assigned_variables, *possibly_assigned_finals, *universe; DefiniteBlockStack *definite_block_stack; DefiniteTryStack *definite_try_stack; DefiniteFinalAssignmentStack *definite_final_assignment_stack; SymbolSet *definite_visible_variables; bool IsIntValueRepresentableInType(AstExpression *, TypeSymbol *); void CheckClassMembers(TypeSymbol *, AstClassBody *); void CheckNestedTypeDuplication(SemanticEnvironment *, LexStream::TokenIndex); TypeSymbol *ProcessNestedClassName(TypeSymbol *, AstClassDeclaration *); void CheckInterfaceMembers(TypeSymbol *, AstInterfaceDeclaration *); TypeSymbol *ProcessNestedInterfaceName(TypeSymbol *, AstInterfaceDeclaration *); TypeSymbol *FindTypeInShadow(TypeShadowSymbol *, LexStream::TokenIndex); void ReportTypeInaccessible(LexStream::TokenIndex, LexStream::TokenIndex, TypeSymbol *); void ReportTypeInaccessible(Ast *ast, TypeSymbol *type) { ReportTypeInaccessible(ast -> LeftToken(), ast -> RightToken(), type); } TypeSymbol *GetBadNestedType(TypeSymbol *, LexStream::TokenIndex); TypeSymbol *FindNestedType(TypeSymbol *, LexStream::TokenIndex); TypeSymbol *MustFindNestedType(TypeSymbol *, Ast *); Symbol *ProcessImportQualifiedName(AstExpression *); Symbol *ProcessPackageOrType(AstExpression *); void ProcessTypeImportOnDemandDeclaration(AstImportDeclaration *); AstExpression *FindFirstType(Ast *); TypeSymbol *FindSimpleNameType(PackageSymbol *, LexStream::TokenIndex); void ProcessSingleTypeImportDeclaration(AstImportDeclaration *); AccessFlags ProcessClassModifiers(AstClassDeclaration *); AccessFlags ProcessLocalClassModifiers(AstClassDeclaration *); AccessFlags ProcessNestedClassModifiers(AstClassDeclaration *); AccessFlags ProcessStaticNestedClassModifiers(AstClassDeclaration *); AccessFlags ProcessInterfaceModifiers(AstInterfaceDeclaration *); AccessFlags ProcessNestedInterfaceModifiers(AstInterfaceDeclaration *); AccessFlags ProcessFieldModifiers(AstFieldDeclaration *); AccessFlags ProcessLocalModifiers(AstLocalVariableDeclarationStatement *); AccessFlags ProcessFormalModifiers(AstFormalParameter *); AccessFlags ProcessMethodModifiers(AstMethodDeclaration *); AccessFlags ProcessConstructorModifiers(AstConstructorDeclaration *); AccessFlags ProcessConstantModifiers(AstFieldDeclaration *); AccessFlags ProcessAbstractMethodModifiers(AstMethodDeclaration *); void AddDefaultConstructor(TypeSymbol *); void ProcessConstructorDeclaration(AstConstructorDeclaration *); void ProcessMethodDeclaration(AstMethodDeclaration *); void ProcessFieldDeclaration(AstFieldDeclaration *); void ProcessFormalParameters(BlockSymbol *, AstMethodDeclarator *); TypeSymbol *ImportType(LexStream::TokenIndex, NameSymbol *); TypeSymbol *FindPrimitiveType(AstPrimitiveType *); TypeSymbol *FindTypeInEnvironment(SemanticEnvironment *, NameSymbol *); TypeSymbol *FindType(LexStream::TokenIndex); TypeSymbol *MustFindType(Ast *); void ProcessInterface(AstExpression *); void InitializeVariable(AstFieldDeclaration *, Tuple<VariableSymbol *> &); void ProcessInitializer(AstBlock *, AstBlock *, MethodSymbol *, Tuple<VariableSymbol *> &); void ProcessStaticInitializers(AstClassBody *); void ProcessBlockInitializers(AstClassBody *); bool CanWideningPrimitiveConvert(TypeSymbol *, TypeSymbol *); bool CanNarrowingPrimitiveConvert(TypeSymbol *, TypeSymbol *); bool CanCastConvert(TypeSymbol *, TypeSymbol *, LexStream::TokenIndex); bool CanMethodInvocationConvert(TypeSymbol *, TypeSymbol *); bool CanAssignmentConvert(TypeSymbol *, AstExpression *); bool CanAssignmentConvertReference(TypeSymbol *, TypeSymbol *); LiteralValue *CastPrimitiveValue(TypeSymbol *, AstExpression *); LiteralValue *CastValue(TypeSymbol *, AstExpression *); AstExpression *ConvertToType(AstExpression *, TypeSymbol *); AstExpression *PromoteUnaryNumericExpression(AstExpression *); void BinaryNumericPromotion(AstAssignmentExpression *); void BinaryNumericPromotion(AstBinaryExpression *); void BinaryNumericPromotion(AstConditionalExpression *); void (Semantic::*DefiniteStmt[Ast::_num_kinds])(Ast *); inline void DefiniteStatement(Ast *ast) { (this ->* DefiniteStmt[ast -> kind])(ast); } void DefiniteLoopBody(AstStatement *); void DefiniteBlock(Ast *); void DefiniteLocalVariableDeclarationStatement(Ast *); void DefiniteExpressionStatement(Ast *); void DefiniteSynchronizedStatement(Ast *); void DefiniteIfStatement(Ast *); void DefiniteWhileStatement(Ast *); void DefiniteForStatement(Ast *); void DefiniteSwitchStatement(Ast *); void DefiniteDoStatement(Ast *); void DefiniteBreakStatement(Ast *); void DefiniteContinueStatement(Ast *); void DefiniteReturnStatement(Ast *); void DefiniteThrowStatement(Ast *); void DefiniteTryStatement(Ast *); void DefiniteEmptyStatement(Ast *); void DefiniteClassDeclaration(Ast *); VariableSymbol *DefiniteFinal(AstFieldAccess *); DefiniteAssignmentSet *(Semantic::*DefiniteExpr[Ast::_num_expression_kinds])(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteSimpleName(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteArrayAccess(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteMethodInvocation(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteClassInstanceCreationExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteArrayCreationExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefinitePreUnaryExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefinitePostUnaryExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteBinaryExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteConditionalExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteAssignmentExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteDefaultExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteFieldAccess(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteParenthesizedExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteCastExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *(Semantic::*DefinitePreUnaryExpr[AstPreUnaryExpression::_num_kinds])(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteDefaultPreUnaryExpression(AstExpression *, BitSet &); DefiniteAssignmentSet *DefiniteNOT(AstExpression *, BitSet &); DefiniteAssignmentSet *DefinitePLUSPLUSOrMINUSMINUS(AstExpression *, BitSet &); DefiniteAssignmentSet *(Semantic::*DefiniteBinaryExpr[AstBinaryExpression::_num_kinds])(AstBinaryExpression *, BitSet &); DefiniteAssignmentSet *DefiniteDefaultBinaryExpression(AstBinaryExpression *, BitSet &); DefiniteAssignmentSet *DefiniteAND(AstBinaryExpression *, BitSet &); DefiniteAssignmentSet *DefiniteIOR(AstBinaryExpression *, BitSet &); DefiniteAssignmentSet *DefiniteXOR(AstBinaryExpression *, BitSet &); DefiniteAssignmentSet *DefiniteAND_AND(AstBinaryExpression *, BitSet &); DefiniteAssignmentSet *DefiniteOR_OR(AstBinaryExpression *, BitSet &); DefiniteAssignmentSet *DefiniteEQUAL_EQUAL(AstBinaryExpression *, BitSet &); DefiniteAssignmentSet *DefiniteNOT_EQUAL(AstBinaryExpression *, BitSet &); DefiniteAssignmentSet *DefiniteAssignmentAND(TypeSymbol *, BitSet *, BitSet &, DefiniteAssignmentSet *, DefiniteAssignmentSet *); DefiniteAssignmentSet *DefiniteAssignmentIOR(TypeSymbol *, BitSet *, BitSet &, DefiniteAssignmentSet *, DefiniteAssignmentSet *); DefiniteAssignmentSet *DefiniteAssignmentXOR(TypeSymbol *, BitSet *, BitSet &, DefiniteAssignmentSet *, DefiniteAssignmentSet *); void DefiniteArrayInitializer(AstArrayInitializer *); void DefiniteVariableInitializer(AstVariableDeclarator *); void DefiniteBlockStatements(AstBlock *); void DefiniteMethodBody(AstMethodDeclaration *, Tuple<VariableSymbol *> &); void DefiniteConstructorBody(AstConstructorDeclaration *, Tuple<VariableSymbol *> &); void DefiniteBlockInitializer(AstBlock *, int, Tuple<VariableSymbol *> &); void DefiniteVariableInitializer(AstVariableDeclarator *, Tuple<VariableSymbol *> &); void ProcessBlockStatements(AstBlock *); void ProcessThisCall(AstThisCall *); void ProcessSuperCall(AstSuperCall *); void CheckThrow(AstExpression *); void ProcessMethodBody(AstMethodDeclaration *); void ProcessConstructorBody(AstConstructorDeclaration *, bool); bool CatchableException(TypeSymbol *); void ReportMethodNotFound(Ast *ast, wchar_t *); MethodSymbol *FindConstructor(TypeSymbol *, Ast *, LexStream::TokenIndex, LexStream::TokenIndex); bool MoreSpecific(MethodSymbol *, MethodSymbol *); bool MoreSpecific(MethodSymbol *, Tuple<MethodSymbol *> &); bool NoMethodMoreSpecific(Tuple<MethodSymbol *> &, MethodSymbol *); void SearchForMethodInEnvironment(Tuple<MethodSymbol *> &, SemanticEnvironment *&, SemanticEnvironment *, AstMethodInvocation *); MethodSymbol *FindMisspelledMethodName(TypeSymbol *, AstMethodInvocation *, NameSymbol *); MethodSymbol *FindMethodInEnvironment(SemanticEnvironment *&, SemanticEnvironment *, AstMethodInvocation *); MethodSymbol *FindMethodInType(TypeSymbol *, AstMethodInvocation *, NameSymbol * = NULL); void ReportAccessedFieldNotFound(AstFieldAccess *, TypeSymbol *); void SearchForVariableInEnvironment(Tuple<VariableSymbol *> &, SemanticEnvironment *&, SemanticEnvironment *, NameSymbol *, LexStream::TokenIndex); VariableSymbol *FindMisspelledVariableName(TypeSymbol *, LexStream::TokenIndex); VariableSymbol *FindVariableInEnvironment(SemanticEnvironment *&, SemanticEnvironment *, LexStream::TokenIndex); VariableSymbol *FindVariableInType(TypeSymbol *, AstFieldAccess *, NameSymbol * = NULL); VariableSymbol *FindInstance(TypeSymbol *, TypeSymbol *); AstExpression *CreateAccessToType(Ast *, TypeSymbol *); void CreateAccessToScopedVariable(AstSimpleName *, TypeSymbol *); void CreateAccessToScopedMethod(AstMethodInvocation *, TypeSymbol *); void TypeAccessCheck(Ast *, TypeSymbol *); void TypeNestAccessCheck(AstExpression *); void ConstructorAccessCheck(AstClassInstanceCreationExpression *, MethodSymbol *); void MemberAccessCheck(AstFieldAccess *, TypeSymbol *, TypeSymbol *, Symbol *); void SimpleNameAccessCheck(AstSimpleName *, TypeSymbol *, Symbol *); void (Semantic::*ProcessPreUnaryExpr[AstPreUnaryExpression::_num_kinds])(AstPreUnaryExpression *); void ProcessPLUS(AstPreUnaryExpression *); void ProcessMINUS(AstPreUnaryExpression *); void ProcessTWIDDLE(AstPreUnaryExpression *); void ProcessNOT(AstPreUnaryExpression *); void ProcessPLUSPLUSOrMINUSMINUS(AstPreUnaryExpression *); void (Semantic::*ProcessBinaryExpr[AstBinaryExpression::_num_kinds])(AstBinaryExpression *); void ProcessPLUS(AstBinaryExpression *); void ProcessLEFT_SHIFT(AstBinaryExpression *); void ProcessRIGHT_SHIFT(AstBinaryExpression *); void ProcessUNSIGNED_RIGHT_SHIFT(AstBinaryExpression *); void ProcessLESS(AstBinaryExpression *); void ProcessGREATER(AstBinaryExpression *); void ProcessLESS_EQUAL(AstBinaryExpression *); void ProcessGREATER_EQUAL(AstBinaryExpression *); void ProcessAND(AstBinaryExpression *); void ProcessXOR(AstBinaryExpression *); void ProcessIOR(AstBinaryExpression *); void ProcessAND_AND(AstBinaryExpression *); void ProcessOR_OR(AstBinaryExpression *); void ProcessEQUAL_EQUAL(AstBinaryExpression *); void ProcessNOT_EQUAL(AstBinaryExpression *); void ProcessSTAR(AstBinaryExpression *); void ProcessMINUS(AstBinaryExpression *); void ProcessSLASH(AstBinaryExpression *); void ProcessMOD(AstBinaryExpression *); void ProcessINSTANCEOF(AstBinaryExpression *); MethodSymbol *FindMethodMember(TypeSymbol *, AstMethodInvocation *); void ProcessMethodName(AstMethodInvocation *); void (Semantic::*ProcessExprOrStmt[Ast::_num_kinds])(Ast *); inline void ProcessStatement(AstStatement *stmt) { (this ->* ProcessExprOrStmt[stmt -> kind])(stmt); } inline void ProcessExpression(AstExpression *expr) { (this ->* ProcessExprOrStmt[expr -> kind])(expr); } inline void ProcessExpressionOrStringConstant(AstExpression *expr) { (this ->* ProcessExprOrStmt[expr -> kind])(expr); // // If the expression is ot type String, check whether or not it is // constant, and if so, compute the result. // if (expr -> symbol == control.String() && (! expr -> IsConstant())) control.Utf8_pool.CheckStringConstant(expr); return; } void ProcessLocalVariableDeclarationStatement(Ast *); void ProcessBlock(Ast *); void ProcessForStatement(Ast *); void ProcessSwitchStatement(Ast *); void ProcessThrowStatement(Ast *); void ProcessTryStatement(Ast *); void ProcessExpressionStatement(Ast *); void ProcessSynchronizedStatement(Ast *); void ProcessIfStatement(Ast *); void ProcessWhileStatement(Ast *); void ProcessDoStatement(Ast *); void ProcessBreakStatement(Ast *); void ProcessContinueStatement(Ast *); void ProcessReturnStatement(Ast *); void ProcessEmptyStatement(Ast *); TypeSymbol *GetLocalType(AstClassDeclaration *); void ProcessClassDeclaration(Ast *); void GenerateLocalConstructor(MethodSymbol *); void ProcessSimpleName(Ast *); void FindVariableMember(TypeSymbol *, AstFieldAccess *); void ProcessAmbiguousName(Ast *); void ProcessFieldAccess(Ast *); void ProcessIntegerLiteral(Ast *); void ProcessLongLiteral(Ast *); void ProcessFloatingPointLiteral(Ast *); void ProcessDoubleLiteral(Ast *); void ProcessTrueLiteral(Ast *); void ProcessFalseLiteral(Ast *); void ProcessStringLiteral(Ast *); void ProcessCharacterLiteral(Ast *); void ProcessArrayAccess(Ast *); void ProcessMethodInvocation(Ast *); void ProcessNullLiteral(Ast *); void ProcessThisExpression(Ast *); void ProcessSuperExpression(Ast *); void ProcessParenthesizedExpression(Ast *); void UpdateGeneratedLocalConstructor(MethodSymbol *); void UpdateLocalConstructors(TypeSymbol *); void GetAnonymousConstructor(AstClassInstanceCreationExpression *, TypeSymbol *); TypeSymbol *GetAnonymousType(AstClassInstanceCreationExpression *, TypeSymbol *); void ProcessClassInstanceCreationExpression(Ast *); void ProcessArrayCreationExpression(Ast *); void ProcessPostUnaryExpression(Ast *); void ProcessPreUnaryExpression(Ast *); void ProcessCastExpression(Ast *); void ProcessBinaryExpression(Ast *); void ProcessTypeExpression(Ast *); void ProcessConditionalExpression(Ast *); void ProcessAssignmentExpression(Ast *); void ProcessVariableInitializer(AstVariableDeclarator *); void ProcessArrayInitializer(AstArrayInitializer *, TypeSymbol *); void CheckInheritedMethodThrows(AstMethodDeclaration *, MethodSymbol *); void CheckMethodOverride(AstMethodDeclaration *, MethodSymbol *); void CheckInheritedMethodThrows(AstClassDeclaration *, MethodSymbol *, MethodSymbol *); void CheckMethodOverride(AstClassDeclaration *, MethodSymbol *, MethodSymbol *); void AddInheritedTypes(TypeSymbol *, TypeSymbol *); void AddInheritedFields(TypeSymbol *, TypeSymbol *); void AddInheritedMethods(TypeSymbol *, TypeSymbol *, LexStream::TokenIndex); void ComputeTypesClosure(TypeSymbol *, LexStream::TokenIndex); void ComputeFieldsClosure(TypeSymbol *, LexStream::TokenIndex); void ComputeMethodsClosure(TypeSymbol *, LexStream::TokenIndex); inline bool InRange(char *buffer_ptr, char *buffer_tail, int size) { return ((buffer_ptr + size) <= buffer_tail); } TypeSymbol *RetrieveNestedTypes(TypeSymbol *, wchar_t *, LexStream::TokenIndex); TypeSymbol *GetClassPool(TypeSymbol *, TypeSymbol **, char **, int, LexStream::TokenIndex); void ProcessBadClass(TypeSymbol *, LexStream::TokenIndex); bool ProcessClassFile(TypeSymbol *, char *, int, LexStream::TokenIndex); void ReadClassFile(TypeSymbol *, LexStream::TokenIndex); // // Any exception that is neither RuntimeException or one of its subclasses nor // Error or one of its subclasses is a checked exception. // inline bool CheckedException(TypeSymbol *exception) { return (! (exception -> IsSubclass(control.RuntimeException()) || exception -> IsSubclass(control.Error()))); } public: static inline u1 GetU1(char *); static inline u2 GetU2(char *); static inline u4 GetU4(char *); static inline u1 GetAndSkipU1(char *&); static inline u2 GetAndSkipU2(char *&); static inline u4 GetAndSkipU4(char *&); static inline void Skip(char *&, int); inline void AddDependence(TypeSymbol *, TypeSymbol *, LexStream::TokenIndex); inline void SetObjectSuperType(TypeSymbol *, LexStream::TokenIndex); inline void AddStringConversionDependence(TypeSymbol *, LexStream::TokenIndex); }; inline void Semantic::AddDependence(TypeSymbol *base_type_, TypeSymbol *parent_type_, LexStream::TokenIndex tok) { TypeSymbol *base_type = base_type_ -> outermost_type, *parent_type = parent_type_ -> outermost_type; parent_type -> dependents -> AddElement(base_type); base_type -> parents -> AddElement(parent_type); if (control.option.pedantic) { if (parent_type -> ContainingPackage() == control.unnamed_package && base_type -> ContainingPackage() != control.unnamed_package) { error -> Report(SemanticError::PARENT_TYPE_IN_UNNAMED_PACKAGE, tok, tok, parent_type_ -> ContainingPackage() -> PackageName(), parent_type_ -> ExternalName()); } } return; } inline void Semantic::SetObjectSuperType(TypeSymbol *type, LexStream::TokenIndex tok) { type -> super = control.Object(); AddDependence(type, type -> super, tok); } inline void Semantic::AddStringConversionDependence(TypeSymbol *type, LexStream::TokenIndex tok) { if (type == control.boolean_type) AddDependence(ThisType(), control.Boolean(), tok); else if (type == control.char_type) AddDependence(ThisType(), control.Character(), tok); else if (type == control.int_type) AddDependence(ThisType(), control.Integer(), tok); else if (type == control.long_type) AddDependence(ThisType(), control.Long(), tok); else if (type == control.float_type) AddDependence(ThisType(), control.Float(), tok); else // (type == control.double_type) AddDependence(ThisType(), control.Double(), tok); } #endif