@@ -485,10 +485,10 @@ static void setScopeInfo(const Token *tok, std::list<ScopeInfo2> *scopeInfo)
485485 }
486486}
487487
488- std::list<TemplateSimplifier::TokenAndName> TemplateSimplifier::getTemplateDeclarations (bool &codeWithTemplates, bool forward )
488+ bool TemplateSimplifier::getTemplateDeclarations ()
489489{
490+ bool codeWithTemplates = false ;
490491 std::list<ScopeInfo2> scopeInfo;
491- std::list<TokenAndName> declarations;
492492 for (Token *tok = mTokenList .front (); tok; tok = tok->next ()) {
493493 if (Token::Match (tok, " }|namespace|class|struct|union" )) {
494494 setScopeInfo (tok, &scopeInfo);
@@ -509,27 +509,23 @@ std::list<TemplateSimplifier::TokenAndName> TemplateSimplifier::getTemplateDecla
509509 tok2 = tok2->link ();
510510 else if (tok2->str () == " )" )
511511 break ;
512- // Just a declaration => ignore this
512+ // Declaration => add to mTemplateForwardDeclarations
513513 else if (tok2->str () == " ;" ) {
514- if (forward) {
515- const int namepos = getTemplateNamePosition (parmEnd, forward);
516- if (namepos > 0 )
517- declarations.emplace_back (tok, getScopeName (scopeInfo), parmEnd->strAt (namepos));
518- }
514+ const int namepos = getTemplateNamePosition (parmEnd, true );
515+ if (namepos > 0 )
516+ mTemplateForwardDeclarations .emplace_back (tok, getScopeName (scopeInfo), parmEnd->strAt (namepos));
519517 break ;
520518 }
521- // Implementation => add to "templates"
519+ // Implementation => add to mTemplateDeclarations
522520 else if (tok2->str () == " {" ) {
523- if (!forward) {
524- const int namepos = getTemplateNamePosition (parmEnd, forward);
525- if (namepos > 0 )
526- declarations.emplace_back (tok, getScopeName (scopeInfo), parmEnd->strAt (namepos));
527- }
521+ const int namepos = getTemplateNamePosition (parmEnd, false );
522+ if (namepos > 0 )
523+ mTemplateDeclarations .emplace_back (tok, getScopeName (scopeInfo), parmEnd->strAt (namepos));
528524 break ;
529525 }
530526 }
531527 }
532- return declarations ;
528+ return codeWithTemplates ;
533529}
534530
535531
@@ -961,15 +957,33 @@ int TemplateSimplifier::getTemplateNamePosition(const Token *tok, bool forward)
961957
962958void TemplateSimplifier::addNamespace (const TokenAndName &templateDeclaration, const Token *tok)
963959{
960+ // find start of qualification
961+ const Token * tokStart = tok;
962+ int offset = 0 ;
963+ while (Token::Match (tokStart->tokAt (-2 ), " %name% ::" )) {
964+ tokStart = tokStart->tokAt (-2 );
965+ offset -= 2 ;
966+ }
967+ // decide if namespace needs to be inserted in or appended to token list
968+ const bool insert = tokStart != tok;
969+
964970 std::string::size_type start = 0 ;
965971 std::string::size_type end = 0 ;
966972 while ((end = templateDeclaration.scope .find (" " , start)) != std::string::npos) {
967973 std::string token = templateDeclaration.scope .substr (start, end - start);
968- mTokenList .addtoken (token, tok->linenr (), tok->fileIndex ());
974+ if (insert)
975+ mTokenList .back ()->tokAt (offset)->insertToken (token, " " );
976+ else
977+ mTokenList .addtoken (token, tok->linenr (), tok->fileIndex ());
969978 start = end + 1 ;
970979 }
971- mTokenList .addtoken (templateDeclaration.scope .substr (start), tok->linenr (), tok->fileIndex ());
972- mTokenList .addtoken (" ::" , tok->linenr (), tok->fileIndex ());
980+ if (insert) {
981+ mTokenList .back ()->tokAt (offset)->insertToken (templateDeclaration.scope .substr (start), " " );
982+ mTokenList .back ()->tokAt (offset)->insertToken (" ::" , " " );
983+ } else {
984+ mTokenList .addtoken (templateDeclaration.scope .substr (start), tok->linenr (), tok->fileIndex ());
985+ mTokenList .addtoken (" ::" , tok->linenr (), tok->fileIndex ());
986+ }
973987}
974988
975989bool TemplateSimplifier::alreadyHasNamespace (const TokenAndName &templateDeclaration, const Token *tok) const
@@ -1961,12 +1975,8 @@ void TemplateSimplifier::replaceTemplateUsage(
19611975
19621976void TemplateSimplifier::fixForwardDeclaredDefaultArgumentValues ()
19631977{
1964- // get all forward declarations
1965- bool dummy;
1966- std::list<TokenAndName> forwardTemplateDeclarations = getTemplateDeclarations (dummy, true );
1967-
19681978 // try to locate a matching declaration for each forward declaration
1969- for (const auto & forwardDecl : forwardTemplateDeclarations ) {
1979+ for (const auto & forwardDecl : mTemplateForwardDeclarations ) {
19701980 std::vector<const Token *> params1;
19711981
19721982 getTemplateParametersInDeclaration (forwardDecl.token , params1);
@@ -1995,29 +2005,8 @@ void TemplateSimplifier::fixForwardDeclaredDefaultArgumentValues()
19952005
19962006void TemplateSimplifier::simplifyTemplates (
19972007 const std::time_t maxtime,
1998- bool &codeWithTemplates
1999- )
2008+ bool &codeWithTemplates)
20002009{
2001- std::set<std::string> expandedtemplates;
2002-
2003- if (getTemplateDeclarations (codeWithTemplates).empty ())
2004- return ;
2005-
2006- // There are templates..
2007- // Remove "typename" unless used in template arguments..
2008- for (Token *tok = mTokenList .front (); tok; tok = tok->next ()) {
2009- if (tok->str () == " typename" )
2010- tok->deleteThis ();
2011-
2012- if (Token::simpleMatch (tok, " template <" )) {
2013- while (tok && tok->str () != " >" )
2014- tok = tok->next ();
2015- if (!tok)
2016- break ;
2017- }
2018- }
2019-
2020- // expand templates
20212010 // TODO: 2 is not the ideal number of loops.
20222011 // We should loop until the number of declarations is 0 but we can't
20232012 // do that until we instantiate unintstantiated templates with their symbolic types.
@@ -2027,12 +2016,36 @@ void TemplateSimplifier::simplifyTemplates(
20272016 // is fixed.
20282017 for (int i = 0 ; i < 2 ; ++i) {
20292018 if (i) {
2030- expandedtemplates.clear ();
2019+ mTemplateDeclarations .clear ();
2020+ mTemplateForwardDeclarations .clear ();
20312021 mTemplateInstantiations .clear ();
20322022 mInstantiatedTemplates .clear ();
20332023 }
20342024
2035- mTemplateDeclarations = getTemplateDeclarations (codeWithTemplates);
2025+ bool hasTemplates = getTemplateDeclarations ();
2026+
2027+ if (i == 0 ) {
2028+ codeWithTemplates = hasTemplates;
2029+ if (hasTemplates) {
2030+ // There are templates..
2031+ // Remove "typename" unless used in template arguments..
2032+ for (Token *tok = mTokenList .front (); tok; tok = tok->next ()) {
2033+ if (tok->str () == " typename" )
2034+ tok->deleteThis ();
2035+
2036+ if (Token::simpleMatch (tok, " template <" )) {
2037+ while (tok && tok->str () != " >" )
2038+ tok = tok->next ();
2039+ if (!tok)
2040+ break ;
2041+ }
2042+ }
2043+ }
2044+ }
2045+
2046+ // Make sure there is something to simplify.
2047+ if (mTemplateDeclarations .empty ())
2048+ return ;
20362049
20372050 // Copy default argument values from forward declaration to declaration
20382051 fixForwardDeclaredDefaultArgumentValues ();
@@ -2045,6 +2058,8 @@ void TemplateSimplifier::simplifyTemplates(
20452058
20462059 simplifyTemplateAliases ();
20472060
2061+ std::set<std::string> expandedtemplates;
2062+
20482063 for (std::list<TokenAndName>::reverse_iterator iter1 = mTemplateDeclarations .rbegin (); iter1 != mTemplateDeclarations .rend (); ++iter1) {
20492064 // get specializations..
20502065 std::list<const Token *> specializations;
0 commit comments