"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/tokenize.cpp" between
cppcheck-1.86.tar.gz and cppcheck-1.87.tar.gz

About: Cppcheck is a static analysis tool for C/C++ code. It checks for memory leaks, mismatching allocation-deallocation, buffer overrun, and many more.

tokenize.cpp  (cppcheck-1.86):tokenize.cpp  (cppcheck-1.87)
/* /*
* Cppcheck - A tool for static C/C++ code analysis * Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2018 Cppcheck team. * Copyright (C) 2007-2019 Cppcheck team.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
skipping to change at line 115 skipping to change at line 115
tok = tok->next(); tok = tok->next();
if (tok && tok->str() == ")") if (tok && tok->str() == ")")
tok = tok->next(); tok = tok->next();
while (tok && tok->str() == "[") while (tok && tok->str() == "[")
tok = tok->link()->next(); tok = tok->link()->next();
if (Token::Match(tok, "throw|noexcept (")) if (Token::Match(tok, "throw|noexcept ("))
tok = tok->linkAt(1)->next(); tok = tok->linkAt(1)->next();
if (Token::Match(tok, "%name% (") && tok->isUpperCaseName()) if (Token::Match(tok, "%name% (") && tok->isUpperCaseName())
tok = tok->linkAt(1)->next(); tok = tok->linkAt(1)->next();
if (tok && tok->str() == ".") { // trailing return type if (tok && tok->str() == ".") { // trailing return type
for (tok = tok->next(); tok && !Token::Match(tok, "[;{]"); tok = tok ->next()) for (tok = tok->next(); tok && !Token::Match(tok, ";|{|override|fina l"); tok = tok->next())
if (tok->link() && Token::Match(tok, "<|[|(")) if (tok->link() && Token::Match(tok, "<|[|("))
tok = tok->link(); tok = tok->link();
} }
while (Token::Match(tok, "override|final !!(") ||
(Token::Match(tok, "%name% !!(") && tok->isUpperCaseName()))
tok = tok->next();
if (Token::Match(tok, "= 0|default|delete ;")) if (Token::Match(tok, "= 0|default|delete ;"))
tok = tok->tokAt(2); tok = tok->tokAt(2);
return (tok && endsWith.find(tok->str()) != std::string::npos) ? tok : n ullptr; return (tok && endsWith.find(tok->str()) != std::string::npos) ? tok : n ullptr;
} }
return nullptr; return nullptr;
} }
/** /**
* is tok the start brace { of a class, struct, union, or enum * is tok the start brace { of a class, struct, union, or enum
*/ */
static bool isClassStructUnionEnumStart(const Token * tok) static bool isClassStructUnionEnumStart(const Token * tok)
{ {
skipping to change at line 174 skipping to change at line 178
mUnnamedCount(0), mUnnamedCount(0),
mCodeWithTemplates(false), //is there any templates? mCodeWithTemplates(false), //is there any templates?
mTimerResults(nullptr) mTimerResults(nullptr)
#ifdef MAXTIME #ifdef MAXTIME
,mMaxTime(std::time(0) + MAXTIME) ,mMaxTime(std::time(0) + MAXTIME)
#endif #endif
{ {
// make sure settings are specified // make sure settings are specified
assert(mSettings); assert(mSettings);
mTemplateSimplifier = new TemplateSimplifier(list, settings, errorLogger); mTemplateSimplifier = new TemplateSimplifier(this);
} }
Tokenizer::~Tokenizer() Tokenizer::~Tokenizer()
{ {
delete mSymbolDatabase; delete mSymbolDatabase;
delete mTemplateSimplifier; delete mTemplateSimplifier;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// SizeOfType - gives the size of a type // SizeOfType - gives the size of a type
skipping to change at line 1520 skipping to change at line 1524
do { do {
if (!tok2->next()) if (!tok2->next())
syntaxError(tok2); // can't recover so quit syntaxError(tok2); // can't recover so quit
if (!inCast && !inSizeof && !inTemplate) if (!inCast && !inSizeof && !inTemplate)
tok2 = tok2->next(); tok2 = tok2->next();
if (tok2->str() == "const") if (tok2->str() == "const")
tok2 = tok2->next(); tok2 = tok2->next();
// reference to array? // reference or pointer to array?
if (tok2->str() == "&") { if (tok2->str() == "&" || tok2->str() == "*") {
tok2 = tok2->previous(); tok2 = tok2->previous();
tok2->insertToken("("); tok2->insertToken("(");
Token *tok3 = tok2->next(); Token *tok3 = tok2->next();
// handle missing variable name // handle missing variable name
if (tok2->strAt(3) == ")" || tok2->strAt(3) == " ,") if (tok2->strAt(3) == ")" || tok2->strAt(3) == " ,")
tok2 = tok2->tokAt(2); tok2 = tok2->tokAt(2);
else else
tok2 = tok2->tokAt(3); tok2 = tok2->tokAt(3);
if (!tok2) if (!tok2)
skipping to change at line 1731 skipping to change at line 1735
} }
} }
} }
bool Tokenizer::createTokens(std::istream &code, bool Tokenizer::createTokens(std::istream &code,
const std::string& FileName) const std::string& FileName)
{ {
// make sure settings specified // make sure settings specified
assert(mSettings); assert(mSettings);
return list.createTokens(code, Path::getRelativePath(Path::simplifyPath(File Name), mSettings->basePaths)); return list.createTokens(code, FileName);
} }
void Tokenizer::createTokens(const simplecpp::TokenList *tokenList) void Tokenizer::createTokens(const simplecpp::TokenList *tokenList)
{ {
// make sure settings specified // make sure settings specified
assert(mSettings); assert(mSettings);
list.createTokens(tokenList); list.createTokens(tokenList);
} }
bool Tokenizer::simplifyTokens1(const std::string &configuration) bool Tokenizer::simplifyTokens1(const std::string &configuration)
{ {
// Fill the map mTypeSize.. // Fill the map mTypeSize..
fillTypeSizes(); fillTypeSizes();
mConfiguration = configuration; mConfiguration = configuration;
if (!simplifyTokenList1(list.getFiles().front().c_str())) if (!simplifyTokenList1(list.getFiles().front().c_str()))
return false; return false;
list.createAst(); if (mTimerResults) {
list.validateAst(); Timer t("Tokenizer::simplifyTokens1::createAst", mSettings->showtime, mT
imerResults);
list.createAst();
list.validateAst();
} else {
list.createAst();
list.validateAst();
}
createSymbolDatabase(); if (mTimerResults) {
Timer t("Tokenizer::simplifyTokens1::createSymbolDatabase", mSettings->s
howtime, mTimerResults);
createSymbolDatabase();
} else {
createSymbolDatabase();
}
// Use symbol database to identify rvalue references. Split && to & &. This is safe, since it doesn't delete any tokens (which might be referenced by symbol database) // Use symbol database to identify rvalue references. Split && to & &. This is safe, since it doesn't delete any tokens (which might be referenced by symbol database)
for (const Variable* var : mSymbolDatabase->variableList()) { for (const Variable* var : mSymbolDatabase->variableList()) {
if (var && var->isRValueReference()) { if (var && var->isRValueReference()) {
Token* endTok = const_cast<Token*>(var->typeEndToken()); Token* endTok = const_cast<Token*>(var->typeEndToken());
endTok->str("&"); endTok->str("&");
endTok->astOperand1(nullptr); endTok->astOperand1(nullptr);
endTok->astOperand2(nullptr); endTok->astOperand2(nullptr);
endTok->insertToken("&"); endTok->insertToken("&");
endTok->next()->scope(endTok->scope()); endTok->next()->scope(endTok->scope());
} }
} }
mSymbolDatabase->setValueTypeInTokenList(); if (mTimerResults) {
ValueFlow::setValues(&list, mSymbolDatabase, mErrorLogger, mSettings); Timer t("Tokenizer::simplifyTokens1::setValueType", mSettings->showtime,
mTimerResults);
mSymbolDatabase->setValueTypeInTokenList();
} else {
mSymbolDatabase->setValueTypeInTokenList();
}
if (mTimerResults) {
Timer t("Tokenizer::simplifyTokens1::ValueFlow", mSettings->showtime, mT
imerResults);
ValueFlow::setValues(&list, mSymbolDatabase, mErrorLogger, mSettings);
} else {
ValueFlow::setValues(&list, mSymbolDatabase, mErrorLogger, mSettings);
}
printDebugOutput(1); printDebugOutput(1);
return true; return true;
} }
bool Tokenizer::tokenize(std::istream &code, bool Tokenizer::tokenize(std::istream &code,
const char FileName[], const char FileName[],
const std::string &configuration) const std::string &configuration)
{ {
skipping to change at line 1835 skipping to change at line 1861
// Combine tokens.. // Combine tokens..
for (Token *tok = list.front(); tok && tok->next(); tok = tok->next()) { for (Token *tok = list.front(); tok && tok->next(); tok = tok->next()) {
const char c1 = tok->str()[0]; const char c1 = tok->str()[0];
if (tok->str().length() == 1 && tok->next()->str().length() == 1) { if (tok->str().length() == 1 && tok->next()->str().length() == 1) {
const char c2 = tok->next()->str()[0]; const char c2 = tok->next()->str()[0];
// combine +-*/ and = // combine +-*/ and =
if (c2 == '=' && (std::strchr("+-*/%|^=!<>", c1))) { if (c2 == '=' && (std::strchr("+-*/%|^=!<>", c1))) {
// skip templates
if (cpp && tok->str() == ">") {
const Token *opening = tok->findOpeningBracket();
if (opening) {
if (Token::Match(opening->previous(), "%name%"))
continue;
}
}
tok->str(tok->str() + c2); tok->str(tok->str() + c2);
tok->deleteNext(); tok->deleteNext();
continue; continue;
} }
} else if (tok->next()->str() == "=") { } else if (tok->next()->str() == "=") {
if (tok->str() == ">>") { if (tok->str() == ">>") {
tok->str(">>="); tok->str(">>=");
tok->deleteNext(); tok->deleteNext();
} else if (tok->str() == "<<") { } else if (tok->str() == "<<") {
tok->str("<<="); tok->str("<<=");
skipping to change at line 1924 skipping to change at line 1958
} }
} }
} }
void Tokenizer::concatenateNegativeNumberAndAnyPositive() void Tokenizer::concatenateNegativeNumberAndAnyPositive()
{ {
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
if (!Token::Match(tok, "?|:|,|(|[|{|return|case|sizeof|%op% +|-") || tok ->tokType() == Token::eIncDecOp) if (!Token::Match(tok, "?|:|,|(|[|{|return|case|sizeof|%op% +|-") || tok ->tokType() == Token::eIncDecOp)
continue; continue;
while (tok->next() && tok->next()->str() == "+") while (tok->str() != ">" && tok->next() && tok->next()->str() == "+")
tok->deleteNext(); tok->deleteNext();
if (Token::Match(tok->next(), "- %num%")) { if (Token::Match(tok->next(), "- %num%")) {
tok->deleteNext(); tok->deleteNext();
tok->next()->str("-" + tok->next()->str()); tok->next()->str("-" + tok->next()->str());
} }
} }
} }
void Tokenizer::simplifyExternC() void Tokenizer::simplifyExternC()
skipping to change at line 2646 skipping to change at line 2680
inlineFunction = false; inlineFunction = false;
const Token * const startToken = (tok->str() == "{") ? tok : tok->li nk(); const Token * const startToken = (tok->str() == "{") ? tok : tok->li nk();
// parse anonymous unions as part of the current scope // parse anonymous unions as part of the current scope
if (!Token::Match(startToken->previous(), "union|struct|enum {") && if (!Token::Match(startToken->previous(), "union|struct|enum {") &&
!(initlist && Token::Match(startToken->previous(), "%name%|>|>>" ) && Token::Match(startToken->link(), "} ,|{"))) { !(initlist && Token::Match(startToken->previous(), "%name%|>|>>" ) && Token::Match(startToken->link(), "} ,|{"))) {
if (tok->str() == "{") { if (tok->str() == "{") {
bool isExecutable; bool isExecutable;
if (tok->strAt(-1) == ")" || Token::Match(tok->tokAt(-2), ") const Token *prev = tok->previous();
%type%") || while (Token::Match(prev, "%name%|."))
prev = prev->previous();
const bool isLambda = prev && prev->str() == ")" && Token::s
impleMatch(prev->link()->previous(), "] (");
if ((!isLambda && (tok->strAt(-1) == ")" || Token::Match(tok
->tokAt(-2), ") %type%"))) ||
(initlist && tok->strAt(-1) == "}")) { (initlist && tok->strAt(-1) == "}")) {
isExecutable = true; isExecutable = true;
} else { } else {
isExecutable = ((scopeStack.top().isExecutable || initli st || tok->strAt(-1) == "else") && isExecutable = ((scopeStack.top().isExecutable || initli st || tok->strAt(-1) == "else") &&
!isClassStructUnionEnumStart(tok)); !isClassStructUnionEnumStart(tok));
if (!(scopeStack.top().isStructInit || tok->strAt(-1) == "=")) if (!(scopeStack.top().isStructInit || tok->strAt(-1) == "="))
variableMap.enterScope(); variableMap.enterScope();
} }
initlist = false; initlist = false;
scopeStack.push(VarIdScopeInfo(isExecutable, scopeStack.top( ).isStructInit || tok->strAt(-1) == "=", isEnumStart(tok), *variableMap.getVarId ())); scopeStack.push(VarIdScopeInfo(isExecutable, scopeStack.top( ).isStructInit || tok->strAt(-1) == "=", isEnumStart(tok), *variableMap.getVarId ()));
skipping to change at line 3173 skipping to change at line 3211
} }
static void linkBrackets(const Tokenizer * const tokenizer, std::stack<const Tok en*>& type, std::stack<Token*>& links, Token * const token, const char open, con st char close) static void linkBrackets(const Tokenizer * const tokenizer, std::stack<const Tok en*>& type, std::stack<Token*>& links, Token * const token, const char open, con st char close)
{ {
if (token->str()[0] == open) { if (token->str()[0] == open) {
links.push(token); links.push(token);
type.push(token); type.push(token);
} else if (token->str()[0] == close) { } else if (token->str()[0] == close) {
if (links.empty()) { if (links.empty()) {
// Error, { and } don't match. // Error, { and } don't match.
tokenizer->syntaxError(token, open); tokenizer->unmatchedToken(token);
} }
if (type.top()->str()[0] != open) { if (type.top()->str()[0] != open) {
tokenizer->syntaxError(type.top(), type.top()->str()[0]); tokenizer->unmatchedToken(type.top());
} }
type.pop(); type.pop();
Token::createMutualLinks(links.top(), token); Token::createMutualLinks(links.top(), token);
links.pop(); links.pop();
} }
} }
void Tokenizer::createLinks() void Tokenizer::createLinks()
{ {
skipping to change at line 3205 skipping to change at line 3243
linkBrackets(this, type, links1, token, '{', '}'); linkBrackets(this, type, links1, token, '{', '}');
linkBrackets(this, type, links2, token, '(', ')'); linkBrackets(this, type, links2, token, '(', ')');
linkBrackets(this, type, links3, token, '[', ']'); linkBrackets(this, type, links3, token, '[', ']');
} }
if (!links1.empty()) { if (!links1.empty()) {
// Error, { and } don't match. // Error, { and } don't match.
syntaxError(links1.top(), '{'); unmatchedToken(links1.top());
} }
if (!links2.empty()) { if (!links2.empty()) {
// Error, ( and ) don't match. // Error, ( and ) don't match.
syntaxError(links2.top(), '('); unmatchedToken(links2.top());
} }
if (!links3.empty()) { if (!links3.empty()) {
// Error, [ and ] don't match. // Error, [ and ] don't match.
syntaxError(links3.top(), '['); unmatchedToken(links3.top());
} }
} }
void Tokenizer::createLinks2() void Tokenizer::createLinks2()
{ {
if (isC()) if (isC())
return; return;
const Token * templateToken = nullptr; const Token * templateToken = nullptr;
bool isStruct = false; bool isStruct = false;
skipping to change at line 3802 skipping to change at line 3840
// Put ^{} statements in asm() // Put ^{} statements in asm()
simplifyAsm2(); simplifyAsm2();
// @.. // @..
simplifyAt(); simplifyAt();
// When the assembly code has been cleaned up, no @ is allowed // When the assembly code has been cleaned up, no @ is allowed
for (const Token *tok = list.front(); tok; tok = tok->next()) { for (const Token *tok = list.front(); tok; tok = tok->next()) {
if (tok->str() == "(") { if (tok->str() == "(") {
const Token *tok1 = tok;
tok = tok->link(); tok = tok->link();
if (!tok) if (!tok)
syntaxError(nullptr); syntaxError(tok1);
} else if (tok->str() == "@") { } else if (tok->str() == "@") {
syntaxError(nullptr); syntaxError(tok);
} }
} }
// Order keywords "static" and "const" // Order keywords "static" and "const"
simplifyStaticConst(); simplifyStaticConst();
// convert platform dependent types to standard types // convert platform dependent types to standard types
// 32 bits: size_t -> unsigned long // 32 bits: size_t -> unsigned long
// 64 bits: size_t -> unsigned long long // 64 bits: size_t -> unsigned long long
simplifyPlatformTypes(); simplifyPlatformTypes();
skipping to change at line 3854 skipping to change at line 3893
// Collapse operator name tokens into single token // Collapse operator name tokens into single token
// operator = => operator= // operator = => operator=
simplifyOperatorName(); simplifyOperatorName();
// Remove redundant parentheses // Remove redundant parentheses
simplifyRedundantParentheses(); simplifyRedundantParentheses();
if (!isC()) { if (!isC()) {
// Handle templates.. // Handle templates..
simplifyTemplates(); if (mTimerResults) {
Timer t("Tokenizer::tokenize::simplifyTemplates", mSettings->showtim
e, mTimerResults);
simplifyTemplates();
} else {
simplifyTemplates();
}
// The simplifyTemplates have inner loops // The simplifyTemplates have inner loops
if (mSettings->terminated()) if (mSettings->terminated())
return false; return false;
// sometimes the "simplifyTemplates" fail and then unsimplified // sometimes the "simplifyTemplates" fail and then unsimplified
// function calls etc remain. These have the "wrong" syntax. So // function calls etc remain. These have the "wrong" syntax. So
// this function will just fix so that the syntax is corrected. // this function will just fix so that the syntax is corrected.
validate(); // #6847 - invalid code validate(); // #6847 - invalid code
mTemplateSimplifier->cleanupAfterSimplify(); mTemplateSimplifier->cleanupAfterSimplify();
skipping to change at line 6052 skipping to change at line 6096
for (; leftTok; leftTok = leftTok->previous()) { for (; leftTok; leftTok = leftTok->previous()) {
for (size_t j = 0; j <= i; j++) { for (size_t j = 0; j <= i; j++) {
if (leftTok->str() == qualifiers[j]) { if (leftTok->str() == qualifiers[j]) {
behindOther = true; behindOther = true;
break; break;
} }
} }
if (behindOther) if (behindOther)
break; break;
if (!Token::Match(leftTok, "%type%|struct|::") || if (!Token::Match(leftTok, "%type%|struct|::") ||
(isCPP() && Token::Match(leftTok, "private:|protected:|publi c:|operator"))) { (isCPP() && Token::Match(leftTok, "private:|protected:|publi c:|operator|template"))) {
break; break;
} }
} }
// The token preceding the declaration should indicate the start of a declaration // The token preceding the declaration should indicate the start of a declaration
if (leftTok == tok) if (leftTok == tok)
continue; continue;
if (leftTok && !behindOther && !Token::Match(leftTok, ";|{|}|(|,|pri vate:|protected:|public:")) { if (leftTok && !behindOther && !Token::Match(leftTok, ";|{|}|(|,|pri vate:|protected:|public:")) {
continue2 = true; continue2 = true;
skipping to change at line 7905 skipping to change at line 7949
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void Tokenizer::syntaxError(const Token *tok) const void Tokenizer::syntaxError(const Token *tok) const
{ {
printDebugOutput(0); printDebugOutput(0);
throw InternalError(tok, "syntax error", InternalError::SYNTAX); throw InternalError(tok, "syntax error", InternalError::SYNTAX);
} }
void Tokenizer::syntaxError(const Token *tok, char c) const void Tokenizer::unmatchedToken(const Token *tok) const
{ {
printDebugOutput(0); printDebugOutput(0);
if (mConfiguration.empty()) throw InternalError(tok,
throw InternalError(tok, "Unmatched '" + tok->str() + "'. Configuration: '" + mCo
std::string("Invalid number of character '") + c + " nfiguration + "'.",
' when no macros are defined.", InternalError::SYNTAX);
InternalError::SYNTAX);
else
throw InternalError(tok,
std::string("Invalid number of character '") + c + "
' when these macros are defined: '" + mConfiguration + "'.",
InternalError::SYNTAX);
} }
void Tokenizer::syntaxErrorC(const Token *tok, const std::string &what) const void Tokenizer::syntaxErrorC(const Token *tok, const std::string &what) const
{ {
printDebugOutput(0); printDebugOutput(0);
throw InternalError(tok, "Code '"+what+"' is invalid C code. Use --std or -- language to configure the language.", InternalError::SYNTAX); throw InternalError(tok, "Code '"+what+"' is invalid C code. Use --std or -- language to configure the language.", InternalError::SYNTAX);
} }
void Tokenizer::unknownMacroError(const Token *tok1) const void Tokenizer::unknownMacroError(const Token *tok1) const
{ {
skipping to change at line 8438 skipping to change at line 8477
if (tok->str() != "[") if (tok->str() != "[")
continue; continue;
for (const Token *inner = tok->next(); inner != tok->link(); inner = inn er->next()) { for (const Token *inner = tok->next(); inner != tok->link(); inner = inn er->next()) {
if (Token::Match(inner, "(|[")) if (Token::Match(inner, "(|["))
inner = inner->link(); inner = inner->link();
else if (Token::Match(inner, ";|goto|return|typedef")) else if (Token::Match(inner, ";|goto|return|typedef"))
syntaxError(inner); syntaxError(inner);
} }
} }
// UNKNOWN_MACRO(return)
for (const Token *tok = tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "throw|return )") && Token::Match(tok->linkAt(1)->
previous(), "%name% ("))
unknownMacroError(tok->linkAt(1)->previous());
}
for (const Token *tok = tokens(); tok; tok = tok->next()) { for (const Token *tok = tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "if|while|for|switch")) { // if|while|for|switch ( EXPR) { ... } if (Token::Match(tok, "if|while|for|switch")) { // if|while|for|switch ( EXPR) { ... }
if (tok->previous() && !Token::Match(tok->previous(), "%name%|:|;|{| }|(|)|,")) if (tok->previous() && !Token::Match(tok->previous(), "%name%|:|;|{| }|(|)|,"))
syntaxError(tok); syntaxError(tok);
if (Token::Match(tok->previous(), "[(,]")) if (Token::Match(tok->previous(), "[(,]"))
continue; continue;
if (!Token::Match(tok->next(), "( !!)")) if (!Token::Match(tok->next(), "( !!)"))
syntaxError(tok); syntaxError(tok);
if (tok->str() != "for") { if (tok->str() != "for") {
if (isGarbageExpr(tok->next(), tok->linkAt(1))) if (isGarbageExpr(tok->next(), tok->linkAt(1)))
skipping to change at line 8766 skipping to change at line 8811
// Skip simplification of unions in class definition // Skip simplification of unions in class definition
std::stack<bool> skip; // true = in function, false = not in function std::stack<bool> skip; // true = in function, false = not in function
skip.push(false); skip.push(false);
// Add names for anonymous structs // Add names for anonymous structs
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
if (!tok->isName()) if (!tok->isName())
continue; continue;
// check for anonymous struct/union // check for anonymous struct/union
if (Token::Match(tok, "struct|union {")) { if (Token::Match(tok, "struct|union {")) {
if (Token::Match(tok->next()->link(), "} *|&| %type% ,|;|[|(|{|=")) { if (Token::Match(tok->next()->link(), "} const| *|&| const| %type% , |;|[|(|{|=")) {
tok->insertToken("Anonymous" + MathLib::toString(count++)); tok->insertToken("Anonymous" + MathLib::toString(count++));
} }
} }
// check for derived anonymous class/struct // check for derived anonymous class/struct
else if (cpp && Token::Match(tok, "class|struct :")) { else if (cpp && Token::Match(tok, "class|struct :")) {
const Token *tok1 = Token::findsimplematch(tok, "{"); const Token *tok1 = Token::findsimplematch(tok, "{");
if (tok1 && Token::Match(tok1->link(), "} *|&| %type% ,|;|[|(|{")) { if (tok1 && Token::Match(tok1->link(), "} const| *|&| const| %type% ,|;|[|(|{")) {
tok->insertToken("Anonymous" + MathLib::toString(count++)); tok->insertToken("Anonymous" + MathLib::toString(count++));
} }
} }
// check for anonymous enum // check for anonymous enum
else if ((Token::simpleMatch(tok, "enum {") && Token::Match(tok->next()- else if ((Token::simpleMatch(tok, "enum {") &&
>link(), "} %type%| ,|;|[|(|{")) || !Token::Match(tok->tokAt(-3), "using %name% =") &&
Token::Match(tok->next()->link(), "} %type%| ,|;|[|(|{")) ||
(Token::Match(tok, "enum : %type% {") && Token::Match(tok->link At(3), "} %type%| ,|;|[|(|{"))) { (Token::Match(tok, "enum : %type% {") && Token::Match(tok->link At(3), "} %type%| ,|;|[|(|{"))) {
tok->insertToken("Anonymous" + MathLib::toString(count++)); tok->insertToken("Anonymous" + MathLib::toString(count++));
} }
} }
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
// check for start of scope and determine if it is in a function // check for start of scope and determine if it is in a function
if (tok->str() == "{") if (tok->str() == "{")
skip.push(Token::Match(tok->previous(), "const|)")); skip.push(Token::Match(tok->previous(), "const|)"));
skipping to change at line 8813 skipping to change at line 8860
next = next->next(); next = next->next();
if (!next) if (!next)
continue; continue;
skip.push(false); skip.push(false);
tok = next->link(); tok = next->link();
if (!tok) if (!tok)
break; // see #4869 segmentation fault in Tokenizer::simplifyStr uctDecl (invalid code) break; // see #4869 segmentation fault in Tokenizer::simplifyStr uctDecl (invalid code)
Token *restart = next; Token *restart = next;
// check for named type // check for named type
if (Token::Match(tok->next(), "*|&| %type% ,|;|[|=|(|{")) { if (Token::Match(tok->next(), "const| *|&| const| %type% ,|;|[|=|(|{ ")) {
tok->insertToken(";"); tok->insertToken(";");
tok = tok->next(); tok = tok->next();
while (!Token::Match(start, "struct|class|union|enum")) { while (!Token::Match(start, "struct|class|union|enum")) {
tok->insertToken(start->str()); tok->insertToken(start->str());
tok = tok->next(); tok = tok->next();
start->deleteThis(); start->deleteThis();
} }
if (!tok) if (!tok)
break; // see #4869 segmentation fault in Tokenizer::simplif yStructDecl (invalid code) break; // see #4869 segmentation fault in Tokenizer::simplif yStructDecl (invalid code)
tok->insertToken(type->str()); tok->insertToken(type->str());
skipping to change at line 8888 skipping to change at line 8935
tok2 = tok2->tokAt(2); tok2 = tok2->tokAt(2);
tok2->insertToken(vartok->str()); tok2->insertToken(vartok->str());
tok2->next()->varId(vartok->varId()); tok2->next()->varId(vartok->varId());
tok2->insertToken("="); tok2->insertToken("=");
tok2 = tok2->tokAt(4); tok2 = tok2->tokAt(4);
} }
} }
} }
// don't remove unnamed anonymous unions from a class, struct or union // don't remove unnamed anonymous unions from a class, struct or union
if (!(!inFunction && tok1->str() == "union")) { if (!(!inFunction && tok1->str() == "union") && !Token::Match(to k1->tokAt(-3), "using %name% =")) {
skip.pop(); skip.pop();
tok1->deleteThis(); tok1->deleteThis();
if (tok1->next() == tok) { if (tok1->next() == tok) {
tok1->deleteThis(); tok1->deleteThis();
tok = tok1; tok = tok1;
} else } else
tok1->deleteThis(); tok1->deleteThis();
restart = tok1->previous(); restart = tok1->previous();
tok->deleteThis(); tok->deleteThis();
if (tok->next()) if (tok->next())
skipping to change at line 9382 skipping to change at line 9429
var.insert(tok->str()); var.insert(tok->str());
tok->isAtAddress(true); tok->isAtAddress(true);
Token::eraseTokens(tok,tok->tokAt(5)); Token::eraseTokens(tok,tok->tokAt(5));
} }
if (Token::Match(tok, "%name% @ %name% : %num% ;") && var.find(tok->strA t(2)) != var.end()) { if (Token::Match(tok, "%name% @ %name% : %num% ;") && var.find(tok->strA t(2)) != var.end()) {
var.insert(tok->str()); var.insert(tok->str());
tok->isAtAddress(true); tok->isAtAddress(true);
Token::eraseTokens(tok,tok->tokAt(5)); Token::eraseTokens(tok,tok->tokAt(5));
} }
// array declaration
if (Token::Match(tok, "] @ %num% ;")) {
tok->isAtAddress(true);
Token::eraseTokens(tok,tok->tokAt(3));
}
// keywords in compiler from cosmic software for STM8 // keywords in compiler from cosmic software for STM8
// TODO: Should use platform configuration. // TODO: Should use platform configuration.
if (Token::Match(tok, "@ builtin|eeprom|far|inline|interrupt|near|noprd| nostack|nosvf|packed|stack|svlreg|tiny|vector")) { if (Token::Match(tok, "@ builtin|eeprom|far|inline|interrupt|near|noprd| nostack|nosvf|packed|stack|svlreg|tiny|vector")) {
tok->str(tok->next()->str() + "@"); tok->str(tok->next()->str() + "@");
tok->deleteNext(); tok->deleteNext();
} }
} }
} }
// Simplify bitfields // Simplify bitfields
skipping to change at line 9881 skipping to change at line 9934
if (par->isName()) { if (par->isName()) {
op += par->str(); op += par->str();
par = par->next(); par = par->next();
// merge namespaces eg. 'operator std :: string () const {' // merge namespaces eg. 'operator std :: string () const {'
if (Token::Match(par, ":: %name%|%op%|.")) { if (Token::Match(par, ":: %name%|%op%|.")) {
op += par->str(); op += par->str();
par = par->next(); par = par->next();
} }
done = false; done = false;
} else if (Token::Match(par, ".|%op%|,")) { } else if (Token::Match(par, ".|%op%|,")) {
op += par->str(); // check for operator in template
par = par->next(); if (!(Token::Match(par, "<|>") && !op.empty())) {
done = false; op += par->str();
par = par->next();
done = false;
}
} else if (Token::simpleMatch(par, "[ ]")) { } else if (Token::simpleMatch(par, "[ ]")) {
op += "[]"; op += "[]";
par = par->tokAt(2); par = par->tokAt(2);
done = false; done = false;
} else if (Token::Match(par, "( *| )")) { } else if (Token::Match(par, "( *| )")) {
// break out and simplify.. // break out and simplify..
if (operatorEnd(par->next())) if (operatorEnd(par->next()))
break; break;
while (par->str() != ")") { while (par->str() != ")") {
op += par->str(); op += par->str();
par = par->next(); par = par->next();
} }
op += ")"; op += ")";
par = par->next(); par = par->next();
done = false; done = false;
} }
} }
if (par && operatorEnd(par->link())) { if (par && (Token::Match(par, "<|>") || isFunctionHead(par, "{|;"))) {
tok->str("operator" + op); tok->str("operator" + op);
Token::eraseTokens(tok, par); Token::eraseTokens(tok, par);
} }
if (!op.empty()) if (!op.empty())
tok->isOperatorKeyword(true); tok->isOperatorKeyword(true);
} }
if (mSettings->debugwarnings) { if (mSettings->debugwarnings) {
const Token *tok = list.front(); const Token *tok = list.front();
 End of changes. 34 change blocks. 
44 lines changed or deleted 105 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)