Implemented generic mechanism for '<'-'>' "linkage" before link() works (Taken from Scope::findClosingBracket, but C++11 right angle bracket support added): Token::findClosingBracket
-> Replaced several indendation-counting mechanisms in tokenize.cpp Fixed build failure in checkclass.cpp
This commit is contained in:
parent
f6fd44910a
commit
cb064dc20e
|
@ -1454,7 +1454,7 @@ bool CheckClass::isVirtualFunc(const Scope *scope, const Token *functionToken) c
|
|||
}
|
||||
|
||||
// check for matching function parameters
|
||||
if (returnMatch && symbolDatabase->argsMatch(scope, tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0)) {
|
||||
if (returnMatch && Function::argsMatch(scope, tok->tokAt(2), functionToken->tokAt(2), std::string(""), 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2000,7 +2000,7 @@ bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const
|
|||
|
||||
if (Token::Match(localTypeTok, "%type% <")) {
|
||||
const Token* closeTok = NULL;
|
||||
bool found = findClosingBracket(localTypeTok->next(), closeTok);
|
||||
bool found = localTypeTok->next()->findClosingBracket(closeTok);
|
||||
if (found) {
|
||||
localVarTok = skipPointers(closeTok->next());
|
||||
|
||||
|
@ -2041,27 +2041,6 @@ bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const
|
|||
return NULL != vartok;
|
||||
}
|
||||
|
||||
bool Scope::findClosingBracket(const Token* tok, const Token*& close)
|
||||
{
|
||||
if (NULL != tok && tok->str() == "<") {
|
||||
unsigned int depth = 0;
|
||||
for (close = tok; close != NULL; close = close->next()) {
|
||||
if (close->str() == "{" || close->str() == "[" || close->str() == "(")
|
||||
close = close->link();
|
||||
else if (close->str() == "}" || close->str() == "]" || close->str() == ")" || close->str() == ";" || close->str() == "=")
|
||||
return false;
|
||||
else if (close->str() == "<") {
|
||||
++depth;
|
||||
} else if (close->str() == ">") {
|
||||
if (--depth == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -525,7 +525,6 @@ public:
|
|||
*/
|
||||
const Variable *getVariable(const std::string &varname) const;
|
||||
|
||||
static bool findClosingBracket(const Token* tok, const Token*& close);
|
||||
private:
|
||||
/**
|
||||
* @brief helper function for getVariableList()
|
||||
|
|
|
@ -811,6 +811,32 @@ Token* Token::nextArgument() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool Token::findClosingBracket(const Token*& closing) const
|
||||
{
|
||||
if (_str == "<") {
|
||||
unsigned int depth = 0;
|
||||
for (closing = this; closing != NULL; closing = closing->next()) {
|
||||
if (closing->str() == "{" || closing->str() == "[" || closing->str() == "(")
|
||||
closing = closing->link();
|
||||
else if (closing->str() == "}" || closing->str() == "]" || closing->str() == ")" || closing->str() == ";" || closing->str() == "=")
|
||||
return false;
|
||||
else if (closing->str() == "<")
|
||||
++depth;
|
||||
else if (closing->str() == ">") {
|
||||
if (--depth == 0)
|
||||
return true;
|
||||
} else if (closing->str() == ">>") {
|
||||
if (--depth == 0)
|
||||
return true;
|
||||
if (--depth == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const Token *Token::findsimplematch(const Token *tok, const char pattern[])
|
||||
|
|
14
lib/token.h
14
lib/token.h
|
@ -433,6 +433,20 @@ public:
|
|||
*/
|
||||
Token* nextArgument() const;
|
||||
|
||||
/**
|
||||
* Returns the closing bracket of opening '<'. Should only be used if link()
|
||||
* is unavailable.
|
||||
* @param closing The closing token is stored in that parameter
|
||||
* @return success
|
||||
*/
|
||||
bool findClosingBracket(const Token*& closing) const;
|
||||
bool findClosingBracket(Token*& closing) const {
|
||||
const Token* tok;
|
||||
bool retVal = findClosingBracket(tok);
|
||||
closing = const_cast<Token*>(tok);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private:
|
||||
void next(Token *nextToken) {
|
||||
_next = nextToken;
|
||||
|
|
123
lib/tokenize.cpp
123
lib/tokenize.cpp
|
@ -1016,21 +1016,7 @@ void Tokenizer::simplifyTypedef()
|
|||
|
||||
// check for template
|
||||
if (tokOffset->str() == "<") {
|
||||
unsigned int level = 0;
|
||||
typeEnd = tokOffset->next();
|
||||
for (; typeEnd ; typeEnd = typeEnd->next()) {
|
||||
if (typeEnd->str() == ">") {
|
||||
if (!level)
|
||||
break;
|
||||
--level;
|
||||
} else if (typeEnd->str() == "<") {
|
||||
++level;
|
||||
} else if (typeEnd->str() == "(" || typeEnd->str() == "[")
|
||||
typeEnd = typeEnd->link();
|
||||
else if (typeEnd->str() == ")" || typeEnd->str() == "]") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tokOffset->findClosingBracket(typeEnd);
|
||||
|
||||
while (typeEnd && Token::Match(typeEnd->next(), ":: %type%"))
|
||||
typeEnd = typeEnd->tokAt(2);
|
||||
|
@ -2837,19 +2823,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::map<std::stri
|
|||
++typeCount;
|
||||
}
|
||||
} else if (tok2->str() == "<" && TemplateSimplifier::templateParameters(tok2) > 0) {
|
||||
unsigned int indentlevel = 1;
|
||||
bool bad = false;
|
||||
while ((indentlevel > 0) && (NULL != (tok2 = tok2->next()))) {
|
||||
if (tok2->str() == "<")
|
||||
++indentlevel;
|
||||
else if (tok2->str() == ">")
|
||||
--indentlevel;
|
||||
else if (tok2->str() == ">>") {
|
||||
if (indentlevel == 1)
|
||||
bad = true;
|
||||
indentlevel -= 2;
|
||||
}
|
||||
}
|
||||
bool bad = tok2->findClosingBracket(tok2);
|
||||
if (bad || !tok2)
|
||||
break;
|
||||
} else if (tok2->str() == "&") {
|
||||
|
@ -5155,17 +5129,7 @@ void Tokenizer::simplifyCasts()
|
|||
|
||||
while (Token::Match(tok->next(), "dynamic_cast|reinterpret_cast|const_cast|static_cast <")) {
|
||||
Token *tok2 = tok->next();
|
||||
unsigned int level = 0;
|
||||
while (tok2) {
|
||||
if (tok2->str() == "<")
|
||||
++level;
|
||||
else if (tok2->str() == ">") {
|
||||
--level;
|
||||
if (level == 0)
|
||||
break;
|
||||
}
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
tok2->next()->findClosingBracket(tok2);
|
||||
|
||||
if (Token::simpleMatch(tok2, "> (")) {
|
||||
Token *closeBracket = tok2->next()->link();
|
||||
|
@ -5599,22 +5563,8 @@ void Tokenizer::simplifyVarDecl(bool only_k_r_fpar)
|
|||
while (tok2 && tok2->str() != "," && tok2->str() != ";") {
|
||||
if (tok2->str() == "{" || tok2->str() == "(" || tok2->str() == "[")
|
||||
tok2 = tok2->link();
|
||||
if (tok2->str() == "<" && TemplateSimplifier::templateParameters(tok2) > 0) {
|
||||
unsigned int level = 1;
|
||||
while (NULL != (tok2 = tok2->next())) {
|
||||
if (tok2->str() == "<")
|
||||
level++;
|
||||
else if (tok2->str() == ">") {
|
||||
if (level <= 1)
|
||||
break;
|
||||
--level;
|
||||
} else if (tok2->str() == ">>") {
|
||||
if (level <= 2)
|
||||
break;
|
||||
level -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tok2->str() == "<" && TemplateSimplifier::templateParameters(tok2) > 0)
|
||||
tok2->findClosingBracket(tok2);
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
if (tok2 && tok2->str() == ";")
|
||||
|
@ -5679,20 +5629,14 @@ void Tokenizer::simplifyVarDecl(bool only_k_r_fpar)
|
|||
else {
|
||||
Token *eq = tok2;
|
||||
|
||||
unsigned int level = 0;
|
||||
while (tok2) {
|
||||
if (tok2->str() == "{" || tok2->str() == "(")
|
||||
tok2 = tok2->link();
|
||||
|
||||
else if (tok2->str() == "<") {
|
||||
if (tok2->previous()->isName() && !tok2->previous()->varId())
|
||||
++level;
|
||||
}
|
||||
else if (tok2->str() == "<" && tok2->previous()->isName() && !tok2->previous()->varId())
|
||||
tok2->findClosingBracket(tok2);
|
||||
|
||||
else if (level > 0 && tok2->str() == ">")
|
||||
--level;
|
||||
|
||||
else if (level == 0 && strchr(";,", tok2->str()[0])) {
|
||||
else if (strchr(";,", tok2->str()[0])) {
|
||||
// "type var =" => "type var; var ="
|
||||
Token *VarTok = type0->tokAt((int)typelen);
|
||||
while (Token::Match(VarTok, "*|&|const"))
|
||||
|
@ -8315,20 +8259,7 @@ void Tokenizer::simplifyComma()
|
|||
|
||||
// Skip unhandled template specifiers..
|
||||
if (Token::Match(tok, "%var% <")) {
|
||||
// Todo.. use the link instead.
|
||||
unsigned int comparelevel = 0;
|
||||
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == "<")
|
||||
++comparelevel;
|
||||
else if (tok2->str() == ">") {
|
||||
if (!comparelevel) {
|
||||
tok = tok2;
|
||||
break;
|
||||
}
|
||||
++comparelevel;
|
||||
} else if (Token::Match(tok2, "[;{}]"))
|
||||
break;
|
||||
}
|
||||
tok->next()->findClosingBracket(tok);
|
||||
}
|
||||
|
||||
// If token after the comma is a constant number, simplification is not required.
|
||||
|
@ -9326,28 +9257,28 @@ void Tokenizer::simplifyBorland()
|
|||
// I think that these classes are always declared at the outer scope
|
||||
// I save some time by ignoring inner classes.
|
||||
for (Token *tok = _tokens; tok; tok = tok->next()) {
|
||||
if (tok->str() == "{") {
|
||||
if (tok->str() == "{" && !Token::Match(tok->tokAt(-2), "namespace %type%")) {
|
||||
tok = tok->link();
|
||||
if (!tok)
|
||||
break;
|
||||
}
|
||||
|
||||
if (Token::Match(tok, "class %var% :|{")) {
|
||||
// count { and } for tok2
|
||||
unsigned int indentlevel = 0;
|
||||
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == "{") {
|
||||
if (indentlevel == 0)
|
||||
indentlevel = 1;
|
||||
else
|
||||
tok2 = tok2->link();
|
||||
} else if (tok2->str() == "}") {
|
||||
break;
|
||||
} else if (tok2->str() == "__property" &&
|
||||
Token::Match(tok2->previous(), ";|{|}|protected:|public:|__published:")) {
|
||||
while (tok2->next() && !Token::Match(tok2, "{|;"))
|
||||
tok2->deleteThis();
|
||||
if (tok2->str() == "{") {
|
||||
else if (Token::Match(tok, "class %var% :|{")) {
|
||||
while (tok && tok->str() != "{" && tok->str() != ";")
|
||||
tok = tok->next();
|
||||
if (!tok)
|
||||
break;
|
||||
if (tok->str() == ";")
|
||||
continue;
|
||||
|
||||
const Token* end = tok->link()->next();
|
||||
for (Token *tok2 = tok->next(); tok2 != end; tok2 = tok2->next()) {
|
||||
if (tok2->str() == "__property" &&
|
||||
Token::Match(tok2->previous(), ";|{|}|protected:|public:|__published:")) {
|
||||
while (tok2->next() && !Token::Match(tok2->next(), "{|;"))
|
||||
tok2->deleteNext();
|
||||
tok2->deleteThis();
|
||||
if (tok2 && tok2->str() == "{") {
|
||||
Token::eraseTokens(tok2, tok2->link());
|
||||
tok2->deleteNext();
|
||||
tok2->deleteThis();
|
||||
|
@ -9642,7 +9573,7 @@ void Tokenizer::printUnknownTypes()
|
|||
if (Token::Match(tok, "struct|union"))
|
||||
name += " ";
|
||||
|
||||
// pointers and referennces are OK in template
|
||||
// pointers and references are OK in template
|
||||
else if (tok->str() == "<")
|
||||
++level;
|
||||
else if (tok->str() == ">")
|
||||
|
|
|
@ -44,7 +44,6 @@ public:
|
|||
,vartok(NULL)
|
||||
,typetok(NULL)
|
||||
,t(NULL)
|
||||
,found(false)
|
||||
,isArray(false)
|
||||
,isPointer(false)
|
||||
,isReference(false)
|
||||
|
@ -59,7 +58,6 @@ private:
|
|||
const Token* vartok;
|
||||
const Token* typetok;
|
||||
const Token* t;
|
||||
bool found;
|
||||
bool isArray;
|
||||
bool isPointer;
|
||||
bool isReference;
|
||||
|
@ -68,7 +66,6 @@ private:
|
|||
vartok = NULL;
|
||||
typetok = NULL;
|
||||
t = NULL;
|
||||
found = false;
|
||||
isArray = false;
|
||||
isPointer = false;
|
||||
isReference = false;
|
||||
|
@ -98,11 +95,6 @@ private:
|
|||
TEST_CASE(isVariableDeclarationIdentifiesReference);
|
||||
TEST_CASE(isVariableDeclarationDoesNotIdentifyTemplateClass);
|
||||
TEST_CASE(isVariableDeclarationPointerConst);
|
||||
TEST_CASE(canFindMatchingBracketsNeedsOpen);
|
||||
TEST_CASE(canFindMatchingBracketsInnerPair);
|
||||
TEST_CASE(canFindMatchingBracketsOuterPair);
|
||||
TEST_CASE(canFindMatchingBracketsWithTooManyClosing);
|
||||
TEST_CASE(canFindMatchingBracketsWithTooManyOpening);
|
||||
|
||||
TEST_CASE(hasRegularFunction);
|
||||
TEST_CASE(hasInlineClassFunction);
|
||||
|
@ -447,57 +439,6 @@ private:
|
|||
ASSERT(false == isReference);
|
||||
}
|
||||
|
||||
void canFindMatchingBracketsNeedsOpen() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
||||
|
||||
found = si.findClosingBracket(var.tokens(), t);
|
||||
ASSERT(! found);
|
||||
ASSERT(! t);
|
||||
}
|
||||
|
||||
void canFindMatchingBracketsInnerPair() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
||||
|
||||
found = si.findClosingBracket(var.tokens()->tokAt(7), t);
|
||||
ASSERT(found);
|
||||
ASSERT_EQUALS(">", t->str());
|
||||
ASSERT_EQUALS(var.tokens()->strAt(9), t->str());
|
||||
}
|
||||
|
||||
void canFindMatchingBracketsOuterPair() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
||||
|
||||
found = si.findClosingBracket(var.tokens()->tokAt(3), t);
|
||||
ASSERT(found);
|
||||
ASSERT_EQUALS(">", t->str());
|
||||
ASSERT_EQUALS(var.tokens()->strAt(10), t->str());
|
||||
|
||||
}
|
||||
|
||||
void canFindMatchingBracketsWithTooManyClosing() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("X< 1>2 > x1;\n");
|
||||
|
||||
found = si.findClosingBracket(var.tokens()->next(), t);
|
||||
ASSERT(found);
|
||||
ASSERT_EQUALS(">", t->str());
|
||||
ASSERT_EQUALS(var.tokens()->strAt(3), t->str());
|
||||
}
|
||||
|
||||
void canFindMatchingBracketsWithTooManyOpening() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("X < (2 < 1) > x1;\n");
|
||||
|
||||
found = si.findClosingBracket(var.tokens()->next(), t);
|
||||
ASSERT(found);
|
||||
|
||||
found = si.findClosingBracket(var.tokens()->tokAt(4), t);
|
||||
ASSERT(!found);
|
||||
}
|
||||
|
||||
void hasRegularFunction() {
|
||||
GET_SYMBOL_DB("void func() { }\n")
|
||||
|
||||
|
|
|
@ -74,6 +74,12 @@ private:
|
|||
TEST_CASE(isNameGuarantees3)
|
||||
TEST_CASE(isNameGuarantees4)
|
||||
TEST_CASE(isNameGuarantees5)
|
||||
|
||||
TEST_CASE(canFindMatchingBracketsNeedsOpen);
|
||||
TEST_CASE(canFindMatchingBracketsInnerPair);
|
||||
TEST_CASE(canFindMatchingBracketsOuterPair);
|
||||
TEST_CASE(canFindMatchingBracketsWithTooManyClosing);
|
||||
TEST_CASE(canFindMatchingBracketsWithTooManyOpening);
|
||||
}
|
||||
|
||||
void nextprevious() {
|
||||
|
@ -607,6 +613,59 @@ private:
|
|||
ASSERT_EQUALS(true, tok.isName());
|
||||
ASSERT_EQUALS(false, tok.isNumber());
|
||||
}
|
||||
|
||||
|
||||
void canFindMatchingBracketsNeedsOpen() {
|
||||
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
||||
|
||||
const Token* t = 0;
|
||||
bool found = var.tokens()->findClosingBracket(t);
|
||||
ASSERT(! found);
|
||||
ASSERT(! t);
|
||||
}
|
||||
|
||||
void canFindMatchingBracketsInnerPair() {
|
||||
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
||||
|
||||
Token* t = 0;
|
||||
bool found = var.tokens()->tokAt(7)->findClosingBracket(t);
|
||||
ASSERT(found);
|
||||
ASSERT_EQUALS(">", t->str());
|
||||
ASSERT(var.tokens()->tokAt(9) == t);
|
||||
}
|
||||
|
||||
void canFindMatchingBracketsOuterPair() {
|
||||
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
||||
|
||||
const Token* t = 0;
|
||||
bool found = var.tokens()->tokAt(3)->findClosingBracket(t);
|
||||
ASSERT(found);
|
||||
ASSERT_EQUALS(">", t->str());
|
||||
ASSERT(var.tokens()->tokAt(10) == t);
|
||||
|
||||
}
|
||||
|
||||
void canFindMatchingBracketsWithTooManyClosing() {
|
||||
givenACodeSampleToTokenize var("X< 1>2 > x1;\n");
|
||||
|
||||
const Token* t = 0;
|
||||
bool found = var.tokens()->next()->findClosingBracket(t);
|
||||
ASSERT(found);
|
||||
ASSERT_EQUALS(">", t->str());
|
||||
ASSERT(var.tokens()->tokAt(3) == t);
|
||||
}
|
||||
|
||||
void canFindMatchingBracketsWithTooManyOpening() {
|
||||
givenACodeSampleToTokenize var("X < (2 < 1) > x1;\n");
|
||||
|
||||
const Token* t = 0;
|
||||
bool found = var.tokens()->next()->findClosingBracket(t);
|
||||
ASSERT(found);
|
||||
|
||||
found = var.tokens()->tokAt(4)->findClosingBracket(t);
|
||||
ASSERT(!found);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestToken)
|
||||
|
|
Loading…
Reference in New Issue