#include "AST.h" #include "code-util.h" #include "compiler.h" #include "decls.h" #include "domain-decls.h" void TreeNode::resolveRequires( ClassDecl *currentClass ) { foriter (child, allChildren(), ChildIter) (*child)->resolveRequires( currentClass ); } void TemplateDeclNode::resolveRequires( ClassDecl * ) { } void TypeDeclNode::resolveRequires( ClassDecl * ) { decl()->requires(*JavaLangClassDecl); TreeNode::resolveRequires( decl() ); } void MethodCallNode::resolveRequires( ClassDecl *currentClass ) { TypeNode * targettype = method()->accessedObjectType(); currentClass->requires( *targettype ); if (isOFAN(method())) { MethodDecl *md = NULL; ((ObjectFieldAccessNode *)method())->canCallStatically(md); if (md) currentClass->requires( *md->container()->asType() ); // may differ from accessedObjectType with opt_finalize } TreeNode::resolveRequires( currentClass ); } void AllocateNode::resolveRequires( ClassDecl *currentClass ) { currentClass->requires( *dtype() ); TreeNode::resolveRequires( currentClass ); } void AllocateSpaceNode::resolveRequires( ClassDecl *currentClass ) { currentClass->requires( *dtype() ); TreeNode::resolveRequires( currentClass ); } void AllocateArrayNode::resolveRequires( ClassDecl *currentClass ) { TypeNode *descend = type(); while (descend->isArrayType()) { if (!descend->isJavaArrayType()) currentClass->requires( *descend ); descend = descend->elementType(); } TreeNode::resolveRequires( currentClass ); } void CatchNode::resolveRequires( ClassDecl *currentClass ) { currentClass->requires( *param()->dtype() ); TreeNode::resolveRequires( currentClass ); } void DynamicTypeNode::resolveRequires( ClassDecl *currentClass ) { if (!dtype()->isPrimitive()) currentClass->requires( *NativeUtilsDecl ); if (!(dtype()->isJavaArrayType() || dtype()->isPrimitive())) currentClass->requires( *dtype() ); TreeNode::resolveRequires( currentClass ); } void FieldAccessNode::resolveRequires( ClassDecl *currentClass ) { if (decl()->category() == Decl::Field && decl()->modifiers() & Static) currentClass->requires( *accessedObjectType() ); // DOB: need actual this type being used for qualified super (PR 604) if (decl()->category() == Decl::Field && isOFAN(this) && ((ObjectFieldAccessNode*)this)->isRewrittenQSFAN()) currentClass->requires( *object()->type() ); if (decl()->category() == Decl::Field && decl()->type()->isImmutable()) currentClass->requires( *decl()->type()); // make sure we include the field type, specifically we need to suck in // the ti_array_empty method so we can initialize ti array fields TreeNode::resolveRequires( currentClass ); } void FieldDeclNode::resolveRequires( ClassDecl *currentClass ) { // this is still required because we use defaultInitializer, // which calls callNoArgConstructor and wraps the resulting native code string in a // CodeLiteralExprNode that we can't examine if (dtype()->isImmutable()) currentClass->requires( *dtype() ); TreeNode::resolveRequires( currentClass ); } void VarDeclNode::resolveRequires( ClassDecl *currentClass ) { // this should really be taken care of by having the rewrite stage // add an explicit initializer if (initExpr()->absent() && dtype()->isImmutable()) currentClass->requires( *dtype() ); TreeNode::resolveRequires( currentClass ); } void DomainNode::resolveRequires( ClassDecl *currentClass ) { // this should really be taken care of by having the rewrite stage // add an explicit allocation / constructor invocation currentClass->requires( *type() ); TreeNode::resolveRequires( currentClass ); } void ForEachStmtNode::resolveRequires( ClassDecl *currentClass ) { TypeNode *RDtype = vars()->child(0)->initExpr()->type(); if (RDtype->isDomainType()) { currentClass->requires(*MultiRectADomainNDecl[RDtype->tiArity()-1]->asType()); } TreeNode::resolveRequires( currentClass ); } void TitaniumArrayAccessNode::resolveRequires( ClassDecl *currentClass ) { currentClass->requires( *array()->type() ); TreeNode::resolveRequires( currentClass ); } void StringLitNode::resolveRequires( ClassDecl *currentClass ) { currentClass->requires( *NativeUtilsDecl ); } //////////////////////////////////////////////////////////////////////// extern int isDomainOrtiDomainType(const TypeNode& t); void ClassDecl::requires( TypeNode &prerequisite ) { requires( *prerequisite.decl() ); } void ClassDecl::requires( Decl &prerequisite ) { if (isDomainOrtiDomainType(*prerequisite.asType())) // HACK for pseudotemplates _requirements.insert( MultiRectADomainNDecl[isDomainOrtiDomainType(*prerequisite.asType())-1] ); else _requirements.insert( &prerequisite ); } void Decl::requires( TypeNode & ) { invalidOperation( "requires" ); } void Decl::requires( Decl & ) { invalidOperation( "requires" ); }