From 38c37ad2d852fc8c69906f42adc4e0c8b64abdf8 Mon Sep 17 00:00:00 2001 From: Pete Johns Date: Sat, 1 Jan 2011 11:19:32 +1100 Subject: [PATCH] Moved array declaration detection into isVariableDeclaration() --- lib/symboldatabase.cpp | 46 +++++++++++-------------------------- lib/symboldatabase.h | 2 ++ test/testclass.cpp | 15 ++++++++++++ test/testsymboldatabase.cpp | 23 ++++++++++++++++++- 4 files changed, 52 insertions(+), 34 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index f7db79018..4ed0c411b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1167,40 +1167,9 @@ void SymbolDatabase::SpaceInfo::getVarList() if (isVariableDeclaration(tok, vartok, typetok)) { - isClass = (!typetok->isStandardType()); + isClass = (!typetok->isStandardType() && typetok->next()->str() != "*"); tok = vartok->next(); } - - // Array? - else if (Token::Match(tok, "%type% %var% [") && tok->next()->str() != "operator") - { - if (!tok->isStandardType()) - { - isClass = true; - typetok = tok; - } - - vartok = tok->next(); - tok = vartok->next()->link()->next(); - } - - // Pointer array? - else if (Token::Match(tok, "%type% * %var% [")) - { - vartok = tok->tokAt(2); - tok = vartok->next(); - } - else if (Token::Match(tok, "%type% :: %type% * %var% [")) - { - vartok = tok->tokAt(4); - tok = vartok->next(); - } - else if (Token::Match(tok, "%type% :: %type% :: %type% * %var% [")) - { - vartok = tok->tokAt(6); - tok = vartok->next(); - } - // Container.. else if (Token::Match(tok, ":: %type% :: %type% :: %type% <") || Token::Match(tok, "%type% :: %type% :: %type% <") || @@ -1264,6 +1233,7 @@ void SymbolDatabase::SpaceInfo::getVarList() } } + // If the vartok was set in the if-blocks above, create a entry for this variable.. if (vartok && vartok->str() != "operator") { @@ -1332,7 +1302,7 @@ bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const To tok = skipPointers(tok->next()); - if (Token::Match(tok, "%var% ;")) + if (isSimpleVariable(tok) || isArrayVariable(tok)) { vartok = tok; typetok = potentialTypetok; @@ -1342,6 +1312,16 @@ bool SymbolDatabase::SpaceInfo::isVariableDeclaration(const Token* tok, const To return NULL != vartok; } +bool SymbolDatabase::SpaceInfo::isSimpleVariable(const Token* tok) const +{ + return Token::Match(tok, "%var% ;"); +} + +bool SymbolDatabase::SpaceInfo::isArrayVariable(const Token* tok) const +{ + return Token::Match(tok, "%var% [") && tok->next()->str() != "operator"; +} + //--------------------------------------------------------------------------- const SymbolDatabase::SpaceInfo *SymbolDatabase::findVarType(const SpaceInfo *start, const Token *type) const diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index b9f54b995..d592f70e6 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -209,6 +209,8 @@ public: * @return true if tok points to a variable declaration, false otherwise */ bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const; + bool isSimpleVariable(const Token* tok) const; + bool isArrayVariable(const Token* tok) const; }; /** @brief Information about all namespaces/classes/structrues */ diff --git a/test/testclass.cpp b/test/testclass.cpp index a36dcd13a..563f07549 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -163,6 +163,7 @@ private: TEST_CASE(const42); // ticket #2282 TEST_CASE(const43); // ticket #2377 TEST_CASE(assigningPointerToPointerIsNotAConstOperation); + TEST_CASE(assigningArrayElementIsNotAConstOperation); TEST_CASE(constoperator1); // operator< can often be const TEST_CASE(constoperator2); // operator<< TEST_CASE(constoperator3); @@ -4937,6 +4938,20 @@ private: ASSERT_EQUALS("", errout.str()); } + void assigningArrayElementIsNotAConstOperation() + { + checkConst("struct s\n" + "{\n" + " ::std::string v[3];\n" + " void f()\n" + " {\n" + " v[0] = \"Happy new year!\";\n" + " }\n" + "};\n" + ); + ASSERT_EQUALS("", errout.str()); + } + // increment/decrement => not const void constincdec() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 4cb424096..57e0afa79 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -56,7 +56,8 @@ private: TEST_CASE(test_isVariableDeclarationIdentifiesScopedPointerDeclaration); TEST_CASE(test_isVariableDeclarationIdentifiesDeclarationWithIndirection); TEST_CASE(test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection); - + TEST_CASE(test_isVariableDeclarationIdentifiesArray); + TEST_CASE(test_isVariableDeclarationIdentifiesOfArrayPointers); } void test_isVariableDeclarationCanHandleNull() @@ -177,6 +178,26 @@ private: ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("int", typetok->str()); } + + void test_isVariableDeclarationIdentifiesArray() + { + reset(); + givenACodeSampleToTokenize array("::std::string v[3];"); + bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("v", vartok->str()); + ASSERT_EQUALS("string", typetok->str()); + } + + void test_isVariableDeclarationIdentifiesOfArrayPointers() + { + reset(); + givenACodeSampleToTokenize array("A *a[5];"); + bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok); + ASSERT_EQUALS(true, result); + ASSERT_EQUALS("a", vartok->str()); + ASSERT_EQUALS("A", typetok->str()); + } }; REGISTER_TEST(TestSymbolDatabase)