// $Id: ast.h,v 1.74 2004/03/25 13:32:26 ericb Exp $ -*- c++ -*- // // 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. // #ifndef ast_INCLUDED #define ast_INCLUDED #include "platform.h" #include "depend.h" #ifdef HAVE_JIKES_NAMESPACE namespace Jikes { // Open namespace Jikes block #endif class Parser; class SemanticEnvironment; class LexStream; class LiteralValue; class Symbol; class BlockSymbol; class VariableSymbol; class MethodSymbol; class TypeSymbol; class StoragePool; struct CaseElement; class VariableSymbolArray { typedef VariableSymbol* T; T** base; size_t base_size; unsigned top; unsigned size; StoragePool* pool; unsigned short log_blksize; unsigned short base_increment; inline size_t Blksize() { return 1 << log_blksize; } // // Allocate another block of storage for the VariableSymbol array. // void AllocateMoreSpace(); public: // // This function is used to reset the size of a VariableSymbol array // without allocating or deallocting space. It may be invoked with an // integer argument n which indicates the new size or with no argument // which indicates that the size should be reset to 0. // void Reset(unsigned n = 0) { assert(n <= size); top = n; } // // Return length of the VariableSymbol array. // unsigned Length() { return top; } // // Return a reference to the ith element of the VariableSymbol array. // // Note that no check is made here to ensure that 0 <= i < top. // Such a check might be useful for debugging and a range exception // should be thrown if it yields true. // T& operator[](unsigned i) { return base[i >> log_blksize][i]; } // // Add an element to the VariableSymbol array and return the top index. // unsigned NextIndex() { unsigned i = top++; if (i == size) AllocateMoreSpace(); return i; } // // Add an element to the VariableSymbol array and return a reference to // that new element. // T& Next() { unsigned i = NextIndex(); return base[i >> log_blksize][i]; } // // Constructor of a VariableSymbol array. // VariableSymbolArray(StoragePool*, unsigned); // // Destructor of an VariableSymbol array. // ~VariableSymbolArray() { assert(false); } }; //*************************************************************************** // // TODO: This documentation is a bit out of date... // // This file contains the definitions of the classes used to construct the // AST representation of a Java program. // // The node Ast is a base class of all other classes. (The name of the other // classes start with the prefix "Ast".) The nodes associated with executable // statements (e.g., AstIfStatement) are subclasses of AstStatement and nodes // associated with expressions (e.g., AstBinaryExpression) are subclasses of // AstExpression. // // The information contained in the AST nodes is described by a grammar where // each rule consists of a left-hand side nonterminal followed by "-->" // followed by a right-hand side symbol or a sequence enclosed in the pair of // symbols "<" and ">". In defining the symbols, the following notation is // used: // // Symbols that are capitalized (e.g., Type) are nonterminals. Symbols that are // in all upper case (e.g., PACKAGE) represent node kinds. Symbols that contain // the substring "_token" represents tokens in the source file. The suffix // "_opt" indicates that a symbol is optional. For example, if Super_opt // appears in a rule, it indicates that either Super or null can be expected. // When a symbol is plural (e.g., Modifiers), it indicates zero or more // instances of such a symbol (a list to be precise) can be expected. Thus, // when "Modifiers" is specified in the right-hand side of a rule either no // Modifier or a sequence of them may appear. // // Implementation Notes: // // A complete AST tree for a Java program always contains an // AstCompilationUnit root node. The kind of that node is // Ast::EMPTY_COMPILATION for a tree with no type declaration, // Ast::COMPILATION for a tree constructed from an otherwise valid program // and Ast::BAD_COMPILATION for a tree constructed from an invalid program. // // All AST tree nodes belong to a StoragePool. When a new node must be // added, it is allocated from the same StoragePool. Thus, you should // never use operator new to construct an AST object, but instead use New* // or Gen* defined in StoragePool. Likewise, AST tree nodes never need // destruction - simply delete the pool to reclaim the entire tree. // // When the preprocessor variable JIKES_DEBUG is defined the user may print // out an AST tree to standard output by calling the virtual function // "Print" for the root node of the tree. // // DynamicArrays are used to implement lists. This representation has the // advantage of being very flexible and easy to use. However, it may be // slightly less time-efficient than a straightforward linked list. My // guess is no more than 10% which justifies this use, but that should be // checked at some point... // //*************************************************************************** // // This is a complete list of all Ast nodes declared here to allow // forward references. // class Ast; template class AstArray; class AstListNode; class AstDeclared; class AstDeclaredType; class AstStatement; class AstMemberValue; class AstExpression; class AstType; class AstBlock; class AstName; class AstPrimitiveType; class AstBrackets; class AstArrayType; class AstWildcard; class AstTypeArguments; class AstTypeName; class AstMemberValuePair; class AstAnnotation; class AstModifierKeyword; class AstModifiers; class AstPackageDeclaration; class AstImportDeclaration; class AstCompilationUnit; class AstEmptyDeclaration; class AstClassBody; class AstTypeParameter; class AstTypeParameters; class AstClassDeclaration; class AstArrayInitializer; class AstVariableDeclaratorId; class AstVariableDeclarator; class AstFieldDeclaration; class AstFormalParameter; class AstMethodDeclarator; class AstMethodBody; class AstMethodDeclaration; class AstInitializerDeclaration; class AstArguments; class AstThisCall; class AstSuperCall; class AstConstructorDeclaration; class AstEnumDeclaration; class AstEnumConstant; class AstInterfaceDeclaration; class AstAnnotationDeclaration; class AstLocalVariableStatement; class AstLocalClassStatement; class AstIfStatement; class AstEmptyStatement; class AstExpressionStatement; class AstSwitchLabel; class AstSwitchBlockStatement; class AstSwitchStatement; class AstWhileStatement; class AstDoStatement; class AstForStatement; class AstForeachStatement; class AstBreakStatement; class AstContinueStatement; class AstReturnStatement; class AstThrowStatement; class AstSynchronizedStatement; class AstAssertStatement; class AstCatchClause; class AstFinallyClause; class AstTryStatement; class AstIntegerLiteral; class AstLongLiteral; class AstFloatLiteral; class AstDoubleLiteral; class AstTrueLiteral; class AstFalseLiteral; class AstStringLiteral; class AstCharacterLiteral; class AstNullLiteral; class AstClassLiteral; class AstThisExpression; class AstSuperExpression; class AstParenthesizedExpression; class AstClassCreationExpression; class AstDimExpr; class AstArrayCreationExpression; class AstFieldAccess; class AstMethodInvocation; class AstArrayAccess; class AstPostUnaryExpression; class AstPreUnaryExpression; class AstCastExpression; class AstBinaryExpression; class AstInstanceofExpression; class AstConditionalExpression; class AstAssignmentExpression; // // The Ast base node. // class Ast { public: // // These tags are used to identify nodes that can represent more than // one kind of objects. // enum AstTag { NO_TAG, PRIMITIVE_TYPE, STATEMENT, EXPRESSION, _num_tags = EXPRESSION }; // // These are the different kinds for the Ast objects. // enum AstKind { AST, // must be first // Expressions NAME, DOT, INTEGER_LITERAL, LONG_LITERAL, FLOAT_LITERAL, DOUBLE_LITERAL, TRUE_LITERAL, FALSE_LITERAL, STRING_LITERAL, CHARACTER_LITERAL, NULL_LITERAL, CLASS_LITERAL, THIS_EXPRESSION, SUPER_EXPRESSION, PARENTHESIZED_EXPRESSION, ARRAY_ACCESS, CALL, CLASS_CREATION, ARRAY_CREATION, POST_UNARY, PRE_UNARY, CAST, BINARY, INSTANCEOF, CONDITIONAL, ASSIGNMENT, _num_expression_kinds, // Statements THIS_CALL, SUPER_CALL, BLOCK, IF, EMPTY_STATEMENT, EXPRESSION_STATEMENT, SWITCH, SWITCH_BLOCK, LOCAL_VARIABLE_DECLARATION, LOCAL_CLASS, WHILE, DO, FOR, FOREACH, BREAK, CONTINUE, RETURN, THROW, SYNCHRONIZED_STATEMENT, ASSERT, TRY, _num_expr_or_stmt_kinds, // All others ARGUMENTS = _num_expr_or_stmt_kinds, DIM, LIST_NODE, INT, DOUBLE, CHAR, LONG, FLOAT, BYTE, SHORT, BOOLEAN, VOID_TYPE, ARRAY, WILDCARD, TYPE_ARGUMENTS, TYPE, COMPILATION, MEMBER_VALUE_PAIR, ANNOTATION, MODIFIER_KEYWORD, MODIFIERS, PACKAGE, IMPORT, EMPTY_DECLARATION, CLASS, TYPE_PARAM, PARAM_LIST, CLASS_BODY, FIELD, VARIABLE_DECLARATOR, VARIABLE_DECLARATOR_NAME, BRACKETS, METHOD, METHOD_DECLARATOR, PARAMETER, CONSTRUCTOR, ENUM_TYPE, ENUM, INTERFACE, ANNOTATION_TYPE, ARRAY_INITIALIZER, INITIALIZER, METHOD_BODY, SWITCH_LABEL, CATCH, FINALLY, _num_kinds }; // // Every node has a unique kind, and class_tag marks groups of similar // nodes. The bit-fields allow smaller Ast objects without sacrificing // type-safety or debug visibility. // const AstKind kind : 8; const AstTag class_tag : 8; // // This is a catch-all set of bits free for the use of subclasses. // See CompilationTag, FieldDeclarationTag, InitializerDeclarationTag, // ClassBodyTag, BlockTag, PreUnaryExpressionTag, PostUnaryExpressionTag, // BinaryExpressionTag, AssignmentExpressionTag. // protected: unsigned other_tag : 8; // // "generated" is a boolean value that indicates whether or not a node // is associated with a construct in a source file or that is was generated // by the compiler. See functions "gen_ ..." and "new_ ..." below. // public: bool generated; #ifdef JIKES_DEBUG const unsigned id; static unsigned count; static bool debug_unparse; #endif // JIKES_DEBUG // // Note that ALL fields of an Ast are initialized to 0 unless modified // by the constructor, thanks to the 0-initialization guaranteed by // operator new. This allows for more efficiency by not redundantly // setting a field to 0, false, or NULL. // inline Ast(AstKind k, AstTag t = NO_TAG) : kind(k) , class_tag(t) #ifdef JIKES_DEBUG , id(++count) #endif // JIKES_DEBUG {} // // Ast nodes should be created from a storage pool. Use the syntax // new (pool) AstSubclass(constructor arguments). The resultant Ast // will be zero-initialized except for what the constructor explicitly // sets, due to the properties of StoragePool. Note that there are // no Ast[]; rather, use AstArray. // inline void* operator new(size_t, StoragePool*); private: void* operator new[](size_t, void* p) { assert(false); return p; } public: // // ASTs should not be destructed. Instead, delete the containing // StoragePool. // virtual ~Ast() { assert(false && "Use the associated StoragePool"); } #ifdef JIKES_DEBUG virtual void Print(LexStream&) = 0; virtual void Unparse(Ostream&, LexStream*) = 0; #endif // JIKES_DEBUG // // General queries. // bool IsLeftHandSide(); bool IsExplicitConstructorInvocation(); bool IsGenerated(); // // The Conversion functions below are provided as a convenient way to // cast a generic Ast node into a specific node. Note that if one knows // the type of a node for sure, it is more efficient to use a specific // cast expression. For example, if one knows that a "Ast* p" pointer // dereferences a FieldDeclaration then a cast expression should be // used to cast p, as follows: // // AstFieldDeclaration* fp = (FieldDeclaration*) p; // // However, if p points to a ClassBodyDeclaration, it may be a // FieldDeclaration, MethodDeclaration, ConstructorDeclaration, // InitializerDeclaration, ClassDeclaration, EnumDeclaration, // InterfaceDeclaration, or AnnotationDeclaration; and the following // sequence of code may be used: // // AstFieldDeclaration* fp = FieldDeclarationCast(); // AstMethodDeclaration* mp = MethodDeclarationCast(); // AstConstructorDeclaration* cp = ConstructorDeclarationCast(); // AstInitializerDeclaration* sp = InitializerdeclarationCast(); // AstClassDeclaration* Cp = ClassDeclarationCast(); // 1.1 only // AstEnumDeclaration* Ep = EnumDeclarationCast(); // 1.5 only // AstInterfaceDeclaration* Ip = InterfaceDeclarationCast(); // 1.1 only // AstAnnotationDeclaration* Ap = AnnotationDeclarationCast(); // 1.5 // // if (fp) // ... // else if (mp) // ... // else if (cp) // ... // else if (sp) // ... // else if (Cp) // ... // else if (Ep) // ... // else if (Ip) // ... // else if (Ap) // ... // // // These cast functions are used for classes that represent more than // one kind of nodes. The functions must be listed after the subclasses // have been defined. // inline AstStatement* StatementCast(); inline AstMemberValue* MemberValueCast(); inline AstExpression* ExpressionCast(); inline AstPrimitiveType* PrimitiveTypeCast(); inline AstFieldDeclaration* StaticFieldCast(); inline AstInitializerDeclaration* StaticInitializerCast(); inline AstClassBody* UnparsedClassBodyCast(); inline AstCompilationUnit* BadCompilationUnitCast(); inline AstCompilationUnit* EmptyCompilationUnitCast(); // // These cast functions are used for classes that represent exactly // one kind of node. // inline AstListNode* ListNodeCast(); inline AstBlock* BlockCast(); inline AstName* NameCast(); inline AstBrackets* BracketsCast(); inline AstArrayType* ArrayTypeCast(); inline AstWildcard* WildcardCast(); inline AstTypeArguments* TypeArgumentsCast(); inline AstTypeName* TypeNameCast(); inline AstMemberValuePair* MemberValuePairCast(); inline AstAnnotation* AnnotationCast(); inline AstModifierKeyword* ModifierKeywordCast(); inline AstModifiers* ModifiersCast(); inline AstPackageDeclaration* PackageDeclarationCast(); inline AstImportDeclaration* ImportDeclarationCast(); inline AstCompilationUnit* CompilationUnitCast(); inline AstEmptyDeclaration* EmptyDeclarationCast(); inline AstClassBody* ClassBodyCast(); inline AstTypeParameter* TypeParameterCast(); inline AstTypeParameters* TypeParametersCast(); inline AstClassDeclaration* ClassDeclarationCast(); inline AstArrayInitializer* ArrayInitializerCast(); inline AstVariableDeclaratorId* VariableDeclaratorIdCast(); inline AstVariableDeclarator* VariableDeclaratorCast(); inline AstFieldDeclaration* FieldDeclarationCast(); inline AstFormalParameter* FormalParameterCast(); inline AstMethodDeclarator* MethodDeclaratorCast(); inline AstMethodBody* MethodBodyCast(); inline AstMethodDeclaration* MethodDeclarationCast(); inline AstInitializerDeclaration* InitializerDeclarationCast(); inline AstArguments* ArgumentsCast(); inline AstThisCall* ThisCallCast(); inline AstSuperCall* SuperCallCast(); inline AstConstructorDeclaration* ConstructorDeclarationCast(); inline AstEnumDeclaration* EnumDeclarationCast(); inline AstEnumConstant* EnumConstantCast(); inline AstInterfaceDeclaration* InterfaceDeclarationCast(); inline AstAnnotationDeclaration* AnnotationDeclarationCast(); inline AstLocalVariableStatement* LocalVariableStatementCast(); inline AstLocalClassStatement* LocalClassStatementCast(); inline AstIfStatement* IfStatementCast(); inline AstEmptyStatement* EmptyStatementCast(); inline AstExpressionStatement* ExpressionStatementCast(); inline AstSwitchLabel* SwitchLabelCast(); inline AstSwitchBlockStatement* SwitchBlockStatementCast(); inline AstSwitchStatement* SwitchStatementCast(); inline AstWhileStatement* WhileStatementCast(); inline AstDoStatement* DoStatementCast(); inline AstForStatement* ForStatementCast(); inline AstForeachStatement* ForeachStatementCast(); inline AstBreakStatement* BreakStatementCast(); inline AstContinueStatement* ContinueStatementCast(); inline AstReturnStatement* ReturnStatementCast(); inline AstThrowStatement* ThrowStatementCast(); inline AstSynchronizedStatement* SynchronizedStatementCast(); inline AstAssertStatement* AssertStatementCast(); inline AstCatchClause* CatchClauseCast(); inline AstFinallyClause* FinallyClauseCast(); inline AstTryStatement* TryStatementCast(); inline AstIntegerLiteral* IntegerLiteralCast(); inline AstLongLiteral* LongLiteralCast(); inline AstFloatLiteral* FloatLiteralCast(); inline AstDoubleLiteral* DoubleLiteralCast(); inline AstTrueLiteral* TrueLiteralCast(); inline AstFalseLiteral* FalseLiteralCast(); inline AstStringLiteral* StringLiteralCast(); inline AstCharacterLiteral* CharacterLiteralCast(); inline AstNullLiteral* NullLiteralCast(); inline AstClassLiteral* ClassLiteralCast(); inline AstThisExpression* ThisExpressionCast(); inline AstSuperExpression* SuperExpressionCast(); inline AstParenthesizedExpression* ParenthesizedExpressionCast(); inline AstClassCreationExpression* ClassCreationExpressionCast(); inline AstDimExpr* DimExprCast(); inline AstArrayCreationExpression* ArrayCreationExpressionCast(); inline AstFieldAccess* FieldAccessCast(); inline AstMethodInvocation* MethodInvocationCast(); inline AstArrayAccess* ArrayAccessCast(); inline AstPostUnaryExpression* PostUnaryExpressionCast(); inline AstPreUnaryExpression* PreUnaryExpressionCast(); inline AstCastExpression* CastExpressionCast(); inline AstBinaryExpression* BinaryExpressionCast(); inline AstInstanceofExpression* InstanceofExpressionCast(); inline AstConditionalExpression* ConditionalExpressionCast(); inline AstAssignmentExpression* AssignmentExpressionCast(); // // It would be nice if this could be covariant, as it would allow // less casting. But MSVC++ can't yet handle covariant return // types at all, and both GCC and HP's aCC croak with covariance during // multiple inheritance (bummer). So, there is a bunch of hideous casting // in ast.cpp that could otherwise be avoided if standards were followed. // // Clones are used for various things, such as pre-evaluating final // constant values. // virtual Ast* Clone(StoragePool*) = 0; // // These functions return the left and right tokens of this tree branch. // virtual TokenIndex LeftToken() = 0; virtual TokenIndex RightToken() = 0; }; // // This AstArray template class can be used to construct a bounds-checking // array of Ast objects. The size of the array must be known up front, as // it is allocated contiguously from a StoragePool (preferably the pool that // also owns the Ast object which contains this array). // template class AstArray { const unsigned size; unsigned top; T* array; public: // // Return length of the Ast array. // unsigned Length() { return top; } // // Return a reference to the ith element of the Ast array. // T& operator[](unsigned i) { assert(i < top); return array[i]; } // // Add an element to the Ast array and return a reference to // that new element. // T& Next() { assert(top < size); return array[top++]; } // // Constructor of an Ast array. // AstArray(StoragePool*, unsigned); // // Ast arrays should not be destroyed. Rather, delete the StoragePool // that was passed to the constructor. // ~AstArray() { assert(false && "Use the associated StoragePool"); } // // Ast arrays must be created via a StoragePool, and there are no // AstArray[]. // inline void* operator new(size_t, StoragePool*); private: void* operator new[](size_t, void* p) { assert(false); return p; } }; // // The Ast list node. This is a temporary object used in constructing lists // while parsing the grammar; once constructed, the contents are extracted // and this list is reclaimed. It is circular to make insertion easy while // maintaining declaration order. // class AstListNode : public Ast { public: AstListNode* next; Ast* element; unsigned index; inline AstListNode() : Ast(LIST_NODE) { #ifdef JIKES_DEBUG --count; // don't count these nodes #endif // JIKES_DEBUG } ~AstListNode() {} // // These next three functions should never be called, since list nodes // only exist long enough to create the AST tree and then are reclaimed. // virtual Ast* Clone(StoragePool*) { assert(false); return NULL; } #ifdef JIKES_DEBUG virtual void Print(LexStream&) { assert(false); } virtual void Unparse(Ostream&, LexStream*) { assert(false); } #endif // JIKES_DEBUG virtual TokenIndex LeftToken() { return element -> LeftToken(); } virtual TokenIndex RightToken() { return element -> RightToken(); } }; // // This class adds some type safety. It represents all member declarations // in types. See DeclaredType, AstFieldDeclaration, AstMethodDeclaration, // AstConstructorDeclaration, AstInitializerDeclaration, and AstEnumConstant. // class AstDeclared : public Ast { public: AstModifiers* modifiers_opt; inline AstDeclared(AstKind k) : Ast(k) {} ~AstDeclared() {} }; // // This class adds some type safety. It represents all type declarations. // See AstClassDeclaration, AstEnumDeclaration, AstInterfaceDeclaration, // AstAnnotationDeclaration, and AstEmptyDeclaration. // class AstDeclaredType : public AstDeclared { public: AstClassBody* class_body; inline AstDeclaredType(AstKind k) : AstDeclared(k) {} ~AstDeclaredType() {} inline bool IsValid(); }; // // This class represents statements. // class AstStatement : public Ast { public: bool is_reachable; bool can_complete_normally; inline AstStatement(AstKind k, bool reachable = false, bool can_complete = false) : Ast(k, STATEMENT) , is_reachable(reachable) , can_complete_normally(can_complete) {} ~AstStatement() {} }; // // This is the superclass of constructs which can appear in an array // initializer, including annotations added by JSR 175. // class AstMemberValue : public Ast { public: // The field or method this expression resolves to, or the annotation type // that the annotation resolves to. Symbol* symbol; inline AstMemberValue(AstKind k, AstTag t = NO_TAG) : Ast(k, t) {} ~AstMemberValue() {} TypeSymbol* Type(); }; // // This is the superclass of constructs which represent an expression. // class AstExpression : public AstMemberValue { public: LiteralValue* value; // The compile-time constant value of the expression. inline AstExpression(AstKind k) : AstMemberValue(k, EXPRESSION) {} ~AstExpression() {} inline bool IsConstant() { return value != NULL; } }; // // This is the superclass of constructs which represent a type: // AstPrimitiveType, AstArrayType, AstWildcard, and AstTypeName. // class AstType : public Ast { public: TypeSymbol* symbol; inline AstType(AstKind k, AstTag t = NO_TAG) : Ast(k, t) {} ~AstType() {} virtual TokenIndex IdentifierToken() = 0; }; // // Blocks represent both method blocks and compound statements. The parser // creates synthetic blocks around statements where blocks are optional (such // as if statement branches), and around loops. // class AstBlock : public AstStatement { protected: StoragePool* pool; private: AstArray* block_statements; VariableSymbolArray* defined_variables; public: enum BlockTag { NONE, TRY_CLAUSE_WITH_FINALLY, TRY_CLAUSE_WITH_CATCH, ABRUPT_TRY_FINALLY, FINALLY, SYNCHRONIZED, SWITCH }; BlockSymbol* block_symbol; unsigned nesting_level; TokenIndex label_opt; TokenIndex left_brace_token; TokenIndex right_brace_token; bool no_braces; inline AstBlock(StoragePool* p, AstKind k = BLOCK, bool reachable = false) : AstStatement(k, reachable) , pool(p) {} ~AstBlock() {} inline BlockTag Tag() { return (BlockTag) other_tag; } inline void SetTag(BlockTag tag) { other_tag = tag; } inline AstStatement*& Statement(unsigned i) { return (*block_statements)[i]; } inline unsigned NumStatements() { return block_statements ? block_statements -> Length() : 0; } inline void AllocateStatements(unsigned estimate = 1); inline void AddStatement(AstStatement*); inline VariableSymbol*& LocallyDefinedVariable(unsigned i) { return (*defined_variables)[i]; } inline unsigned NumLocallyDefinedVariables() { return defined_variables ? defined_variables -> Length() : 0; } inline void AllocateLocallyDefinedVariables(unsigned estimate = 1); inline void AddLocallyDefinedVariable(VariableSymbol*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_brace_token; } virtual TokenIndex RightToken() { return right_brace_token; } protected: void CloneBlock(StoragePool*, AstBlock*); }; // // Simple and qualified names. // class AstName : public AstExpression { public: AstName* base_opt; TokenIndex identifier_token; // // When a name refers to a member in an enclosing scope, it is mapped // into an expression that creates a path to the member in question. // AstExpression* resolution_opt; inline AstName(TokenIndex token) : AstExpression(NAME) , identifier_token(token) {} ~AstName() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return base_opt ? base_opt -> LeftToken() : identifier_token; } virtual TokenIndex RightToken() { return identifier_token; } }; // // Type --> PrimitiveType // | ReferenceType // // PrimitiveType --> // // PrimitiveKind --> BYTE | SHORT | INT | LONG | CHAR | FLOAT | DOUBLE | // BOOLEAN | VOID // // PrimitiveName --> byte_token | short_token | int_token | long_token | // char_token | float_token | double_token | boolean_token | // void_token // class AstPrimitiveType : public AstType { public: TokenIndex primitive_kind_token; inline AstPrimitiveType(AstKind k, TokenIndex token) : AstType(k, PRIMITIVE_TYPE) , primitive_kind_token(token) {} ~AstPrimitiveType() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return primitive_kind_token; } virtual TokenIndex RightToken() { return primitive_kind_token; } virtual TokenIndex IdentifierToken() { return primitive_kind_token; } }; // // Represents one or more pairs of '[' ']'. // class AstBrackets : public Ast { public: TokenIndex left_bracket_token; TokenIndex right_bracket_token; unsigned dims; inline AstBrackets(TokenIndex l, TokenIndex r) : Ast(BRACKETS) , left_bracket_token(l) , right_bracket_token(r) , dims(1) {} ~AstBrackets() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_bracket_token; } virtual TokenIndex RightToken() { return right_bracket_token; } }; // // ReferenceType --> ClassType // | ArrayType // // ClassType --> Name // // ArrayType --> // // ArrayKind --> PrimitiveType // | Name // | ArrayType // class AstArrayType : public AstType { public: AstType* type; // AstPrimitiveType, AstTypeName AstBrackets* brackets; inline AstArrayType(AstType* t, AstBrackets* b) : AstType(ARRAY) , type(t) , brackets(b) {} ~AstArrayType() {} inline unsigned NumBrackets() { return brackets -> dims; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return type -> LeftToken(); } virtual TokenIndex RightToken() { return brackets -> right_bracket_token; } virtual TokenIndex IdentifierToken() { return type -> IdentifierToken(); } }; // // Represents a wildcard type. Only occurs in type arguments for naming a // generic type or method (but not in explicit type arguments for invoking // a method). // class AstWildcard : public AstType { public: TokenIndex question_token; // 0 or 1 of the next two fields, but never both TokenIndex extends_token_opt; TokenIndex super_token_opt; AstType* bounds_opt; // AstArrayType, AstTypeName inline AstWildcard(TokenIndex t) : AstType(WILDCARD) , question_token(t) {} ~AstWildcard() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return question_token; } virtual TokenIndex RightToken() { return bounds_opt ? bounds_opt -> RightToken() : question_token; } virtual TokenIndex IdentifierToken() { return question_token; } }; // // Represents the type arguments associated with a TypeName, as well as the // explicit type arguments of ThisCall, SuperCall,MethodInvocation, and // ClassCreationExpression. The grammar always allows wildcards, so the // semantic engine must reject them when they are illegal. // class AstTypeArguments : public Ast { StoragePool* pool; // AstTypeName, AstArrayType, AstWildcard AstArray* type_arguments; public: TokenIndex left_angle_token; TokenIndex right_angle_token; inline AstTypeArguments(StoragePool* p, TokenIndex l, TokenIndex r) : Ast(TYPE_ARGUMENTS) , pool(p) , left_angle_token(l) , right_angle_token(r) {} ~AstTypeArguments() {} inline AstType*& TypeArgument(unsigned i) { return (*type_arguments)[i]; } inline unsigned NumTypeArguments() { assert(type_arguments); return type_arguments -> Length(); } inline void AllocateTypeArguments(unsigned estimate = 1); inline void AddTypeArgument(AstType*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_angle_token; } virtual TokenIndex RightToken() { return right_angle_token; } }; // // Represents a type. Occurs in several contexts - imports; supertypes; // throws clauses; parameter, field, and method return types; qualified this // and super; class literals; casts. Some of these uses can be parameterized. // class AstTypeName : public AstType { public: AstTypeName* base_opt; AstName* name; AstTypeArguments* type_arguments_opt; inline AstTypeName(AstName* n) : AstType(TYPE) , name(n) {} ~AstTypeName() {} inline AstType*& TypeArgument(unsigned i) { return type_arguments_opt -> TypeArgument(i); } inline unsigned NumTypeArguments() { return type_arguments_opt ? type_arguments_opt -> NumTypeArguments() : 0; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return base_opt ? base_opt -> LeftToken() : name -> LeftToken(); } virtual TokenIndex RightToken() { return type_arguments_opt ? type_arguments_opt -> right_angle_token : name -> identifier_token; } virtual TokenIndex IdentifierToken() { return name -> identifier_token; } }; // // MemberValuePair is added by JSR 175. This covers MemberValuePair and // SingleMemberAnnotation in the grammar. // class AstMemberValuePair : public Ast { public: TokenIndex identifier_token_opt; AstMemberValue* member_value; MethodSymbol* name_symbol; // The annotation method this value maps to. inline AstMemberValuePair() : Ast(MEMBER_VALUE_PAIR) {} ~AstMemberValuePair() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return identifier_token_opt ? identifier_token_opt : member_value -> LeftToken(); } virtual TokenIndex RightToken() { return member_value -> RightToken(); } }; // // Annotation is added by JSR 175. This covers NormalAnnotation, // MarkerAnnotation, and SingleMemberAnnotation in the grammar. // class AstAnnotation : public AstMemberValue { StoragePool* pool; AstArray* member_value_pairs; public: TokenIndex at_token; AstName* name; TokenIndex right_paren_token_opt; inline AstAnnotation(StoragePool* p) : AstMemberValue(ANNOTATION) , pool(p) {} ~AstAnnotation() {} inline AstMemberValuePair*& MemberValuePair(unsigned i) { return (*member_value_pairs)[i]; } inline unsigned NumMemberValuePairs() { return member_value_pairs ? member_value_pairs -> Length() : 0; } inline void AllocateMemberValuePairs(unsigned estimate = 1); inline void AddMemberValuePair(AstMemberValuePair*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return at_token; } virtual TokenIndex RightToken() { return right_paren_token_opt ? right_paren_token_opt : name -> identifier_token; } }; // Represents a single modifier keyword ('public', 'protected', 'private', // 'static', 'abstract', 'final', 'native', 'synchronized', 'transient', // 'volatile', and 'strictfp'). // class AstModifierKeyword : public Ast { public: TokenIndex modifier_token; AstModifierKeyword(TokenIndex token) : Ast(MODIFIER_KEYWORD) , modifier_token(token) {} ~AstModifierKeyword() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifier_token; } virtual TokenIndex RightToken() { return modifier_token; } }; // // Represents one or more modifier keywords, as well as annotations (added in // JSR 175). // class AstModifiers : public Ast { StoragePool* pool; AstArray* modifiers; // AstAnnotation, AstModifierKeyword public: // Allows sorting between static and non-static declarations. TokenIndex static_token_opt; inline AstModifiers(StoragePool* p) : Ast(MODIFIERS) , pool(p) {} ~AstModifiers() {} inline Ast*& Modifier(unsigned i) { return (*modifiers)[i]; } inline unsigned NumModifiers() { assert(modifiers); return modifiers -> Length(); } inline void AllocateModifiers(unsigned estimate = 1); inline void AddModifier(AstAnnotation*); inline void AddModifier(AstModifierKeyword*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return Modifier(0) -> LeftToken(); } virtual TokenIndex RightToken() { return Modifier(NumModifiers() - 1) -> RightToken(); } }; // // Represents the PackageDeclaration, including the annotations made possible // in package-info.java by JSR 175. // class AstPackageDeclaration : public Ast { public: AstModifiers* modifiers_opt; TokenIndex package_token; AstName* name; TokenIndex semicolon_token; inline AstPackageDeclaration() : Ast(PACKAGE) {} ~AstPackageDeclaration() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : package_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // ImportDeclaration --> // class AstImportDeclaration : public Ast { public: TokenIndex import_token; TokenIndex static_token_opt; AstName* name; TokenIndex star_token_opt; TokenIndex semicolon_token; inline AstImportDeclaration() : Ast(IMPORT) {} ~AstImportDeclaration() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return import_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // The root node for compilation. // class AstCompilationUnit : public Ast { AstArray* import_declarations; AstArray* type_declarations; public: enum CompilationTag { NONE, BAD_COMPILATION, EMPTY_COMPILATION }; StoragePool* ast_pool; AstPackageDeclaration* package_declaration_opt; inline AstCompilationUnit(StoragePool* p) : Ast(COMPILATION) , ast_pool(p) {} ~AstCompilationUnit() {} void FreeAst(); inline void MarkBad() { other_tag = BAD_COMPILATION; } inline void MarkEmpty() { other_tag = EMPTY_COMPILATION; } inline AstImportDeclaration*& ImportDeclaration(unsigned i) { return (*import_declarations)[i]; } inline unsigned NumImportDeclarations() { return import_declarations ? import_declarations -> Length() : 0; } inline void AllocateImportDeclarations(unsigned estimate = 1); inline void AddImportDeclaration(AstImportDeclaration*); inline AstDeclaredType*& TypeDeclaration(unsigned i) { return (*type_declarations)[i]; } inline unsigned NumTypeDeclarations() { return type_declarations ? type_declarations -> Length() : 0; } inline void AllocateTypeDeclarations(unsigned estimate = 1); inline void AddTypeDeclaration(AstDeclaredType*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); // special forms virtual void Unparse(LexStream*, const char* const directory); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { if (package_declaration_opt) return package_declaration_opt -> package_token; if (NumImportDeclarations()) return ImportDeclaration(0) -> import_token; if (NumTypeDeclarations()) return TypeDeclaration(0) -> LeftToken(); return 0; } virtual TokenIndex RightToken() { if (NumTypeDeclarations()) return TypeDeclaration(NumTypeDeclarations() - 1) -> RightToken(); if (NumImportDeclarations()) return ImportDeclaration(NumImportDeclarations() - 1) -> semicolon_token; if (package_declaration_opt) return package_declaration_opt -> semicolon_token; return 0; } }; // // EmptyDeclaration --> // class AstEmptyDeclaration : public AstDeclaredType { public: TokenIndex semicolon_token; inline AstEmptyDeclaration(TokenIndex token) : AstDeclaredType(EMPTY_DECLARATION) , semicolon_token(token) {} ~AstEmptyDeclaration() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return semicolon_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // Represents the class body of the following: AstClassDeclaration, // AstEnumDeclaration, AstInterfaceDeclaration, AstAnnotationDeclaration, // AstEnumConstant, and AstClassCreationExpression. Not all uses can legally // have all class body members, so some filtering is in order in the semantic // pass. // class AstClassBody : public Ast { friend class Parser; StoragePool* pool; AstArray* class_body_declarations; AstArray* instance_variables; AstArray* class_variables; AstArray* methods; AstArray* constructors; AstArray* static_initializers; AstArray* instance_initializers; AstArray* inner_classes; AstArray* inner_enums; AstArray* inner_interfaces; AstArray* inner_annotations; AstArray* empty_declarations; public: enum ClassBodyTag { NONE, UNPARSED }; SemanticEnvironment* semantic_environment; AstConstructorDeclaration* default_constructor; // // Filled in by the owning AstClassDeclaration, AstEnumDeclaration, // AstInterfaceDeclaration, or AstAnnotationDeclaration to allow nicer // error messages. Note that owner is null for anonymous classes, // including enum constants. // AstDeclaredType* owner; TokenIndex identifier_token; // // The actual delimiters of the class body. // TokenIndex left_brace_token; TokenIndex right_brace_token; inline AstClassBody(StoragePool* p) : Ast(CLASS_BODY) , pool(p) {} ~AstClassBody() {} inline void MarkUnparsed() { other_tag = UNPARSED; } inline void MarkParsed() { other_tag = NONE; } inline AstDeclared*& ClassBodyDeclaration(unsigned i) { return (*class_body_declarations)[i]; } inline unsigned NumClassBodyDeclarations() { return class_body_declarations ? class_body_declarations -> Length() : 0; } inline void AllocateClassBodyDeclarations(unsigned estimate = 1); void AddClassBodyDeclaration(AstDeclared*); inline AstFieldDeclaration*& InstanceVariable(unsigned i) { return (*instance_variables)[i]; } inline unsigned NumInstanceVariables() { return instance_variables ? instance_variables -> Length() : 0; } inline void AllocateInstanceVariables(unsigned estimate = 1); inline void AddInstanceVariable(AstFieldDeclaration*); inline AstFieldDeclaration*& ClassVariable(unsigned i) { return (*class_variables)[i]; } inline unsigned NumClassVariables() { return class_variables ? class_variables -> Length() : 0; } inline void AllocateClassVariables(unsigned estimate = 1); inline void AddClassVariable(AstFieldDeclaration*); inline AstMethodDeclaration*& Method(unsigned i) { return (*methods)[i]; } inline unsigned NumMethods() { return methods ? methods -> Length() : 0; } inline void AllocateMethods(unsigned estimate = 1); inline void AddMethod(AstMethodDeclaration*); inline AstConstructorDeclaration*& Constructor(unsigned i) { return (*constructors)[i]; } inline unsigned NumConstructors() { return constructors ? constructors -> Length() : 0; } inline void AllocateConstructors(unsigned estimate = 1); inline void AddConstructor(AstConstructorDeclaration*); inline AstInitializerDeclaration*& StaticInitializer(unsigned i) { return (*static_initializers)[i]; } inline unsigned NumStaticInitializers() { return static_initializers ? static_initializers -> Length() : 0; } inline void AllocateStaticInitializers(unsigned estimate = 1); inline void AddStaticInitializer(AstInitializerDeclaration*); inline AstInitializerDeclaration*& InstanceInitializer(unsigned i) { return (*instance_initializers)[i]; } inline unsigned NumInstanceInitializers() { return instance_initializers ? instance_initializers -> Length() : 0; } inline void AllocateInstanceInitializers(unsigned estimate = 1); inline void AddInstanceInitializer(AstInitializerDeclaration*); inline AstClassDeclaration*& NestedClass(unsigned i) { return (*inner_classes)[i]; } inline unsigned NumNestedClasses() { return inner_classes ? inner_classes -> Length() : 0; } inline void AllocateNestedClasses(unsigned estimate = 1); inline void AddNestedClass(AstClassDeclaration*); inline AstEnumDeclaration*& NestedEnum(unsigned i) { return (*inner_enums)[i]; } inline unsigned NumNestedEnums() { return inner_enums ? inner_enums -> Length() : 0; } inline void AllocateNestedEnums(unsigned estimate = 1); inline void AddNestedEnum(AstEnumDeclaration*); inline AstInterfaceDeclaration*& NestedInterface(unsigned i) { return (*inner_interfaces)[i]; } inline unsigned NumNestedInterfaces() { return inner_interfaces ? inner_interfaces -> Length() : 0; } inline void AllocateNestedInterfaces(unsigned estimate = 1); inline void AddNestedInterface(AstInterfaceDeclaration*); inline AstAnnotationDeclaration*& NestedAnnotation(unsigned i) { return (*inner_annotations)[i]; } inline unsigned NumNestedAnnotations() { return inner_annotations ? inner_annotations -> Length() : 0; } inline void AllocateNestedAnnotations(unsigned estimate = 1); inline void AddNestedAnnotation(AstAnnotationDeclaration*); inline AstEmptyDeclaration*& EmptyDeclaration(unsigned i) { return (*empty_declarations)[i]; } inline unsigned NumEmptyDeclarations() { return empty_declarations ? empty_declarations -> Length() : 0; } inline void AllocateEmptyDeclarations(unsigned estimate = 1); inline void AddEmptyDeclaration(AstEmptyDeclaration*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream& o, LexStream* l) { Unparse(o, l, false); } void Unparse(Ostream&, LexStream*, bool); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_brace_token; } virtual TokenIndex RightToken() { return right_brace_token; } }; // // Represents a type parameter, used by AstTypeParameters. // class AstTypeParameter : public Ast { StoragePool* pool; AstArray* bounds; public: TokenIndex identifier_token; TypeSymbol* symbol; inline AstTypeParameter(StoragePool* p, TokenIndex token) : Ast(TYPE_PARAM) , pool(p) , identifier_token(token) {} ~AstTypeParameter() {} inline AstTypeName*& Bound(unsigned i) { return (*bounds)[i]; } inline unsigned NumBounds() { return bounds ? bounds -> Length() : 0; } inline void AllocateBounds(unsigned estimate = 1); inline void AddBound(AstTypeName*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return identifier_token; } virtual TokenIndex RightToken() { return NumBounds() ? Bound(NumBounds() - 1) -> RightToken() : identifier_token; } }; // // Represents type parameter declarations, used by AstClassDeclaration, // AstInterfaceDeclaration, AstMethodDeclaration, AstConstructorDeclaration. // class AstTypeParameters : public Ast { StoragePool* pool; AstArray* parameters; public: TokenIndex left_angle_token; TokenIndex right_angle_token; inline AstTypeParameters(StoragePool* p) : Ast(PARAM_LIST) , pool(p) {} ~AstTypeParameters() {} inline AstTypeParameter*& TypeParameter(unsigned i) { return (*parameters)[i]; } inline unsigned NumTypeParameters() { return parameters ? parameters -> Length() : 0; } inline void AllocateTypeParameters(unsigned estimate = 1); inline void AddTypeParameter(AstTypeParameter*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_angle_token; } virtual TokenIndex RightToken() { return right_angle_token; } }; // // Represents a class declaration. // class AstClassDeclaration : public AstDeclaredType { StoragePool* pool; AstArray* interfaces; public: TokenIndex class_token; AstTypeParameters* type_parameters_opt; AstTypeName* super_opt; inline AstClassDeclaration(StoragePool* p) : AstDeclaredType(CLASS) , pool(p) {} ~AstClassDeclaration() {} inline AstTypeName*& Interface(unsigned i) { return (*interfaces)[i]; } inline unsigned NumInterfaces() { return interfaces ? interfaces -> Length() : 0; } inline void AllocateInterfaces(unsigned estimate = 1); inline void AddInterface(AstTypeName*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : class_token; } virtual TokenIndex RightToken() { return class_body -> right_brace_token; } }; // // Covers all array initializer expressions, including those added by JSR 175. // class AstArrayInitializer : public AstMemberValue { StoragePool* pool; AstArray* variable_initializers; public: TokenIndex left_brace_token; TokenIndex right_brace_token; inline AstArrayInitializer(StoragePool* p) : AstMemberValue(ARRAY_INITIALIZER) , pool(p) {} ~AstArrayInitializer() {} inline AstMemberValue*& VariableInitializer(unsigned i) { return (*variable_initializers)[i]; } inline unsigned NumVariableInitializers() { return variable_initializers ? variable_initializers -> Length() : 0; } inline void AllocateVariableInitializers(unsigned estimate = 1); inline void AddVariableInitializer(AstMemberValue*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_brace_token; } virtual TokenIndex RightToken() { return right_brace_token; } }; // // VariableDeclaratorId --> // class AstVariableDeclaratorId : public Ast { public: TokenIndex identifier_token; AstBrackets* brackets_opt; inline AstVariableDeclaratorId() : Ast(VARIABLE_DECLARATOR_NAME) {} ~AstVariableDeclaratorId() {} inline unsigned NumBrackets() { return brackets_opt ? brackets_opt -> dims : 0; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return identifier_token; } virtual TokenIndex RightToken() { return brackets_opt ? brackets_opt -> right_bracket_token : identifier_token; } }; // // VariableDeclarator --> // // Technically, this is not a statement. But it is similar to local variable // declarations, which are, and treating it as a statement makes compiling // initializer blocks more uniform. // class AstVariableDeclarator : public AstStatement { public: VariableSymbol* symbol; // when true, this variable signals that the variable_initializer_opt // for this variable is currently being evaluated bool pending; AstVariableDeclaratorId* variable_declarator_name; Ast* variable_initializer_opt; inline AstVariableDeclarator() : AstStatement(VARIABLE_DECLARATOR, true, true) {} ~AstVariableDeclarator() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return variable_declarator_name -> LeftToken(); } virtual TokenIndex RightToken() { return variable_initializer_opt ? variable_initializer_opt -> RightToken() : variable_declarator_name -> RightToken(); } }; // // FieldDeclaration --> // // FieldModifier --> Modifier (PUBLIC, PROTECTED, PRIVATE, FINAL, STATIC, // TRANSIENT or VOLATILE) // class AstFieldDeclaration : public AstDeclared { StoragePool* pool; AstArray* variable_declarators; public: enum FieldDeclarationTag { NONE, STATIC }; AstType* type; TokenIndex semicolon_token; inline AstFieldDeclaration(StoragePool* p) : AstDeclared(FIELD) , pool(p) {} ~AstFieldDeclaration() {} inline void MarkStatic() { other_tag = STATIC; } inline AstVariableDeclarator*& VariableDeclarator(unsigned i) { return (*variable_declarators)[i]; } inline unsigned NumVariableDeclarators() { return variable_declarators ? variable_declarators -> Length() : 0; } inline void AllocateVariableDeclarators(unsigned estimate = 1); inline void AddVariableDeclarator(AstVariableDeclarator*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : type -> LeftToken(); } virtual TokenIndex RightToken() { return semicolon_token; } }; // // FormalParameter --> // class AstFormalParameter : public Ast { public: AstModifiers* modifiers_opt; AstType* type; TokenIndex ellipsis_token_opt; AstVariableDeclarator* formal_declarator; inline AstFormalParameter() : Ast(PARAMETER) {} ~AstFormalParameter() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : type -> LeftToken(); } virtual TokenIndex RightToken() { return formal_declarator -> RightToken(); } }; // // MethodDeclarator --> // class AstMethodDeclarator : public Ast { StoragePool* pool; AstArray* formal_parameters; public: TokenIndex identifier_token; TokenIndex left_parenthesis_token; TokenIndex right_parenthesis_token; AstBrackets* brackets_opt; inline AstMethodDeclarator(StoragePool* p) : Ast(METHOD_DECLARATOR) , pool(p) {} ~AstMethodDeclarator() {} inline AstFormalParameter*& FormalParameter(unsigned i) { return (*formal_parameters)[i]; } inline unsigned NumFormalParameters() { return formal_parameters ? formal_parameters -> Length() : 0; } inline void AllocateFormalParameters(unsigned estimate = 1); inline void AddFormalParameter(AstFormalParameter*); inline unsigned NumBrackets() { return brackets_opt ? brackets_opt -> dims : 0; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return identifier_token; } virtual TokenIndex RightToken() { return brackets_opt ? brackets_opt -> right_bracket_token : right_parenthesis_token; } }; // // This class represents a method body, for methods, constructors, and // initializers. It is basically a block, with the addition of an explicit // constructor invocation (used only in the context of constructors, NULL // otherwise). // class AstMethodBody : public AstBlock { public: AstStatement* explicit_constructor_opt; inline AstMethodBody(StoragePool* p) : AstBlock(p, METHOD_BODY, true) { no_braces = true; } ~AstMethodBody() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); // Inherited LeftToken(), RightToken() are adequate. }; // // Represents MethodDeclaration, AbstractMethodDeclaration, and Annotation // method declarations added in JSR 175. // class AstMethodDeclaration : public AstDeclared { StoragePool* pool; AstArray* throws; public: MethodSymbol* method_symbol; AstTypeParameters* type_parameters_opt; AstType* type; AstMethodDeclarator* method_declarator; AstMemberValue* default_value_opt; AstMethodBody* method_body_opt; TokenIndex semicolon_token_opt; inline AstMethodDeclaration(StoragePool* p) : AstDeclared(METHOD) , pool(p) {} ~AstMethodDeclaration() {} bool IsValid() { return method_symbol != NULL; } bool IsSignature() { return ! method_body_opt; } inline AstTypeName*& Throw(unsigned i) { return (*throws)[i]; } inline unsigned NumThrows() { return throws ? throws -> Length() : 0; } inline void AllocateThrows(unsigned estimate = 1); inline void AddThrow(AstTypeName*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : type_parameters_opt ? type_parameters_opt -> left_angle_token : type -> LeftToken(); } virtual TokenIndex RightToken() { return method_body_opt ? method_body_opt -> right_brace_token : semicolon_token_opt; } }; // // This class represents static and instance initializers. It also accepts // other modifiers, to give a nicer error message. // class AstInitializerDeclaration : public AstDeclared { public: enum InitializerDeclarationTag { NONE, STATIC }; AstMethodBody* block; inline AstInitializerDeclaration() : AstDeclared(INITIALIZER) {} ~AstInitializerDeclaration() {} inline void MarkStatic() { other_tag = STATIC; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : block -> left_brace_token; } virtual TokenIndex RightToken() { return block -> right_brace_token; } }; // // Represents the arguments of AstThisCall, AstSuperCall, AstMethodInvocation, // AstClassCreationExpression, and AstEnumConstant. For convenience, the need // to add null argument or pass shadow parameters is contained here, even // though not all the calling instances can use these features. // class AstArguments : public Ast { StoragePool* pool; AstArray* arguments; AstArray* shadow_arguments; public: TokenIndex left_parenthesis_token; TokenIndex right_parenthesis_token; inline AstArguments(StoragePool* p, TokenIndex l, TokenIndex r) : Ast(ARGUMENTS) , pool(p) , left_parenthesis_token(l) , right_parenthesis_token(r) {} ~AstArguments() {} inline AstExpression*& Argument(unsigned i) { return (*arguments)[i]; } inline unsigned NumArguments() { return arguments ? arguments -> Length() : 0; } inline void AllocateArguments(unsigned estimate = 1); inline void AddArgument(AstExpression*); inline AstName*& LocalArgument(unsigned i) { return (*shadow_arguments)[i]; } inline unsigned NumLocalArguments() { return shadow_arguments ? shadow_arguments -> Length() : 0; } inline void AllocateLocalArguments(unsigned estimate = 1); inline void AddLocalArgument(AstName*); inline void AddNullArgument() { other_tag = true; } inline bool NeedsExtraNullArgument() { return (bool) other_tag; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_parenthesis_token; } virtual TokenIndex RightToken() { return right_parenthesis_token; } }; // // Represents an explicit call to another constructor in this class. // class AstThisCall : public AstStatement { public: MethodSymbol* symbol; AstTypeArguments* type_arguments_opt; TokenIndex this_token; AstArguments* arguments; TokenIndex semicolon_token; inline AstThisCall() : AstStatement(THIS_CALL, true, true) {} ~AstThisCall() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return type_arguments_opt ? type_arguments_opt -> left_angle_token : this_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // Represents an explicit call to a superconstructor. // class AstSuperCall : public AstStatement { public: MethodSymbol* symbol; AstExpression* base_opt; AstTypeArguments* type_arguments_opt; TokenIndex super_token; AstArguments* arguments; TokenIndex semicolon_token; inline AstSuperCall() : AstStatement(SUPER_CALL, true, true) {} ~AstSuperCall() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return base_opt ? base_opt -> LeftToken() : type_arguments_opt ? type_arguments_opt -> left_angle_token : super_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // ConstructorDeclaration --> // // ConstructorBody --> // // ConstructorModifier --> Modifier (PUBLIC, PROTECTED or PRIVATE) // // ExplicitConstructorInvocation --> ThisCall // | SuperCall // // NOTE: We do not actually build ConstructorBodies. Instead, we have // overloaded MethodBody to store the necessary information. This is // because this() and super() are treated as Statements in the grammar; // and in the bytecode, constructors are just methods with a special // name. // class AstConstructorDeclaration : public AstDeclared { StoragePool* pool; AstArray* throws; public: MethodSymbol* constructor_symbol; int index; // Used in depend.cpp to detect cycles. AstTypeParameters* type_parameters_opt; AstMethodDeclarator* constructor_declarator; AstMethodBody* constructor_body; inline AstConstructorDeclaration(StoragePool* p) : AstDeclared(CONSTRUCTOR) , pool(p) , index(ConstructorCycleChecker::OMEGA) {} ~AstConstructorDeclaration() {} bool IsValid() { return constructor_symbol != NULL; } inline AstTypeName*& Throw(unsigned i) { return (*throws)[i]; } inline unsigned NumThrows() { return throws ? throws -> Length() : 0; } inline void AllocateThrows(unsigned estimate = 1); inline void AddThrow(AstTypeName*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : type_parameters_opt ? type_parameters_opt -> left_angle_token : constructor_declarator -> identifier_token; } virtual TokenIndex RightToken() { return constructor_body -> right_brace_token; } }; // // Represents an enum type, added by JSR 201. // class AstEnumDeclaration : public AstDeclaredType { StoragePool* pool; AstArray* interfaces; AstArray* enum_constants; public: TokenIndex enum_token; inline AstEnumDeclaration(StoragePool* p) : AstDeclaredType(ENUM_TYPE) , pool(p) {} ~AstEnumDeclaration() {} inline AstTypeName*& Interface(unsigned i) { return (*interfaces)[i]; } inline unsigned NumInterfaces() { return interfaces ? interfaces -> Length() : 0; } inline void AllocateInterfaces(unsigned estimate = 1); inline void AddInterface(AstTypeName*); inline AstEnumConstant*& EnumConstant(unsigned i) { return (*enum_constants)[i]; } inline unsigned NumEnumConstants() { return enum_constants ? enum_constants -> Length() : 0; } inline void AllocateEnumConstants(unsigned estimate = 1); inline void AddEnumConstant(AstEnumConstant*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : enum_token; } virtual TokenIndex RightToken() { return class_body -> right_brace_token; } }; // // Represents an enum constant, added by JSR 201. // class AstEnumConstant : public AstDeclared { public: TokenIndex identifier_token; AstArguments* arguments_opt; AstClassBody* class_body_opt; u4 ordinal; // the sequential position of the constant VariableSymbol* field_symbol; // the field the constant lives in MethodSymbol* ctor_symbol; // the constructor that builds the constant inline AstEnumConstant(TokenIndex t) : AstDeclared(ENUM) , identifier_token(t) {} ~AstEnumConstant() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : identifier_token; } virtual TokenIndex RightToken() { return class_body_opt ? class_body_opt -> right_brace_token : arguments_opt ? arguments_opt -> right_parenthesis_token : identifier_token; } }; // // Represents an interface type. // class AstInterfaceDeclaration : public AstDeclaredType { StoragePool* pool; AstArray* interfaces; public: TokenIndex interface_token; AstTypeParameters* type_parameters_opt; inline AstInterfaceDeclaration(StoragePool* p) : AstDeclaredType(INTERFACE) , pool(p) {} ~AstInterfaceDeclaration() {} inline AstTypeName*& Interface(unsigned i) { return (*interfaces)[i]; } inline unsigned NumInterfaces() { return interfaces ? interfaces -> Length() : 0; } inline void AllocateInterfaces(unsigned estimate = 1); inline void AddInterface(AstTypeName*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : interface_token; } virtual TokenIndex RightToken() { return class_body -> right_brace_token; } }; // // Represents an annotation type, added by JSR 175. // class AstAnnotationDeclaration : public AstDeclaredType { public: TokenIndex interface_token; inline AstAnnotationDeclaration(TokenIndex t) : AstDeclaredType(ANNOTATION_TYPE) , interface_token(t) {} ~AstAnnotationDeclaration() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : interface_token - 1; } virtual TokenIndex RightToken() { return class_body -> right_brace_token; } }; // // Represents a local variable declaration statement. // class AstLocalVariableStatement : public AstStatement { StoragePool* pool; AstArray* variable_declarators; public: AstModifiers* modifiers_opt; AstType* type; TokenIndex semicolon_token_opt; inline AstLocalVariableStatement(StoragePool* p) : AstStatement(LOCAL_VARIABLE_DECLARATION) , pool(p) {} ~AstLocalVariableStatement() {} inline AstVariableDeclarator*& VariableDeclarator(unsigned i) { return (*variable_declarators)[i]; } inline unsigned NumVariableDeclarators() { return variable_declarators ? variable_declarators -> Length() : 0; } inline void AllocateVariableDeclarators(unsigned estimate = 1); inline void AddVariableDeclarator(AstVariableDeclarator*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return modifiers_opt ? modifiers_opt -> LeftToken() : type -> LeftToken(); } virtual TokenIndex RightToken() { return semicolon_token_opt ? semicolon_token_opt : (VariableDeclarator(NumVariableDeclarators() - 1) -> RightToken()); } }; // // Represents a local class declaration statement. // class AstLocalClassStatement : public AstStatement { public: AstDeclaredType* declaration; // AstClassDeclaration, AstEnumDeclaration inline AstLocalClassStatement(AstClassDeclaration* decl) : AstStatement(LOCAL_CLASS, false, true) , declaration(decl) {} inline AstLocalClassStatement(AstEnumDeclaration* decl) : AstStatement(LOCAL_CLASS, false, true) , declaration(decl) {} ~AstLocalClassStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return declaration -> LeftToken(); } virtual TokenIndex RightToken() { return declaration -> class_body -> right_brace_token; } }; // // The parser always makes blocks for the enclosed statements, so we denote // that here (even though any statement is legal). // class AstIfStatement : public AstStatement { public: TokenIndex if_token; AstExpression* expression; AstBlock* true_statement; AstBlock* false_statement_opt; inline AstIfStatement() : AstStatement(IF) {} ~AstIfStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return if_token; } virtual TokenIndex RightToken() { return false_statement_opt ? false_statement_opt -> RightToken() : true_statement -> RightToken(); } }; // // EmptyStatement --> // class AstEmptyStatement : public AstStatement { public: TokenIndex semicolon_token; inline AstEmptyStatement(TokenIndex token) : AstStatement(EMPTY_STATEMENT) , semicolon_token(token) {} ~AstEmptyStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return semicolon_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // ExpressionStatement --> // class AstExpressionStatement : public AstStatement { public: AstExpression* expression; TokenIndex semicolon_token_opt; inline AstExpressionStatement() : AstStatement(EXPRESSION_STATEMENT) {} ~AstExpressionStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return expression -> LeftToken(); } virtual TokenIndex RightToken() { return semicolon_token_opt ? semicolon_token_opt : expression -> RightToken(); } }; // // Represents "case :" and "default :". // class AstSwitchLabel : public Ast { public: TokenIndex case_token; AstExpression* expression_opt; TokenIndex colon_token; // // The sorted index of this label in the overall switch. Default cases // are set to NumCases(). // unsigned map_index; inline AstSwitchLabel() : Ast(SWITCH_LABEL) {} ~AstSwitchLabel() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return case_token; } virtual TokenIndex RightToken() { return colon_token; } }; // // SwitchBlockStatement --> // class AstSwitchBlockStatement : public AstBlock { AstArray* switch_labels; public: inline AstSwitchBlockStatement(StoragePool* p) : AstBlock(p, SWITCH_BLOCK) { no_braces = true; } ~AstSwitchBlockStatement() {} inline AstSwitchLabel*& SwitchLabel(unsigned i) { return (*switch_labels)[i]; } inline unsigned NumSwitchLabels() { return switch_labels ? switch_labels -> Length() : 0; } inline void AllocateSwitchLabels(unsigned estimate = 1); inline void AddSwitchLabel(AstSwitchLabel*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return SwitchLabel(0) -> case_token; } // Inherited RightToken() is adequate. }; // // This structure allows a switch statement to sort its case labels. It should // be a plain-old-data type (POD) for efficient copying. // struct CaseElement { unsigned block_index; // which SwitchBlockStatement unsigned case_index; // which case label within the block i4 value; // the value of the case's expression // // This keeps the sort stable, so that duplicates stay later in the list. // inline bool operator<(CaseElement& right) { return value < right.value || (value == right.value && (block_index < right.block_index || (block_index == right.block_index && case_index < right.case_index))); } }; // // SwitchStatement --> // class AstSwitchStatement : public AstStatement { StoragePool* pool; // // The sorted list of case label values. Index 0 is reserved for the // default case. Index 1 - size are for the case labels, and get sorted. // CaseElement** cases; unsigned num_cases; #ifdef JIKES_DEBUG unsigned max_cases; // bounds check only when debugging #endif // JIKES_DEBUG public: TokenIndex switch_token; AstExpression* expression; AstBlock* switch_block; inline AstSwitchStatement(StoragePool* p) : AstStatement(SWITCH) , pool(p) {} ~AstSwitchStatement() {} inline CaseElement*& Case(unsigned i) { assert(i < num_cases); return cases[i + 1]; } inline CaseElement*& DefaultCase() { return cases[0]; } inline unsigned NumCases() { return num_cases; } inline void AllocateCases(unsigned estimate = 1); inline void AddCase(CaseElement*); inline AstSwitchBlockStatement* Block(unsigned i) { return (AstSwitchBlockStatement*) switch_block -> Statement(i); } inline unsigned NumBlocks() { return switch_block -> NumStatements(); } void SortCases(); CaseElement* CaseForValue(i4 value); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return switch_token; } virtual TokenIndex RightToken() { return switch_block -> right_brace_token; } }; // // WhileStatement --> // class AstWhileStatement : public AstStatement { public: TokenIndex while_token; AstExpression* expression; AstBlock* statement; inline AstWhileStatement() : AstStatement(WHILE) {} ~AstWhileStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return while_token; } virtual TokenIndex RightToken() { return statement -> right_brace_token; } }; // // DoStatement --> // class AstDoStatement : public AstStatement { public: TokenIndex do_token; AstBlock* statement; TokenIndex while_token; AstExpression* expression; TokenIndex semicolon_token; inline AstDoStatement() : AstStatement(DO) {} ~AstDoStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return do_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // Represents the traditional for statement. The parser has already enclosed // the overall for statement in its own block, as well as the enclosed // statement. // class AstForStatement : public AstStatement { StoragePool* pool; AstArray* for_init_statements; AstArray* for_update_statements; public: TokenIndex for_token; AstExpression* end_expression_opt; AstBlock* statement; inline AstForStatement(StoragePool* p) : AstStatement(FOR) , pool(p) {} ~AstForStatement() {} inline AstStatement*& ForInitStatement(unsigned i) { return (*for_init_statements)[i]; } inline unsigned NumForInitStatements() { return for_init_statements ? for_init_statements -> Length() : 0; } inline void AllocateForInitStatements(unsigned estimate = 1); inline void AddForInitStatement(AstStatement*); inline AstExpressionStatement*& ForUpdateStatement(unsigned i) { return (*for_update_statements)[i]; } inline unsigned NumForUpdateStatements() { return for_update_statements ? for_update_statements -> Length() : 0; } inline void AllocateForUpdateStatements(unsigned estimate = 1); inline void AddForUpdateStatement(AstExpressionStatement*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return for_token; } virtual TokenIndex RightToken() { return statement -> right_brace_token; } }; // // ForeachStatement is added in JDK 1.5 by JSR 201. It has the syntax // "for (FormalParameter : expression) statement", where expression must // be an array type or an instance of java.lang.Iterable. The parser already // wrapped the statement in a block. // class AstForeachStatement : public AstStatement { public: TokenIndex for_token; AstFormalParameter* formal_parameter; AstExpression* expression; AstBlock* statement; inline AstForeachStatement() : AstStatement(FOREACH) {} ~AstForeachStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return for_token; } virtual TokenIndex RightToken() { return statement -> right_brace_token; } }; // // BreakStatement --> // class AstBreakStatement : public AstStatement { public: TokenIndex break_token; TokenIndex identifier_token_opt; TokenIndex semicolon_token; unsigned nesting_level; inline AstBreakStatement() : AstStatement(BREAK) {} ~AstBreakStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return break_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // ContinueStatement --> // class AstContinueStatement : public AstStatement { public: TokenIndex continue_token; TokenIndex identifier_token_opt; TokenIndex semicolon_token; unsigned nesting_level; inline AstContinueStatement() : AstStatement(CONTINUE) {} ~AstContinueStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return continue_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // ReturnStatement --> // class AstReturnStatement : public AstStatement { public: TokenIndex return_token; AstExpression* expression_opt; TokenIndex semicolon_token; inline AstReturnStatement() : AstStatement(RETURN) {} ~AstReturnStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return return_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // ThrowStatement --> // class AstThrowStatement : public AstStatement { public: TokenIndex throw_token; AstExpression* expression; TokenIndex semicolon_token; inline AstThrowStatement() : AstStatement(THROW) {} ~AstThrowStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return throw_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // SynchronizedStatement --> // class AstSynchronizedStatement : public AstStatement { public: TokenIndex synchronized_token; AstExpression* expression; AstBlock* block; inline AstSynchronizedStatement() : AstStatement(SYNCHRONIZED_STATEMENT) {} ~AstSynchronizedStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return synchronized_token; } virtual TokenIndex RightToken() { return block -> right_brace_token; } }; // // AssertStatement --> // --> // class AstAssertStatement : public AstStatement { public: TokenIndex assert_token; TokenIndex semicolon_token; AstExpression* condition; AstExpression* message_opt; VariableSymbol* assert_variable; inline AstAssertStatement() : AstStatement(ASSERT) {} ~AstAssertStatement() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return assert_token; } virtual TokenIndex RightToken() { return semicolon_token; } }; // // CatchClause --> // class AstCatchClause : public Ast { public: VariableSymbol* parameter_symbol; TokenIndex catch_token; AstFormalParameter* formal_parameter; AstBlock* block; inline AstCatchClause() : Ast(CATCH) {} ~AstCatchClause() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return catch_token; } virtual TokenIndex RightToken() { return block -> right_brace_token; } }; // // FinallyClause --> // class AstFinallyClause : public Ast { public: TokenIndex finally_token; AstBlock* block; inline AstFinallyClause() : Ast(FINALLY) {} ~AstFinallyClause() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return finally_token; } virtual TokenIndex RightToken() { return block -> right_brace_token; } }; // // TryStatement --> // class AstTryStatement : public AstStatement { StoragePool* pool; AstArray* catch_clauses; public: TokenIndex try_token; AstBlock* block; AstFinallyClause* finally_clause_opt; bool processing_try_block; inline AstTryStatement(StoragePool* p) : AstStatement(TRY) , pool(p) {} ~AstTryStatement() {} inline AstCatchClause*& CatchClause(unsigned i) { return (*catch_clauses)[i]; } inline unsigned NumCatchClauses() { return catch_clauses ? catch_clauses -> Length() : 0; } inline void AllocateCatchClauses(unsigned estimate = 1); inline void AddCatchClause(AstCatchClause*); #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return try_token; } virtual TokenIndex RightToken() { return finally_clause_opt ? finally_clause_opt -> RightToken() : CatchClause(NumCatchClauses() - 1) -> RightToken(); } }; // // Represents an int literal. // class AstIntegerLiteral : public AstExpression { public: TokenIndex integer_literal_token; inline AstIntegerLiteral(TokenIndex token) : AstExpression(INTEGER_LITERAL) , integer_literal_token(token) {} ~AstIntegerLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return integer_literal_token; } virtual TokenIndex RightToken() { return integer_literal_token; } }; // // LongLiteral --> // class AstLongLiteral : public AstExpression { public: TokenIndex long_literal_token; inline AstLongLiteral(TokenIndex token) : AstExpression(LONG_LITERAL) , long_literal_token(token) {} ~AstLongLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return long_literal_token; } virtual TokenIndex RightToken() { return long_literal_token; } }; // // FloatLiteral --> // class AstFloatLiteral : public AstExpression { public: TokenIndex float_literal_token; inline AstFloatLiteral(TokenIndex token) : AstExpression(FLOAT_LITERAL) , float_literal_token(token) {} ~AstFloatLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return float_literal_token; } virtual TokenIndex RightToken() { return float_literal_token; } }; // // DoubleLiteral --> // class AstDoubleLiteral : public AstExpression { public: TokenIndex double_literal_token; inline AstDoubleLiteral(TokenIndex token) : AstExpression(DOUBLE_LITERAL) , double_literal_token(token) {} ~AstDoubleLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return double_literal_token; } virtual TokenIndex RightToken() { return double_literal_token; } }; // // TrueLiteral --> // class AstTrueLiteral : public AstExpression { public: TokenIndex true_literal_token; inline AstTrueLiteral(TokenIndex token) : AstExpression(TRUE_LITERAL) , true_literal_token(token) {} ~AstTrueLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return true_literal_token; } virtual TokenIndex RightToken() { return true_literal_token; } }; // // FalseLiteral --> // class AstFalseLiteral : public AstExpression { public: TokenIndex false_literal_token; inline AstFalseLiteral(TokenIndex token) : AstExpression(FALSE_LITERAL) , false_literal_token(token) {} ~AstFalseLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return false_literal_token; } virtual TokenIndex RightToken() { return false_literal_token; } }; // // StringLiteral --> // class AstStringLiteral : public AstExpression { public: TokenIndex string_literal_token; inline AstStringLiteral(TokenIndex token) : AstExpression(STRING_LITERAL) , string_literal_token(token) {} ~AstStringLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return string_literal_token; } virtual TokenIndex RightToken() { return string_literal_token; } }; // // CharacterLiteral --> // class AstCharacterLiteral : public AstExpression { public: TokenIndex character_literal_token; inline AstCharacterLiteral(TokenIndex token) : AstExpression(CHARACTER_LITERAL) , character_literal_token(token) {} ~AstCharacterLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return character_literal_token; } virtual TokenIndex RightToken() { return character_literal_token; } }; // // NullLiteral --> // class AstNullLiteral : public AstExpression { public: TokenIndex null_token; inline AstNullLiteral(TokenIndex token) : AstExpression(NULL_LITERAL) , null_token(token) {} ~AstNullLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return null_token; } virtual TokenIndex RightToken() { return null_token; } }; // // Represents class literals. // class AstClassLiteral : public AstExpression { public: AstType* type; TokenIndex class_token; // // If this expression requires a caching variable and a call to class$(), // the resolution holds the needed class$xxx or array$xxx cache. // AstExpression* resolution_opt; inline AstClassLiteral(TokenIndex token) : AstExpression(CLASS_LITERAL) , class_token(token) {} ~AstClassLiteral() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return type -> LeftToken(); } virtual TokenIndex RightToken() { return class_token; } }; // // Represents qualified and simple 'this'. // class AstThisExpression : public AstExpression { public: AstTypeName* base_opt; TokenIndex this_token; // // If this expression accesses an enclosing instance, the resolution // holds the needed chain of "this$0" traversals. // AstExpression* resolution_opt; inline AstThisExpression(TokenIndex token) : AstExpression(THIS_EXPRESSION) , this_token(token) {} ~AstThisExpression() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return base_opt ? base_opt -> LeftToken() : this_token; } virtual TokenIndex RightToken() { return this_token; } }; // // Represents qualified and simple 'super'. // class AstSuperExpression : public AstExpression { public: AstTypeName* base_opt; TokenIndex super_token; // // If this expression accesses an enclosing instance, the resolution // holds the needed chain of "this$0" traversals. // AstExpression* resolution_opt; inline AstSuperExpression(TokenIndex token) : AstExpression(SUPER_EXPRESSION) , super_token(token) {} ~AstSuperExpression() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return base_opt ? base_opt -> LeftToken() : super_token; } virtual TokenIndex RightToken() { return super_token; } }; // // ParenthesizedExpression --> // class AstParenthesizedExpression : public AstExpression { public: TokenIndex left_parenthesis_token; AstExpression* expression; TokenIndex right_parenthesis_token; inline AstParenthesizedExpression() : AstExpression(PARENTHESIZED_EXPRESSION) {} ~AstParenthesizedExpression() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_parenthesis_token; } virtual TokenIndex RightToken() { return right_parenthesis_token; } }; // // ClassCreationExpression represents a class instance creation (keyword new, // including anonymous classes). Also see ArrayCreationExpression. Sometimes, // during semantic analysis an artificial base_opt expression is constructed. // In such a case, the user can determine this condition by testing // base_opt -> generated. // class AstClassCreationExpression : public AstExpression { public: AstExpression* base_opt; TokenIndex new_token; AstTypeArguments* type_arguments_opt; AstTypeName* class_type; AstArguments* arguments; AstClassBody* class_body_opt; // // For anonymous classes, we resolve the original statement into a new // one that does not have a class_body_opt. This is necessary to get // the parameters called in the correct order. // AstClassCreationExpression* resolution_opt; inline AstClassCreationExpression() : AstExpression(CLASS_CREATION) {} ~AstClassCreationExpression() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return base_opt ? base_opt -> LeftToken() : new_token; } virtual TokenIndex RightToken() { return class_body_opt ? class_body_opt -> right_brace_token : arguments -> right_parenthesis_token; } }; // // DimExpr --> // class AstDimExpr : public Ast { public: TokenIndex left_bracket_token; AstExpression* expression; TokenIndex right_bracket_token; inline AstDimExpr() : Ast(DIM) {} ~AstDimExpr() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_bracket_token; } virtual TokenIndex RightToken() { return right_bracket_token; } }; // // ArrayCreationExpression --> // class AstArrayCreationExpression : public AstExpression { StoragePool* pool; AstArray* dim_exprs; public: TokenIndex new_token; AstType* array_type; AstBrackets* brackets_opt; AstArrayInitializer* array_initializer_opt; inline AstArrayCreationExpression(StoragePool* p) : AstExpression(ARRAY_CREATION) , pool(p) {} ~AstArrayCreationExpression() {} inline AstDimExpr*& DimExpr(unsigned i) { return (*dim_exprs)[i]; } inline unsigned NumDimExprs() { return dim_exprs ? dim_exprs -> Length() : 0; } inline void AllocateDimExprs(unsigned estimate = 1); inline void AddDimExpr(AstDimExpr*); inline unsigned NumBrackets() { return brackets_opt ? brackets_opt -> dims : 0; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return new_token; } virtual TokenIndex RightToken() { return array_initializer_opt ? array_initializer_opt -> right_brace_token : brackets_opt ? brackets_opt -> right_bracket_token : DimExpr(NumDimExprs() - 1) -> right_bracket_token; } }; // // FieldAccess --> // class AstFieldAccess : public AstExpression { public: AstExpression* base; // Not AstName. TokenIndex identifier_token; // // If the base expression of FieldAccess expression is of the form // type.this.X, where X is a private variable that is a member of an // outer class, then we resolve it into a method call to the read_mehod // that gives access to X. // AstExpression* resolution_opt; inline AstFieldAccess() : AstExpression(DOT) {} ~AstFieldAccess() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return base -> LeftToken(); } virtual TokenIndex RightToken() { return identifier_token; } }; // // Represents a method call. Sometimes, during semantic analysis an // artificial base_opt expression is constructed. In such a case, the user // can determine this condition by testing base_opt -> generated. // class AstMethodInvocation : public AstExpression { public: AstExpression* base_opt; AstTypeArguments* type_arguments_opt; TokenIndex identifier_token; AstArguments* arguments; // // When a method refers to a member in an enclosing scope, // it is mapped into a new expression that creates a path to // the member in question. // AstExpression* resolution_opt; inline AstMethodInvocation(TokenIndex t) : AstExpression(CALL) , identifier_token(t) {} ~AstMethodInvocation() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { if (type_arguments_opt) assert(base_opt); return base_opt ? base_opt -> LeftToken() : identifier_token; } virtual TokenIndex RightToken() { return arguments -> right_parenthesis_token; } }; // // ArrayAccess --> // class AstArrayAccess : public AstExpression { public: AstExpression* base; TokenIndex left_bracket_token; AstExpression* expression; TokenIndex right_bracket_token; inline AstArrayAccess() : AstExpression(ARRAY_ACCESS) {} ~AstArrayAccess() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return base -> LeftToken(); } virtual TokenIndex RightToken() { return right_bracket_token; } }; // // UnaryExpression --> PreUnaryExpression // | PostUnaryExpression // | CastExpression // // PostUnaryExpression --> // // PostUnaryTag --> PLUSPLUS | MINUSMINUS // // PostOperator --> ++_token | --_token // class AstPostUnaryExpression : public AstExpression { public: enum PostUnaryExpressionTag { NONE, PLUSPLUS, MINUSMINUS, _num_kinds }; AstExpression* expression; TokenIndex post_operator_token; // // When the left-hand side of an assignment is a name that refers // to a private field in an enclosing scope, the access method // that gives write-permission to that field is recorded here. // MethodSymbol* write_method; inline AstPostUnaryExpression(PostUnaryExpressionTag tag) : AstExpression(POST_UNARY) { other_tag = tag; } ~AstPostUnaryExpression() {} inline PostUnaryExpressionTag Tag() { return (PostUnaryExpressionTag) other_tag; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return expression -> LeftToken(); } virtual TokenIndex RightToken() { return post_operator_token; } }; // // PreUnaryExpression --> // // PreUnaryTag --> PLUS | MINUS | TWIDDLE | NOT | PLUSPLUS | MINUSMINUS // // PreOperator --> +_token | -_token | ~_token | !_token | ++_token | --_token // class AstPreUnaryExpression : public AstExpression { public: enum PreUnaryExpressionTag { NONE, PLUSPLUS, MINUSMINUS, PLUS, MINUS, TWIDDLE, NOT, _num_kinds }; TokenIndex pre_operator_token; AstExpression* expression; // // When the left-hand side of an assignment is a name that refers // to a private field in an enclosing scope, the access method // that gives write-permission to that field is recorded here. // MethodSymbol* write_method; inline AstPreUnaryExpression(PreUnaryExpressionTag tag) : AstExpression(PRE_UNARY) { other_tag = tag; } ~AstPreUnaryExpression() {} inline PreUnaryExpressionTag Tag() { return (PreUnaryExpressionTag) other_tag; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return pre_operator_token; } virtual TokenIndex RightToken() { return expression -> RightToken(); } }; // // CastExpression --> // // NOTE that the optional symbols above are absent only when the compiler // inserts a CAST conversion node into the program. // class AstCastExpression : public AstExpression { public: TokenIndex left_parenthesis_token; AstType* type; TokenIndex right_parenthesis_token; AstExpression* expression; inline AstCastExpression() : AstExpression(CAST) {} ~AstCastExpression() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_parenthesis_token; } virtual TokenIndex RightToken() { return expression -> RightToken(); } }; // // BinaryExpression --> // // BinaryTag --> STAR | SLASH | MOD | PLUS | MINUS | LEFT_SHIFT | RIGHT_SHIFT | // UNSIGNED_RIGHT_SHIFT | LESS | GREATER | // LESS_EQUAL | GREATER_EQUAL | EQUAL_EQUAL | NOT_EQUAL | // AND | XOR | IOR | AND_AND | OR_OR // // BinaryOperator --> *_token | /_token | %_token | +_token | -_token | // <<_token | >>_token | >>>_token | <_token | >_token | // <=_token | >=_token | ==_token | !=_token | &_token | // ^_token | |_token | &&_token | ||_token // class AstBinaryExpression : public AstExpression { public: enum BinaryExpressionTag { NONE, STAR, SLASH, MOD, PLUS, MINUS, LEFT_SHIFT, RIGHT_SHIFT, UNSIGNED_RIGHT_SHIFT, LESS, GREATER, AND, XOR, IOR, AND_AND, OR_OR, LESS_EQUAL, GREATER_EQUAL, EQUAL_EQUAL, NOT_EQUAL, _num_kinds }; AstExpression* left_expression; TokenIndex binary_operator_token; AstExpression* right_expression; inline AstBinaryExpression(BinaryExpressionTag tag) : AstExpression(BINARY) { other_tag = tag; } ~AstBinaryExpression() {} inline BinaryExpressionTag Tag() { return (BinaryExpressionTag) other_tag; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_expression -> LeftToken(); } virtual TokenIndex RightToken() { return right_expression -> RightToken(); } }; // // Represents instanceof expressions. // class AstInstanceofExpression : public AstExpression { public: AstExpression* expression; TokenIndex instanceof_token; AstType* type; // AstArrayType, AstTypeName inline AstInstanceofExpression() : AstExpression(INSTANCEOF) {} ~AstInstanceofExpression() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return expression -> LeftToken(); } virtual TokenIndex RightToken() { return type -> RightToken(); } }; // // ConditionalExpression --> // class AstConditionalExpression : public AstExpression { public: AstExpression* test_expression; TokenIndex question_token; AstExpression* true_expression; TokenIndex colon_token; AstExpression* false_expression; inline AstConditionalExpression() : AstExpression(CONDITIONAL) {} ~AstConditionalExpression() {} #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return test_expression -> LeftToken(); } virtual TokenIndex RightToken() { return false_expression -> RightToken(); } }; // // Assignment --> // // AssignmentTag --> EQUAL | STAR_EQUAL | SLASH_EQUAL | MOD_EQUAL | // PLUS_EQUAL | MINUS_EQUAL | LEFT_SHIFT_EQUAL | // RIGHT_SHIFT_EQUAL | UNSIGNED_RIGHT_SHIFT_EQUAL | // AND_EQUAL | XOR_EQUAL | IOR_EQUAL // // LeftHandSide --> Name | FieldAccess | ArrayAccess | ParenthesizedExpression // | CastExpression // // NOTE: that a LeftHandSide appears as a cast node only when the // assignment_operator in question is of the form "op=" and the application // of the operator requires a casting of the value of the left-hand side. // // AssignmentOperator --> =_token | *=_token | /=_token | %=_token | +=_token | // -=_token | <<=_token | >>=_token | >>>=_token | // &=_token | ^=_token | |=_token // class AstAssignmentExpression : public AstExpression { public: enum AssignmentExpressionTag { NONE, SIMPLE_EQUAL, STAR_EQUAL, SLASH_EQUAL, MOD_EQUAL, PLUS_EQUAL, MINUS_EQUAL, LEFT_SHIFT_EQUAL, RIGHT_SHIFT_EQUAL, UNSIGNED_RIGHT_SHIFT_EQUAL, AND_EQUAL, XOR_EQUAL, IOR_EQUAL, _num_kinds }; // // When the left-hand side of an assignment is a name that refers // to a private field in an enclosing scope, the access method // that gives write-permission to that field is recorded here. // MethodSymbol* write_method; AstExpression* left_hand_side; TokenIndex assignment_operator_token; AstExpression* expression; inline AstAssignmentExpression(AssignmentExpressionTag tag, TokenIndex t) : AstExpression(ASSIGNMENT) , assignment_operator_token(t) { other_tag = tag; } ~AstAssignmentExpression() {} inline AssignmentExpressionTag Tag() { return (AssignmentExpressionTag) other_tag; } inline bool SimpleAssignment() { return other_tag == SIMPLE_EQUAL; } #ifdef JIKES_DEBUG virtual void Print(LexStream&); virtual void Unparse(Ostream&, LexStream*); #endif // JIKES_DEBUG virtual Ast* Clone(StoragePool*); virtual TokenIndex LeftToken() { return left_hand_side -> LeftToken(); } virtual TokenIndex RightToken() { return expression -> RightToken(); } }; // // This Storage pool is similar to dynamic arrays (class Tuple). The // difference is that instead of a Next() function we have an Alloc(size_t) // function. The value of the size_t argument represents the size of the // object to allocate. The allocated memory is guaranteed to be // zero-initialized. // // All AST nodes for a given parse should be allocated from the same storage // pool, so they have a placement new operator that requires a StoragePool. // You should never delete an AST object, as all resources they allocate come // from the same pool. Instead, to reclaim memory when processing is complete, // simply delete the underlying storage pool. // class StoragePool { public: typedef void* Cell; inline size_t Blksize() { return 1U << log_blksize; } private: Cell** base; unsigned base_size; // number of segment slots in base unsigned base_index; // index of current non-full segment unsigned offset; // offset to next free pointer in base[base_index] unsigned log_blksize; // log2(words per segment) unsigned base_increment; // number of segment slots to add when growing // // Allocate another block of storage for the storage pool. block_size // allows the creation of larger than normal segments, which are rare, // but are sometimes requested by AstArray. // void AllocateMoreSpace(size_t block_size = 0) { // // This advances base_index to the next slot unless this is the first // allocation. Then it allocates a segment to live in that slot. // The offset field should only be 0 after construction or after a // reset, when base_index should stay at 0. All other times, offset // is nonzero, so we allocate advance base_index. // assert(offset ? base != NULL : ! base_index); if (offset) base_index++; if (base_index == base_size) { unsigned old_base_size = base_size; Cell** old_base = base; base_size += base_increment; base = new Cell*[base_size]; if (old_base) { memcpy(base, old_base, old_base_size * sizeof(Cell*)); delete [] old_base; } memset(base + old_base_size, 0, base_increment * sizeof(Cell*)); } if (block_size) { assert(block_size > Blksize()); delete [] base[base_index]; base[base_index] = new Cell[block_size]; } else if (! base[base_index]) { block_size = Blksize(); base[base_index] = new Cell[block_size]; } memset(base[base_index], 0, block_size * sizeof(Cell)); } public: // // Constructor of a storage pool. The parameter is the number of tokens // which the AST tree will contain. // StoragePool(unsigned num_tokens) : base(NULL) , base_size(0) , base_index(0) , offset(0) { // // Make a guess on the size that will be required for the ast // based on the number of tokens. On average, we have about 1 node // to 2 tokens, but about 10 words (40 bytes) per node. We add some // fudge factor to avoid reallocations, resulting in num_tokens * 8. // unsigned estimate = num_tokens << 3; // // Find a block of size 2**log_blksize that is large enough // to satisfy our estimate. // for (log_blksize = 8; (1U << log_blksize) < estimate && log_blksize < 31; log_blksize++) ; if (log_blksize < 13) // estimate is < 2**(13+2) == 32k { base_increment = 1U << (log_blksize - 8); log_blksize = 8; // fragment in 2**(8+2) == 1k chunks } else if (log_blksize < 17) // estimate is < 2**(17+2) == 512k { base_increment = 1U << (log_blksize - 10); log_blksize = 10; // fragment in 2**(10+2) == 4k chunks } else // estimate is >= 512k, which is rare { base_increment = 1U << (log_blksize - 12); log_blksize = 12; // fragment in 2**(12+2) == 16k chunks } // // Double the size of the base and add an extra margin to avoid // reallocating the base, especially for things like Cloning. // base_increment += base_increment + 3; } // // Destructor of a storage pool. This frees the memory of all of the AST // nodes allocated in this pool. // ~StoragePool() { if (base) for (unsigned i = 0; i <= base_index; i++) delete [] base[i]; delete [] base; } // // Alloc allocates an object of size n in the pool and returns a pointer // to it. The memory will be zero-initialized. // inline void* Alloc(size_t n) { unsigned chunk_size = (n + sizeof(Cell) - 1) / sizeof(Cell); if (chunk_size > Blksize()) { // // Handle large requests separately. These are rare, when an // AstArray is requested that is larger than a segment. In this // case, we allocate the extra large segment in the next free // slot, and swap it with the previous segment if that one still // had room. // AllocateMoreSpace(chunk_size); Cell result = base[base_index]; if (base_index) { Cell* temp = base[base_index]; base[base_index] = base[base_index - 1]; base[base_index - 1] = temp; } return result; } if (! base || offset + chunk_size > Blksize()) { // // Here, we overflow the current segment, but fit in a normal // next segment. // AllocateMoreSpace(); offset = 0; } Cell result = base[base_index] + offset; offset += chunk_size; return result; } // // This function is used to reset the Storage pool. This action // automatically invalidates all objects that had been allocated in the // pool. At least, YOU should assume it does!!! // inline void Reset() { base_index = 0; offset = 0; } // ******************************************************************** inline VariableSymbolArray* NewVariableSymbolArray(unsigned size = 0) { return new (Alloc(sizeof(VariableSymbolArray))) VariableSymbolArray(this, size); } inline AstListNode* NewListNode() { return new (this) AstListNode(); } inline AstBlock* NewBlock() { return new (this) AstBlock(this); } inline AstName* NewName(TokenIndex token) { return new (this) AstName(token); } inline AstPrimitiveType* NewPrimitiveType(Ast::AstKind kind, TokenIndex t) { return new (this) AstPrimitiveType(kind, t); } inline AstBrackets* NewBrackets(TokenIndex left, TokenIndex right) { return new (this) AstBrackets(left, right); } inline AstArrayType* NewArrayType(AstType* type, AstBrackets* brackets) { return new (this) AstArrayType(type, brackets); } inline AstWildcard* NewWildcard(TokenIndex question) { return new (this) AstWildcard(question); } inline AstTypeArguments* NewTypeArguments(TokenIndex l, TokenIndex r) { return new (this) AstTypeArguments(this, l, r); } inline AstTypeName* NewTypeName(AstName* name) { return new (this) AstTypeName(name); } inline AstMemberValuePair* NewMemberValuePair() { return new (this) AstMemberValuePair(); } inline AstAnnotation* NewAnnotation() { return new (this) AstAnnotation(this); } inline AstModifierKeyword* NewModifierKeyword(TokenIndex token) { return new (this) AstModifierKeyword(token); } inline AstModifiers* NewModifiers() { return new (this) AstModifiers(this); } inline AstPackageDeclaration* NewPackageDeclaration() { return new (this) AstPackageDeclaration(); } inline AstImportDeclaration* NewImportDeclaration() { return new (this) AstImportDeclaration(); } inline AstCompilationUnit* NewCompilationUnit() { return new (this) AstCompilationUnit(this); } inline AstEmptyDeclaration* NewEmptyDeclaration(TokenIndex t) { return new (this) AstEmptyDeclaration(t); } inline AstClassBody* NewClassBody() { return new (this) AstClassBody(this); } inline AstTypeParameter* NewTypeParameter(TokenIndex token) { return new (this) AstTypeParameter(this, token); } inline AstTypeParameters* NewTypeParameters() { return new (this) AstTypeParameters(this); } inline AstClassDeclaration* NewClassDeclaration() { return new (this) AstClassDeclaration(this); } inline AstArrayInitializer* NewArrayInitializer() { return new (this) AstArrayInitializer(this); } inline AstVariableDeclaratorId* NewVariableDeclaratorId() { return new (this) AstVariableDeclaratorId(); } inline AstVariableDeclarator* NewVariableDeclarator() { return new (this) AstVariableDeclarator(); } inline AstFieldDeclaration* NewFieldDeclaration() { return new (this) AstFieldDeclaration(this); } inline AstFormalParameter* NewFormalParameter() { return new (this) AstFormalParameter(); } inline AstMethodDeclarator* NewMethodDeclarator() { return new (this) AstMethodDeclarator(this); } inline AstMethodBody* NewMethodBody() { return new (this) AstMethodBody(this); } inline AstMethodDeclaration* NewMethodDeclaration() { return new (this) AstMethodDeclaration(this); } inline AstInitializerDeclaration* NewInitializerDeclaration() { return new (this) AstInitializerDeclaration(); } inline AstArguments* NewArguments(TokenIndex left, TokenIndex right) { return new (this) AstArguments(this, left, right); } inline AstThisCall* NewThisCall() { return new (this) AstThisCall(); } inline AstSuperCall* NewSuperCall() { return new (this) AstSuperCall(); } inline AstConstructorDeclaration* NewConstructorDeclaration() { return new (this) AstConstructorDeclaration(this); } inline AstEnumDeclaration* NewEnumDeclaration() { return new (this) AstEnumDeclaration(this); } inline AstEnumConstant* NewEnumConstant(TokenIndex t) { return new (this) AstEnumConstant(t); } inline AstInterfaceDeclaration* NewInterfaceDeclaration() { return new (this) AstInterfaceDeclaration(this); } inline AstAnnotationDeclaration* NewAnnotationDeclaration(TokenIndex t) { return new (this) AstAnnotationDeclaration(t); } inline AstLocalVariableStatement* NewLocalVariableStatement() { return new (this) AstLocalVariableStatement(this); } inline AstLocalClassStatement* NewLocalClassStatement(AstClassDeclaration* decl) { return new (this) AstLocalClassStatement(decl); } inline AstLocalClassStatement* NewLocalClassStatement(AstEnumDeclaration* decl) { return new (this) AstLocalClassStatement(decl); } inline AstIfStatement* NewIfStatement() { return new (this) AstIfStatement(); } inline AstEmptyStatement* NewEmptyStatement(TokenIndex token) { return new (this) AstEmptyStatement(token); } inline AstExpressionStatement* NewExpressionStatement() { return new (this) AstExpressionStatement(); } inline AstSwitchLabel* NewSwitchLabel() { return new (this) AstSwitchLabel(); } inline AstSwitchBlockStatement* NewSwitchBlockStatement() { return new (this) AstSwitchBlockStatement(this); } inline AstSwitchStatement* NewSwitchStatement() { return new (this) AstSwitchStatement(this); } inline AstWhileStatement* NewWhileStatement() { return new (this) AstWhileStatement(); } inline AstDoStatement* NewDoStatement() { return new (this) AstDoStatement(); } inline AstForStatement* NewForStatement() { return new (this) AstForStatement(this); } inline AstForeachStatement* NewForeachStatement() { return new (this) AstForeachStatement(); } inline AstBreakStatement* NewBreakStatement() { return new (this) AstBreakStatement(); } inline AstContinueStatement* NewContinueStatement() { return new (this) AstContinueStatement(); } inline AstReturnStatement* NewReturnStatement() { return new (this) AstReturnStatement(); } inline AstThrowStatement* NewThrowStatement() { return new (this) AstThrowStatement(); } inline AstSynchronizedStatement* NewSynchronizedStatement() { return new (this) AstSynchronizedStatement(); } inline AstAssertStatement* NewAssertStatement() { return new (this) AstAssertStatement(); } inline AstCatchClause* NewCatchClause() { return new (this) AstCatchClause(); } inline AstFinallyClause* NewFinallyClause() { return new (this) AstFinallyClause(); } inline AstTryStatement* NewTryStatement() { return new (this) AstTryStatement(this); } inline AstIntegerLiteral* NewIntegerLiteral(TokenIndex token) { return new (this) AstIntegerLiteral(token); } inline AstLongLiteral* NewLongLiteral(TokenIndex token) { return new (this) AstLongLiteral(token); } inline AstFloatLiteral* NewFloatLiteral(TokenIndex token) { return new (this) AstFloatLiteral(token); } inline AstDoubleLiteral* NewDoubleLiteral(TokenIndex token) { return new (this) AstDoubleLiteral(token); } inline AstTrueLiteral* NewTrueLiteral(TokenIndex token) { return new (this) AstTrueLiteral(token); } inline AstFalseLiteral* NewFalseLiteral(TokenIndex token) { return new (this) AstFalseLiteral(token); } inline AstStringLiteral* NewStringLiteral(TokenIndex token) { return new (this) AstStringLiteral(token); } inline AstCharacterLiteral* NewCharacterLiteral(TokenIndex token) { return new (this) AstCharacterLiteral(token); } inline AstNullLiteral* NewNullLiteral(TokenIndex token) { return new (this) AstNullLiteral(token); } inline AstClassLiteral* NewClassLiteral(TokenIndex token) { return new (this) AstClassLiteral(token); } inline AstThisExpression* NewThisExpression(TokenIndex token) { return new (this) AstThisExpression(token); } inline AstSuperExpression* NewSuperExpression(TokenIndex token) { return new (this) AstSuperExpression(token); } inline AstParenthesizedExpression* NewParenthesizedExpression() { return new (this) AstParenthesizedExpression(); } inline AstClassCreationExpression* NewClassCreationExpression() { return new (this) AstClassCreationExpression(); } inline AstDimExpr* NewDimExpr() { return new (this) AstDimExpr(); } inline AstArrayCreationExpression* NewArrayCreationExpression() { return new (this) AstArrayCreationExpression(this); } inline AstFieldAccess* NewFieldAccess() { return new (this) AstFieldAccess(); } inline AstMethodInvocation* NewMethodInvocation(TokenIndex t) { return new (this) AstMethodInvocation(t); } inline AstArrayAccess* NewArrayAccess() { return new (this) AstArrayAccess(); } inline AstPostUnaryExpression* NewPostUnaryExpression(AstPostUnaryExpression::PostUnaryExpressionTag tag) { return new (this) AstPostUnaryExpression(tag); } inline AstPreUnaryExpression* NewPreUnaryExpression(AstPreUnaryExpression::PreUnaryExpressionTag tag) { return new (this) AstPreUnaryExpression(tag); } inline AstCastExpression* NewCastExpression() { return new (this) AstCastExpression(); } inline AstBinaryExpression* NewBinaryExpression(AstBinaryExpression::BinaryExpressionTag tag) { return new (this) AstBinaryExpression(tag); } inline AstInstanceofExpression* NewInstanceofExpression() { return new (this) AstInstanceofExpression(); } inline AstConditionalExpression* NewConditionalExpression() { return new (this) AstConditionalExpression(); } inline AstAssignmentExpression* NewAssignmentExpression(AstAssignmentExpression::AssignmentExpressionTag tag, TokenIndex token) { return new (this) AstAssignmentExpression(tag, token); } // ********************************************************************* // // Note that CaseElement nodes are always generated. Since they are not // Ast nodes they do not need to be marked. // inline CaseElement* GenCaseElement(unsigned block_index, unsigned case_index) { CaseElement* p = new (Alloc(sizeof(CaseElement))) CaseElement(); p -> block_index = block_index; p -> case_index = case_index; return p; } inline AstBlock* GenBlock() { AstBlock* p = NewBlock(); p -> generated = true; p -> no_braces = true; return p; } inline AstName* GenName(TokenIndex token) { AstName* p = NewName(token); p -> generated = true; return p; } inline AstPrimitiveType* GenPrimitiveType(Ast::AstKind kind, TokenIndex t) { AstPrimitiveType* p = NewPrimitiveType(kind, t); p -> generated = true; return p; } inline AstBrackets* GenBrackets(TokenIndex left, TokenIndex right) { AstBrackets* p = NewBrackets(left, right); p -> generated = true; return p; } inline AstArrayType* GenArrayType(AstType* type, AstBrackets* brackets) { AstArrayType* p = NewArrayType(type, brackets); p -> generated = true; return p; } inline AstWildcard* GenWildcard(TokenIndex question) { AstWildcard* p = NewWildcard(question); p -> generated = true; return p; } inline AstTypeArguments* GenTypeArguments(TokenIndex l, TokenIndex r) { AstTypeArguments* p = NewTypeArguments(l, r); p -> generated = true; return p; } inline AstTypeName* GenTypeName(AstName* type) { AstTypeName* p = NewTypeName(type); p -> generated = true; return p; } inline AstMemberValuePair* GenMemberValuePair() { AstMemberValuePair* p = NewMemberValuePair(); p -> generated = true; return p; } inline AstAnnotation* GenAnnotation() { AstAnnotation* p = NewAnnotation(); p -> generated = true; return p; } inline AstModifierKeyword* GenModifierKeyword(TokenIndex token) { AstModifierKeyword* p = NewModifierKeyword(token); p -> generated = true; return p; } inline AstModifiers* GenModifiers() { AstModifiers* p = NewModifiers(); p -> generated = true; return p; } inline AstPackageDeclaration* GenPackageDeclaration() { AstPackageDeclaration* p = NewPackageDeclaration(); p -> generated = true; return p; } inline AstImportDeclaration* GenImportDeclaration() { AstImportDeclaration* p = NewImportDeclaration(); p -> generated = true; return p; } inline AstCompilationUnit* GenCompilationUnit() { AstCompilationUnit* p = NewCompilationUnit(); p -> generated = true; return p; } inline AstEmptyDeclaration* GenEmptyDeclaration(TokenIndex t) { AstEmptyDeclaration* p = NewEmptyDeclaration(t); p -> generated = true; return p; } inline AstClassBody* GenClassBody() { AstClassBody* p = NewClassBody(); p -> generated = true; return p; } inline AstTypeParameter* GenTypeParameter(TokenIndex token) { AstTypeParameter* p = NewTypeParameter(token); p -> generated = true; return p; } inline AstTypeParameters* GenTypeParameters() { AstTypeParameters* p = NewTypeParameters(); p -> generated = true; return p; } inline AstClassDeclaration* GenClassDeclaration() { AstClassDeclaration* p = NewClassDeclaration(); p -> generated = true; return p; } inline AstArrayInitializer* GenArrayInitializer() { AstArrayInitializer* p = NewArrayInitializer(); p -> generated = true; return p; } inline AstVariableDeclaratorId* GenVariableDeclaratorId() { AstVariableDeclaratorId* p = NewVariableDeclaratorId(); p -> generated = true; return p; } inline AstVariableDeclarator* GenVariableDeclarator() { AstVariableDeclarator* p = NewVariableDeclarator(); p -> generated = true; return p; } inline AstFieldDeclaration* GenFieldDeclaration() { AstFieldDeclaration* p = NewFieldDeclaration(); p -> generated = true; return p; } inline AstFormalParameter* GenFormalParameter() { AstFormalParameter* p = NewFormalParameter(); p -> generated = true; return p; } inline AstMethodDeclarator* GenMethodDeclarator() { AstMethodDeclarator* p = NewMethodDeclarator(); p -> generated = true; return p; } inline AstMethodBody* GenMethodBody() { AstMethodBody* p = NewMethodBody(); p -> generated = true; return p; } inline AstMethodDeclaration* GenMethodDeclaration() { AstMethodDeclaration* p = NewMethodDeclaration(); p -> generated = true; return p; } inline AstInitializerDeclaration* GenInitializerDeclaration() { AstInitializerDeclaration* p = NewInitializerDeclaration(); p -> generated = true; return p; } inline AstArguments* GenArguments(TokenIndex left, TokenIndex right) { AstArguments* p = NewArguments(left, right); p -> generated = true; return p; } inline AstThisCall* GenThisCall() { AstThisCall* p = NewThisCall(); p -> generated = true; return p; } inline AstSuperCall* GenSuperCall() { AstSuperCall* p = NewSuperCall(); p -> generated = true; return p; } inline AstConstructorDeclaration* GenConstructorDeclaration() { AstConstructorDeclaration* p = NewConstructorDeclaration(); p -> generated = true; return p; } inline AstEnumDeclaration* GenEnumDeclaration() { AstEnumDeclaration* p = NewEnumDeclaration(); p -> generated = true; return p; } inline AstEnumConstant* GenEnumConstant(TokenIndex t) { AstEnumConstant* p = NewEnumConstant(t); p -> generated = true; return p; } inline AstInterfaceDeclaration* GenInterfaceDeclaration() { AstInterfaceDeclaration* p = NewInterfaceDeclaration(); p -> generated = true; return p; } inline AstAnnotationDeclaration* GenAnnotationDeclaration(TokenIndex t) { AstAnnotationDeclaration* p = NewAnnotationDeclaration(t); p -> generated = true; return p; } inline AstLocalVariableStatement* GenLocalVariableStatement() { AstLocalVariableStatement* p = NewLocalVariableStatement(); p -> generated = true; return p; } inline AstLocalClassStatement* GenLocalClassStatement(AstClassDeclaration* decl) { AstLocalClassStatement* p = NewLocalClassStatement(decl); p -> generated = true; return p; } inline AstLocalClassStatement* GenLocalClassStatement(AstEnumDeclaration* decl) { AstLocalClassStatement* p = NewLocalClassStatement(decl); p -> generated = true; return p; } inline AstIfStatement* GenIfStatement() { AstIfStatement* p = NewIfStatement(); p -> generated = true; return p; } inline AstEmptyStatement* GenEmptyStatement(TokenIndex token) { AstEmptyStatement* p = NewEmptyStatement(token); p -> generated = true; return p; } inline AstExpressionStatement* GenExpressionStatement() { AstExpressionStatement* p = NewExpressionStatement(); p -> generated = true; return p; } inline AstSwitchLabel* GenSwitchLabel() { AstSwitchLabel* p = NewSwitchLabel(); p -> generated = true; return p; } inline AstSwitchBlockStatement* GenSwitchBlockStatement() { AstSwitchBlockStatement* p = NewSwitchBlockStatement(); p -> generated = true; return p; } inline AstSwitchStatement* GenSwitchStatement() { AstSwitchStatement* p = NewSwitchStatement(); p -> generated = true; return p; } inline AstWhileStatement* GenWhileStatement() { AstWhileStatement* p = NewWhileStatement(); p -> generated = true; return p; } inline AstDoStatement* GenDoStatement() { AstDoStatement* p = NewDoStatement(); p -> generated = true; return p; } inline AstForStatement* GenForStatement() { AstForStatement* p = NewForStatement(); p -> generated = true; return p; } inline AstForeachStatement* GenForeachStatement() { AstForeachStatement* p = NewForeachStatement(); p -> generated = true; return p; } inline AstBreakStatement* GenBreakStatement() { AstBreakStatement* p = NewBreakStatement(); p -> generated = true; return p; } inline AstContinueStatement* GenContinueStatement() { AstContinueStatement* p = NewContinueStatement(); p -> generated = true; return p; } inline AstReturnStatement* GenReturnStatement() { AstReturnStatement* p = NewReturnStatement(); p -> generated = true; return p; } inline AstThrowStatement* GenThrowStatement() { AstThrowStatement* p = NewThrowStatement(); p -> generated = true; return p; } inline AstSynchronizedStatement* GenSynchronizedStatement() { AstSynchronizedStatement* p = NewSynchronizedStatement(); p -> generated = true; return p; } inline AstAssertStatement* GenAssertStatement() { AstAssertStatement* p = NewAssertStatement(); p -> generated = true; return p; } inline AstCatchClause* GenCatchClause() { AstCatchClause* p = NewCatchClause(); p -> generated = true; return p; } inline AstFinallyClause* GenFinallyClause() { AstFinallyClause* p = NewFinallyClause(); p -> generated = true; return p; } inline AstTryStatement* GenTryStatement() { AstTryStatement* p = NewTryStatement(); p -> generated = true; return p; } inline AstIntegerLiteral* GenIntegerLiteral(TokenIndex token) { AstIntegerLiteral* p = NewIntegerLiteral(token); p -> generated = true; return p; } inline AstLongLiteral* GenLongLiteral(TokenIndex token) { AstLongLiteral* p = NewLongLiteral(token); p -> generated = true; return p; } inline AstFloatLiteral* GenFloatLiteral(TokenIndex token) { AstFloatLiteral* p = NewFloatLiteral(token); p -> generated = true; return p; } inline AstDoubleLiteral* GenDoubleLiteral(TokenIndex token) { AstDoubleLiteral* p = NewDoubleLiteral(token); p -> generated = true; return p; } inline AstTrueLiteral* GenTrueLiteral(TokenIndex token) { AstTrueLiteral* p = NewTrueLiteral(token); p -> generated = true; return p; } inline AstFalseLiteral* GenFalseLiteral(TokenIndex token) { AstFalseLiteral* p = NewFalseLiteral(token); p -> generated = true; return p; } inline AstStringLiteral* GenStringLiteral(TokenIndex token) { AstStringLiteral* p = NewStringLiteral(token); p -> generated = true; return p; } inline AstCharacterLiteral* GenCharacterLiteral(TokenIndex token) { AstCharacterLiteral* p = NewCharacterLiteral(token); p -> generated = true; return p; } inline AstNullLiteral* GenNullLiteral(TokenIndex token) { AstNullLiteral* p = NewNullLiteral(token); p -> generated = true; return p; } inline AstClassLiteral* GenClassLiteral(TokenIndex token) { AstClassLiteral* p = NewClassLiteral(token); p -> generated = true; return p; } inline AstThisExpression* GenThisExpression(TokenIndex token) { AstThisExpression* p = NewThisExpression(token); p -> generated = true; return p; } inline AstSuperExpression* GenSuperExpression(TokenIndex token) { AstSuperExpression* p = NewSuperExpression(token); p -> generated = true; return p; } inline AstParenthesizedExpression* GenParenthesizedExpression() { AstParenthesizedExpression* p = NewParenthesizedExpression(); p -> generated = true; return p; } inline AstClassCreationExpression* GenClassCreationExpression() { AstClassCreationExpression* p = NewClassCreationExpression(); p -> generated = true; return p; } inline AstDimExpr* GenDimExpr() { AstDimExpr* p = NewDimExpr(); p -> generated = true; return p; } inline AstArrayCreationExpression* GenArrayCreationExpression() { AstArrayCreationExpression* p = NewArrayCreationExpression(); p -> generated = true; return p; } inline AstFieldAccess* GenFieldAccess() { AstFieldAccess* p = NewFieldAccess(); p -> generated = true; return p; } inline AstMethodInvocation* GenMethodInvocation(TokenIndex t) { AstMethodInvocation* p = NewMethodInvocation(t); p -> generated = true; return p; } inline AstArrayAccess* GenArrayAccess() { AstArrayAccess* p = NewArrayAccess(); p -> generated = true; return p; } inline AstPostUnaryExpression* GenPostUnaryExpression(AstPostUnaryExpression::PostUnaryExpressionTag tag) { AstPostUnaryExpression* p = NewPostUnaryExpression(tag); p -> generated = true; return p; } inline AstPreUnaryExpression* GenPreUnaryExpression(AstPreUnaryExpression::PreUnaryExpressionTag tag) { AstPreUnaryExpression* p = NewPreUnaryExpression(tag); p -> generated = true; return p; } inline AstCastExpression* GenCastExpression() { AstCastExpression* p = NewCastExpression(); p -> generated = true; return p; } inline AstBinaryExpression* GenBinaryExpression(AstBinaryExpression::BinaryExpressionTag tag) { AstBinaryExpression* p = NewBinaryExpression(tag); p -> generated = true; return p; } inline AstInstanceofExpression* GenInstanceofExpression() { AstInstanceofExpression* p = NewInstanceofExpression(); p -> generated = true; return p; } inline AstConditionalExpression* GenConditionalExpression() { AstConditionalExpression* p = NewConditionalExpression(); p -> generated = true; return p; } inline AstAssignmentExpression* GenAssignmentExpression(AstAssignmentExpression::AssignmentExpressionTag tag, TokenIndex token) { AstAssignmentExpression* p = NewAssignmentExpression(tag, token); p -> generated = true; return p; } }; //*********************************** // // Given an Ast tree, check whether it is a variable (not a value). // inline bool Ast::IsLeftHandSide() { return kind == NAME || kind == DOT || kind == ARRAY_ACCESS; } // // Given an Ast tree, check whether it is an explicit constructor invocation. // inline bool Ast::IsExplicitConstructorInvocation() { return kind == THIS_CALL || kind == SUPER_CALL; } // // Given an Ast tree, check whether or not it is generated. // inline bool Ast::IsGenerated() { return generated; } // // Cast conversions for Ast // inline AstStatement* Ast::StatementCast() { return DYNAMIC_CAST (class_tag == STATEMENT ? this : NULL); } inline AstMemberValue* Ast::MemberValueCast() { return DYNAMIC_CAST ((class_tag == EXPRESSION || kind == ANNOTATION || kind == ARRAY_INITIALIZER) ? this : NULL); } inline AstExpression* Ast::ExpressionCast() { return DYNAMIC_CAST (class_tag == EXPRESSION ? this : NULL); } inline AstPrimitiveType* Ast::PrimitiveTypeCast() { return DYNAMIC_CAST (class_tag == PRIMITIVE_TYPE ? this : NULL); } inline AstFieldDeclaration* Ast::StaticFieldCast() { return DYNAMIC_CAST (kind == FIELD && other_tag == AstFieldDeclaration::STATIC ? this : NULL); } inline AstInitializerDeclaration* Ast::StaticInitializerCast() { return DYNAMIC_CAST (kind == INITIALIZER && other_tag == AstInitializerDeclaration::STATIC ? this : NULL); } inline AstClassBody* Ast::UnparsedClassBodyCast() { return DYNAMIC_CAST (kind == CLASS_BODY && other_tag == AstClassBody::UNPARSED ? this : NULL); } inline AstCompilationUnit* Ast::BadCompilationUnitCast() { return DYNAMIC_CAST (kind == COMPILATION && other_tag == AstCompilationUnit::BAD_COMPILATION ? this : NULL); } inline AstCompilationUnit* Ast::EmptyCompilationUnitCast() { return DYNAMIC_CAST (kind == COMPILATION && other_tag == AstCompilationUnit::EMPTY_COMPILATION ? this : NULL); } // // These cast functions are used for classes that represent exactly // one kind of node. // inline AstListNode* Ast::ListNodeCast() { return DYNAMIC_CAST (kind == LIST_NODE ? this : NULL); } inline AstBlock* Ast::BlockCast() { return DYNAMIC_CAST (kind == BLOCK || kind == METHOD_BODY || kind == SWITCH_BLOCK ? this : NULL); } inline AstName* Ast::NameCast() { return DYNAMIC_CAST (kind == NAME ? this : NULL); } inline AstBrackets* Ast::BracketsCast() { return DYNAMIC_CAST (kind == BRACKETS ? this : NULL); } inline AstArrayType* Ast::ArrayTypeCast() { return DYNAMIC_CAST (kind == ARRAY ? this : NULL); } inline AstWildcard* Ast::WildcardCast() { return DYNAMIC_CAST (kind == WILDCARD ? this : NULL); } inline AstTypeArguments* Ast::TypeArgumentsCast() { return DYNAMIC_CAST (kind == TYPE_ARGUMENTS ? this : NULL); } inline AstTypeName* Ast::TypeNameCast() { return DYNAMIC_CAST (kind == TYPE ? this : NULL); } inline AstMemberValuePair* Ast::MemberValuePairCast() { return DYNAMIC_CAST (kind == MEMBER_VALUE_PAIR ? this : NULL); } inline AstAnnotation* Ast::AnnotationCast() { return DYNAMIC_CAST (kind == ANNOTATION ? this : NULL); } inline AstModifierKeyword* Ast::ModifierKeywordCast() { return DYNAMIC_CAST (kind == MODIFIER_KEYWORD ? this : NULL); } inline AstModifiers* Ast::ModifiersCast() { return DYNAMIC_CAST (kind == MODIFIERS ? this : NULL); } inline AstPackageDeclaration* Ast::PackageDeclarationCast() { return DYNAMIC_CAST (kind == PACKAGE ? this : NULL); } inline AstImportDeclaration* Ast::ImportDeclarationCast() { return DYNAMIC_CAST (kind == IMPORT ? this : NULL); } inline AstCompilationUnit* Ast::CompilationUnitCast() { return DYNAMIC_CAST (kind == COMPILATION ? this : NULL); } inline AstEmptyDeclaration* Ast::EmptyDeclarationCast() { return DYNAMIC_CAST (kind == EMPTY_DECLARATION ? this : NULL); } inline AstClassBody* Ast::ClassBodyCast() { return DYNAMIC_CAST (kind == CLASS_BODY ? this : NULL); } inline AstTypeParameter* Ast::TypeParameterCast() { return DYNAMIC_CAST (kind == TYPE_PARAM ? this : NULL); } inline AstTypeParameters* Ast::TypeParametersCast() { return DYNAMIC_CAST (kind == PARAM_LIST ? this : NULL); } inline AstClassDeclaration* Ast::ClassDeclarationCast() { return DYNAMIC_CAST (kind == CLASS ? this : NULL); } inline AstArrayInitializer* Ast::ArrayInitializerCast() { return DYNAMIC_CAST (kind == ARRAY_INITIALIZER ? this : NULL); } inline AstVariableDeclaratorId* Ast::VariableDeclaratorIdCast() { return DYNAMIC_CAST (kind == VARIABLE_DECLARATOR_NAME ? this : NULL); } inline AstVariableDeclarator* Ast::VariableDeclaratorCast() { return DYNAMIC_CAST (kind == VARIABLE_DECLARATOR ? this : NULL); } inline AstFieldDeclaration* Ast::FieldDeclarationCast() { return DYNAMIC_CAST (kind == FIELD ? this : NULL); } inline AstFormalParameter* Ast::FormalParameterCast() { return DYNAMIC_CAST (kind == PARAMETER ? this : NULL); } inline AstMethodDeclarator* Ast::MethodDeclaratorCast() { return DYNAMIC_CAST (kind == METHOD_DECLARATOR ? this : NULL); } inline AstMethodBody* Ast::MethodBodyCast() { return DYNAMIC_CAST (kind == METHOD_BODY ? this : NULL); } inline AstMethodDeclaration* Ast::MethodDeclarationCast() { return DYNAMIC_CAST (kind == METHOD ? this : NULL); } inline AstInitializerDeclaration* Ast::InitializerDeclarationCast() { return DYNAMIC_CAST (kind == INITIALIZER ? this : NULL); } inline AstArguments* Ast::ArgumentsCast() { return DYNAMIC_CAST (kind == ARGUMENTS ? this : NULL); } inline AstThisCall* Ast::ThisCallCast() { return DYNAMIC_CAST (kind == THIS_CALL ? this : NULL); } inline AstSuperCall* Ast::SuperCallCast() { return DYNAMIC_CAST (kind == SUPER_CALL ? this : NULL); } inline AstConstructorDeclaration* Ast::ConstructorDeclarationCast() { return DYNAMIC_CAST (kind == CONSTRUCTOR ? this : NULL); } inline AstEnumDeclaration* Ast::EnumDeclarationCast() { return DYNAMIC_CAST (kind == ENUM_TYPE ? this : NULL); } inline AstEnumConstant* Ast::EnumConstantCast() { return DYNAMIC_CAST (kind == ENUM ? this : NULL); } inline AstInterfaceDeclaration* Ast::InterfaceDeclarationCast() { return DYNAMIC_CAST (kind == INTERFACE ? this : NULL); } inline AstAnnotationDeclaration* Ast::AnnotationDeclarationCast() { return DYNAMIC_CAST (kind == ANNOTATION_TYPE ? this : NULL); } inline AstLocalVariableStatement* Ast::LocalVariableStatementCast() { return DYNAMIC_CAST (kind == LOCAL_VARIABLE_DECLARATION ? this : NULL); } inline AstLocalClassStatement* Ast::LocalClassStatementCast() { return DYNAMIC_CAST (kind == LOCAL_CLASS ? this : NULL); } inline AstIfStatement* Ast::IfStatementCast() { return DYNAMIC_CAST (kind == IF ? this : NULL); } inline AstEmptyStatement* Ast::EmptyStatementCast() { return DYNAMIC_CAST (kind == EMPTY_STATEMENT ? this : NULL); } inline AstExpressionStatement* Ast::ExpressionStatementCast() { return DYNAMIC_CAST (kind == EXPRESSION_STATEMENT ? this : NULL); } inline AstSwitchLabel* Ast::SwitchLabelCast() { return DYNAMIC_CAST (kind == SWITCH_LABEL ? this : NULL); } inline AstSwitchBlockStatement* Ast::SwitchBlockStatementCast() { return DYNAMIC_CAST (kind == SWITCH_BLOCK ? this : NULL); } inline AstSwitchStatement* Ast::SwitchStatementCast() { return DYNAMIC_CAST (kind == SWITCH ? this : NULL); } inline AstWhileStatement* Ast::WhileStatementCast() { return DYNAMIC_CAST (kind == WHILE ? this : NULL); } inline AstDoStatement* Ast::DoStatementCast() { return DYNAMIC_CAST (kind == DO ? this : NULL); } inline AstForStatement* Ast::ForStatementCast() { return DYNAMIC_CAST (kind == FOR ? this : NULL); } inline AstForeachStatement* Ast::ForeachStatementCast() { return DYNAMIC_CAST (kind == FOREACH ? this : NULL); } inline AstBreakStatement* Ast::BreakStatementCast() { return DYNAMIC_CAST (kind == BREAK ? this : NULL); } inline AstContinueStatement* Ast::ContinueStatementCast() { return DYNAMIC_CAST (kind == CONTINUE ? this : NULL); } inline AstReturnStatement* Ast::ReturnStatementCast() { return DYNAMIC_CAST (kind == RETURN ? this : NULL); } inline AstThrowStatement* Ast::ThrowStatementCast() { return DYNAMIC_CAST (kind == THROW ? this : NULL); } inline AstSynchronizedStatement* Ast::SynchronizedStatementCast() { return DYNAMIC_CAST (kind == SYNCHRONIZED_STATEMENT ? this : NULL); } inline AstAssertStatement* Ast::AssertStatementCast() { return DYNAMIC_CAST (kind == ASSERT ? this : NULL); } inline AstCatchClause* Ast::CatchClauseCast() { return DYNAMIC_CAST (kind == CATCH ? this : NULL); } inline AstFinallyClause* Ast::FinallyClauseCast() { return DYNAMIC_CAST (kind == FINALLY ? this : NULL); } inline AstTryStatement* Ast::TryStatementCast() { return DYNAMIC_CAST (kind == TRY ? this : NULL); } inline AstIntegerLiteral* Ast::IntegerLiteralCast() { return DYNAMIC_CAST (kind == INTEGER_LITERAL ? this : NULL); } inline AstLongLiteral* Ast::LongLiteralCast() { return DYNAMIC_CAST (kind == LONG_LITERAL ? this : NULL); } inline AstFloatLiteral* Ast::FloatLiteralCast() { return DYNAMIC_CAST (kind == FLOAT_LITERAL ? this : NULL); } inline AstDoubleLiteral* Ast::DoubleLiteralCast() { return DYNAMIC_CAST (kind == DOUBLE_LITERAL ? this : NULL); } inline AstTrueLiteral* Ast::TrueLiteralCast() { return DYNAMIC_CAST (kind == TRUE_LITERAL ? this : NULL); } inline AstFalseLiteral* Ast::FalseLiteralCast() { return DYNAMIC_CAST (kind == FALSE_LITERAL ? this : NULL); } inline AstStringLiteral* Ast::StringLiteralCast() { return DYNAMIC_CAST (kind == STRING_LITERAL ? this : NULL); } inline AstCharacterLiteral* Ast::CharacterLiteralCast() { return DYNAMIC_CAST (kind == CHARACTER_LITERAL ? this : NULL); } inline AstNullLiteral* Ast::NullLiteralCast() { return DYNAMIC_CAST (kind == NULL_LITERAL ? this : NULL); } inline AstClassLiteral* Ast::ClassLiteralCast() { return DYNAMIC_CAST (kind == CLASS_LITERAL ? this : NULL); } inline AstThisExpression* Ast::ThisExpressionCast() { return DYNAMIC_CAST (kind == THIS_EXPRESSION ? this : NULL); } inline AstSuperExpression* Ast::SuperExpressionCast() { return DYNAMIC_CAST (kind == SUPER_EXPRESSION ? this : NULL); } inline AstParenthesizedExpression* Ast::ParenthesizedExpressionCast() { return DYNAMIC_CAST (kind == PARENTHESIZED_EXPRESSION ? this : NULL); } inline AstClassCreationExpression* Ast::ClassCreationExpressionCast() { return DYNAMIC_CAST (kind == CLASS_CREATION ? this : NULL); } inline AstDimExpr* Ast::DimExprCast() { return DYNAMIC_CAST (kind == DIM ? this : NULL); } inline AstArrayCreationExpression* Ast::ArrayCreationExpressionCast() { return DYNAMIC_CAST (kind == ARRAY_CREATION ? this : NULL); } inline AstFieldAccess* Ast::FieldAccessCast() { return DYNAMIC_CAST (kind == DOT ? this : NULL); } inline AstMethodInvocation* Ast::MethodInvocationCast() { return DYNAMIC_CAST (kind == CALL ? this : NULL); } inline AstArrayAccess* Ast::ArrayAccessCast() { return DYNAMIC_CAST (kind == ARRAY_ACCESS ? this : NULL); } inline AstPostUnaryExpression* Ast::PostUnaryExpressionCast() { return DYNAMIC_CAST (kind == POST_UNARY ? this : NULL); } inline AstPreUnaryExpression* Ast::PreUnaryExpressionCast() { return DYNAMIC_CAST (kind == PRE_UNARY ? this : NULL); } inline AstCastExpression* Ast::CastExpressionCast() { return DYNAMIC_CAST (kind == CAST ? this : NULL); } inline AstBinaryExpression* Ast::BinaryExpressionCast() { return DYNAMIC_CAST (kind == BINARY ? this : NULL); } inline AstInstanceofExpression* Ast::InstanceofExpressionCast() { return DYNAMIC_CAST (kind == INSTANCEOF ? this : NULL); } inline AstConditionalExpression* Ast::ConditionalExpressionCast() { return DYNAMIC_CAST (kind == CONDITIONAL ? this : NULL); } inline AstAssignmentExpression* Ast::AssignmentExpressionCast() { return DYNAMIC_CAST (kind == ASSIGNMENT ? this : NULL); } // ********************************************** inline bool AstDeclaredType::IsValid() { return class_body && class_body -> semantic_environment; } inline void AstBlock::AllocateStatements(unsigned estimate) { assert(! block_statements); block_statements = new (pool) AstArray (pool, estimate); } inline void AstBlock::AddStatement(AstStatement* statement) { assert(block_statements); block_statements -> Next() = statement; } inline void AstBlock::AllocateLocallyDefinedVariables(unsigned estimate) { if (! defined_variables) defined_variables = pool -> NewVariableSymbolArray(estimate); } inline void AstBlock::AddLocallyDefinedVariable(VariableSymbol* variable_symbol) { if (! defined_variables) AllocateLocallyDefinedVariables(1); defined_variables -> Next() = variable_symbol; } inline void AstTypeArguments::AllocateTypeArguments(unsigned estimate) { assert(! type_arguments && estimate); type_arguments = new (pool) AstArray (pool, estimate); } inline void AstTypeArguments::AddTypeArgument(AstType* argument) { assert(! argument -> PrimitiveTypeCast()); assert(type_arguments); type_arguments -> Next() = argument; } inline void AstAnnotation::AllocateMemberValuePairs(unsigned estimate) { assert(! member_value_pairs); member_value_pairs = new (pool) AstArray (pool, estimate); } inline void AstAnnotation::AddMemberValuePair(AstMemberValuePair* pair) { assert(member_value_pairs); member_value_pairs -> Next() = pair; } inline void AstModifiers::AllocateModifiers(unsigned estimate) { assert(! modifiers && estimate); modifiers = new (pool) AstArray (pool, estimate); } inline void AstModifiers::AddModifier(AstAnnotation* annotation) { assert(modifiers); modifiers -> Next() = annotation; } inline void AstModifiers::AddModifier(AstModifierKeyword* keyword) { assert(modifiers); modifiers -> Next() = keyword; } inline void AstCompilationUnit::AllocateImportDeclarations(unsigned estimate) { assert(! import_declarations); import_declarations = new (ast_pool) AstArray (ast_pool, estimate); } inline void AstCompilationUnit::AddImportDeclaration(AstImportDeclaration* import_declaration) { assert(import_declarations); import_declarations -> Next() = import_declaration; } inline void AstCompilationUnit::AllocateTypeDeclarations(unsigned estimate) { assert(! type_declarations); type_declarations = new (ast_pool) AstArray (ast_pool, estimate); } inline void AstCompilationUnit::AddTypeDeclaration(AstDeclaredType* type_declaration) { assert(type_declarations); type_declarations -> Next() = type_declaration; } inline void AstClassBody::AllocateClassBodyDeclarations(unsigned estimate) { assert(! class_body_declarations); class_body_declarations = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AllocateInstanceVariables(unsigned estimate) { assert(! instance_variables); instance_variables = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddInstanceVariable(AstFieldDeclaration* field_declaration) { assert(instance_variables); instance_variables -> Next() = field_declaration; } inline void AstClassBody::AllocateClassVariables(unsigned estimate) { assert(! class_variables); class_variables = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddClassVariable(AstFieldDeclaration* field_declaration) { assert(class_variables); class_variables -> Next() = field_declaration; } inline void AstClassBody::AllocateMethods(unsigned estimate) { assert(! methods); methods = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddMethod(AstMethodDeclaration* method_declaration) { assert(methods); methods -> Next() = method_declaration; } inline void AstClassBody::AllocateConstructors(unsigned estimate) { assert(! constructors); constructors = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddConstructor(AstConstructorDeclaration* constructor_declaration) { assert(constructors); constructors -> Next() = constructor_declaration; } inline void AstClassBody::AllocateStaticInitializers(unsigned estimate) { assert(! static_initializers); static_initializers = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddStaticInitializer(AstInitializerDeclaration* initializer) { assert(static_initializers); static_initializers -> Next() = initializer; } inline void AstClassBody::AllocateInstanceInitializers(unsigned estimate) { assert(! instance_initializers); instance_initializers = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddInstanceInitializer(AstInitializerDeclaration* initializer) { assert(instance_initializers); instance_initializers -> Next() = initializer; } inline void AstClassBody::AllocateNestedClasses(unsigned estimate) { assert(! inner_classes); inner_classes = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddNestedClass(AstClassDeclaration* class_declaration) { assert(inner_classes); inner_classes -> Next() = class_declaration; } inline void AstClassBody::AllocateNestedEnums(unsigned estimate) { assert(! inner_enums); inner_enums = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddNestedEnum(AstEnumDeclaration* enum_declaration) { assert(inner_enums); inner_enums -> Next() = enum_declaration; } inline void AstClassBody::AllocateNestedInterfaces(unsigned estimate) { assert(! inner_interfaces); inner_interfaces = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddNestedInterface(AstInterfaceDeclaration* interface_declaration) { assert(inner_interfaces); inner_interfaces -> Next() = interface_declaration; } inline void AstClassBody::AllocateNestedAnnotations(unsigned estimate) { assert(! inner_annotations); inner_annotations = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddNestedAnnotation(AstAnnotationDeclaration* ann) { assert(inner_annotations); inner_annotations -> Next() = ann; } inline void AstClassBody::AllocateEmptyDeclarations(unsigned estimate) { assert(! empty_declarations); empty_declarations = new (pool) AstArray (pool, estimate); } inline void AstClassBody::AddEmptyDeclaration(AstEmptyDeclaration* empty_declaration) { assert(empty_declarations); empty_declarations -> Next() = empty_declaration; } inline void AstTypeParameter::AllocateBounds(unsigned estimate) { assert(! bounds); bounds = new (pool) AstArray (pool, estimate); } inline void AstTypeParameter::AddBound(AstTypeName* bound) { assert(bounds); bounds -> Next() = bound; } inline void AstTypeParameters::AllocateTypeParameters(unsigned estimate) { assert(! parameters); parameters = new (pool) AstArray (pool, estimate); } inline void AstTypeParameters::AddTypeParameter(AstTypeParameter* type) { assert(parameters); parameters -> Next() = type; } inline void AstClassDeclaration::AllocateInterfaces(unsigned estimate) { assert(! interfaces); interfaces = new (pool) AstArray (pool, estimate); } inline void AstClassDeclaration::AddInterface(AstTypeName* interf) { assert(interfaces); interfaces -> Next() = interf; } inline void AstArrayInitializer::AllocateVariableInitializers(unsigned estimate) { assert(! variable_initializers); variable_initializers = new (pool) AstArray (pool, estimate); } inline void AstArrayInitializer::AddVariableInitializer(AstMemberValue* initializer) { assert(variable_initializers); variable_initializers -> Next() = initializer; } inline void AstFieldDeclaration::AllocateVariableDeclarators(unsigned estimate) { assert(! variable_declarators); variable_declarators = new (pool) AstArray (pool, estimate); } inline void AstFieldDeclaration::AddVariableDeclarator(AstVariableDeclarator* variable_declarator) { assert(variable_declarators); variable_declarators -> Next() = variable_declarator; } inline void AstMethodDeclarator::AllocateFormalParameters(unsigned estimate) { assert(! formal_parameters); formal_parameters = new (pool) AstArray (pool, estimate); } inline void AstMethodDeclarator::AddFormalParameter(AstFormalParameter* formal_parameter) { assert(formal_parameters); formal_parameters -> Next() = formal_parameter; } inline void AstMethodDeclaration::AllocateThrows(unsigned estimate) { assert(! throws); throws = new (pool) AstArray (pool, estimate); } inline void AstMethodDeclaration::AddThrow(AstTypeName* exception) { assert(throws); throws -> Next() = exception; } inline void AstArguments::AllocateArguments(unsigned estimate) { assert(! arguments); arguments = new (pool) AstArray (pool, estimate); } inline void AstArguments::AddArgument(AstExpression* argument) { assert(arguments); arguments -> Next() = argument; } inline void AstArguments::AllocateLocalArguments(unsigned estimate) { assert(! shadow_arguments); shadow_arguments = new (pool) AstArray (pool, estimate); } inline void AstArguments::AddLocalArgument(AstName* argument) { assert(shadow_arguments); shadow_arguments -> Next() = argument; } inline void AstConstructorDeclaration::AllocateThrows(unsigned estimate) { assert(! throws); throws = new (pool) AstArray (pool, estimate); } inline void AstConstructorDeclaration::AddThrow(AstTypeName* exception) { assert(throws); throws -> Next() = exception; } inline void AstEnumDeclaration::AllocateInterfaces(unsigned estimate) { assert(! interfaces); interfaces = new (pool) AstArray (pool, estimate); } inline void AstEnumDeclaration::AddInterface(AstTypeName* interf) { assert(interfaces); interfaces -> Next() = interf; } inline void AstEnumDeclaration::AllocateEnumConstants(unsigned estimate) { assert(! enum_constants); enum_constants = new (pool) AstArray (pool, estimate); } inline void AstEnumDeclaration::AddEnumConstant(AstEnumConstant* constant) { assert(enum_constants); constant -> ordinal = enum_constants -> Length(); enum_constants -> Next() = constant; } inline void AstInterfaceDeclaration::AllocateInterfaces(unsigned estimate) { assert(! interfaces); interfaces = new (pool) AstArray (pool, estimate); } inline void AstInterfaceDeclaration::AddInterface(AstTypeName* interf) { assert(interfaces); interfaces -> Next() = interf; } inline void AstLocalVariableStatement::AllocateVariableDeclarators(unsigned estimate) { assert(! variable_declarators); variable_declarators = new (pool) AstArray (pool, estimate); } inline void AstLocalVariableStatement::AddVariableDeclarator(AstVariableDeclarator* variable_declarator) { assert(variable_declarators); variable_declarators -> Next() = variable_declarator; } inline void AstSwitchBlockStatement::AllocateSwitchLabels(unsigned estimate) { assert(! switch_labels); switch_labels = new (pool) AstArray (pool, estimate); } inline void AstSwitchBlockStatement::AddSwitchLabel(AstSwitchLabel* case_label) { assert(switch_labels); switch_labels -> Next() = case_label; } inline void AstSwitchStatement::AllocateCases(unsigned estimate) { // // Add one to the estimate to save room for the default case in element 0. // assert(! cases); cases = new (pool -> Alloc((estimate + 1) * sizeof(CaseElement*))) CaseElement*[estimate + 1]; #ifdef JIKES_DEBUG max_cases = estimate + 1; #endif // JIKES_DEBUG } inline void AstSwitchStatement::AddCase(CaseElement* case_element) { assert(cases); cases[++num_cases] = case_element; #ifdef JIKES_DEBUG assert(num_cases < max_cases); #endif // JIKES_DEBUG } inline void AstForStatement::AllocateForInitStatements(unsigned estimate) { assert(! for_init_statements); for_init_statements = new (pool) AstArray (pool, estimate); } inline void AstForStatement::AddForInitStatement(AstStatement* statement) { assert(for_init_statements); for_init_statements -> Next() = statement; } inline void AstForStatement::AllocateForUpdateStatements(unsigned estimate) { assert(! for_update_statements); for_update_statements = new (pool) AstArray (pool, estimate); } inline void AstForStatement::AddForUpdateStatement(AstExpressionStatement* statement) { assert(for_update_statements); for_update_statements -> Next() = statement; } inline void AstTryStatement::AllocateCatchClauses(unsigned estimate) { assert(! catch_clauses); catch_clauses = new (pool) AstArray (pool, estimate); } inline void AstTryStatement::AddCatchClause(AstCatchClause* catch_clause) { assert(catch_clauses); catch_clauses -> Next() = catch_clause; } inline void AstArrayCreationExpression::AllocateDimExprs(unsigned estimate) { assert(! dim_exprs); dim_exprs = new (pool) AstArray (pool, estimate); } inline void AstArrayCreationExpression::AddDimExpr(AstDimExpr* dim_expr) { assert(dim_exprs); dim_exprs -> Next() = dim_expr; } // ****************************************** // // Overridden placement new operator allows us to allocate storage from the // same pool as everything else in the compilation unit. // inline void* Ast::operator new(size_t size, StoragePool* pool) { return pool -> Alloc(size); } template inline void* AstArray::operator new(size_t size, StoragePool* pool) { return pool -> Alloc(size); } // // Constructor of an Ast array. // template AstArray::AstArray(StoragePool* pool, unsigned estimate) : size(estimate) { // // This bit of code is a compile-time assertion that only Ast* are stuck // in an AstArray. // #if defined JIKES_DEBUG && defined HAVE_STATIC_CAST assert(true || static_cast (T())); #endif // JIKES_DEBUG if(estimate) array = new (pool -> Alloc(size * sizeof(T))) T[size]; } #ifdef HAVE_JIKES_NAMESPACE } // Close namespace Jikes block #endif #endif // ast_INCLUDED