@@ -69,8 +69,15 @@ TemplateSimplifier::TokenAndName::TokenAndName(Token *token, const std::string &
6969 mFullName(mScope .empty() ? mName : (mScope + " :: " + mName )),
7070 mNameToken(nullptr ), mParamEnd(nullptr ), mFlags(0 )
7171{
72- if (mToken )
72+ if (mToken ) {
73+ if (mToken ->strAt (1 ) == " <" ) {
74+ const Token *end = mToken ->next ()->findClosingBracket ();
75+ if (end && end->strAt (1 ) == " (" ) {
76+ isFunction (true );
77+ }
78+ }
7379 mToken ->templateSimplifierPointer (this );
80+ }
7481}
7582
7683TemplateSimplifier::TokenAndName::TokenAndName (Token *token, const std::string &scope, const Token *nameToken, const Token *paramEnd) :
@@ -749,7 +756,18 @@ void TemplateSimplifier::addInstantiation(Token *token, const std::string &scope
749756
750757static void getFunctionArguments (const Token *nameToken, std::vector<const Token *> &args)
751758{
752- const Token *argToken = nameToken->tokAt (2 );
759+ const Token *argToken;
760+
761+ if (nameToken->strAt (1 ) == " (" )
762+ argToken = nameToken->tokAt (2 );
763+ else if (nameToken->strAt (1 ) == " <" ) {
764+ const Token *end = nameToken->next ()->findClosingBracket ();
765+ if (end)
766+ argToken = end->tokAt (2 );
767+ else
768+ return ;
769+ } else
770+ return ;
753771
754772 if (argToken->str () == " )" )
755773 return ;
@@ -3041,6 +3059,27 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
30413059 continue ;
30423060 }
30433061
3062+ if (templateDeclaration.isFunction () && instantiation.isFunction ()) {
3063+ std::vector<const Token*> declFuncArgs;
3064+ getFunctionArguments (templateDeclaration.nameToken (), declFuncArgs);
3065+ std::vector<const Token*> instFuncParams;
3066+ getFunctionArguments (instantiation.token (), instFuncParams);
3067+
3068+ if (declFuncArgs.size () != instFuncParams.size ()) {
3069+ // check for default arguments
3070+ const Token* tok = templateDeclaration.nameToken ()->tokAt (2 );
3071+ const Token* end = templateDeclaration.nameToken ()->linkAt (1 );
3072+ size_t count = 0 ;
3073+ for (; tok != end; tok = tok->next ()) {
3074+ if (tok->str () == " =" )
3075+ count++;
3076+ }
3077+
3078+ if (instFuncParams.size () < (declFuncArgs.size () - count) || instFuncParams.size () > declFuncArgs.size ())
3079+ continue ;
3080+ }
3081+ }
3082+
30443083 // A global function can't be called through a pointer.
30453084 if (templateDeclaration.isFunction () && templateDeclaration.scope ().empty () &&
30463085 (instantiation.token ()->strAt (-1 ) == " ." ||
@@ -3300,7 +3339,26 @@ static bool specMatch(
33003339 if (decl.isPartialSpecialization () || decl.isSpecialization () || decl.isAlias () || decl.isFriend ())
33013340 return false ;
33023341
3303- return spec.isSameFamily (decl);
3342+ if (!spec.isSameFamily (decl))
3343+ return false ;
3344+
3345+ // make sure the scopes and names match
3346+ if (spec.fullName () == decl.fullName ()) {
3347+ if (spec.isFunction ()) {
3348+ std::vector<const Token*> specArgs;
3349+ std::vector<const Token*> declArgs;
3350+ getFunctionArguments (spec.nameToken (), specArgs);
3351+ getFunctionArguments (decl.nameToken (), declArgs);
3352+
3353+ if (specArgs.size () == declArgs.size ()) {
3354+ // @todo make sure function parameters also match
3355+ return true ;
3356+ }
3357+ } else
3358+ return true ;
3359+ }
3360+
3361+ return false ;
33043362}
33053363
33063364void TemplateSimplifier::getSpecializations ()
@@ -3310,26 +3368,18 @@ void TemplateSimplifier::getSpecializations()
33103368 if (spec.isSpecialization ()) {
33113369 bool found = false ;
33123370 for (auto & decl : mTemplateDeclarations ) {
3313- if (!specMatch (spec, decl))
3314- continue ;
3315-
3316- // make sure the scopes and names match
3317- if (spec.fullName () == decl.fullName ()) {
3318- // @todo make sure function parameters also match
3371+ if (specMatch (spec, decl)) {
33193372 mTemplateSpecializationMap [spec.token ()] = decl.token ();
33203373 found = true ;
3374+ break ;
33213375 }
33223376 }
33233377
33243378 if (!found) {
33253379 for (auto & decl : mTemplateForwardDeclarations ) {
3326- if (!specMatch (spec, decl))
3327- continue ;
3328-
3329- // make sure the scopes and names match
3330- if (spec.fullName () == decl.fullName ()) {
3331- // @todo make sure function parameters also match
3380+ if (specMatch (spec, decl)) {
33323381 mTemplateSpecializationMap [spec.token ()] = decl.token ();
3382+ break ;
33333383 }
33343384 }
33353385 }
@@ -3344,26 +3394,18 @@ void TemplateSimplifier::getPartialSpecializations()
33443394 if (spec.isPartialSpecialization ()) {
33453395 bool found = false ;
33463396 for (auto & decl : mTemplateDeclarations ) {
3347- if (!specMatch (spec, decl))
3348- continue ;
3349-
3350- // make sure the scopes and names match
3351- if (spec.fullName () == decl.fullName ()) {
3352- // @todo make sure function parameters also match
3397+ if (specMatch (spec, decl)) {
33533398 mTemplatePartialSpecializationMap [spec.token ()] = decl.token ();
33543399 found = true ;
3400+ break ;
33553401 }
33563402 }
33573403
33583404 if (!found) {
33593405 for (auto & decl : mTemplateForwardDeclarations ) {
3360- if (!specMatch (spec, decl))
3361- continue ;
3362-
3363- // make sure the scopes and names match
3364- if (spec.fullName () == decl.fullName ()) {
3365- // @todo make sure function parameters also match
3406+ if (specMatch (spec, decl)) {
33663407 mTemplatePartialSpecializationMap [spec.token ()] = decl.token ();
3408+ break ;
33673409 }
33683410 }
33693411 }
0 commit comments