forked from danmar/cppcheck
-
Notifications
You must be signed in to change notification settings - Fork 0
/
templatesimplifier.h
180 lines (155 loc) · 6.11 KB
/
templatesimplifier.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2013 Daniel Marjamäki and Cppcheck team.
*
* 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
//---------------------------------------------------------------------------
#include <set>
#include <list>
#include <string>
#include <vector>
#include "config.h"
class Token;
class TokenList;
class ErrorLogger;
class Settings;
/// @addtogroup Core
/// @{
/** @brief Simplify templates from the preprocessed and partially simplified code. */
class CPPCHECKLIB TemplateSimplifier {
TemplateSimplifier();
~TemplateSimplifier();
public:
/**
* 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);
/**
* @return 0 if there are no syntax errors or return token which identifies
* the location of syntax error.
*/
static const Token* hasComplicatedSyntaxErrorsInTemplates(Token *tokens);
/**
* 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);
/**
* Expand specialized templates : "template<>.."
* @return names of expanded templates
*/
static std::set<std::string> expandSpecialized(Token *tokens);
/**
* Get template declarations
* @return list of template declarations
*/
static std::list<Token *> getTemplateDeclarations(Token *tokens, bool &codeWithTemplates);
/**
* Get template instantiations
* @return list of template instantiations
*/
static std::list<Token *> getTemplateInstantiations(Token *tokens);
/**
* simplify template instantiations (use default argument values)
* @param templates list of template declarations
* @param templateInstantiations list of template instantiations
*/
static void useDefaultArgumentValues(const std::list<Token *> &templates,
std::list<Token *> *templateInstantiations);
/**
* Match template declaration/instantiation
* @param instance template instantiation
* @param name name of template
* @param numberOfArguments number of template arguments
* @param patternAfter pattern that must match the tokens after the ">"
* @return match => true
*/
static bool instantiateMatch(const Token *instance, const std::string &name, std::size_t numberOfArguments, const char patternAfter[]);
/**
* 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.
*/
static int getTemplateNamePosition(const Token *tok);
static void expandTemplate(
TokenList& tokenlist,
const Token *tok,
const std::string &name,
std::vector<const Token *> &typeParametersInDeclaration,
const std::string &newName,
std::vector<const Token *> &typesUsedInTemplateInstantiation,
std::list<Token *> &templateInstantiations);
/**
* Simplify templates : expand all instantiations for a template
* @todo It seems that inner templates should be instantiated recursively
* @param tokenlist token list
* @param errorlogger error logger
* @param _settings settings
* @param tok token where the template declaration begins
* @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.
* @return true if the template was instantiated
*/
static bool simplifyTemplateInstantiations(
TokenList& tokenlist,
ErrorLogger& errorlogger,
const Settings *_settings,
const Token *tok,
std::list<Token *> &templateInstantiations,
std::set<std::string> &expandedtemplates);
/**
* Simplify templates
* @param tokenlist token list
* @param errorlogger error logger
* @param _settings settings
* @param _codeWithTemplates output parameter that is set if code contains templates
*/
static void simplifyTemplates(
TokenList& tokenlist,
ErrorLogger& errorlogger,
const Settings *_settings,
bool &_codeWithTemplates);
/**
* Simplify constant calculations such as "1+2" => "3"
* @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".
* This also performs simple cleanup of parentheses etc.
* @param _tokens start token
* @return true if modifications to token-list are done.
* false if no modifications are done.
*/
static bool simplifyCalculations(Token *_tokens);
private:
/**
* Remove a specific "template < ..." template class/function
*/
static bool removeTemplate(Token *tok);
};
/// @}
//---------------------------------------------------------------------------
#endif // templatesimplifierH