2010-12-30 09:46:44 +01:00
/*
* Cppcheck - A tool for static C / C + + code analysis
2014-02-15 07:45:39 +01:00
* Copyright ( C ) 2007 - 2014 Daniel Marjamäki and Cppcheck team .
2010-12-30 09:46:44 +01:00
*
* 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
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "testsuite.h"
# include "testutils.h"
# include "symboldatabase.h"
2012-10-30 15:48:06 +01:00
# include <sstream>
2010-12-30 09:46:44 +01:00
2011-01-28 08:33:02 +01:00
# define GET_SYMBOL_DB(code) \
errout . str ( " " ) ; \
Settings settings ; \
Tokenizer tokenizer ( & settings , this ) ; \
std : : istringstream istr ( code ) ; \
tokenizer . tokenize ( istr , " test.cpp " ) ; \
const SymbolDatabase * db = tokenizer . getSymbolDatabase ( ) ;
2012-01-28 01:24:01 +01:00
# define GET_SYMBOL_DB_C(code) \
errout . str ( " " ) ; \
Settings settings ; \
Tokenizer tokenizer ( & settings , this ) ; \
std : : istringstream istr ( code ) ; \
tokenizer . tokenize ( istr , " test.c " ) ; \
const SymbolDatabase * db = tokenizer . getSymbolDatabase ( ) ;
2011-10-13 20:53:06 +02:00
class TestSymbolDatabase : public TestFixture {
2010-12-30 09:46:44 +01:00
public :
TestSymbolDatabase ( )
: TestFixture ( " TestSymbolDatabase " )
2014-02-16 10:32:10 +01:00
, si ( nullptr , nullptr , nullptr )
, vartok ( nullptr )
, typetok ( nullptr )
, t ( nullptr )
2013-08-07 16:27:37 +02:00
, found ( false ) {
}
2010-12-30 09:46:44 +01:00
private :
2011-01-17 18:29:19 +01:00
const Scope si ;
2010-12-30 09:46:44 +01:00
const Token * vartok ;
2010-12-30 22:57:43 +01:00
const Token * typetok ;
2011-01-02 00:36:22 +01:00
const Token * t ;
2012-05-11 17:56:47 +02:00
bool found ;
2010-12-30 22:57:43 +01:00
2011-10-13 20:53:06 +02:00
void reset ( ) {
2014-02-16 10:32:10 +01:00
vartok = nullptr ;
typetok = nullptr ;
t = nullptr ;
2012-05-11 17:56:47 +02:00
found = false ;
2010-12-30 22:57:43 +01:00
}
2010-12-30 09:46:44 +01:00
2013-03-12 15:42:00 +01:00
static const Scope * findFunctionScopeByToken ( const SymbolDatabase * db , const Token * tok ) {
2013-01-28 06:47:48 +01:00
std : : list < Scope > : : const_iterator scope ;
for ( scope = db - > scopeList . begin ( ) ; scope ! = db - > scopeList . end ( ) ; + + scope ) {
if ( scope - > type = = Scope : : eFunction ) {
if ( scope - > classDef = = tok )
return & ( * scope ) ;
}
}
return 0 ;
}
2013-03-12 15:42:00 +01:00
static const Function * findFunctionByName ( const std : : string & str , const Scope * startScope ) {
2013-01-28 06:47:48 +01:00
const Scope * currScope = startScope ;
while ( currScope & & currScope - > isExecutable ( ) ) {
if ( currScope - > functionOf )
currScope = currScope - > functionOf ;
else
currScope = currScope - > nestedIn ;
}
while ( currScope ) {
for ( std : : list < Function > : : const_iterator i = currScope - > functionList . begin ( ) ; i ! = currScope - > functionList . end ( ) ; + + i ) {
if ( i - > tokenDef - > str ( ) = = str )
return & * i ;
}
currScope = currScope - > nestedIn ;
}
return 0 ;
}
2011-10-13 20:53:06 +02:00
void run ( ) {
2012-08-10 11:01:12 +02:00
TEST_CASE ( array ) ;
2010-12-30 09:46:44 +01:00
TEST_CASE ( test_isVariableDeclarationCanHandleNull ) ;
TEST_CASE ( test_isVariableDeclarationIdentifiesSimpleDeclaration ) ;
TEST_CASE ( test_isVariableDeclarationIdentifiesScopedDeclaration ) ;
TEST_CASE ( test_isVariableDeclarationIdentifiesStdDeclaration ) ;
TEST_CASE ( test_isVariableDeclarationIdentifiesScopedStdDeclaration ) ;
TEST_CASE ( test_isVariableDeclarationIdentifiesManyScopes ) ;
2010-12-30 22:57:43 +01:00
TEST_CASE ( test_isVariableDeclarationIdentifiesPointers ) ;
2010-12-30 09:46:44 +01:00
TEST_CASE ( test_isVariableDeclarationDoesNotIdentifyConstness ) ;
TEST_CASE ( test_isVariableDeclarationIdentifiesFirstOfManyVariables ) ;
2010-12-30 22:57:43 +01:00
TEST_CASE ( test_isVariableDeclarationIdentifiesScopedPointerDeclaration ) ;
TEST_CASE ( test_isVariableDeclarationIdentifiesDeclarationWithIndirection ) ;
TEST_CASE ( test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection ) ;
2011-01-01 01:19:32 +01:00
TEST_CASE ( test_isVariableDeclarationIdentifiesArray ) ;
TEST_CASE ( test_isVariableDeclarationIdentifiesOfArrayPointers ) ;
2011-01-02 00:36:22 +01:00
TEST_CASE ( isVariableDeclarationIdentifiesTemplatedPointerVariable ) ;
2011-01-18 08:29:42 +01:00
TEST_CASE ( isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable ) ;
2011-01-18 10:14:12 +01:00
TEST_CASE ( isVariableDeclarationIdentifiesTemplatedArrayVariable ) ;
2011-01-02 00:36:22 +01:00
TEST_CASE ( isVariableDeclarationIdentifiesTemplatedVariable ) ;
TEST_CASE ( isVariableDeclarationIdentifiesTemplatedVariableIterator ) ;
TEST_CASE ( isVariableDeclarationIdentifiesNestedTemplateVariable ) ;
2012-01-26 17:04:25 +01:00
TEST_CASE ( isVariableDeclarationIdentifiesReference ) ;
2011-01-02 00:36:22 +01:00
TEST_CASE ( isVariableDeclarationDoesNotIdentifyTemplateClass ) ;
2012-03-24 15:10:06 +01:00
TEST_CASE ( isVariableDeclarationPointerConst ) ;
2013-04-04 18:47:44 +02:00
TEST_CASE ( isVariableDeclarationRValueRef ) ;
2014-01-28 15:44:56 +01:00
TEST_CASE ( isVariableStlType ) ;
2011-01-28 08:33:02 +01:00
2013-07-20 17:46:39 +02:00
TEST_CASE ( arrayMemberVar1 ) ;
TEST_CASE ( arrayMemberVar2 ) ;
TEST_CASE ( arrayMemberVar3 ) ;
2012-05-15 21:03:43 +02:00
TEST_CASE ( staticMemberVar ) ;
2011-01-28 08:33:02 +01:00
TEST_CASE ( hasRegularFunction ) ;
TEST_CASE ( hasInlineClassFunction ) ;
TEST_CASE ( hasMissingInlineClassFunction ) ;
TEST_CASE ( hasClassFunction ) ;
TEST_CASE ( hasRegularFunctionReturningFunctionPointer ) ;
TEST_CASE ( hasInlineClassFunctionReturningFunctionPointer ) ;
TEST_CASE ( hasMissingInlineClassFunctionReturningFunctionPointer ) ;
TEST_CASE ( hasClassFunctionReturningFunctionPointer ) ;
2014-03-28 17:43:40 +01:00
TEST_CASE ( complexFunctionArrayPtr ) ;
2012-09-15 20:13:32 +02:00
TEST_CASE ( hasSubClassConstructor ) ;
2013-04-04 19:53:55 +02:00
TEST_CASE ( testConstructors ) ;
2012-08-22 12:37:50 +02:00
TEST_CASE ( functionDeclarationTemplate ) ;
2012-03-23 17:59:51 +01:00
TEST_CASE ( functionDeclarations ) ;
2014-03-30 11:06:44 +02:00
TEST_CASE ( memberFunctionOfUnknownClassMacro ) ;
2011-02-25 13:17:55 +01:00
2012-02-24 20:45:56 +01:00
TEST_CASE ( classWithFriend ) ;
2011-11-05 12:23:05 +01:00
TEST_CASE ( parseFunctionCorrect ) ;
2012-05-22 21:30:10 +02:00
TEST_CASE ( parseFunctionDeclarationCorrect ) ;
2012-07-10 15:15:11 +02:00
TEST_CASE ( Cpp11InitInInitList ) ;
2011-11-05 12:23:05 +01:00
2011-02-25 13:17:55 +01:00
TEST_CASE ( hasGlobalVariables1 ) ;
TEST_CASE ( hasGlobalVariables2 ) ;
TEST_CASE ( hasGlobalVariables3 ) ;
2011-04-29 02:53:31 +02:00
2013-09-28 11:44:26 +02:00
TEST_CASE ( checkTypeStartEndToken1 ) ;
TEST_CASE ( checkTypeStartEndToken2 ) ; // handling for unknown macro: 'void f() MACRO {..'
2012-06-08 18:05:02 +02:00
2011-04-29 02:53:31 +02:00
TEST_CASE ( functionArgs1 ) ;
2011-08-28 19:32:42 +02:00
TEST_CASE ( functionArgs2 ) ;
2012-05-22 10:29:33 +02:00
TEST_CASE ( functionArgs3 ) ;
2012-12-29 08:32:43 +01:00
TEST_CASE ( functionArgs4 ) ;
2011-04-29 03:03:57 +02:00
2012-01-07 09:28:26 +01:00
TEST_CASE ( namespaces1 ) ;
TEST_CASE ( namespaces2 ) ;
2012-06-05 06:37:55 +02:00
TEST_CASE ( namespaces3 ) ; // #3854 - unknown macro
2012-01-07 09:28:26 +01:00
2012-01-26 04:48:18 +01:00
TEST_CASE ( tryCatch1 ) ;
2011-04-29 03:03:57 +02:00
TEST_CASE ( symboldatabase1 ) ;
TEST_CASE ( symboldatabase2 ) ;
TEST_CASE ( symboldatabase3 ) ; // ticket #2000
TEST_CASE ( symboldatabase4 ) ;
TEST_CASE ( symboldatabase5 ) ; // ticket #2178
TEST_CASE ( symboldatabase6 ) ; // ticket #2221
TEST_CASE ( symboldatabase7 ) ; // ticket #2230
TEST_CASE ( symboldatabase8 ) ; // ticket #2252
TEST_CASE ( symboldatabase9 ) ; // ticket #2525
TEST_CASE ( symboldatabase10 ) ; // ticket #2537
TEST_CASE ( symboldatabase11 ) ; // ticket #2539
TEST_CASE ( symboldatabase12 ) ; // ticket #2547
TEST_CASE ( symboldatabase13 ) ; // ticket #2577
TEST_CASE ( symboldatabase14 ) ; // ticket #2589
TEST_CASE ( symboldatabase15 ) ; // ticket #2591
TEST_CASE ( symboldatabase16 ) ; // ticket #2637
TEST_CASE ( symboldatabase17 ) ; // ticket #2657
2011-06-27 13:31:10 +02:00
TEST_CASE ( symboldatabase18 ) ; // ticket #2865
2011-08-11 23:57:54 +02:00
TEST_CASE ( symboldatabase19 ) ; // ticket #2991 (segmentation fault)
2011-08-17 01:16:58 +02:00
TEST_CASE ( symboldatabase20 ) ; // ticket #3013 (segmentation fault)
2011-09-29 04:05:26 +02:00
TEST_CASE ( symboldatabase21 ) ;
2011-12-22 09:20:37 +01:00
TEST_CASE ( symboldatabase22 ) ; // ticket #3437 (segmentation fault)
2011-12-25 11:05:06 +01:00
TEST_CASE ( symboldatabase23 ) ; // ticket #3435
2012-01-22 19:34:53 +01:00
TEST_CASE ( symboldatabase24 ) ; // ticket #3508 (constructor, destructor)
2012-01-28 01:24:01 +01:00
TEST_CASE ( symboldatabase25 ) ; // ticket #3561 (throw C++)
TEST_CASE ( symboldatabase26 ) ; // ticket #3561 (throw C)
2012-01-31 19:34:55 +01:00
TEST_CASE ( symboldatabase27 ) ; // ticket #3543 (segmentation fault)
2012-04-27 21:51:13 +02:00
TEST_CASE ( symboldatabase28 ) ;
2012-12-28 08:36:20 +01:00
TEST_CASE ( symboldatabase29 ) ; // ticket #4442 (segmentation fault)
2013-01-27 02:46:00 +01:00
TEST_CASE ( symboldatabase30 ) ;
2013-03-05 13:33:38 +01:00
TEST_CASE ( symboldatabase31 ) ;
2014-01-06 17:04:38 +01:00
TEST_CASE ( symboldatabase32 ) ;
2013-03-28 06:36:49 +01:00
TEST_CASE ( symboldatabase33 ) ; // ticket #4682 (false negatives)
2013-05-30 15:13:09 +02:00
TEST_CASE ( symboldatabase34 ) ; // ticket #4694 (segmentation fault)
2013-06-16 21:46:01 +02:00
TEST_CASE ( symboldatabase35 ) ; // ticket #4806 (segmentation fault)
2013-07-08 11:45:26 +02:00
TEST_CASE ( symboldatabase36 ) ; // ticket #4892 (segmentation fault)
2013-08-12 06:21:03 +02:00
TEST_CASE ( symboldatabase37 ) ;
2013-10-29 21:41:47 +01:00
TEST_CASE ( symboldatabase38 ) ; // ticket #5125 (infinite recursion)
2013-10-30 10:15:03 +01:00
TEST_CASE ( symboldatabase39 ) ; // ticket #5120 (infinite recursion)
2013-11-08 12:56:32 +01:00
TEST_CASE ( symboldatabase40 ) ; // ticket #5153
2013-11-25 03:43:39 +01:00
TEST_CASE ( symboldatabase41 ) ; // ticket #5197 (unknown macro)
2013-12-31 17:51:56 +01:00
TEST_CASE ( symboldatabase42 ) ; // only put variables in variable list
2012-04-17 19:50:44 +02:00
TEST_CASE ( isImplicitlyVirtual ) ;
2012-09-14 15:32:35 +02:00
TEST_CASE ( garbage ) ;
2012-10-30 15:48:06 +01:00
TEST_CASE ( findFunction1 ) ;
2014-02-19 06:35:51 +01:00
TEST_CASE ( findFunction2 ) ; // mismatch: parameter passed by address => reference argument
2010-12-30 09:46:44 +01:00
}
2013-03-12 15:42:00 +01:00
void array ( ) const {
2012-08-10 11:01:12 +02:00
std : : istringstream code ( " int a[10+2]; " ) ;
2014-02-16 10:32:10 +01:00
TokenList list ( nullptr ) ;
2012-08-10 11:01:12 +02:00
list . createTokens ( code , " test.c " ) ;
list . front ( ) - > tokAt ( 2 ) - > link ( list . front ( ) - > tokAt ( 6 ) ) ;
2014-02-16 10:32:10 +01:00
Variable v ( list . front ( ) - > next ( ) , list . front ( ) , list . back ( ) , 0 , Public , nullptr , nullptr ) ;
2012-08-10 11:01:12 +02:00
ASSERT ( v . isArray ( ) ) ;
ASSERT_EQUALS ( 1U , v . dimensions ( ) . size ( ) ) ;
ASSERT_EQUALS ( 0U , v . dimension ( 0 ) ) ;
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationCanHandleNull ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
2014-02-16 10:32:10 +01:00
bool result = si . isVariableDeclaration ( nullptr , vartok , typetok ) ;
2010-12-30 09:46:44 +01:00
ASSERT_EQUALS ( false , result ) ;
2014-02-16 10:32:10 +01:00
ASSERT ( nullptr = = vartok ) ;
ASSERT ( nullptr = = typetok ) ;
Variable v ( nullptr , nullptr , nullptr , 0 , Public , 0 , 0 ) ;
2010-12-30 09:46:44 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesSimpleDeclaration ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
2010-12-30 09:46:44 +01:00
givenACodeSampleToTokenize simpleDeclaration ( " int x; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( simpleDeclaration . tokens ( ) , vartok , typetok ) ;
2010-12-30 09:46:44 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " x " , vartok - > str ( ) ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( " int " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2010-12-30 09:46:44 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesScopedDeclaration ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
2010-12-30 09:46:44 +01:00
givenACodeSampleToTokenize ScopedDeclaration ( " ::int x; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( ScopedDeclaration . tokens ( ) , vartok , typetok ) ;
2010-12-30 09:46:44 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " x " , vartok - > str ( ) ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( " int " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2010-12-30 09:46:44 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesStdDeclaration ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
2010-12-30 09:46:44 +01:00
givenACodeSampleToTokenize StdDeclaration ( " std::string x; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( StdDeclaration . tokens ( ) , vartok , typetok ) ;
2010-12-30 09:46:44 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " x " , vartok - > str ( ) ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( " string " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2010-12-30 09:46:44 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesScopedStdDeclaration ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
2010-12-30 09:46:44 +01:00
givenACodeSampleToTokenize StdDeclaration ( " ::std::string x; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( StdDeclaration . tokens ( ) , vartok , typetok ) ;
2010-12-30 09:46:44 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " x " , vartok - > str ( ) ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( " string " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2010-12-30 09:46:44 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesManyScopes ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
2010-12-30 09:46:44 +01:00
givenACodeSampleToTokenize manyScopes ( " AA::BB::CC::DD::EE x; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( manyScopes . tokens ( ) , vartok , typetok ) ;
2010-12-30 09:46:44 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " x " , vartok - > str ( ) ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( " EE " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2010-12-30 09:46:44 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesPointers ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
2010-12-30 09:46:44 +01:00
givenACodeSampleToTokenize pointer ( " int* p; " ) ;
2012-05-14 21:47:02 +02:00
bool result1 = si . isVariableDeclaration ( pointer . tokens ( ) , vartok , typetok ) ;
ASSERT_EQUALS ( true , result1 ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( " p " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " int " , typetok - > str ( ) ) ;
2012-05-14 21:47:02 +02:00
Variable v1 ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v1 . isArray ( ) ) ;
ASSERT ( true = = v1 . isPointer ( ) ) ;
ASSERT ( false = = v1 . isReference ( ) ) ;
reset ( ) ;
givenACodeSampleToTokenize constpointer ( " const int* p; " ) ;
Variable v2 ( constpointer . tokens ( ) - > tokAt ( 3 ) , constpointer . tokens ( ) - > next ( ) , constpointer . tokens ( ) - > tokAt ( 2 ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v2 . isArray ( ) ) ;
ASSERT ( true = = v2 . isPointer ( ) ) ;
ASSERT ( false = = v2 . isConst ( ) ) ;
ASSERT ( false = = v2 . isReference ( ) ) ;
reset ( ) ;
givenACodeSampleToTokenize pointerconst ( " int* const p; " ) ;
bool result2 = si . isVariableDeclaration ( pointerconst . tokens ( ) , vartok , typetok ) ;
ASSERT_EQUALS ( true , result2 ) ;
ASSERT_EQUALS ( " p " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " int " , typetok - > str ( ) ) ;
Variable v3 ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v3 . isArray ( ) ) ;
ASSERT ( true = = v3 . isPointer ( ) ) ;
ASSERT ( true = = v3 . isConst ( ) ) ;
ASSERT ( false = = v3 . isReference ( ) ) ;
2010-12-30 09:46:44 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationDoesNotIdentifyConstness ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
2010-12-30 09:46:44 +01:00
givenACodeSampleToTokenize constness ( " const int* cp; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( constness . tokens ( ) , vartok , typetok ) ;
2010-12-30 09:46:44 +01:00
ASSERT_EQUALS ( false , result ) ;
2014-02-16 10:32:10 +01:00
ASSERT ( nullptr = = vartok ) ;
ASSERT ( nullptr = = typetok ) ;
2010-12-30 09:46:44 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesFirstOfManyVariables ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
2010-12-30 09:46:44 +01:00
givenACodeSampleToTokenize multipleDeclaration ( " int first, second; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( multipleDeclaration . tokens ( ) , vartok , typetok ) ;
2010-12-30 09:46:44 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " first " , vartok - > str ( ) ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( " int " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2010-12-30 22:57:43 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesScopedPointerDeclaration ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
givenACodeSampleToTokenize manyScopes ( " AA::BB::CC::DD::EE* p; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( manyScopes . tokens ( ) , vartok , typetok ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " p " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " EE " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( true = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2010-12-30 22:57:43 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesDeclarationWithIndirection ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
givenACodeSampleToTokenize pointerToPointer ( " int** pp; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( pointerToPointer . tokens ( ) , vartok , typetok ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " pp " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " int " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( true = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2010-12-30 22:57:43 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection ( ) {
2010-12-30 22:57:43 +01:00
reset ( ) ;
givenACodeSampleToTokenize pointerToPointer ( " int***** p; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( pointerToPointer . tokens ( ) , vartok , typetok ) ;
2010-12-30 22:57:43 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " p " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " int " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( true = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2010-12-30 09:46:44 +01:00
}
2011-01-01 01:19:32 +01:00
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesArray ( ) {
2011-01-01 01:19:32 +01:00
reset ( ) ;
2012-08-12 17:04:37 +02:00
givenACodeSampleToTokenize arr ( " ::std::string v[3]; " ) ;
bool result = si . isVariableDeclaration ( arr . tokens ( ) , vartok , typetok ) ;
2011-01-01 01:19:32 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " v " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " string " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( true = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2011-01-01 01:19:32 +01:00
}
2011-10-13 20:53:06 +02:00
void test_isVariableDeclarationIdentifiesOfArrayPointers ( ) {
2011-01-01 01:19:32 +01:00
reset ( ) ;
2012-08-12 17:04:37 +02:00
givenACodeSampleToTokenize arr ( " A *a[5]; " ) ;
bool result = si . isVariableDeclaration ( arr . tokens ( ) , vartok , typetok ) ;
2011-01-01 01:19:32 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " a " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " A " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( true = = v . isArray ( ) ) ;
ASSERT ( true = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2011-01-01 01:19:32 +01:00
}
2011-01-02 00:36:22 +01:00
2011-10-13 20:53:06 +02:00
void isVariableDeclarationIdentifiesTemplatedPointerVariable ( ) {
2011-01-02 00:36:22 +01:00
reset ( ) ;
givenACodeSampleToTokenize var ( " std::set<char>* chars; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( var . tokens ( ) , vartok , typetok ) ;
2011-01-02 00:36:22 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " chars " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " set " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( true = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2011-01-02 00:36:22 +01:00
}
2011-10-13 20:53:06 +02:00
void isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable ( ) {
2011-01-18 08:29:42 +01:00
reset ( ) ;
givenACodeSampleToTokenize var ( " std::deque<int>*** ints; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( var . tokens ( ) , vartok , typetok ) ;
2011-01-18 10:14:12 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " ints " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " deque " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( true = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2011-01-18 10:14:12 +01:00
}
2011-10-13 20:53:06 +02:00
void isVariableDeclarationIdentifiesTemplatedArrayVariable ( ) {
2011-01-18 10:14:12 +01:00
reset ( ) ;
givenACodeSampleToTokenize var ( " std::deque<int> ints[3]; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( var . tokens ( ) , vartok , typetok ) ;
2011-01-18 10:14:12 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " ints " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " deque " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( true = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2011-01-18 08:29:42 +01:00
}
2011-10-13 20:53:06 +02:00
void isVariableDeclarationIdentifiesTemplatedVariable ( ) {
2011-01-02 00:36:22 +01:00
reset ( ) ;
givenACodeSampleToTokenize var ( " std::vector<int> ints; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( var . tokens ( ) , vartok , typetok ) ;
2011-01-02 00:36:22 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " ints " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " vector " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2011-01-02 00:36:22 +01:00
}
2011-10-13 20:53:06 +02:00
void isVariableDeclarationIdentifiesTemplatedVariableIterator ( ) {
2011-01-02 00:36:22 +01:00
reset ( ) ;
givenACodeSampleToTokenize var ( " std::list<int>::const_iterator floats; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( var . tokens ( ) , vartok , typetok ) ;
2011-01-02 00:36:22 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " floats " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " const_iterator " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2011-01-02 00:36:22 +01:00
}
2011-10-13 20:53:06 +02:00
void isVariableDeclarationIdentifiesNestedTemplateVariable ( ) {
2011-01-02 00:36:22 +01:00
reset ( ) ;
givenACodeSampleToTokenize var ( " std::deque<std::set<int> > intsets; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( var . tokens ( ) , vartok , typetok ) ;
2011-01-02 00:36:22 +01:00
ASSERT_EQUALS ( true , result ) ;
ASSERT_EQUALS ( " intsets " , vartok - > str ( ) ) ;
ASSERT_EQUALS ( " deque " , typetok - > str ( ) ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2012-01-26 17:04:25 +01:00
}
void isVariableDeclarationIdentifiesReference ( ) {
reset ( ) ;
givenACodeSampleToTokenize var1 ( " int& foo; " ) ;
2012-05-11 17:56:47 +02:00
bool result1 = si . isVariableDeclaration ( var1 . tokens ( ) , vartok , typetok ) ;
2012-01-26 17:04:25 +01:00
ASSERT_EQUALS ( true , result1 ) ;
2012-05-11 17:56:47 +02:00
Variable v1 ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v1 . isArray ( ) ) ;
ASSERT ( false = = v1 . isPointer ( ) ) ;
ASSERT ( true = = v1 . isReference ( ) ) ;
2012-01-26 17:04:25 +01:00
reset ( ) ;
givenACodeSampleToTokenize var2 ( " foo*& bar; " ) ;
2012-05-11 17:56:47 +02:00
bool result2 = si . isVariableDeclaration ( var2 . tokens ( ) , vartok , typetok ) ;
2012-01-26 17:04:25 +01:00
ASSERT_EQUALS ( true , result2 ) ;
2012-05-11 17:56:47 +02:00
Variable v2 ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v2 . isArray ( ) ) ;
ASSERT ( true = = v2 . isPointer ( ) ) ;
ASSERT ( true = = v2 . isReference ( ) ) ;
2012-01-26 17:04:25 +01:00
reset ( ) ;
givenACodeSampleToTokenize var3 ( " std::vector<int>& foo; " ) ;
2012-05-11 17:56:47 +02:00
bool result3 = si . isVariableDeclaration ( var3 . tokens ( ) , vartok , typetok ) ;
2012-01-26 17:04:25 +01:00
ASSERT_EQUALS ( true , result3 ) ;
2012-05-11 17:56:47 +02:00
Variable v3 ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v3 . isArray ( ) ) ;
ASSERT ( false = = v3 . isPointer ( ) ) ;
ASSERT ( true = = v3 . isReference ( ) ) ;
2011-01-02 00:36:22 +01:00
}
2011-10-13 20:53:06 +02:00
void isVariableDeclarationDoesNotIdentifyTemplateClass ( ) {
2011-01-02 00:36:22 +01:00
reset ( ) ;
givenACodeSampleToTokenize var ( " template <class T> class SomeClass{}; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( var . tokens ( ) , vartok , typetok ) ;
2011-01-02 00:36:22 +01:00
ASSERT_EQUALS ( false , result ) ;
}
2012-03-24 15:10:06 +01:00
void isVariableDeclarationPointerConst ( ) {
reset ( ) ;
givenACodeSampleToTokenize var ( " std::string const* s; " ) ;
2012-05-11 17:56:47 +02:00
bool result = si . isVariableDeclaration ( var . tokens ( ) , vartok , typetok ) ;
2012-03-24 15:10:06 +01:00
ASSERT_EQUALS ( true , result ) ;
2012-05-11 17:56:47 +02:00
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( true = = v . isPointer ( ) ) ;
ASSERT ( false = = v . isReference ( ) ) ;
2012-03-24 15:10:06 +01:00
}
2013-04-04 18:47:44 +02:00
void isVariableDeclarationRValueRef ( ) {
reset ( ) ;
givenACodeSampleToTokenize var ( " int&& i; " ) ;
bool result = si . isVariableDeclaration ( var . tokens ( ) , vartok , typetok ) ;
ASSERT_EQUALS ( true , result ) ;
Variable v ( vartok , typetok , vartok - > previous ( ) , 0 , Public , 0 , 0 ) ;
ASSERT ( false = = v . isArray ( ) ) ;
ASSERT ( false = = v . isPointer ( ) ) ;
ASSERT ( true = = v . isReference ( ) ) ;
ASSERT ( true = = v . isRValueReference ( ) ) ;
2013-05-14 11:06:16 +02:00
ASSERT ( var . tokens ( ) - > tokAt ( 2 ) - > scope ( ) ! = 0 ) ;
2013-04-04 18:47:44 +02:00
}
2014-01-28 15:44:56 +01:00
void isVariableStlType ( ) {
{
reset ( ) ;
std : : istringstream code ( " std::string s; " ) ;
2014-02-16 10:32:10 +01:00
TokenList list ( nullptr ) ;
2014-01-28 15:44:56 +01:00
list . createTokens ( code , " test.cpp " ) ;
bool result = si . isVariableDeclaration ( list . front ( ) , vartok , typetok ) ;
ASSERT_EQUALS ( true , result ) ;
Variable v ( vartok , list . front ( ) , list . back ( ) , 0 , Public , 0 , 0 ) ;
const char * types [ ] = { " string " , " wstring " } ;
const char * no_types [ ] = { " set " } ;
ASSERT_EQUALS ( true , v . isStlType ( ) ) ;
ASSERT_EQUALS ( true , v . isStlType ( types ) ) ;
ASSERT_EQUALS ( false , v . isStlType ( no_types ) ) ;
}
{
reset ( ) ;
std : : istringstream code ( " std::vector<int> v; " ) ;
2014-02-16 10:32:10 +01:00
TokenList list ( nullptr ) ;
2014-01-28 15:44:56 +01:00
list . createTokens ( code , " test.cpp " ) ;
list . front ( ) - > tokAt ( 3 ) - > link ( list . front ( ) - > tokAt ( 5 ) ) ;
bool result = si . isVariableDeclaration ( list . front ( ) , vartok , typetok ) ;
ASSERT_EQUALS ( true , result ) ;
Variable v ( vartok , list . front ( ) , list . back ( ) , 0 , Public , 0 , 0 ) ;
const char * types [ ] = { " bitset " , " set " , " vector " , " wstring " } ;
const char * no_types [ ] = { " bitset " , " map " , " set " } ;
ASSERT_EQUALS ( true , v . isStlType ( ) ) ;
ASSERT_EQUALS ( true , v . isStlType ( types ) ) ;
ASSERT_EQUALS ( false , v . isStlType ( no_types ) ) ;
}
{
reset ( ) ;
std : : istringstream code ( " SomeClass s; " ) ;
2014-02-16 10:32:10 +01:00
TokenList list ( nullptr ) ;
2014-01-28 15:44:56 +01:00
list . createTokens ( code , " test.cpp " ) ;
bool result = si . isVariableDeclaration ( list . front ( ) , vartok , typetok ) ;
ASSERT_EQUALS ( true , result ) ;
Variable v ( vartok , list . front ( ) , list . back ( ) , 0 , Public , 0 , 0 ) ;
const char * types [ ] = { " bitset " , " set " , " vector " } ;
ASSERT_EQUALS ( false , v . isStlType ( ) ) ;
ASSERT_EQUALS ( false , v . isStlType ( types ) ) ;
}
}
2013-07-20 17:46:39 +02:00
void arrayMemberVar1 ( ) {
const char code [ ] = " struct Foo { \n "
" int x; \n "
" }; \n "
" void f() { \n "
" struct Foo foo[10]; \n "
" foo[1].x = 123; \n " // <- x should get a variable() pointer
" } " ;
Settings settings ;
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
const Token * tok = Token : : findmatch ( tokenizer . tokens ( ) , " . x " ) ;
2014-02-16 10:32:10 +01:00
tok = tok ? tok - > next ( ) : nullptr ;
2013-07-20 17:46:39 +02:00
ASSERT ( tok & & tok - > variable ( ) & & Token : : Match ( tok - > variable ( ) - > typeStartToken ( ) , " int x ; " ) ) ;
ASSERT ( tok & & tok - > varId ( ) = = 0U ) ; // It's possible to set a varId
}
void arrayMemberVar2 ( ) {
const char code [ ] = " struct Foo { \n "
" int x; \n "
" }; \n "
" void f() { \n "
" struct Foo foo[10][10]; \n "
" foo[1][2].x = 123; \n " // <- x should get a variable() pointer
" } " ;
Settings settings ;
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
const Token * tok = Token : : findmatch ( tokenizer . tokens ( ) , " . x " ) ;
2014-02-16 10:32:10 +01:00
tok = tok ? tok - > next ( ) : nullptr ;
2013-07-20 17:46:39 +02:00
ASSERT ( tok & & tok - > variable ( ) & & Token : : Match ( tok - > variable ( ) - > typeStartToken ( ) , " int x ; " ) ) ;
ASSERT ( tok & & tok - > varId ( ) = = 0U ) ; // It's possible to set a varId
}
void arrayMemberVar3 ( ) {
const char code [ ] = " struct Foo { \n "
" int x; \n "
" }; \n "
" void f() { \n "
" struct Foo foo[10]; \n "
" (foo[1]).x = 123; \n " // <- x should get a variable() pointer
" } " ;
Settings settings ;
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
const Token * tok = Token : : findmatch ( tokenizer . tokens ( ) , " . x " ) ;
2014-02-16 10:32:10 +01:00
tok = tok ? tok - > next ( ) : nullptr ;
2013-07-20 17:46:39 +02:00
ASSERT ( tok & & tok - > variable ( ) & & Token : : Match ( tok - > variable ( ) - > typeStartToken ( ) , " int x ; " ) ) ;
ASSERT ( tok & & tok - > varId ( ) = = 0U ) ; // It's possible to set a varId
}
2012-05-15 21:03:43 +02:00
void staticMemberVar ( ) {
GET_SYMBOL_DB ( " class Foo { \n "
" static const double d; \n "
" }; \n "
" const double Foo::d = 5.0; " ) ;
const Variable * v = db - > getVariableFromVarId ( 1 ) ;
ASSERT ( v & & db - > getVariableListSize ( ) = = 2 ) ;
ASSERT ( v & & v - > isStatic ( ) & & v - > isConst ( ) & & v - > isPrivate ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void hasRegularFunction ( ) {
2011-01-28 08:33:02 +01:00
GET_SYMBOL_DB ( " void func() { } \n " )
// 2 scopes: Global and Function
2012-09-11 18:03:47 +02:00
ASSERT ( db & & db - > scopeList . size ( ) = = 2 ) ;
2011-01-28 08:33:02 +01:00
2011-10-13 20:53:06 +02:00
if ( db ) {
2013-01-28 06:47:48 +01:00
const Scope * scope = findFunctionScopeByToken ( db , tokenizer . tokens ( ) - > next ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( scope & & scope - > className = = " func " ) ;
2012-05-11 17:56:47 +02:00
ASSERT ( scope & & scope - > functionOf = = 0 ) ;
2011-01-28 08:33:02 +01:00
2013-01-28 06:47:48 +01:00
const Function * function = findFunctionByName ( " func " , & db - > scopeList . front ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( function & & function - > token - > str ( ) = = " func " ) ;
2011-11-20 15:09:57 +01:00
ASSERT ( function & & function - > token = = tokenizer . tokens ( ) - > next ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( function & & function - > hasBody ) ;
2012-05-24 17:40:43 +02:00
ASSERT ( function & & function - > functionScope = = scope & & scope - > function = = function & & function - > nestedIn ! = scope ) ;
2013-09-03 10:48:01 +02:00
ASSERT ( function & & function - > retDef = = tokenizer . tokens ( ) ) ;
2011-01-28 08:33:02 +01:00
}
}
2011-10-13 20:53:06 +02:00
void hasInlineClassFunction ( ) {
2011-01-28 08:33:02 +01:00
GET_SYMBOL_DB ( " class Fred { void func() { } }; \n " )
// 3 scopes: Global, Class, and Function
2012-09-11 18:03:47 +02:00
ASSERT ( db & & db - > scopeList . size ( ) = = 3 ) ;
2011-01-28 08:33:02 +01:00
2011-10-13 20:53:06 +02:00
if ( db ) {
2013-01-28 06:47:48 +01:00
const Scope * scope = findFunctionScopeByToken ( db , tokenizer . tokens ( ) - > tokAt ( 4 ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( scope & & scope - > className = = " func " ) ;
2012-05-11 17:56:47 +02:00
ASSERT ( scope & & scope - > functionOf & & scope - > functionOf = = db - > findScopeByName ( " Fred " ) ) ;
2011-01-28 08:33:02 +01:00
2013-01-28 06:47:48 +01:00
const Function * function = findFunctionByName ( " func " , & db - > scopeList . back ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( function & & function - > token - > str ( ) = = " func " ) ;
ASSERT ( function & & function - > token = = tokenizer . tokens ( ) - > tokAt ( 4 ) ) ;
ASSERT ( function & & function - > hasBody & & function - > isInline ) ;
2012-05-24 17:40:43 +02:00
ASSERT ( function & & function - > functionScope = = scope & & scope - > function = = function & & function - > nestedIn = = db - > findScopeByName ( " Fred " ) ) ;
2013-09-03 10:48:01 +02:00
ASSERT ( function & & function - > retDef = = tokenizer . tokens ( ) - > tokAt ( 3 ) ) ;
2013-03-14 17:00:22 +01:00
ASSERT ( db & & db - > findScopeByName ( " Fred " ) & & db - > findScopeByName ( " Fred " ) - > definedType - > getFunction ( " func " ) = = function ) ;
2011-01-28 08:33:02 +01:00
}
}
2011-10-13 20:53:06 +02:00
void hasMissingInlineClassFunction ( ) {
2011-01-28 08:33:02 +01:00
GET_SYMBOL_DB ( " class Fred { void func(); }; \n " )
// 2 scopes: Global and Class (no Function scope because there is no function implementation)
2012-09-11 18:03:47 +02:00
ASSERT ( db & & db - > scopeList . size ( ) = = 2 ) ;
2011-01-28 08:33:02 +01:00
2011-10-13 20:53:06 +02:00
if ( db ) {
2013-01-28 06:47:48 +01:00
const Scope * scope = findFunctionScopeByToken ( db , tokenizer . tokens ( ) - > tokAt ( 4 ) ) ;
2011-01-28 08:33:02 +01:00
2014-02-16 10:32:10 +01:00
ASSERT ( scope = = nullptr ) ;
2011-01-28 08:33:02 +01:00
2013-01-28 06:47:48 +01:00
const Function * function = findFunctionByName ( " func " , & db - > scopeList . back ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( function & & function - > token - > str ( ) = = " func " ) ;
ASSERT ( function & & function - > token = = tokenizer . tokens ( ) - > tokAt ( 4 ) ) ;
ASSERT ( function & & ! function - > hasBody ) ;
}
}
2011-10-13 20:53:06 +02:00
void hasClassFunction ( ) {
2011-01-28 08:33:02 +01:00
GET_SYMBOL_DB ( " class Fred { void func(); }; Fred::func() { } \n " )
// 3 scopes: Global, Class, and Function
2012-09-11 18:03:47 +02:00
ASSERT ( db & & db - > scopeList . size ( ) = = 3 ) ;
2011-01-28 08:33:02 +01:00
2011-10-13 20:53:06 +02:00
if ( db ) {
2013-01-28 06:47:48 +01:00
const Scope * scope = findFunctionScopeByToken ( db , tokenizer . tokens ( ) - > tokAt ( 12 ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( scope & & scope - > className = = " func " ) ;
2012-05-11 17:56:47 +02:00
ASSERT ( scope & & scope - > functionOf & & scope - > functionOf = = db - > findScopeByName ( " Fred " ) ) ;
2011-01-28 08:33:02 +01:00
2013-01-28 06:47:48 +01:00
const Function * function = findFunctionByName ( " func " , & db - > scopeList . back ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( function & & function - > token - > str ( ) = = " func " ) ;
ASSERT ( function & & function - > token = = tokenizer . tokens ( ) - > tokAt ( 12 ) ) ;
ASSERT ( function & & function - > hasBody & & ! function - > isInline ) ;
2012-05-24 17:40:43 +02:00
ASSERT ( function & & function - > functionScope = = scope & & scope - > function = = function & & function - > nestedIn = = db - > findScopeByName ( " Fred " ) ) ;
2011-01-28 08:33:02 +01:00
}
}
2011-10-13 20:53:06 +02:00
void hasRegularFunctionReturningFunctionPointer ( ) {
2011-01-28 08:33:02 +01:00
GET_SYMBOL_DB ( " void (*func(int f))(char) { } \n " )
// 2 scopes: Global and Function
2012-09-11 18:03:47 +02:00
ASSERT ( db & & db - > scopeList . size ( ) = = 2 ) ;
2011-01-28 08:33:02 +01:00
2011-10-13 20:53:06 +02:00
if ( db ) {
2013-01-28 06:47:48 +01:00
const Scope * scope = findFunctionScopeByToken ( db , tokenizer . tokens ( ) - > tokAt ( 3 ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( scope & & scope - > className = = " func " ) ;
2013-01-28 06:47:48 +01:00
const Function * function = findFunctionByName ( " func " , & db - > scopeList . front ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( function & & function - > token - > str ( ) = = " func " ) ;
ASSERT ( function & & function - > token = = tokenizer . tokens ( ) - > tokAt ( 3 ) ) ;
ASSERT ( function & & function - > hasBody & & function - > retFuncPtr ) ;
}
}
2011-10-13 20:53:06 +02:00
void hasInlineClassFunctionReturningFunctionPointer ( ) {
2011-01-28 08:33:02 +01:00
GET_SYMBOL_DB ( " class Fred { void (*func(int f))(char) { } }; \n " )
// 3 scopes: Global, Class, and Function
2012-09-11 18:03:47 +02:00
ASSERT ( db & & db - > scopeList . size ( ) = = 3 ) ;
2011-01-28 08:33:02 +01:00
2011-10-13 20:53:06 +02:00
if ( db ) {
2013-01-28 06:47:48 +01:00
const Scope * scope = findFunctionScopeByToken ( db , tokenizer . tokens ( ) - > tokAt ( 6 ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( scope & & scope - > className = = " func " ) ;
2013-01-28 06:47:48 +01:00
const Function * function = findFunctionByName ( " func " , & db - > scopeList . back ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( function & & function - > token - > str ( ) = = " func " ) ;
ASSERT ( function & & function - > token = = tokenizer . tokens ( ) - > tokAt ( 6 ) ) ;
ASSERT ( function & & function - > hasBody & & function - > isInline & & function - > retFuncPtr ) ;
}
}
2011-10-13 20:53:06 +02:00
void hasMissingInlineClassFunctionReturningFunctionPointer ( ) {
2011-01-28 08:33:02 +01:00
GET_SYMBOL_DB ( " class Fred { void (*func(int f))(char); }; \n " )
// 2 scopes: Global and Class (no Function scope because there is no function implementation)
2012-09-11 18:03:47 +02:00
ASSERT ( db & & db - > scopeList . size ( ) = = 2 ) ;
2011-01-28 08:33:02 +01:00
2011-10-13 20:53:06 +02:00
if ( db ) {
2013-01-28 06:47:48 +01:00
const Scope * scope = findFunctionScopeByToken ( db , tokenizer . tokens ( ) - > tokAt ( 6 ) ) ;
2011-01-28 08:33:02 +01:00
2014-02-16 10:32:10 +01:00
ASSERT ( scope = = nullptr ) ;
2011-01-28 08:33:02 +01:00
2013-01-28 06:47:48 +01:00
const Function * function = findFunctionByName ( " func " , & db - > scopeList . back ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( function & & function - > token - > str ( ) = = " func " ) ;
ASSERT ( function & & function - > token = = tokenizer . tokens ( ) - > tokAt ( 6 ) ) ;
ASSERT ( function & & ! function - > hasBody & & function - > retFuncPtr ) ;
}
}
2011-10-13 20:53:06 +02:00
void hasClassFunctionReturningFunctionPointer ( ) {
2011-01-28 08:33:02 +01:00
GET_SYMBOL_DB ( " class Fred { void (*func(int f))(char); }; void (*Fred::func(int f))(char) { } \n " )
// 3 scopes: Global, Class, and Function
2012-09-11 18:03:47 +02:00
ASSERT ( db & & db - > scopeList . size ( ) = = 3 ) ;
2011-01-28 08:33:02 +01:00
2011-10-13 20:53:06 +02:00
if ( db ) {
2013-01-28 06:47:48 +01:00
const Scope * scope = findFunctionScopeByToken ( db , tokenizer . tokens ( ) - > tokAt ( 23 ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( scope & & scope - > className = = " func " ) ;
2013-01-28 06:47:48 +01:00
const Function * function = findFunctionByName ( " func " , & db - > scopeList . back ( ) ) ;
2011-01-28 08:33:02 +01:00
ASSERT ( function & & function - > token - > str ( ) = = " func " ) ;
ASSERT ( function & & function - > token = = tokenizer . tokens ( ) - > tokAt ( 23 ) ) ;
ASSERT ( function & & function - > hasBody & & ! function - > isInline & & function - > retFuncPtr ) ;
}
}
2011-02-25 13:17:55 +01:00
2014-03-28 17:43:40 +01:00
void complexFunctionArrayPtr ( ) {
GET_SYMBOL_DB ( " int(*p1)[10]; \n " // pointer to array 10 of int
" void(*p2)(char); \n " // pointer to function (char) returning void
" int(*(*p3)(char))[10]; \n " // pointer to function (char) returning pointer to array 10 of int
" float(*(*p4)(char))(long); \n " // pointer to function (char) returning pointer to function (long) returning float
" short(*(*(p5) (char))(long))(double); \n " // pointer to function (char) returning pointer to function (long) returning pointer to function (double) returning short
" int(*a1[10])(void); \n " // array 10 of pointer to function (void) returning int
" float(*(*a2[10])(char))(long); \n " // array 10 of pointer to func (char) returning pointer to func (long) returning float
" short(*(*(*a3[10])(char))(long))(double); \n " // array 10 of pointer to function (char) returning pointer to function (long) returning pointer to function (double) returning short
" ::boost::rational(&r_)[9]; \n " // reference to array of ::boost::rational
" ::boost::rational<T>(&r_)[9]; " ) ; // reference to array of ::boost::rational<T> (template!)
ASSERT ( db ! = nullptr ) ;
if ( db ) {
ASSERT_EQUALS ( 10 , db - > getVariableListSize ( ) - 1 ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 1 ) ! = nullptr ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 2 ) ! = nullptr ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 3 ) ! = nullptr ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 4 ) ! = nullptr ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 5 ) ! = nullptr ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 6 ) ! = nullptr ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 7 ) ! = nullptr ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 8 ) ! = nullptr ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 9 ) ! = nullptr ) ;
ASSERT_EQUALS ( true , db - > getVariableFromVarId ( 10 ) ! = nullptr ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
}
2012-09-15 20:13:32 +02:00
void hasSubClassConstructor ( ) {
GET_SYMBOL_DB ( " class Foo { class Sub; }; class Foo::Sub { Sub() {} }; " ) ;
2014-02-16 11:47:52 +01:00
ASSERT ( db ! = nullptr ) ;
2012-09-15 20:13:32 +02:00
if ( db ) {
bool seen_something = false ;
for ( std : : list < Scope > : : const_iterator scope = db - > scopeList . begin ( ) ; scope ! = db - > scopeList . end ( ) ; + + scope ) {
for ( std : : list < Function > : : const_iterator func = scope - > functionList . begin ( ) ; func ! = scope - > functionList . end ( ) ; + + func ) {
ASSERT_EQUALS ( " Sub " , func - > token - > str ( ) ) ;
ASSERT_EQUALS ( true , func - > hasBody ) ;
ASSERT_EQUALS ( Function : : eConstructor , func - > type ) ;
seen_something = true ;
}
}
2012-11-30 06:03:58 +01:00
ASSERT_EQUALS ( true , seen_something ) ;
2012-09-15 20:13:32 +02:00
}
}
2013-04-04 19:53:55 +02:00
void testConstructors ( ) {
{
GET_SYMBOL_DB ( " class Foo { Foo(Foo f); }; " ) ;
const Function * ctor = tokenizer . tokens ( ) - > tokAt ( 3 ) - > function ( ) ;
ASSERT ( db & & ctor & & ctor - > type = = Function : : eConstructor & & ! ctor - > isExplicit ) ;
2013-09-03 10:48:01 +02:00
ASSERT ( ctor & & ctor - > retDef = = 0 ) ;
2013-04-04 19:53:55 +02:00
}
{
GET_SYMBOL_DB ( " class Foo { explicit Foo(Foo f); }; " ) ;
const Function * ctor = tokenizer . tokens ( ) - > tokAt ( 4 ) - > function ( ) ;
ASSERT ( db & & ctor & & ctor - > type = = Function : : eConstructor & & ctor - > isExplicit ) ;
2013-09-03 10:48:01 +02:00
ASSERT ( ctor & & ctor - > retDef = = 0 ) ;
2013-04-04 19:53:55 +02:00
}
{
GET_SYMBOL_DB ( " class Foo { Foo(Foo& f); }; " ) ;
const Function * ctor = tokenizer . tokens ( ) - > tokAt ( 3 ) - > function ( ) ;
ASSERT ( db & & ctor & & ctor - > type = = Function : : eCopyConstructor ) ;
2013-09-03 10:48:01 +02:00
ASSERT ( ctor & & ctor - > retDef = = 0 ) ;
2013-04-04 19:53:55 +02:00
}
{
GET_SYMBOL_DB ( " class Foo { Foo(Foo&& f); }; " ) ;
const Function * ctor = tokenizer . tokens ( ) - > tokAt ( 3 ) - > function ( ) ;
ASSERT ( db & & ctor & & ctor - > type = = Function : : eMoveConstructor ) ;
2013-09-03 10:48:01 +02:00
ASSERT ( ctor & & ctor - > retDef = = 0 ) ;
2013-04-04 19:53:55 +02:00
}
}
2012-08-22 12:37:50 +02:00
void functionDeclarationTemplate ( ) {
GET_SYMBOL_DB ( " std::map<int, string> foo() {} " )
// 2 scopes: Global and Function
2013-01-28 06:47:48 +01:00
ASSERT ( db & & db - > scopeList . size ( ) = = 2 & & findFunctionByName ( " foo " , & db - > scopeList . back ( ) ) ) ;
2012-08-22 12:37:50 +02:00
if ( db ) {
const Scope * scope = & db - > scopeList . front ( ) ;
ASSERT ( scope & & scope - > functionList . size ( ) = = 1 ) ;
const Function * foo = & scope - > functionList . front ( ) ;
ASSERT ( foo & & foo - > token - > str ( ) = = " foo " ) ;
ASSERT ( foo & & foo - > hasBody ) ;
}
}
2012-03-23 17:59:51 +01:00
void functionDeclarations ( ) {
GET_SYMBOL_DB ( " void foo(); \n void foo(); \n int foo(int i); \n void foo() {} " )
2012-08-22 12:37:50 +02:00
// 2 scopes: Global and Function
2013-01-28 06:47:48 +01:00
ASSERT ( db & & db - > scopeList . size ( ) = = 2 & & findFunctionByName ( " foo " , & db - > scopeList . back ( ) ) ) ;
2012-03-23 17:59:51 +01:00
if ( db ) {
const Scope * scope = & db - > scopeList . front ( ) ;
ASSERT ( scope & & scope - > functionList . size ( ) = = 2 ) ;
const Function * foo = & scope - > functionList . front ( ) ;
const Function * foo_int = & scope - > functionList . back ( ) ;
ASSERT ( foo & & foo - > token - > str ( ) = = " foo " ) ;
ASSERT ( foo & & foo - > hasBody ) ;
ASSERT ( foo & & foo - > token - > strAt ( 2 ) = = " ) " ) ;
ASSERT ( foo_int & & ! foo_int - > token ) ;
ASSERT ( foo_int & & foo_int - > tokenDef - > str ( ) = = " foo " ) ;
ASSERT ( foo_int & & ! foo_int - > hasBody ) ;
ASSERT ( foo_int & & foo_int - > tokenDef - > strAt ( 2 ) = = " int " ) ;
2013-04-04 18:47:44 +02:00
ASSERT ( & foo_int - > argumentList . front ( ) = = db - > getVariableFromVarId ( 1 ) ) ;
2012-03-23 17:59:51 +01:00
}
}
2014-03-30 11:06:44 +02:00
void memberFunctionOfUnknownClassMacro ( ) {
GET_SYMBOL_DB ( " class ScVbaFormatCondition { OUString getServiceImplName() SAL_OVERRIDE; }; \n "
" void ScVbaValidation::getFormula1() { \n "
" sal_uInt16 nFlags = 0; \n "
" if (pDocSh && !getCellRangesForAddress(nFlags)) ; \n "
" } " ) ;
ASSERT ( db & & errout . str ( ) = = " " ) ;
if ( db ) {
const Scope * scope = db - > findScopeByName ( " getFormula1 " ) ;
ASSERT ( scope ! = nullptr ) ;
ASSERT ( scope & & scope - > nestedIn = = & db - > scopeList . front ( ) ) ;
}
}
2012-02-24 20:45:56 +01:00
void classWithFriend ( ) {
GET_SYMBOL_DB ( " class Foo {}; class Bar1 { friend class Foo; }; class Bar2 { friend Foo; }; " )
// 3 scopes: Global, 3 classes
ASSERT ( db & & db - > scopeList . size ( ) = = 4 ) ;
if ( db ) {
const Scope * foo = db - > findScopeByName ( " Foo " ) ;
2014-02-16 11:47:52 +01:00
ASSERT ( foo ! = nullptr ) ;
2012-02-24 20:45:56 +01:00
const Scope * bar1 = db - > findScopeByName ( " Bar1 " ) ;
2014-02-16 11:47:52 +01:00
ASSERT ( bar1 ! = nullptr ) ;
2012-02-24 20:45:56 +01:00
const Scope * bar2 = db - > findScopeByName ( " Bar2 " ) ;
2014-02-16 11:47:52 +01:00
ASSERT ( bar2 ! = nullptr ) ;
2012-02-24 20:45:56 +01:00
if ( foo & & bar1 & & bar2 ) {
2013-03-05 15:46:34 +01:00
ASSERT ( bar1 - > definedType - > friendList . size ( ) = = 1 & & bar1 - > definedType - > friendList . front ( ) . name = = " Foo " & & bar1 - > definedType - > friendList . front ( ) . type = = foo - > definedType ) ;
ASSERT ( bar2 - > definedType - > friendList . size ( ) = = 1 & & bar2 - > definedType - > friendList . front ( ) . name = = " Foo " & & bar2 - > definedType - > friendList . front ( ) . type = = foo - > definedType ) ;
2012-02-24 20:45:56 +01:00
}
}
}
2011-11-05 12:23:05 +01:00
void parseFunctionCorrect ( ) {
// ticket 3188 - "if" statement parsed as function
GET_SYMBOL_DB ( " void func(i) int i; { if (i == 1) return; } \n " )
2014-02-16 10:32:10 +01:00
ASSERT ( db ! = nullptr ) ;
2011-11-05 12:23:05 +01:00
// 3 scopes: Global, function, if
ASSERT_EQUALS ( 3 , db - > scopeList . size ( ) ) ;
2014-02-16 10:32:10 +01:00
ASSERT ( findFunctionByName ( " func " , & db - > scopeList . back ( ) ) ! = nullptr ) ;
ASSERT ( findFunctionByName ( " if " , & db - > scopeList . back ( ) ) = = nullptr ) ;
2011-11-05 12:23:05 +01:00
}
2012-05-22 21:30:10 +02:00
void parseFunctionDeclarationCorrect ( ) {
GET_SYMBOL_DB ( " void func(); \n "
" int bar() {} \n "
" void func() {} " )
2012-05-22 21:58:46 +02:00
ASSERT_EQUALS ( 3 , db - > findScopeByName ( " func " ) - > classStart - > linenr ( ) ) ;
2012-05-22 21:30:10 +02:00
}
2012-07-10 15:15:11 +02:00
void Cpp11InitInInitList ( ) {
GET_SYMBOL_DB ( " class Foo { \n "
" std::vector<std::string> bar; \n "
" Foo() : bar({ \" a \" , \" b \" }) \n "
" {} \n "
" }; " ) ;
ASSERT_EQUALS ( 4 , db - > scopeList . front ( ) . nestedList . front ( ) - > nestedList . front ( ) - > classStart - > linenr ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void hasGlobalVariables1 ( ) {
2011-02-25 13:17:55 +01:00
GET_SYMBOL_DB ( " int i; \n " )
ASSERT ( db & & db - > scopeList . size ( ) = = 1 ) ;
2011-10-13 20:53:06 +02:00
if ( db & & db - > scopeList . size ( ) = = 1 ) {
2011-03-11 01:43:29 +01:00
std : : list < Scope > : : const_iterator it = db - > scopeList . begin ( ) ;
ASSERT ( it - > varlist . size ( ) = = 1 ) ;
2011-10-13 20:53:06 +02:00
if ( it - > varlist . size ( ) = = 1 ) {
2011-03-11 01:43:29 +01:00
std : : list < Variable > : : const_iterator var = it - > varlist . begin ( ) ;
2011-02-25 13:17:55 +01:00
ASSERT ( var - > name ( ) = = " i " ) ;
ASSERT ( var - > typeStartToken ( ) - > str ( ) = = " int " ) ;
}
}
}
2011-10-13 20:53:06 +02:00
void hasGlobalVariables2 ( ) {
2011-02-25 13:17:55 +01:00
GET_SYMBOL_DB ( " int array[2][2]; \n " )
ASSERT ( db & & db - > scopeList . size ( ) = = 1 ) ;
2011-10-13 20:53:06 +02:00
if ( db & & db - > scopeList . size ( ) = = 1 ) {
2011-03-11 01:43:29 +01:00
std : : list < Scope > : : const_iterator it = db - > scopeList . begin ( ) ;
ASSERT ( it - > varlist . size ( ) = = 1 ) ;
2011-10-13 20:53:06 +02:00
if ( it - > varlist . size ( ) = = 1 ) {
2011-03-11 01:43:29 +01:00
std : : list < Variable > : : const_iterator var = it - > varlist . begin ( ) ;
2011-02-25 13:17:55 +01:00
ASSERT ( var - > name ( ) = = " array " ) ;
ASSERT ( var - > typeStartToken ( ) - > str ( ) = = " int " ) ;
}
}
}
2011-10-13 20:53:06 +02:00
void hasGlobalVariables3 ( ) {
2011-02-25 13:17:55 +01:00
GET_SYMBOL_DB ( " int array[2][2] = { { 0, 0 }, { 0, 0 } }; \n " )
ASSERT ( db & & db - > scopeList . size ( ) = = 1 ) ;
2011-10-13 20:53:06 +02:00
if ( db & & db - > scopeList . size ( ) = = 1 ) {
2011-03-11 01:43:29 +01:00
std : : list < Scope > : : const_iterator it = db - > scopeList . begin ( ) ;
ASSERT ( it - > varlist . size ( ) = = 1 ) ;
2011-10-13 20:53:06 +02:00
if ( it - > varlist . size ( ) = = 1 ) {
2011-03-11 01:43:29 +01:00
std : : list < Variable > : : const_iterator var = it - > varlist . begin ( ) ;
2011-02-25 13:17:55 +01:00
ASSERT ( var - > name ( ) = = " array " ) ;
ASSERT ( var - > typeStartToken ( ) - > str ( ) = = " int " ) ;
}
}
}
2011-04-29 02:53:31 +02:00
2013-09-28 11:44:26 +02:00
void checkTypeStartEndToken1 ( ) {
2012-06-08 18:05:02 +02:00
GET_SYMBOL_DB ( " static std::string i; \n "
" static const std::string j; \n "
" const std::string* k; \n "
" const char m[]; \n "
" void f(const char* const l;) {} " ) ;
ASSERT ( db & & db - > getVariableListSize ( ) = = 6 & & db - > getVariableFromVarId ( 1 ) & & db - > getVariableFromVarId ( 2 ) & & db - > getVariableFromVarId ( 3 ) & & db - > getVariableFromVarId ( 4 ) & & db - > getVariableFromVarId ( 5 ) ) ;
if ( db & & db - > getVariableFromVarId ( 1 ) & & db - > getVariableFromVarId ( 2 ) & & db - > getVariableFromVarId ( 3 ) & & db - > getVariableFromVarId ( 4 ) & & db - > getVariableFromVarId ( 5 ) ) {
ASSERT_EQUALS ( " std " , db - > getVariableFromVarId ( 1 ) - > typeStartToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( " std " , db - > getVariableFromVarId ( 2 ) - > typeStartToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( " std " , db - > getVariableFromVarId ( 3 ) - > typeStartToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( " char " , db - > getVariableFromVarId ( 4 ) - > typeStartToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( " char " , db - > getVariableFromVarId ( 5 ) - > typeStartToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( " string " , db - > getVariableFromVarId ( 1 ) - > typeEndToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( " string " , db - > getVariableFromVarId ( 2 ) - > typeEndToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( " * " , db - > getVariableFromVarId ( 3 ) - > typeEndToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( " char " , db - > getVariableFromVarId ( 4 ) - > typeEndToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( " * " , db - > getVariableFromVarId ( 5 ) - > typeEndToken ( ) - > str ( ) ) ;
}
}
2013-09-28 11:44:26 +02:00
void checkTypeStartEndToken2 ( ) {
GET_SYMBOL_DB ( " class CodeGenerator { \n "
" DiagnosticsEngine Diags; \n "
" public: \n "
" void Initialize() { \n "
" Builder.reset(Diags); \n "
" } \n "
" \n "
" void HandleTagDeclRequiredDefinition() LLVM_OVERRIDE { \n "
" if (Diags.hasErrorOccurred()) \n "
" return; \n "
" } \n "
" }; " ) ;
ASSERT_EQUALS ( " DiagnosticsEngine " , db - > getVariableFromVarId ( 1 ) - > typeStartToken ( ) - > str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void check ( const char code [ ] , bool debug = true ) {
2011-04-29 02:53:31 +02:00
// Clear the error log
errout . str ( " " ) ;
// Check..
Settings settings ;
2011-09-29 04:05:26 +02:00
settings . debugwarnings = debug ;
2011-04-29 02:53:31 +02:00
// Tokenize..
Tokenizer tokenizer ( & settings , this ) ;
std : : istringstream istr ( code ) ;
tokenizer . tokenize ( istr , " test.cpp " ) ;
2013-12-30 17:45:28 +01:00
tokenizer . simplifyTokenList2 ( ) ;
2011-04-29 02:53:31 +02:00
// force symbol database creation
tokenizer . getSymbolDatabase ( ) ;
}
2011-10-13 20:53:06 +02:00
void functionArgs1 ( ) {
2012-05-11 17:56:47 +02:00
{
GET_SYMBOL_DB ( " void f(std::vector<std::string>, const std::vector<int> & v) { } " ) ;
2012-05-13 07:55:35 +02:00
ASSERT_EQUALS ( 1 + 1 , db - > getVariableListSize ( ) ) ;
const Variable * v = db - > getVariableFromVarId ( 1 ) ;
2012-05-11 17:56:47 +02:00
ASSERT ( v & & v - > isReference ( ) & & v - > isConst ( ) & & v - > isArgument ( ) ) ;
const Scope * f = db - > findScopeByName ( " f " ) ;
ASSERT ( f & & f - > type = = Scope : : eFunction & & f - > function ) ;
if ( f & & f - > function )
ASSERT ( f - > function - > argumentList . size ( ) = = 2 & & f - > function - > argumentList . front ( ) . index ( ) = = 0 & & f - > function - > argumentList . front ( ) . name ( ) = = " " & & f - > function - > argumentList . back ( ) . index ( ) = = 1 ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
{
GET_SYMBOL_DB ( " void g(std::map<std::string, std::vector<int> > m) { } " ) ;
ASSERT_EQUALS ( 1 + 1 , db - > getVariableListSize ( ) ) ;
const Variable * m = db - > getVariableFromVarId ( 1 ) ;
ASSERT ( m & & ! m - > isReference ( ) & & ! m - > isConst ( ) & & m - > isArgument ( ) & & m - > isClass ( ) ) ;
const Scope * g = db - > findScopeByName ( " g " ) ;
ASSERT ( g & & g - > type = = Scope : : eFunction & & g - > function & & g - > function - > argumentList . size ( ) = = 1 & & g - > function - > argumentList . front ( ) . index ( ) = = 0 ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2012-09-06 20:02:53 +02:00
{
GET_SYMBOL_DB ( " void g(std::map<int, int> m = std::map<int, int>()) { } " ) ;
const Scope * g = db - > findScopeByName ( " g " ) ;
ASSERT ( g & & g - > type = = Scope : : eFunction & & g - > function & & g - > function - > argumentList . size ( ) = = 1 & & g - > function - > argumentList . front ( ) . index ( ) = = 0 & & g - > function - > initializedArgCount ( ) = = 1 ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2012-09-06 20:50:46 +02:00
{
GET_SYMBOL_DB ( " void g(int = 0) { } " ) ;
const Scope * g = db - > findScopeByName ( " g " ) ;
ASSERT ( g & & g - > type = = Scope : : eFunction & & g - > function & & g - > function - > argumentList . size ( ) = = 1 & & g - > function - > argumentList . front ( ) . hasDefault ( ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-04-29 02:53:31 +02:00
}
2011-04-29 03:03:57 +02:00
2011-10-13 20:53:06 +02:00
void functionArgs2 ( ) {
2011-08-28 19:32:42 +02:00
GET_SYMBOL_DB ( " void f(int a[][4]) { } " ) ;
const Variable * a = db - > getVariableFromVarId ( 1 ) ;
ASSERT_EQUALS ( " a " , a - > nameToken ( ) - > str ( ) ) ;
ASSERT_EQUALS ( 2UL , a - > dimensions ( ) . size ( ) ) ;
ASSERT_EQUALS ( 0UL , a - > dimension ( 0 ) ) ;
2012-09-10 16:23:00 +02:00
ASSERT_EQUALS ( false , a - > dimensions ( ) [ 0 ] . known ) ;
2011-08-28 19:32:42 +02:00
ASSERT_EQUALS ( 4UL , a - > dimension ( 1 ) ) ;
2012-09-10 16:23:00 +02:00
ASSERT_EQUALS ( true , a - > dimensions ( ) [ 1 ] . known ) ;
2011-08-28 19:32:42 +02:00
}
2012-05-22 10:29:33 +02:00
void functionArgs3 ( ) {
GET_SYMBOL_DB ( " void f(int i,) { } " ) ; // Don't crash
const Variable * a = db - > getVariableFromVarId ( 1 ) ;
ASSERT_EQUALS ( " i " , a - > nameToken ( ) - > str ( ) ) ;
}
2012-12-29 08:32:43 +01:00
void functionArgs4 ( ) {
GET_SYMBOL_DB ( " void f1(char [10], struct foo [10]); " ) ;
ASSERT_EQUALS ( true , db - > scopeList . front ( ) . functionList . size ( ) = = 1UL ) ;
const Function * func = & db - > scopeList . front ( ) . functionList . front ( ) ;
ASSERT_EQUALS ( true , func & & func - > argumentList . size ( ) = = 2UL ) ;
if ( func & & func - > argumentList . size ( ) = = 2UL ) {
const Variable * first = & func - > argumentList . front ( ) ;
ASSERT_EQUALS ( 0UL , first - > name ( ) . size ( ) ) ;
ASSERT_EQUALS ( 1UL , first - > dimensions ( ) . size ( ) ) ;
ASSERT_EQUALS ( 10UL , first - > dimension ( 0 ) ) ;
const Variable * second = & func - > argumentList . back ( ) ;
ASSERT_EQUALS ( 0UL , second - > name ( ) . size ( ) ) ;
ASSERT_EQUALS ( 1UL , second - > dimensions ( ) . size ( ) ) ;
ASSERT_EQUALS ( 10UL , second - > dimension ( 0 ) ) ;
}
}
2012-01-07 09:28:26 +01:00
void namespaces1 ( ) {
GET_SYMBOL_DB ( " namespace fred { \n "
" namespace barney { \n "
" class X { X(int); }; \n "
" } \n "
" } \n "
2013-03-20 15:36:16 +01:00
" namespace barney { X::X(int) { } } " ) ;
2012-01-07 09:28:26 +01:00
// Locate the scope for the class..
2014-02-16 10:32:10 +01:00
const Scope * scope = nullptr ;
2012-01-07 09:28:26 +01:00
for ( std : : list < Scope > : : const_iterator it = db - > scopeList . begin ( ) ; it ! = db - > scopeList . end ( ) ; + + it ) {
if ( it - > isClassOrStruct ( ) ) {
scope = & ( * it ) ;
break ;
}
}
2014-02-16 11:47:52 +01:00
ASSERT ( scope ! = nullptr ) ;
2012-01-21 10:08:09 +01:00
if ( ! scope )
return ;
2012-01-07 09:28:26 +01:00
ASSERT_EQUALS ( " X " , scope - > className ) ;
2012-01-07 09:37:38 +01:00
// The class has a constructor but the implementation _is not_ seen
2012-01-07 09:28:26 +01:00
ASSERT_EQUALS ( 1U , scope - > functionList . size ( ) ) ;
const Function * function = & ( scope - > functionList . front ( ) ) ;
ASSERT_EQUALS ( false , function - > hasBody ) ;
}
// based on namespaces1 but here the namespaces match
void namespaces2 ( ) {
GET_SYMBOL_DB ( " namespace fred { \n "
" namespace barney { \n "
" class X { X(int); }; \n "
" } \n "
" } \n "
" namespace fred { \n "
" namespace barney { \n "
" X::X(int) { } \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-01-07 09:28:26 +01:00
// Locate the scope for the class..
2014-02-16 10:32:10 +01:00
const Scope * scope = nullptr ;
2012-01-07 09:28:26 +01:00
for ( std : : list < Scope > : : const_iterator it = db - > scopeList . begin ( ) ; it ! = db - > scopeList . end ( ) ; + + it ) {
if ( it - > isClassOrStruct ( ) ) {
scope = & ( * it ) ;
break ;
}
}
2014-02-16 11:47:52 +01:00
ASSERT ( scope ! = nullptr ) ;
2012-01-21 10:08:09 +01:00
if ( ! scope )
return ;
2012-01-07 09:28:26 +01:00
ASSERT_EQUALS ( " X " , scope - > className ) ;
2012-01-07 09:37:38 +01:00
// The class has a constructor and the implementation _is_ seen
2012-01-07 09:28:26 +01:00
ASSERT_EQUALS ( 1U , scope - > functionList . size ( ) ) ;
const Function * function = & ( scope - > functionList . front ( ) ) ;
ASSERT_EQUALS ( " X " , function - > tokenDef - > str ( ) ) ;
ASSERT_EQUALS ( true , function - > hasBody ) ;
}
2012-09-05 19:46:44 +02:00
void namespaces3 ( ) { // #3854 - namespace with unknown macro
2012-06-05 06:37:55 +02:00
GET_SYMBOL_DB ( " namespace fred UNKNOWN_MACRO(default) { \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-06-05 06:37:55 +02:00
ASSERT_EQUALS ( 2U , db - > scopeList . size ( ) ) ;
ASSERT_EQUALS ( Scope : : eGlobal , db - > scopeList . front ( ) . type ) ;
ASSERT_EQUALS ( Scope : : eNamespace , db - > scopeList . back ( ) . type ) ;
}
2012-01-07 09:28:26 +01:00
2012-01-26 04:48:18 +01:00
void tryCatch1 ( ) {
const std : : string str ( " void foo() { \n "
" try { } \n "
" catch (const Error1 & x) { } \n "
" catch (const X::Error2 & x) { } \n "
" catch (Error3 x) { } \n "
" catch (X::Error4 x) { } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-01-26 04:48:18 +01:00
GET_SYMBOL_DB ( str . c_str ( ) )
check ( str . c_str ( ) , false ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
ASSERT ( db & & db - > getVariableListSize ( ) = = 5 ) ; // index 0 + 4 variables
ASSERT ( db & & db - > scopeList . size ( ) = = 7 ) ; // global + function + try + 4 catch
}
2011-10-13 20:53:06 +02:00
void symboldatabase1 ( ) {
2011-04-29 03:03:57 +02:00
check ( " namespace foo { \n "
" class bar; \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " class foo : public bar < int, int> { \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase2 ( ) {
2011-04-29 03:03:57 +02:00
check ( " class foo { \n "
" public slots : \n "
" foo() { } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " class foo { \n "
" class bar; \n "
" foo() { } \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase3 ( ) {
2011-04-29 03:03:57 +02:00
check ( " typedef void (func_type)(); \n "
" struct A { \n "
" friend func_type f : 2; \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase4 ( ) {
2011-04-29 03:03:57 +02:00
check ( " static void function_declaration_before(void) __attribute__((__used__)); \n "
" static void function_declaration_before(void) {} \n "
" static void function_declaration_after(void) {} \n "
" static void function_declaration_after(void) __attribute__((__used__)); \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-03-20 15:36:16 +01:00
check ( " main(int argc, char *argv[]) { } " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " namespace boost { \n "
" std::locale generate_locale() \n "
" { \n "
" return std::locale(); \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " namespace X { \n "
" static void function_declaration_before(void) __attribute__((__used__)); \n "
" static void function_declaration_before(void) {} \n "
" static void function_declaration_after(void) {} \n "
" static void function_declaration_after(void) __attribute__((__used__)); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " testing::testing() \n "
" { \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase5 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2178 - segmentation fault
check ( " int CL_INLINE_DECL(integer_decode_float) (int x) { \n "
" return (sign ? cl_I() : 0); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase6 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2221 - segmentation fault
check ( " template<int i> class X { }; \n "
" X< 1>2 > x1; \n "
" X<(1>2)> x2; \n "
" template<class T> class Y { }; \n "
" Y<X<1>> x3; \n "
" Y<X<6>>1>> x4; \n "
2011-09-29 04:05:26 +02:00
" Y<X<(6>>1)>> x5; \n " , false ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase7 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2230 - segmentation fault
check ( " template<template<class> class E,class D> class C : E<D> \n "
" { \n "
" public: \n "
" int f(); \n "
" }; \n "
" class E : C<D,int> \n "
" { \n "
" public: \n "
" int f() { return C< ::D,int>::f(); } \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2013-11-19 06:07:25 +01:00
ASSERT_EQUALS ( " [test.cpp:1]: (debug) simplifyTemplates: bailing out \n " , errout . str ( ) ) ;
2011-04-29 03:03:57 +02:00
}
2011-10-13 20:53:06 +02:00
void symboldatabase8 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2252 - segmentation fault
check ( " struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>, \n "
" PaletteColorSpaceHolder> \n "
" { \n "
" uno::Reference<rendering::XColorSpace> operator()() \n "
" { \n "
" return vcl::unotools::createStandardColorSpace(); \n "
" } \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase9 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2425 - segmentation fault
check ( " class CHyperlink : public CString \n "
" { \n "
" public: \n "
" const CHyperlink& operator=(LPCTSTR lpsz) { \n "
" CString::operator=(lpsz); \n "
" return *this; \n "
" } \n "
2011-09-29 04:05:26 +02:00
" }; \n " , false ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase10 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2537 - segmentation fault
check ( " class A { \n "
" private: \n "
" void f(); \n "
" }; \n "
" class B { \n "
" friend void A::f(); \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase11 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2539 - segmentation fault
check ( " int g (); \n "
" struct S { \n "
" int i : (false ? g () : 1); \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase12 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2547 - segmentation fault
check ( " class foo { \n "
" void bar2 () = __null; \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase13 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2577 - segmentation fault
check ( " class foo { \n "
" void bar2 () = A::f; \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase14 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2589 - segmentation fault
2014-03-27 19:06:13 +01:00
ASSERT_THROW ( check ( " struct B : A \n " ) , InternalError ) ;
2011-04-29 03:03:57 +02:00
}
2011-10-13 20:53:06 +02:00
void symboldatabase15 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2591 - segmentation fault
2014-03-27 19:06:13 +01:00
ASSERT_THROW ( check ( " struct A : \n " ) , InternalError ) ;
2011-04-29 03:03:57 +02:00
}
2011-10-13 20:53:06 +02:00
void symboldatabase16 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2637 - segmentation fault
check ( " {} const const \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase17 ( ) {
2011-04-29 03:03:57 +02:00
// ticket #2657 - segmentation fault
2013-03-20 15:36:16 +01:00
check ( " return f(){} " ) ;
2011-04-29 03:03:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase18 ( ) {
2011-06-27 13:31:10 +02:00
// ticket #2865 - segmentation fault
check ( " char a[1] \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase19 ( ) {
2011-08-11 23:57:54 +02:00
// ticket #2991 - segmentation fault
2013-03-20 15:36:16 +01:00
check ( " ::y(){x} " ) ;
2011-08-11 23:57:54 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void symboldatabase20 ( ) {
2011-08-17 01:16:58 +02:00
// ticket #3013 - segmentation fault
2014-03-27 19:06:13 +01:00
ASSERT_THROW ( check ( " struct x : virtual y \n " ) , InternalError ) ;
2011-08-17 01:16:58 +02:00
}
2011-10-13 20:53:06 +02:00
void symboldatabase21 ( ) {
2011-09-29 04:05:26 +02:00
check ( " class Fred { \n "
" class Foo { }; \n "
" void func() const; \n "
" }; \n "
" Fred::func() const { \n "
" Foo foo; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-09-29 04:05:26 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-12-22 09:20:37 +01:00
// #ticket 3437 (segmentation fault)
void symboldatabase22 ( ) {
check ( " template <class C> struct A {}; \n "
" A<int> a; \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-12-25 11:05:06 +01:00
// #ticket 3435 (std::vector)
void symboldatabase23 ( ) {
2013-03-20 15:36:16 +01:00
GET_SYMBOL_DB ( " class A { std::vector<int*> ints; }; " ) ;
2011-12-25 11:05:06 +01:00
ASSERT_EQUALS ( 2U , db - > scopeList . size ( ) ) ;
const Scope & scope = db - > scopeList . back ( ) ;
ASSERT_EQUALS ( 1U , scope . varlist . size ( ) ) ;
const Variable & var = scope . varlist . front ( ) ;
ASSERT_EQUALS ( std : : string ( " ints " ) , var . name ( ) ) ;
ASSERT_EQUALS ( true , var . isClass ( ) ) ;
}
2012-01-22 19:34:53 +01:00
// #ticket 3508 (constructor, destructor)
void symboldatabase24 ( ) {
GET_SYMBOL_DB ( " struct Fred { \n "
" ~Fred(); \n "
" Fred(); \n "
" }; \n "
" Fred::Fred() { } \n "
" Fred::~Fred() { } " ) ;
// Global scope, Fred, Fred::Fred, Fred::~Fred
ASSERT_EQUALS ( 4U , db - > scopeList . size ( ) ) ;
// Find the scope for the Fred struct..
2014-02-16 10:32:10 +01:00
const Scope * fredScope = nullptr ;
2012-01-22 19:34:53 +01:00
for ( std : : list < Scope > : : const_iterator scope = db - > scopeList . begin ( ) ; scope ! = db - > scopeList . end ( ) ; + + scope ) {
if ( scope - > isClassOrStruct ( ) & & scope - > className = = " Fred " )
fredScope = & ( * scope ) ;
}
2014-02-16 10:32:10 +01:00
ASSERT ( fredScope ! = nullptr ) ;
if ( fredScope = = nullptr )
2012-01-22 19:34:53 +01:00
return ;
// The struct Fred has two functions, a constructor and a destructor
ASSERT_EQUALS ( 2U , fredScope - > functionList . size ( ) ) ;
// Get linenumbers where the bodies for the constructor and destructor are..
unsigned int constructor = 0 ;
unsigned int destructor = 0 ;
for ( std : : list < Function > : : const_iterator it = fredScope - > functionList . begin ( ) ; it ! = fredScope - > functionList . end ( ) ; + + it ) {
if ( it - > type = = Function : : eConstructor )
constructor = it - > token - > linenr ( ) ; // line number for constructor body
if ( it - > type = = Function : : eDestructor )
destructor = it - > token - > linenr ( ) ; // line number for destructor body
}
// The body for the constructor is located at line 5..
ASSERT_EQUALS ( 5U , constructor ) ;
// The body for the destructor is located at line 6..
ASSERT_EQUALS ( 6U , destructor ) ;
}
2012-01-28 01:24:01 +01:00
// #ticket #3561 (throw C++)
void symboldatabase25 ( ) {
const std : : string str ( " int main() { \n "
" foo bar; \n "
" throw bar; \n "
" } " ) ;
GET_SYMBOL_DB ( str . c_str ( ) ) ;
check ( str . c_str ( ) , false ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
ASSERT ( db & & db - > getVariableListSize ( ) = = 2 ) ; // index 0 + 1 variable
}
// #ticket #3561 (throw C)
void symboldatabase26 ( ) {
const std : : string str ( " int main() { \n "
" throw bar; \n "
" } " ) ;
GET_SYMBOL_DB_C ( str . c_str ( ) ) ;
check ( str . c_str ( ) , false ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
ASSERT ( db & & db - > getVariableListSize ( ) = = 2 ) ; // index 0 + 1 variable
}
2011-12-25 11:05:06 +01:00
2012-01-31 19:34:55 +01:00
// #ticket #3543 (segmentation fault)
void symboldatabase27 ( ) {
check ( " class C : public B1 \n "
" { \n "
" B1() \n "
" {} C(int) : B1() class \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2012-01-31 19:34:55 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2012-04-27 21:51:13 +02:00
void symboldatabase28 ( ) {
GET_SYMBOL_DB ( " struct S {}; \n "
" void foo(struct S s) {} " ) ;
2013-03-05 13:33:38 +01:00
ASSERT ( db & & db - > getVariableFromVarId ( 1 ) & & db - > getVariableFromVarId ( 1 ) - > typeScope ( ) & & db - > getVariableFromVarId ( 1 ) - > typeScope ( ) - > className = = " S " ) ;
2012-04-27 21:51:13 +02:00
}
2012-12-28 08:36:20 +01:00
// #ticket #4442 (segmentation fault)
void symboldatabase29 ( ) {
check ( " struct B : A { \n "
" B() : A {} \n "
" }; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2013-01-27 02:46:00 +01:00
void symboldatabase30 ( ) {
GET_SYMBOL_DB ( " struct A { void foo(const int a); }; \n "
" void A::foo(int a) { } " ) ;
ASSERT ( db & & db - > functionScopes . size ( ) = = 1 & & db - > functionScopes [ 0 ] - > functionOf ) ;
}
2013-03-05 13:33:38 +01:00
void symboldatabase31 ( ) {
GET_SYMBOL_DB ( " class Foo; \n "
" class Bar; \n "
" class Sub; \n "
" class Foo { class Sub; }; \n "
" class Bar { class Sub; }; \n "
" class Bar::Sub { \n "
" int b; \n "
" public: \n "
" Sub() { } \n "
" Sub(int); \n "
" }; \n "
" Bar::Sub::Sub(int) { }; \n "
" class ::Foo::Sub { \n "
" int f; \n "
" public: \n "
" ~Sub(); \n "
" Sub(); \n "
" }; \n "
" ::Foo::Sub::~Sub() { } \n "
" ::Foo::Sub::Sub() { } \n "
" class Foo; \n "
" class Bar; \n "
" class Sub; \n " ) ;
ASSERT ( db & & db - > typeList . size ( ) = = 5 ) ;
ASSERT ( db & & db - > isClassOrStruct ( " Foo " ) ) ;
ASSERT ( db & & db - > isClassOrStruct ( " Bar " ) ) ;
ASSERT ( db & & db - > isClassOrStruct ( " Sub " ) ) ;
if ( ! db | | db - > typeList . size ( ) < 5 )
return ;
std : : list < Type > : : const_iterator i = db - > typeList . begin ( ) ;
const Type * Foo = & ( * i + + ) ;
const Type * Bar = & ( * i + + ) ;
const Type * Sub = & ( * i + + ) ;
const Type * Foo_Sub = & ( * i + + ) ;
const Type * Bar_Sub = & ( * i ) ;
ASSERT ( Foo & & Foo - > classDef & & Foo - > classScope & & Foo - > enclosingScope & & Foo - > name ( ) = = " Foo " ) ;
ASSERT ( Bar & & Bar - > classDef & & Bar - > classScope & & Bar - > enclosingScope & & Bar - > name ( ) = = " Bar " ) ;
ASSERT ( Sub & & Sub - > classDef & & ! Sub - > classScope & & Sub - > enclosingScope & & Sub - > name ( ) = = " Sub " ) ;
ASSERT ( Foo_Sub & & Foo_Sub - > classDef & & Foo_Sub - > classScope & & Foo_Sub - > enclosingScope = = Foo - > classScope & & Foo_Sub - > name ( ) = = " Sub " ) ;
ASSERT ( Bar_Sub & & Bar_Sub - > classDef & & Bar_Sub - > classScope & & Bar_Sub - > enclosingScope = = Bar - > classScope & & Bar_Sub - > name ( ) = = " Sub " ) ;
ASSERT ( Foo_Sub & & Foo_Sub - > classScope & & Foo_Sub - > classScope - > numConstructors = = 1 & & Foo_Sub - > classScope - > className = = " Sub " ) ;
ASSERT ( Bar_Sub & & Bar_Sub - > classScope & & Bar_Sub - > classScope - > numConstructors = = 2 & & Bar_Sub - > classScope - > className = = " Sub " ) ;
}
2013-03-14 17:00:22 +01:00
void symboldatabase32 ( ) {
GET_SYMBOL_DB ( " struct Base { \n "
" void foo() {} \n "
" }; \n "
" class Deri : Base { \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Deri " ) & & db - > findScopeByName ( " Deri " ) - > definedType - > getFunction ( " foo " ) ) ;
}
2013-03-28 06:36:49 +01:00
void symboldatabase33 ( ) { // ticket #4682
GET_SYMBOL_DB ( " static struct A::B s; \n "
" static struct A::B t = { 0 }; \n "
" static struct A::B u(0); \n "
" static struct A::B v{0}; \n "
" static struct A::B w({0}); \n "
" void foo() { } " ) ;
ASSERT ( db & & db - > functionScopes . size ( ) = = 1 ) ;
}
2013-05-30 15:13:09 +02:00
void symboldatabase34 ( ) { // ticket #4694
check ( " typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int; \n "
2013-06-09 16:04:59 +02:00
" typedef _Atomic(int)&atomic_int_ref; \n "
" struct S { \n "
" _Atomic union { int n; }; \n "
" }; " ) ;
2013-05-30 15:13:09 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2013-06-16 21:46:01 +02:00
void symboldatabase35 ( ) { // ticket #4806 and #4841
check ( " class FragmentQueue : public CL_NS(util)::PriorityQueue<CL_NS(util)::Deletor::Object<TextFragment> > \n "
" {}; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2013-07-08 11:45:26 +02:00
void symboldatabase36 ( ) { // ticket #4892
check ( " void struct ( ) { if ( 1 ) } int main ( ) { } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2013-08-12 06:21:03 +02:00
void symboldatabase37 ( ) {
GET_SYMBOL_DB ( " class Fred { \n "
" public: \n "
2013-08-16 05:42:12 +02:00
" struct Wilma { }; \n "
2013-08-12 06:21:03 +02:00
" struct Barney { \n "
" bool operator == (const struct Barney & b) const { return true; } \n "
2013-08-16 05:42:12 +02:00
" bool operator == (const struct Wilma & w) const { return true; } \n "
2013-08-12 06:21:03 +02:00
" }; \n "
" Fred(const struct Barney & b) { barney = b; } \n "
" private: \n "
" struct Barney barney; \n "
" }; \n " ) ;
2013-08-16 05:42:12 +02:00
ASSERT ( db & & db - > typeList . size ( ) = = 3 ) ;
2013-08-12 06:21:03 +02:00
ASSERT ( db & & db - > isClassOrStruct ( " Fred " ) ) ;
2013-08-16 05:42:12 +02:00
ASSERT ( db & & db - > isClassOrStruct ( " Wilma " ) ) ;
2013-08-12 06:21:03 +02:00
ASSERT ( db & & db - > isClassOrStruct ( " Barney " ) ) ;
2013-08-16 05:42:12 +02:00
if ( ! db | | db - > typeList . size ( ) ! = 3 )
2013-08-12 06:21:03 +02:00
return ;
std : : list < Type > : : const_iterator i = db - > typeList . begin ( ) ;
const Type * Fred = & ( * i + + ) ;
2013-08-16 05:42:12 +02:00
const Type * Wilma = & ( * i + + ) ;
2013-08-12 06:21:03 +02:00
const Type * Barney = & ( * i + + ) ;
ASSERT ( Fred & & Fred - > classDef & & Fred - > classScope & & Fred - > enclosingScope & & Fred - > name ( ) = = " Fred " ) ;
2013-08-16 05:42:12 +02:00
ASSERT ( Wilma & & Wilma - > classDef & & Wilma - > classScope & & Wilma - > enclosingScope & & Wilma - > name ( ) = = " Wilma " ) ;
2013-08-12 06:21:03 +02:00
ASSERT ( Barney & & Barney - > classDef & & Barney - > classScope & & Barney - > enclosingScope & & Barney - > name ( ) = = " Barney " ) ;
2014-01-17 18:10:10 +01:00
ASSERT ( db - > getVariableListSize ( ) = = 5 ) ;
if ( db - > getVariableListSize ( ) ! = 5 )
2013-08-12 06:21:03 +02:00
return ;
2014-01-17 18:10:10 +01:00
ASSERT ( db - > getVariableFromVarId ( 1 ) & & db - > getVariableFromVarId ( 1 ) - > type ( ) & & db - > getVariableFromVarId ( 1 ) - > type ( ) - > name ( ) = = " Barney " ) ;
ASSERT ( db - > getVariableFromVarId ( 2 ) & & db - > getVariableFromVarId ( 2 ) - > type ( ) & & db - > getVariableFromVarId ( 2 ) - > type ( ) - > name ( ) = = " Wilma " ) ;
ASSERT ( db - > getVariableFromVarId ( 3 ) & & db - > getVariableFromVarId ( 3 ) - > type ( ) & & db - > getVariableFromVarId ( 3 ) - > type ( ) - > name ( ) = = " Barney " ) ;
2013-08-12 06:21:03 +02:00
}
2013-10-29 21:41:47 +01:00
void symboldatabase38 ( ) { // ticket #5125
check ( " template <typename T = class service> struct scoped_service; \n "
" struct service {}; \n "
" template <> struct scoped_service<service> {}; \n "
" template <typename T> \n "
" struct scoped_service : scoped_service<service> \n "
" { \n "
" scoped_service( T* ptr ) : scoped_service<service>(ptr), m_ptr(ptr) {} \n "
" T* const m_ptr; \n "
" }; " ) ;
}
2013-10-30 10:15:03 +01:00
void symboldatabase39 ( ) { // ticket #5120
check ( " struct V : { public case {} ; struct U : U void { V *f (int x) (x) } } " ) ;
}
2013-11-08 12:56:32 +01:00
void symboldatabase40 ( ) { // ticket #5153
check ( " void f() { \n "
" try { } \n "
" catch (std::bad_alloc) { } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2013-11-25 03:43:39 +01:00
void symboldatabase41 ( ) { // ticket #5197 (unknown macro)
GET_SYMBOL_DB ( " struct X1 { MACRO1 f(int spd) MACRO2; }; \n " ) ;
ASSERT ( db & & db - > findScopeByName ( " X1 " ) & & db - > findScopeByName ( " X1 " ) - > functionList . size ( ) = = 1 & & ! db - > findScopeByName ( " X1 " ) - > functionList . front ( ) . hasBody ) ;
}
2013-12-31 17:51:56 +01:00
void symboldatabase42 ( ) { // only put variables in variable list
GET_SYMBOL_DB ( " void f() { extern int x(); } \n " ) ;
2014-01-08 12:26:48 +01:00
ASSERT ( ! ! db ) ;
2014-02-16 10:32:10 +01:00
const Scope * const fscope = db ? db - > findScopeByName ( " f " ) : nullptr ;
2014-01-08 12:26:48 +01:00
ASSERT ( ! ! fscope ) ;
2013-12-31 17:51:56 +01:00
ASSERT_EQUALS ( 0U , fscope ? fscope - > varlist . size ( ) : ~ 0U ) ; // "x" is not a variable
}
2012-04-17 19:50:44 +02:00
void isImplicitlyVirtual ( ) {
{
GET_SYMBOL_DB ( " class Base { \n "
" virtual void foo() {} \n "
" }; \n "
" class Deri : Base { \n "
" void foo() {} \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Deri " ) & & db - > findScopeByName ( " Deri " ) - > functionList . front ( ) . isImplicitlyVirtual ( ) ) ;
}
{
GET_SYMBOL_DB ( " class Base { \n "
" virtual void foo() {} \n "
" }; \n "
" class Deri1 : Base { \n "
" void foo() {} \n "
" }; \n "
" class Deri2 : Deri1 { \n "
" void foo() {} \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Deri2 " ) & & db - > findScopeByName ( " Deri2 " ) - > functionList . front ( ) . isImplicitlyVirtual ( ) ) ;
}
{
GET_SYMBOL_DB ( " class Base { \n "
" void foo() {} \n "
" }; \n "
" class Deri : Base { \n "
" void foo() {} \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Deri " ) & & ! db - > findScopeByName ( " Deri " ) - > functionList . front ( ) . isImplicitlyVirtual ( true ) ) ;
}
{
GET_SYMBOL_DB ( " class Base { \n "
" virtual void foo() {} \n "
" }; \n "
" class Deri : Base { \n "
" void foo(std::string& s) {} \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Deri " ) & & ! db - > findScopeByName ( " Deri " ) - > functionList . front ( ) . isImplicitlyVirtual ( true ) ) ;
}
{
GET_SYMBOL_DB ( " class Base { \n "
" virtual void foo() {} \n "
" }; \n "
" class Deri1 : Base { \n "
" void foo(int i) {} \n "
" }; \n "
" class Deri2 : Deri1 { \n "
" void foo() {} \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Deri2 " ) & & db - > findScopeByName ( " Deri2 " ) - > functionList . front ( ) . isImplicitlyVirtual ( ) ) ;
}
{
GET_SYMBOL_DB ( " class Base : Base2 { \n " // We don't know Base2
" void foo() {} \n "
" }; \n "
" class Deri : Base { \n "
" void foo() {} \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Deri " ) & & db - > findScopeByName ( " Deri " ) - > functionList . front ( ) . isImplicitlyVirtual ( true ) ) ; // Default true -> true
}
{
GET_SYMBOL_DB ( " class Base : Base2 { \n " // We don't know Base2
" void foo() {} \n "
" }; \n "
" class Deri : Base { \n "
" void foo() {} \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Deri " ) & & ! db - > findScopeByName ( " Deri " ) - > functionList . front ( ) . isImplicitlyVirtual ( false ) ) ; // Default false -> false
}
{
GET_SYMBOL_DB ( " class Base : Base2 { \n " // We don't know Base2
" virtual void foo() {} \n "
" }; \n "
" class Deri : Base { \n "
" void foo() {} \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Deri " ) & & db - > findScopeByName ( " Deri " ) - > functionList . front ( ) . isImplicitlyVirtual ( false ) ) ; // Default false, but we saw "virtual" -> true
}
2014-01-05 19:10:16 +01:00
// #5289
{
GET_SYMBOL_DB ( " template<> \n "
" class Bar<void, void> { \n "
" }; \n "
" template<typename K, typename V, int KeySize> \n "
" class Bar : private Bar<void, void> { \n "
" void foo() { \n "
" } \n "
" }; " ) ;
ASSERT ( db & & db - > findScopeByName ( " Bar " ) & & ! db - > findScopeByName ( " Bar " ) - > functionList . front ( ) . isImplicitlyVirtual ( false ) ) ;
2014-03-22 08:49:28 +01:00
ASSERT_EQUALS ( 1 , db - > findScopeByName ( " Bar " ) - > functionList . size ( ) ) ;
}
// #5590
{
GET_SYMBOL_DB ( " class InfiniteB : InfiniteA { \n "
" class D { \n "
" }; \n "
" }; \n "
" namespace N { \n "
" class InfiniteA : InfiniteB { \n "
" }; \n "
" } \n "
" class InfiniteA : InfiniteB { \n "
" void foo(); \n "
" }; \n "
" void InfiniteA::foo() { \n "
" C a; \n "
" } " ) ;
//ASSERT(db && db->findScopeByName("InfiniteA") && !db->findScopeByName("InfiniteA")->functionList.front().isImplicitlyVirtual());
TODO_ASSERT_EQUALS ( 1 , 0 , db - > findScopeByName ( " InfiniteA " ) - > functionList . size ( ) ) ;
2014-01-05 19:10:16 +01:00
}
2012-04-17 19:50:44 +02:00
}
2012-09-14 15:32:35 +02:00
void garbage ( ) {
2014-03-23 20:08:16 +01:00
{
GET_SYMBOL_DB ( " void f( { u = 1 ; } ) { } " ) ;
( void ) db ;
}
{
GET_SYMBOL_DB ( " { }; void namespace A::f; { g() { int } } " ) ;
( void ) db ;
}
2014-03-27 19:06:13 +01:00
{
ASSERT_THROW ( GET_SYMBOL_DB ( " class Foo {}; class Bar : public Foo " ) , InternalError ) ;
}
2012-09-14 15:32:35 +02:00
}
2012-10-30 15:48:06 +01:00
void findFunction1 ( ) {
GET_SYMBOL_DB ( " int foo(int x); \n " /* 1 */
" void foo(); \n " /* 2 */
" void bar() { \n " /* 3 */
" foo(); \n " /* 4 */
" foo(1); \n " /* 5 */
" } " ) ; /* 6 */
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
if ( db ) {
const Scope * bar = db - > findScopeByName ( " bar " ) ;
2014-02-16 11:47:52 +01:00
ASSERT ( bar ! = nullptr ) ;
2012-10-30 15:48:06 +01:00
if ( bar ) {
unsigned int linenrs [ ] = { 2 , 1 } ;
unsigned int index = 0 ;
for ( const Token * tok = bar - > classStart - > next ( ) ; tok ! = bar - > classEnd ; tok = tok - > next ( ) ) {
if ( Token : : Match ( tok , " %var% ( " ) & & ! tok - > varId ( ) & & Token : : simpleMatch ( tok - > linkAt ( 1 ) , " ) ; " ) ) {
2013-01-28 06:47:48 +01:00
const Function * function = db - > findFunction ( tok ) ;
2014-02-16 11:47:52 +01:00
ASSERT ( function ! = nullptr ) ;
2012-10-30 15:48:06 +01:00
if ( function ) {
std : : stringstream expected ;
expected < < " Function call on line " < < tok - > linenr ( ) < < " calls function on line " < < linenrs [ index ] < < std : : endl ;
std : : stringstream actual ;
actual < < " Function call on line " < < tok - > linenr ( ) < < " calls function on line " < < function - > tokenDef - > linenr ( ) < < std : : endl ;
ASSERT_EQUALS ( expected . str ( ) . c_str ( ) , actual . str ( ) . c_str ( ) ) ;
}
index + + ;
}
}
}
}
}
2014-02-19 06:35:51 +01:00
void findFunction2 ( ) {
// The function does not match the function call.
GET_SYMBOL_DB ( " void func(const int x, const Fred &fred); \n "
" void otherfunc() { \n "
" float t; \n "
" func(x, &t); \n "
" } " ) ;
const Token * callfunc = Token : : findmatch ( tokenizer . tokens ( ) , " func ( x , & t ) ; " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
ASSERT_EQUALS ( true , db ! = nullptr ) ; // not null
ASSERT_EQUALS ( true , callfunc ! = nullptr ) ; // not null
ASSERT_EQUALS ( false , ( callfunc & & callfunc - > function ( ) ) ) ; // callfunc->function() should be null
}
2010-12-30 09:46:44 +01:00
} ;
REGISTER_TEST ( TestSymbolDatabase )