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) :
|
||||
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)
|
||||
token->templateSimplifierPointer(this);
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
|
@ -1012,17 +1024,16 @@ void TemplateSimplifier::expandTemplate(
|
|||
const Token *endOfTemplateDefinition = nullptr;
|
||||
const Token * const templateDeclarationNameToken = templateDeclaration.nameToken;
|
||||
const Token * const templateDeclarationToken = templateDeclaration.paramEnd;
|
||||
const bool isClass = Token::Match(templateDeclaration.paramEnd->next(), "class|struct|union %name% <|{|:");
|
||||
const bool isFunction = templateDeclarationNameToken->strAt(1) == "(" ||
|
||||
(templateDeclarationNameToken->strAt(1) == "<" && templateDeclarationNameToken->next()->findClosingBracket()->strAt(1) == "(");
|
||||
const bool isSpecialization = Token::Match(templateDeclaration.token, "template < >");
|
||||
const bool isClass = templateDeclaration.isClass();
|
||||
const bool isFunction = templateDeclaration.isFunction();
|
||||
const bool isSpecialization = templateDeclaration.isSpecialized();
|
||||
|
||||
// add forward declarations
|
||||
if (copy && isClass) {
|
||||
templateDeclaration.token->insertToken(templateDeclarationToken->strAt(1), "", true);
|
||||
templateDeclaration.token->insertToken(newName, "", true);
|
||||
templateDeclaration.token->insertToken(";", "", true);
|
||||
} else if (isFunction && (copy || (!copy && isSpecialization))) {
|
||||
} else if (isFunction && (copy || isSpecialization)) {
|
||||
Token * dst = templateDeclaration.token;
|
||||
bool isStatic = false;
|
||||
std::string scope;
|
||||
|
@ -1812,16 +1823,8 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
|
|||
std::vector<const Token *> typeParametersInDeclaration;
|
||||
getTemplateParametersInDeclaration(templateDeclaration.token->tokAt(2), typeParametersInDeclaration);
|
||||
const bool printDebug = mSettings->debugwarnings;
|
||||
const bool specialized = Token::simpleMatch(templateDeclaration.token, "template < >");
|
||||
bool isfunc = false;
|
||||
|
||||
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;
|
||||
}
|
||||
const bool specialized = templateDeclaration.isSpecialized();
|
||||
const bool isfunc = templateDeclaration.isFunction();
|
||||
|
||||
// locate template usage..
|
||||
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
|
||||
for (auto & spec : mTemplateDeclarations) {
|
||||
if (Token::Match(spec.token, "template < >")) {
|
||||
if (spec.isSpecialized()) {
|
||||
std::string specName = getPathName(spec);
|
||||
|
||||
bool found = false;
|
||||
for (auto & decl : mTemplateDeclarations) {
|
||||
if (Token::Match(decl.token, "template < >"))
|
||||
if (decl.isSpecialized())
|
||||
continue;
|
||||
std::string declName = getPathName(decl);
|
||||
|
||||
|
@ -2111,6 +2114,7 @@ void TemplateSimplifier::getUserDefinedSpecializations()
|
|||
if (specName == declName) {
|
||||
// @todo make sure function parameters also match
|
||||
mTemplateUserSpecializationMap[spec.token] = decl.token;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2258,7 +2262,7 @@ void TemplateSimplifier::simplifyTemplates(
|
|||
break;
|
||||
}
|
||||
if (decl != mTemplateDeclarations.end()) {
|
||||
if (Token::simpleMatch(it->token, "template < >")) {
|
||||
if (it->isSpecialized()) {
|
||||
// delete the "template < >"
|
||||
Token * tok = it->token;
|
||||
tok->deleteNext(2);
|
||||
|
@ -2296,7 +2300,7 @@ void TemplateSimplifier::simplifyTemplates(
|
|||
end = end->next();
|
||||
if (start->previous())
|
||||
start = start->previous();
|
||||
if (end->next())
|
||||
if (end && end->next())
|
||||
end = end->next();
|
||||
eraseTokens(start, end);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ class TokenList;
|
|||
/** @brief Simplify templates from the preprocessed and partially simplified code. */
|
||||
class CPPCHECKLIB TemplateSimplifier {
|
||||
public:
|
||||
TemplateSimplifier(Tokenizer *tokenizer);
|
||||
explicit TemplateSimplifier(Tokenizer *tokenizer);
|
||||
~TemplateSimplifier();
|
||||
|
||||
/**
|
||||
|
@ -74,13 +74,76 @@ public:
|
|||
~TokenAndName();
|
||||
|
||||
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;
|
||||
std::string scope;
|
||||
std::string name;
|
||||
const Token *nameToken;
|
||||
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
|
||||
* 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
|
||||
|
@ -107,7 +170,7 @@ public:
|
|||
* @param namepos return offset to name
|
||||
* @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
|
||||
|
@ -132,7 +195,7 @@ public:
|
|||
* @return true if modifications to token-list are done.
|
||||
* false if no modifications are done.
|
||||
*/
|
||||
bool simplifyCalculations(Token* tok = nullptr);
|
||||
bool simplifyCalculations(Token* frontToken = nullptr);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -196,7 +259,7 @@ private:
|
|||
* @param tok place to start looking for namespace
|
||||
* @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.
|
||||
|
@ -241,7 +304,7 @@ private:
|
|||
/**
|
||||
* Remove a specific "template < ..." template class/function
|
||||
*/
|
||||
bool removeTemplate(Token *tok);
|
||||
static bool removeTemplate(Token *tok);
|
||||
|
||||
/** Syntax error */
|
||||
static void syntaxError(const Token *tok);
|
||||
|
@ -256,7 +319,7 @@ private:
|
|||
* @param begin Tokens after 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.
|
||||
|
|
Loading…
Reference in New Issue