@@ -4410,10 +4410,26 @@ static void setVarIdStructMembers(Token *&tok1,
44104410 tok1 = tok;
44114411}
44124412
4413+ static void addTemplateVarIdUsage (const std::string &tokstr,
4414+ const std::map<std::string, std::set<std::string>>& templateVarUsage,
4415+ const std::unordered_map<std::string, nonneg int >& variableMap,
4416+ std::set<nonneg int >& templateVarIdUsage) {
4417+ const auto v = templateVarUsage.find (tokstr);
4418+ if (v != templateVarUsage.end ()) {
4419+ for (const std::string& varname: v->second ) {
4420+ const auto it = variableMap.find (varname);
4421+ if (it != variableMap.end ())
4422+ templateVarIdUsage.insert (it->second );
4423+ }
4424+ }
4425+ }
4426+
44134427static bool setVarIdClassDeclaration (Token* const startToken,
44144428 VariableMap& variableMap,
44154429 const nonneg int scopeStartVarId,
4416- std::map<nonneg int , std::map<std::string, nonneg int >>& structMembers)
4430+ const std::map<std::string, std::set<std::string>>& templateVarUsage,
4431+ std::map<nonneg int , std::map<std::string, nonneg int >>& structMembers,
4432+ std::set<nonneg int >& templateVarIdUsage)
44174433{
44184434 // end of scope
44194435 const Token* const endToken = startToken->link ();
@@ -4480,6 +4496,8 @@ static bool setVarIdClassDeclaration(Token* const startToken,
44804496 if (it != variableMap.map (false ).end ()) {
44814497 tok->varId (it->second );
44824498 setVarIdStructMembers (tok, structMembers, variableMap.getVarId ());
4499+ } else if (tok->str ().back () == ' >' ) {
4500+ addTemplateVarIdUsage (tok->str (), templateVarUsage, variableMap.map (false ), templateVarIdUsage);
44834501 }
44844502 }
44854503 }
@@ -4659,7 +4677,9 @@ void Tokenizer::setVarIdPass1()
46594677 if (!setVarIdClassDeclaration (tok->link (),
46604678 variableMap,
46614679 scopeStack.top ().startVarid ,
4662- structMembers)) {
4680+ mTemplateSimplifier ->getUsedVariables (),
4681+ structMembers,
4682+ mTemplateVarIdUsage )) {
46634683 syntaxError (nullptr );
46644684 }
46654685 }
@@ -4746,6 +4766,16 @@ void Tokenizer::setVarIdPass1()
47464766
47474767 if (decl) {
47484768 if (cpp) {
4769+ for (const Token* tok3 = tok->next (); tok3->isName (); tok3 = tok3->next ()) {
4770+ addTemplateVarIdUsage (tok3->str (),
4771+ mTemplateSimplifier ->getUsedVariables (),
4772+ variableMap.map (false ),
4773+ mTemplateVarIdUsage );
4774+ addTemplateVarIdUsage (tok3->str (),
4775+ mTemplateSimplifier ->getUsedVariables (),
4776+ variableMap.map (true ),
4777+ mTemplateVarIdUsage );
4778+ }
47494779 if (Token *declTypeTok = Token::findsimplematch (tok, " decltype (" , tok2)) {
47504780 for (Token *declTok = declTypeTok->linkAt (1 ); declTok != declTypeTok; declTok = declTok->previous ()) {
47514781 if (declTok->isName () && !Token::Match (declTok->previous (), " ::|." ) && variableMap.hasVariable (declTok->str ()))
@@ -4859,6 +4889,13 @@ void Tokenizer::setVarIdPass1()
48594889 continue ;
48604890 }
48614891
4892+ if (tok->str ().back () == ' >' ) {
4893+ addTemplateVarIdUsage (tok->str (),
4894+ mTemplateSimplifier ->getUsedVariables (),
4895+ variableMap.map (globalNamespace),
4896+ mTemplateVarIdUsage );
4897+ }
4898+
48624899 // function declaration inside executable scope? Function declaration is of form: type name "(" args ")"
48634900 if (scopeStack.top ().isExecutable && !scopeStack.top ().isStructInit && Token::Match (tok, " %name% [,)[]" )) {
48644901 bool par = false ;
@@ -6175,6 +6212,12 @@ void Tokenizer::dump(std::ostream &out) const
61756212 outs += dumpTypedefInfo ();
61766213
61776214 outs += mTemplateSimplifier ->dump ();
6215+ if (!mTemplateVarIdUsage .empty ()) {
6216+ outs += " <template-varid-usage>\n " ;
6217+ for (nonneg int id: mTemplateVarIdUsage )
6218+ outs += " <var id=\" " + std::to_string (id) + " \" />\n " ;
6219+ outs += " </template-varid-usage>\n " ;
6220+ }
61786221
61796222 out << outs;
61806223}
0 commit comments