#include "../AST.h" static string arguments( int count ) { string result( int2string( count ) ); result += " argument"; if (count == 1) result += 's'; return result; } ClassDecl *TemplateInstanceTypeNode::checkTemplateUse() const { TypeDecl &typeDecl = *dtype()->decl(); if (!typeDecl.category() & (Decl::Class | Decl::Interface)) { error() << typeDecl.errorName() << " is neither a class nor an interface" << endl; return UnknownClassDecl; } ClassDecl &basisDecl = static_cast< ClassDecl & >( typeDecl ); if (!basisDecl.instantiations) { const string errorName( basisDecl.errorName() ); error() << errorName << " is not a template" << endl; basisDecl.source()->message() << errorName << " originally declared here" << endl; return UnknownClassDecl; } TreeListNode &formals = *basisDecl.source()->parent()->params(); TreeListNode &actuals = *args(); const int numFormals = formals.arity(); const int numActuals = actuals.arity(); if (numFormals != numActuals) { actuals.error() << arguments( numActuals ) << " used to instantiate template " << errorName() << endl; formals.message() << arguments( numFormals ) << " expected by template declaration" << endl; return UnknownClassDecl; } // sanity checked ok; now we can disambiguate for (int arg = 0; arg < numActuals; ++arg) { TreeNode &formal = *formals.child( arg ); TreeNode &actual = *actuals.child( arg ); TreeNode *fixed = formal.fixTemplateActual( actual ); actuals.child( arg, fixed ); } return 0; } // Local Variables: // c-file-style: "gnu" // End: