2012-01-01 21:55:05 +01:00
|
|
|
/*
|
|
|
|
* Cppcheck - A tool for static C/C++ code analysis
|
2018-01-14 15:37:52 +01:00
|
|
|
* Copyright (C) 2007-2017 Cppcheck team.
|
2012-01-01 21:55:05 +01:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
#ifndef templatesimplifierH
|
|
|
|
#define templatesimplifierH
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <ctime>
|
2012-01-02 22:05:27 +01:00
|
|
|
#include <list>
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <set>
|
2012-01-02 21:53:13 +01:00
|
|
|
#include <string>
|
2012-01-03 22:35:06 +01:00
|
|
|
#include <vector>
|
2012-01-01 21:55:05 +01:00
|
|
|
|
2012-05-06 10:38:55 +02:00
|
|
|
class ErrorLogger;
|
2012-01-09 20:33:11 +01:00
|
|
|
class Settings;
|
2017-05-27 04:33:47 +02:00
|
|
|
class Token;
|
|
|
|
class TokenList;
|
2012-01-01 21:55:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
/// @addtogroup Core
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
/** @brief Simplify templates from the preprocessed and partially simplified code. */
|
2012-06-10 14:19:09 +02:00
|
|
|
class CPPCHECKLIB TemplateSimplifier {
|
2012-01-01 21:55:05 +01:00
|
|
|
TemplateSimplifier();
|
2012-02-24 20:45:56 +01:00
|
|
|
~TemplateSimplifier();
|
2012-04-23 20:45:36 +02:00
|
|
|
public:
|
2012-01-01 21:55:05 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Used after simplifyTemplates to perform a little cleanup.
|
|
|
|
* Sometimes the simplifyTemplates isn't fully successful and then
|
|
|
|
* there are function calls etc with "wrong" syntax.
|
|
|
|
*/
|
|
|
|
static void cleanupAfterSimplify(Token *tokens);
|
2012-01-02 21:37:32 +01:00
|
|
|
|
|
|
|
/**
|
2015-05-28 21:38:20 +02:00
|
|
|
* \param[in] tokens token list
|
|
|
|
* @return false if there are no syntax errors or true
|
2012-01-02 21:37:32 +01:00
|
|
|
*/
|
2015-08-19 19:11:53 +02:00
|
|
|
static void checkComplicatedSyntaxErrorsInTemplates(const Token *tokens);
|
2012-01-02 21:43:38 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* is the token pointing at a template parameters block
|
|
|
|
* < int , 3 > => yes
|
|
|
|
* \param tok start token that must point at "<"
|
|
|
|
* \return number of parameters (invalid parameters => 0)
|
|
|
|
*/
|
|
|
|
static unsigned int templateParameters(const Token *tok);
|
2012-01-02 21:46:43 +01:00
|
|
|
|
2012-01-02 21:53:13 +01:00
|
|
|
/**
|
|
|
|
* Expand specialized templates : "template<>.."
|
|
|
|
* @return names of expanded templates
|
|
|
|
*/
|
2012-09-12 20:46:56 +02:00
|
|
|
static std::set<std::string> expandSpecialized(Token *tokens);
|
2012-01-02 22:05:27 +01:00
|
|
|
|
2017-12-26 10:55:18 +01:00
|
|
|
/**
|
|
|
|
* Token and its full scopename
|
|
|
|
*/
|
|
|
|
struct TokenAndName {
|
2017-12-30 09:00:19 +01:00
|
|
|
TokenAndName(Token *tok, const std::string &s, const std::string &n) : token(tok), scope(s), name(n) {}
|
2017-12-26 10:55:18 +01:00
|
|
|
Token *token;
|
2017-12-30 09:00:19 +01:00
|
|
|
std::string scope;
|
2017-12-26 10:55:18 +01:00
|
|
|
std::string name;
|
|
|
|
};
|
|
|
|
|
2012-01-02 22:05:27 +01:00
|
|
|
/**
|
|
|
|
* Get template declarations
|
|
|
|
* @return list of template declarations
|
|
|
|
*/
|
2017-12-26 10:55:18 +01:00
|
|
|
static std::list<TokenAndName> getTemplateDeclarations(Token *tokens, bool &codeWithTemplates);
|
2012-01-02 22:05:27 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get template instantiations
|
2017-12-30 09:00:19 +01:00
|
|
|
* @param tokens start of token list
|
|
|
|
* @param declarations template declarations, so names can be matched
|
2012-01-02 22:05:27 +01:00
|
|
|
* @return list of template instantiations
|
|
|
|
*/
|
2017-12-30 09:00:19 +01:00
|
|
|
static std::list<TokenAndName> getTemplateInstantiations(Token *tokens, const std::list<TokenAndName> &declarations);
|
2012-01-03 22:35:06 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* simplify template instantiations (use default argument values)
|
|
|
|
* @param templates list of template declarations
|
|
|
|
* @param templateInstantiations list of template instantiations
|
|
|
|
*/
|
2017-12-26 10:55:18 +01:00
|
|
|
static void useDefaultArgumentValues(const std::list<TokenAndName> &templates,
|
|
|
|
std::list<TokenAndName> *templateInstantiations);
|
2012-01-03 22:35:06 +01:00
|
|
|
|
2017-12-29 22:47:07 +01:00
|
|
|
/**
|
|
|
|
* simplify template aliases
|
|
|
|
* @param templateInstantiations pointer to list of template instantiations
|
|
|
|
*/
|
|
|
|
static void simplifyTemplateAliases(std::list<TokenAndName> *templateInstantiations);
|
|
|
|
|
2012-01-03 22:35:06 +01:00
|
|
|
/**
|
|
|
|
* Match template declaration/instantiation
|
|
|
|
* @param instance template instantiation
|
|
|
|
* @param numberOfArguments number of template arguments
|
|
|
|
* @param patternAfter pattern that must match the tokens after the ">"
|
|
|
|
* @return match => true
|
|
|
|
*/
|
2017-12-26 10:55:18 +01:00
|
|
|
static bool instantiateMatch(const Token *instance, const std::size_t numberOfArguments, const char patternAfter[]);
|
2012-01-03 22:35:06 +01:00
|
|
|
|
2012-01-03 22:49:50 +01:00
|
|
|
/**
|
|
|
|
* Match template declaration/instantiation
|
|
|
|
* @param tok The ">" token e.g. before "class"
|
|
|
|
* @return -1 to bail out or positive integer to identity the position
|
|
|
|
* of the template name.
|
|
|
|
*/
|
2012-09-12 20:46:56 +02:00
|
|
|
static int getTemplateNamePosition(const Token *tok);
|
2012-01-05 21:45:19 +01:00
|
|
|
|
2017-12-26 22:34:39 +01:00
|
|
|
/**
|
|
|
|
* Expand a template. Create "expanded" class/function at end of tokenlist.
|
|
|
|
* @param tokenlist The tokenlist that is changed
|
|
|
|
* @param templateDeclarationToken The template declaration token for the template that will be "expanded"
|
|
|
|
* @param fullName Full name of template
|
|
|
|
* @param typeParametersInDeclaration The type parameters of the template
|
|
|
|
* @param newName New name of class/function.
|
|
|
|
* @param typesUsedInTemplateInstantiation Type parameters in instantiation
|
|
|
|
* @param templateInstantiations List of template instantiations.
|
|
|
|
*/
|
2012-09-12 20:46:56 +02:00
|
|
|
static void expandTemplate(
|
2012-05-06 10:38:55 +02:00
|
|
|
TokenList& tokenlist,
|
2017-12-26 10:55:18 +01:00
|
|
|
const Token *templateDeclarationToken,
|
|
|
|
const std::string &fullName,
|
2016-10-31 17:24:15 +01:00
|
|
|
const std::vector<const Token *> &typeParametersInDeclaration,
|
2012-01-05 21:45:19 +01:00
|
|
|
const std::string &newName,
|
2016-10-31 17:24:15 +01:00
|
|
|
const std::vector<const Token *> &typesUsedInTemplateInstantiation,
|
2017-12-26 10:55:18 +01:00
|
|
|
std::list<TokenAndName> &templateInstantiations);
|
2012-01-09 20:33:11 +01:00
|
|
|
|
2014-11-01 22:07:24 +01:00
|
|
|
/**
|
|
|
|
* @brief TemplateParametersInDeclaration
|
|
|
|
* @param tok template < typename T, typename S >
|
|
|
|
* ^ tok
|
|
|
|
* @param typeParametersInDeclaration template < typename T, typename S >
|
|
|
|
* ^ [0] ^ [1]
|
|
|
|
* @return template < typename T, typename S >
|
|
|
|
* ^ return
|
|
|
|
*/
|
2017-12-28 22:10:10 +01:00
|
|
|
static const Token * getTemplateParametersInDeclaration(
|
2014-11-01 22:07:24 +01:00
|
|
|
const Token * tok,
|
|
|
|
std::vector<const Token *> & typeParametersInDeclaration);
|
|
|
|
|
2012-01-09 20:33:11 +01:00
|
|
|
/**
|
2013-02-10 07:43:09 +01:00
|
|
|
* Simplify templates : expand all instantiations for a template
|
2012-01-09 20:33:11 +01:00
|
|
|
* @todo It seems that inner templates should be instantiated recursively
|
2012-07-08 19:32:33 +02:00
|
|
|
* @param tokenlist token list
|
|
|
|
* @param errorlogger error logger
|
2018-06-16 16:10:28 +02:00
|
|
|
* @param mSettings settings
|
2017-12-26 10:55:18 +01:00
|
|
|
* @param templateDeclaration template declaration
|
2017-12-30 22:14:48 +01:00
|
|
|
* @param specializations template specializations (list each template name token)
|
2016-02-12 12:05:32 +01:00
|
|
|
* @param maxtime time when the simplification will stop
|
2012-01-09 20:33:11 +01:00
|
|
|
* @param templateInstantiations a list of template usages (not necessarily just for this template)
|
|
|
|
* @param expandedtemplates all templates that has been expanded so far. The full names are stored.
|
2012-07-29 16:01:05 +02:00
|
|
|
* @return true if the template was instantiated
|
2012-01-09 20:33:11 +01:00
|
|
|
*/
|
2013-02-10 07:43:09 +01:00
|
|
|
static bool simplifyTemplateInstantiations(
|
2012-05-06 10:38:55 +02:00
|
|
|
TokenList& tokenlist,
|
2014-05-20 21:55:08 +02:00
|
|
|
ErrorLogger* errorlogger,
|
2018-06-16 16:10:28 +02:00
|
|
|
const Settings *mSettings,
|
2017-12-26 10:55:18 +01:00
|
|
|
const TokenAndName &templateDeclaration,
|
2017-12-30 22:14:48 +01:00
|
|
|
const std::list<const Token *> &specializations,
|
2016-02-12 12:05:32 +01:00
|
|
|
const std::time_t maxtime,
|
2017-12-26 10:55:18 +01:00
|
|
|
std::list<TokenAndName> &templateInstantiations,
|
2012-01-09 20:33:11 +01:00
|
|
|
std::set<std::string> &expandedtemplates);
|
|
|
|
|
2017-06-08 00:16:43 +02:00
|
|
|
/**
|
|
|
|
* Replace all matching template usages 'Foo < int >' => 'Foo<int>'
|
|
|
|
* @param instantiationToken Template instantiation token
|
2017-12-26 10:55:18 +01:00
|
|
|
* @param templateName full template name with scope info
|
2017-12-26 22:34:39 +01:00
|
|
|
* @param typeStringsUsedInTemplateInstantiation template parameters. list of token strings.
|
2017-06-08 00:16:43 +02:00
|
|
|
* @param newName The new type name
|
|
|
|
* @param typesUsedInTemplateInstantiation template instantiation parameters
|
|
|
|
* @param templateInstantiations All seen instantiations
|
|
|
|
*/
|
|
|
|
static void replaceTemplateUsage(Token *const instantiationToken,
|
2017-12-26 10:55:18 +01:00
|
|
|
const std::string &templateName,
|
2017-12-26 22:34:39 +01:00
|
|
|
const std::list<std::string> &typeStringsUsedInTemplateInstantiation,
|
2017-06-08 00:16:43 +02:00
|
|
|
const std::string &newName,
|
|
|
|
const std::vector<const Token *> &typesUsedInTemplateInstantiation,
|
2017-12-26 10:55:18 +01:00
|
|
|
std::list<TokenAndName> &templateInstantiations);
|
2017-06-08 00:16:43 +02:00
|
|
|
|
2012-01-09 20:33:11 +01:00
|
|
|
/**
|
|
|
|
* Simplify templates
|
2012-07-08 19:32:33 +02:00
|
|
|
* @param tokenlist token list
|
|
|
|
* @param errorlogger error logger
|
2018-06-16 16:10:28 +02:00
|
|
|
* @param mSettings settings
|
2016-02-12 12:05:32 +01:00
|
|
|
* @param maxtime time when the simplification should be stopped
|
2012-07-08 19:32:33 +02:00
|
|
|
* @param _codeWithTemplates output parameter that is set if code contains templates
|
2012-01-09 20:33:11 +01:00
|
|
|
*/
|
|
|
|
static void simplifyTemplates(
|
2012-05-06 10:38:55 +02:00
|
|
|
TokenList& tokenlist,
|
2014-05-20 21:55:08 +02:00
|
|
|
ErrorLogger* errorlogger,
|
2018-06-16 16:10:28 +02:00
|
|
|
const Settings *mSettings,
|
2016-02-12 12:05:32 +01:00
|
|
|
const std::time_t maxtime,
|
2012-01-09 20:33:11 +01:00
|
|
|
bool &_codeWithTemplates);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Simplify constant calculations such as "1+2" => "3"
|
2012-08-20 18:10:32 +02:00
|
|
|
* @param tok start token
|
|
|
|
* @return true if modifications to token-list are done.
|
|
|
|
* false if no modifications are done.
|
|
|
|
*/
|
|
|
|
static bool simplifyNumericCalculations(Token *tok);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Simplify constant calculations such as "1+2" => "3".
|
2013-02-10 07:43:09 +01:00
|
|
|
* This also performs simple cleanup of parentheses etc.
|
2018-05-11 21:26:28 +02:00
|
|
|
* @param _tokens start token
|
2012-01-09 20:33:11 +01:00
|
|
|
* @return true if modifications to token-list are done.
|
|
|
|
* false if no modifications are done.
|
|
|
|
*/
|
2018-05-11 21:26:28 +02:00
|
|
|
static bool simplifyCalculations(Token *_tokens);
|
2012-07-29 16:01:05 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
/**
|
|
|
|
* Remove a specific "template < ..." template class/function
|
|
|
|
*/
|
|
|
|
static bool removeTemplate(Token *tok);
|
|
|
|
|
2015-06-23 20:53:57 +02:00
|
|
|
/** Syntax error */
|
|
|
|
static void syntaxError(const Token *tok);
|
|
|
|
|
2012-01-01 21:55:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
//---------------------------------------------------------------------------
|
2013-09-04 20:59:49 +02:00
|
|
|
#endif // templatesimplifierH
|