#include #include "../AST.h" #include "TemplateContext.h" #include "TemplateCheckContext.h" #include "depth.h" void TreeNode::resolveTemplate( const TemplateContext &context ) { foriter (child, allChildren(), ChildIter) (*child)->resolveTemplate( context ); } void TemplateDeclNode::resolveTemplate( const TemplateContext & ) { } void TemplateInstanceTypeNode::resolveTemplate( const TemplateContext &context ) { if (!decl()) { TreeNode::resolveTemplate( context ); ClassDecl * const instDecl = resolveTemplate( !context.postponed ); if (instDecl) { decl( instDecl ); instDecl->drequire(); context.progress = true; } else *context.postponed = true; } } ClassDecl *TemplateInstanceTypeNode::resolveTemplate( bool force ) { ClassDecl &basisDecl = static_cast< ClassDecl & >( *dtype()->decl() ); assert( basisDecl.category() & (Decl::Class | Decl::Interface) ); assert( basisDecl.instantiations != NULL ); TreeListNode &formals = *basisDecl.source()->parent()->params(); TreeListNode &actuals = *args(); const int numActuals = actuals.arity(); assert( numActuals == formals.arity() ); TemplateCheckContext context( force ); for (int arg = 0; arg < numActuals; ++arg) { TreeNode &formal = *formals.child( arg ); TreeNode &actual = *actuals.child( arg ); formal.checkTemplateActual( context, actual ); } if (!context.valid) return UnknownClassDecl; if (!context.ready) if (force) return UnknownClassDecl; else return 0; int deepest = 0; foriter (actual, actuals.allChildren(), ChildIter) deepest = max( deepest, (*actual)->templateDepth() ); if (deepest >= maxTemplateDepth) { actuals.error() << "template instantiation depth exceeds maximum of " << maxTemplateDepth << endl; actuals.message() << " (use \"-template-depth \" to increase the maximum)" << endl; return UnknownClassDecl; } return basisDecl.instantiateDecl( actuals, deepest + 1 ); } // Local Variables: // c-file-style: "gnu" // End: