#include #include "../AST.h" #include "../compiler.h" #include "../streq.h" #include "Instantiations.h" #include "PseudonymDecl.h" #include "depth.h" bool debug_instantiation = false; //////////////////////////////////////////////////////////////////////// ClassDecl *ClassDecl::instantiateDecl( TreeListNode &actuals, int depth ) { assert( instantiations != NULL ); TypeDeclNode &basis = static_cast< TypeDeclNode & >( *source() ); TreeListNode &formals = *basis.parent()->params(); assert( basis.decl() == this ); const int numFormals = formals.arity(); const int numActuals = actuals.arity(); assert( numFormals == numActuals ); ////////////////////////////////////////////////////////////////////// // // The instantiation appears to be valid, provided that subsequent // constant folding reduces all actual expression parameters to // constant expressions. For now, we can go ahead and return a // real decl. // ClassDecl *&instDecl = (*instantiations)[ actuals ]; if (!instDecl) instDecl = new ClassDecl( *this, actuals, depth ); return instDecl; // ////////////////////////////////////////////////////////////////////// } ClassDecl::ClassDecl( ClassDecl &basis, TreeListNode &actuals, int depth ) : TypeDecl( basis.name(), invalid( basis.name() ) ), instantiations( 0 ), templateActuals( &actuals ), templateBasis( &basis ), templateDepth( depth ), _container( basis.container() ), _modifiers( (Modifiers) 0 ), _source( 0 ), _environ( 0 ), _superClass( 0 ), _interfaces( 0 ), _valid( false ) { assert( depth > 0 ); if (debug_instantiation) cerr << "instantiate decl at depth " << depth << ':' << endl << "\tbasis decl: " << &basis << ": " << basis.errorName() << endl << "\tinst decl: " << this << ": " << errorName() << endl; } void ClassDecl::instantiateSource() { ClassDecl &basisDecl = *templateBasis; assert( basisDecl.source() != NULL ); assert( !source() ); assert( basisDecl.instantiations != NULL ); assert( templateActuals != NULL ); TypeDeclNode &basisSource = static_cast< TypeDeclNode & >(*basisDecl.source()); TemplateDeclNode &basisTemplate = static_cast< TemplateDeclNode & >(*basisSource.parent()); CompileUnitNode &basisUnit = static_cast< CompileUnitNode & >(*basisTemplate.parent()->parent()); assert( streq( basisUnit.oper_name(), "CompileUnitNode" ) ); TreeListNode &formals = *basisTemplate.params(); TreeListNode &actuals = *templateActuals; const int numFormals = formals.arity(); const int numActuals = actuals.arity(); assert( numFormals == numActuals ); Environ * const instEnv = new Environ( basisUnit.environ() ); instEnv->add( this ); for (int arg = 0; arg < numActuals; ++arg) instEnv->add( formals.child( arg )->bindPseudonym( *actuals.child( arg ) ) ); TypeDeclNode * const instSource = basisSource.deepClone(); TemplateInstanceDeclNode * const instDeclNode = new TemplateInstanceDeclNode( instSource, instEnv, instSource->position() ); CompileUnitNode &instUnit = *basisUnit.clone(); instUnit.types( instDeclNode ); source( instSource ); instSource->simpName()->decl( this ); assert( !_environ ); _environ = new Environ( instEnv ); if (debug_instantiation) cerr << "instantiate source:" << endl << "\tbasis decl: " << &basisDecl << ": " << basisDecl.errorName() << endl << "\tinst decl: " << this << ": " << errorName() << endl << "\tbasis source: " << &basisUnit << " --> (list) --> " << &basisSource << endl << "\tinst source: " << &instUnit << " --> " << instDeclNode << " --> " << instSource << endl; instUnit.resolveTypes( 0, 0, 0 ); instUnit.loaded(); } // Local Variables: // c-file-style: "gnu" // End: