diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 4b3ef8cad..60be19dec 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -147,6 +147,10 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (std::strcmp(argv[i], "--debug-warnings") == 0) mSettings->debugwarnings = true; + // Show template information + else if (std::strcmp(argv[i], "--debug-template") == 0) + mSettings->debugtemplate = true; + // dump cppcheck data else if (std::strcmp(argv[i], "--dump") == 0) mSettings->dump = true; diff --git a/lib/settings.cpp b/lib/settings.cpp index 222eeda29..dd36fc308 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -27,6 +27,7 @@ Settings::Settings() debugSimplified(false), debugnormal(false), debugwarnings(false), + debugtemplate(false), dump(false), exceptionHandling(false), inconclusive(false), diff --git a/lib/settings.h b/lib/settings.h index 87bf1c598..4b43e8178 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -82,6 +82,9 @@ public: /** @brief Is --debug-warnings given? */ bool debugwarnings; + /** @brief Is --debug-template given? */ + bool debugtemplate; + /** @brief Is --dump given? */ bool dump; std::string dumpFile; diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 2877dad0e..3e937056a 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -51,10 +51,20 @@ namespace { private: const std::string mName; }; + + class FindFullName { + public: + explicit FindFullName(const std::string &fullName) : mFullName(fullName) {} + bool operator()(const TemplateSimplifier::TokenAndName &tokenAndName) const { + return tokenAndName.fullName == mFullName; + } + private: + const std::string mFullName; + }; } TemplateSimplifier::TokenAndName::TokenAndName(Token *tok, const std::string &s, const std::string &n, const Token *nt, const Token *pe) : - token(tok), scope(s), name(n), nameToken(nt), paramEnd(pe), flags(0) + token(tok), scope(s), name(n), fullName(s.empty() ? n : (s + " :: " + name)), nameToken(nt), paramEnd(pe), flags(0) { // only set flags for declaration if (token && nameToken && paramEnd) { @@ -72,7 +82,7 @@ TemplateSimplifier::TokenAndName::TokenAndName(Token *tok, const std::string &s, } TemplateSimplifier::TokenAndName::TokenAndName(const TokenAndName& otherTok) : - token(otherTok.token), scope(otherTok.scope), name(otherTok.name), + token(otherTok.token), scope(otherTok.scope), name(otherTok.name), fullName(otherTok.fullName), nameToken(otherTok.nameToken), paramEnd(otherTok.paramEnd), flags(otherTok.flags) { if (token) @@ -2175,6 +2185,80 @@ void TemplateSimplifier::fixForwardDeclaredDefaultArgumentValues() } } +void TemplateSimplifier::printOut(const TokenAndName &tokenAndName, const std::string &indent) const +{ + std::cout << indent << "token: "; + if (tokenAndName.token) + std::cout << "\"" << tokenAndName.token->str() << "\" " << mTokenList.fileLine(tokenAndName.token); + else + std::cout << "nullptr"; + std::cout << std::endl; + std::cout << indent << "scope: \"" << tokenAndName.scope << "\"" << std::endl; + std::cout << indent << "name: \"" << tokenAndName.name << "\"" << std::endl; + std::cout << indent << "fullName: \"" << tokenAndName.fullName << "\"" << std::endl; + std::cout << indent << "nameToken: "; + if (tokenAndName.nameToken) + std::cout << "\"" << tokenAndName.nameToken->str() << "\" " << mTokenList.fileLine(tokenAndName.nameToken); + else + std::cout << "nullptr"; + std::cout << std::endl; + std::cout << indent << "paramEnd: "; + if (tokenAndName.paramEnd) + std::cout << "\"" << tokenAndName.paramEnd->str() << "\" " << mTokenList.fileLine(tokenAndName.paramEnd); + else + std::cout << "nullptr"; + std::cout << std::endl; + std::cout << indent << "flags: "; + if (tokenAndName.isClass()) + std::cout << " isClass"; + if (tokenAndName.isFunction()) + std::cout << " isFunction"; + if (tokenAndName.isVariable()) + std::cout << " isVariable"; + if (tokenAndName.isAlias()) + std::cout << " isAlias"; + if (tokenAndName.isSpecialized()) + std::cout << " isSpecialized"; + std::cout << std::endl; + if (tokenAndName.token && !tokenAndName.paramEnd && tokenAndName.token->strAt(1) == "<") { + const Token *end = tokenAndName.token->next()->findClosingBracket(); + if (end) { + const Token *start = tokenAndName.token->next(); + std::cout << indent << "type: "; + while (start && start != end) { + std::cout << start->str(); + start = start->next(); + } + std::cout << end->str() << std::endl; + } + } +} + +void TemplateSimplifier::printOut(const std::string & text) const +{ + std::cout << std::endl; + std::cout << text << std::endl; + std::cout << std::endl; + std::cout << "mTemplateDeclarations: " << mTemplateDeclarations.size() << std::endl; + int count = 0; + for (const auto & decl : mTemplateDeclarations) { + std::cout << "mTemplateDeclarations[" << count++ << "]:" << std::endl; + printOut(decl); + } + std::cout << "mTemplateForwardDeclarations: " << mTemplateForwardDeclarations.size() << std::endl; + count = 0; + for (const auto & decl : mTemplateForwardDeclarations) { + std::cout << "mTemplateForwardDeclarations[" << count++ << "]:" << std::endl; + printOut(decl); + } + std::cout << "mTemplateInstantiations: " << mTemplateInstantiations.size() << std::endl; + count = 0; + for (const auto & decl : mTemplateInstantiations) { + std::cout << "mTemplateInstantiations[" << count++ << "]:" << std::endl; + printOut(decl); + } +} + void TemplateSimplifier::simplifyTemplates( const std::time_t maxtime, bool &codeWithTemplates) @@ -2236,6 +2320,9 @@ void TemplateSimplifier::simplifyTemplates( simplifyTemplateAliases(); + if (mSettings->debugtemplate) + printOut("### Template Simplifier pass " + std::to_string(i + 1) + " ###"); + std::set expandedtemplates; for (std::list::reverse_iterator iter1 = mTemplateDeclarations.rbegin(); iter1 != mTemplateDeclarations.rend(); ++iter1) { diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h index d0b306d7d..82cb14133 100644 --- a/lib/templatesimplifier.h +++ b/lib/templatesimplifier.h @@ -74,12 +74,13 @@ public: ~TokenAndName(); bool operator == (const TokenAndName & rhs) const { - return token == rhs.token && scope == rhs.scope && name == rhs.name && + return token == rhs.token && scope == rhs.scope && name == rhs.name && fullName == rhs.fullName && nameToken == rhs.nameToken && paramEnd == rhs.paramEnd && flags == rhs.flags; } Token *token; std::string scope; std::string name; + std::string fullName; const Token *nameToken; const Token *paramEnd; unsigned int flags; @@ -338,6 +339,11 @@ private: Token *tok2, std::list &typeStringsUsedInTemplateInstantiation); + void printOut( + const TokenAndName &tokenAndName, + const std::string &indent = " ") const; + void printOut(const std::string &text = "") const; + TokenList &mTokenList; const Settings *mSettings; ErrorLogger *mErrorLogger;