template simplifier: Add flag variable to cache information about dec… (#1569)
* template simplifier: Add flag variable to cache information about declarations. Also fix some cppcheck warnings. * Make variable const.
This commit is contained in:
parent
286cb2fc2c
commit
07da4b4d37
|
@ -54,14 +54,26 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplateSimplifier::TokenAndName::TokenAndName(Token *tok, const std::string &s, const std::string &n, const Token *nt, const Token *pe) :
|
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)
|
token(tok), scope(s), name(n), nameToken(nt), paramEnd(pe), flags(0)
|
||||||
{
|
{
|
||||||
|
// only set flags for declaration
|
||||||
|
if (token && nameToken && paramEnd) {
|
||||||
|
isClass(Token::Match(paramEnd->next(), "class|struct|union %name% <|{|:"));
|
||||||
|
isFunction(nameToken->strAt(1) == "(" ||
|
||||||
|
(nameToken->strAt(1) == "<" && nameToken->next()->findClosingBracket()->strAt(1) == "("));
|
||||||
|
isVariable(Token::Match(nameToken->next(), "=|;") ||
|
||||||
|
(nameToken->strAt(1) == "<" && Token::Match(nameToken->next()->findClosingBracket()->next(), "=|;")));
|
||||||
|
isAlias(paramEnd->strAt(1) == "using");
|
||||||
|
isSpecialized(Token::Match(token, "template < >"));
|
||||||
|
}
|
||||||
|
|
||||||
if (token)
|
if (token)
|
||||||
token->templateSimplifierPointer(this);
|
token->templateSimplifierPointer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplateSimplifier::TokenAndName::TokenAndName(const TokenAndName& otherTok) :
|
TemplateSimplifier::TokenAndName::TokenAndName(const TokenAndName& otherTok) :
|
||||||
token(otherTok.token), scope(otherTok.scope), name(otherTok.name), nameToken(otherTok.nameToken), paramEnd(otherTok.paramEnd)
|
token(otherTok.token), scope(otherTok.scope), name(otherTok.name),
|
||||||
|
nameToken(otherTok.nameToken), paramEnd(otherTok.paramEnd), flags(otherTok.flags)
|
||||||
{
|
{
|
||||||
if (token)
|
if (token)
|
||||||
token->templateSimplifierPointer(this);
|
token->templateSimplifierPointer(this);
|
||||||
|
@ -983,7 +995,7 @@ void TemplateSimplifier::addNamespace(const TokenAndName &templateDeclaration, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TemplateSimplifier::alreadyHasNamespace(const TokenAndName &templateDeclaration, const Token *tok) const
|
bool TemplateSimplifier::alreadyHasNamespace(const TokenAndName &templateDeclaration, const Token *tok)
|
||||||
{
|
{
|
||||||
std::string scope = templateDeclaration.scope;
|
std::string scope = templateDeclaration.scope;
|
||||||
|
|
||||||
|
@ -1012,17 +1024,16 @@ void TemplateSimplifier::expandTemplate(
|
||||||
const Token *endOfTemplateDefinition = nullptr;
|
const Token *endOfTemplateDefinition = nullptr;
|
||||||
const Token * const templateDeclarationNameToken = templateDeclaration.nameToken;
|
const Token * const templateDeclarationNameToken = templateDeclaration.nameToken;
|
||||||
const Token * const templateDeclarationToken = templateDeclaration.paramEnd;
|
const Token * const templateDeclarationToken = templateDeclaration.paramEnd;
|
||||||
const bool isClass = Token::Match(templateDeclaration.paramEnd->next(), "class|struct|union %name% <|{|:");
|
const bool isClass = templateDeclaration.isClass();
|
||||||
const bool isFunction = templateDeclarationNameToken->strAt(1) == "(" ||
|
const bool isFunction = templateDeclaration.isFunction();
|
||||||
(templateDeclarationNameToken->strAt(1) == "<" && templateDeclarationNameToken->next()->findClosingBracket()->strAt(1) == "(");
|
const bool isSpecialization = templateDeclaration.isSpecialized();
|
||||||
const bool isSpecialization = Token::Match(templateDeclaration.token, "template < >");
|
|
||||||
|
|
||||||
// add forward declarations
|
// add forward declarations
|
||||||
if (copy && isClass) {
|
if (copy && isClass) {
|
||||||
templateDeclaration.token->insertToken(templateDeclarationToken->strAt(1), "", true);
|
templateDeclaration.token->insertToken(templateDeclarationToken->strAt(1), "", true);
|
||||||
templateDeclaration.token->insertToken(newName, "", true);
|
templateDeclaration.token->insertToken(newName, "", true);
|
||||||
templateDeclaration.token->insertToken(";", "", true);
|
templateDeclaration.token->insertToken(";", "", true);
|
||||||
} else if (isFunction && (copy || (!copy && isSpecialization))) {
|
} else if (isFunction && (copy || isSpecialization)) {
|
||||||
Token * dst = templateDeclaration.token;
|
Token * dst = templateDeclaration.token;
|
||||||
bool isStatic = false;
|
bool isStatic = false;
|
||||||
std::string scope;
|
std::string scope;
|
||||||
|
@ -1812,16 +1823,8 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
|
||||||
std::vector<const Token *> typeParametersInDeclaration;
|
std::vector<const Token *> typeParametersInDeclaration;
|
||||||
getTemplateParametersInDeclaration(templateDeclaration.token->tokAt(2), typeParametersInDeclaration);
|
getTemplateParametersInDeclaration(templateDeclaration.token->tokAt(2), typeParametersInDeclaration);
|
||||||
const bool printDebug = mSettings->debugwarnings;
|
const bool printDebug = mSettings->debugwarnings;
|
||||||
const bool specialized = Token::simpleMatch(templateDeclaration.token, "template < >");
|
const bool specialized = templateDeclaration.isSpecialized();
|
||||||
bool isfunc = false;
|
const bool isfunc = templateDeclaration.isFunction();
|
||||||
|
|
||||||
if (templateDeclaration.nameToken->strAt(1) == "(")
|
|
||||||
isfunc = true;
|
|
||||||
else if (templateDeclaration.nameToken->strAt(1) == "<") {
|
|
||||||
const Token *tok1 = templateDeclaration.nameToken->tokAt(1)->findClosingBracket();
|
|
||||||
if (tok1 && tok1->strAt(1) == "(")
|
|
||||||
isfunc = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// locate template usage..
|
// locate template usage..
|
||||||
std::string::size_type numberOfTemplateInstantiations = mTemplateInstantiations.size();
|
std::string::size_type numberOfTemplateInstantiations = mTemplateInstantiations.size();
|
||||||
|
@ -2098,12 +2101,12 @@ void TemplateSimplifier::getUserDefinedSpecializations()
|
||||||
{
|
{
|
||||||
// try to locate a matching declaration for each user defined specialization
|
// try to locate a matching declaration for each user defined specialization
|
||||||
for (auto & spec : mTemplateDeclarations) {
|
for (auto & spec : mTemplateDeclarations) {
|
||||||
if (Token::Match(spec.token, "template < >")) {
|
if (spec.isSpecialized()) {
|
||||||
std::string specName = getPathName(spec);
|
std::string specName = getPathName(spec);
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto & decl : mTemplateDeclarations) {
|
for (auto & decl : mTemplateDeclarations) {
|
||||||
if (Token::Match(decl.token, "template < >"))
|
if (decl.isSpecialized())
|
||||||
continue;
|
continue;
|
||||||
std::string declName = getPathName(decl);
|
std::string declName = getPathName(decl);
|
||||||
|
|
||||||
|
@ -2111,6 +2114,7 @@ void TemplateSimplifier::getUserDefinedSpecializations()
|
||||||
if (specName == declName) {
|
if (specName == declName) {
|
||||||
// @todo make sure function parameters also match
|
// @todo make sure function parameters also match
|
||||||
mTemplateUserSpecializationMap[spec.token] = decl.token;
|
mTemplateUserSpecializationMap[spec.token] = decl.token;
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2258,7 +2262,7 @@ void TemplateSimplifier::simplifyTemplates(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (decl != mTemplateDeclarations.end()) {
|
if (decl != mTemplateDeclarations.end()) {
|
||||||
if (Token::simpleMatch(it->token, "template < >")) {
|
if (it->isSpecialized()) {
|
||||||
// delete the "template < >"
|
// delete the "template < >"
|
||||||
Token * tok = it->token;
|
Token * tok = it->token;
|
||||||
tok->deleteNext(2);
|
tok->deleteNext(2);
|
||||||
|
@ -2296,7 +2300,7 @@ void TemplateSimplifier::simplifyTemplates(
|
||||||
end = end->next();
|
end = end->next();
|
||||||
if (start->previous())
|
if (start->previous())
|
||||||
start = start->previous();
|
start = start->previous();
|
||||||
if (end->next())
|
if (end && end->next())
|
||||||
end = end->next();
|
end = end->next();
|
||||||
eraseTokens(start, end);
|
eraseTokens(start, end);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ class TokenList;
|
||||||
/** @brief Simplify templates from the preprocessed and partially simplified code. */
|
/** @brief Simplify templates from the preprocessed and partially simplified code. */
|
||||||
class CPPCHECKLIB TemplateSimplifier {
|
class CPPCHECKLIB TemplateSimplifier {
|
||||||
public:
|
public:
|
||||||
TemplateSimplifier(Tokenizer *tokenizer);
|
explicit TemplateSimplifier(Tokenizer *tokenizer);
|
||||||
~TemplateSimplifier();
|
~TemplateSimplifier();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,13 +74,76 @@ public:
|
||||||
~TokenAndName();
|
~TokenAndName();
|
||||||
|
|
||||||
bool operator == (const TokenAndName & rhs) const {
|
bool operator == (const TokenAndName & rhs) const {
|
||||||
return token == rhs.token && scope == rhs.scope && name == rhs.name && nameToken == rhs.nameToken && paramEnd == rhs.paramEnd;;
|
return token == rhs.token && scope == rhs.scope && name == rhs.name &&
|
||||||
|
nameToken == rhs.nameToken && paramEnd == rhs.paramEnd && flags == rhs.flags;
|
||||||
}
|
}
|
||||||
Token *token;
|
Token *token;
|
||||||
std::string scope;
|
std::string scope;
|
||||||
std::string name;
|
std::string name;
|
||||||
const Token *nameToken;
|
const Token *nameToken;
|
||||||
const Token *paramEnd;
|
const Token *paramEnd;
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
fIsClass = (1 << 0), // class template
|
||||||
|
fIsFunction = (1 << 1), // function template
|
||||||
|
fIsVariable = (1 << 2), // variable template
|
||||||
|
fIsAlias = (1 << 3), // alias template
|
||||||
|
fIsSpecialized = (1 << 4), // user specialized template
|
||||||
|
};
|
||||||
|
|
||||||
|
bool isClass() const {
|
||||||
|
return getFlag(fIsClass);
|
||||||
|
}
|
||||||
|
void isClass(bool state) {
|
||||||
|
setFlag(fIsClass, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFunction() const {
|
||||||
|
return getFlag(fIsFunction);
|
||||||
|
}
|
||||||
|
void isFunction(bool state) {
|
||||||
|
setFlag(fIsFunction, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isVariable() const {
|
||||||
|
return getFlag(fIsVariable);
|
||||||
|
}
|
||||||
|
void isVariable(bool state) {
|
||||||
|
setFlag(fIsVariable, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAlias() const {
|
||||||
|
return getFlag(fIsAlias);
|
||||||
|
}
|
||||||
|
void isAlias(bool state) {
|
||||||
|
setFlag(fIsAlias, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSpecialized() const {
|
||||||
|
return getFlag(fIsSpecialized);
|
||||||
|
}
|
||||||
|
void isSpecialized(bool state) {
|
||||||
|
setFlag(fIsSpecialized, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get specified flag state.
|
||||||
|
* @param flag flag to get state of
|
||||||
|
* @return true if flag set or false in flag not set
|
||||||
|
*/
|
||||||
|
bool getFlag(unsigned int flag) const {
|
||||||
|
return ((flags & flag) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set specified flag state.
|
||||||
|
* @param flag flag to set state
|
||||||
|
* @param state new state of flag
|
||||||
|
*/
|
||||||
|
void setFlag(unsigned int flag, bool state) {
|
||||||
|
flags = state ? flags | flag : flags & ~flag;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,7 +162,7 @@ public:
|
||||||
* @return -1 to bail out or positive integer to identity the position
|
* @return -1 to bail out or positive integer to identity the position
|
||||||
* of the template name.
|
* of the template name.
|
||||||
*/
|
*/
|
||||||
int getTemplateNamePosition(const Token *tok, bool forward = false);
|
static int getTemplateNamePosition(const Token *tok, bool forward = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get template name position
|
* Get template name position
|
||||||
|
@ -107,7 +170,7 @@ public:
|
||||||
* @param namepos return offset to name
|
* @param namepos return offset to name
|
||||||
* @return true if name found, false if not
|
* @return true if name found, false if not
|
||||||
* */
|
* */
|
||||||
bool getTemplateNamePositionTemplateFunction(const Token *tok, int &namepos);
|
static bool getTemplateNamePositionTemplateFunction(const Token *tok, int &namepos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplify templates
|
* Simplify templates
|
||||||
|
@ -132,7 +195,7 @@ public:
|
||||||
* @return true if modifications to token-list are done.
|
* @return true if modifications to token-list are done.
|
||||||
* false if no modifications are done.
|
* false if no modifications are done.
|
||||||
*/
|
*/
|
||||||
bool simplifyCalculations(Token* tok = nullptr);
|
bool simplifyCalculations(Token* frontToken = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -196,7 +259,7 @@ private:
|
||||||
* @param tok place to start looking for namespace
|
* @param tok place to start looking for namespace
|
||||||
* @return true if namespace already present
|
* @return true if namespace already present
|
||||||
*/
|
*/
|
||||||
bool alreadyHasNamespace(const TokenAndName &templateDeclaration, const Token *tok) const;
|
static bool alreadyHasNamespace(const TokenAndName &templateDeclaration, const Token *tok);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand a template. Create "expanded" class/function at end of tokenlist.
|
* Expand a template. Create "expanded" class/function at end of tokenlist.
|
||||||
|
@ -241,7 +304,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* Remove a specific "template < ..." template class/function
|
* Remove a specific "template < ..." template class/function
|
||||||
*/
|
*/
|
||||||
bool removeTemplate(Token *tok);
|
static bool removeTemplate(Token *tok);
|
||||||
|
|
||||||
/** Syntax error */
|
/** Syntax error */
|
||||||
static void syntaxError(const Token *tok);
|
static void syntaxError(const Token *tok);
|
||||||
|
@ -256,7 +319,7 @@ private:
|
||||||
* @param begin Tokens after this will be erased.
|
* @param begin Tokens after this will be erased.
|
||||||
* @param end Tokens before this will be erased.
|
* @param end Tokens before this will be erased.
|
||||||
*/
|
*/
|
||||||
void eraseTokens(Token *begin, const Token *end);
|
static void eraseTokens(Token *begin, const Token *end);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete specified token without invalidating pointer to following token.
|
* Delete specified token without invalidating pointer to following token.
|
||||||
|
|
Loading…
Reference in New Issue