#include #include "../AST.h" #include "TemplateContext.h" #include "TemplateCheckContext.h" #include "../tclimits.h" int maxTemplateInstantiations = 70; void TreeNode::resolveTemplate( const TemplateContext &context ) { foriter (child, allChildren(), ChildIter) (*child)->resolveTemplate( context ); } void TemplateDeclNode::resolveTemplate( const TemplateContext & ) { } void TypeDeclNode::resolveTemplate( const TemplateContext &context ) { if (!decl()->isTypeReady()) { // All template instances in this declaration must undergo type resolution // before we can proceed with instantiation. if (context.postponed) *context.postponed = true; // Except of course the supertypes, which always has undergone type resolution. if (decl()->category() == Decl::Class) superClass()->resolveTemplate( context ); interfaces()->resolveTemplate( context ); } else TreeNode::resolveTemplate( context ); } 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; if (basisDecl.numInstantiations >= maxTemplateInstantiations) { actuals.error() << "number of instantiations of " << basisDecl.errorName() << " exceeds maximum of " << maxTemplateInstantiations << endl; actuals.message() << " (use \"-template-instantiations \" to increase the maximum)" << endl; return UnknownClassDecl; } 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: