From f81557da50e90af4c5c1fc0e78ff8680d82db553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 22 Jan 2012 19:34:53 +0100 Subject: [PATCH] Fixed #3508 (Symbol database: mixing up constructors and destructors) --- lib/symboldatabase.cpp | 12 +++++------ test/testsymboldatabase.cpp | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index c9c6cb2f5..cd379845d 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -906,8 +906,10 @@ void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token * unsigned int path_length = 0; const Token *tok1; + const bool destructor((*tok)->previous()->str() == "~"); + // skip class/struct name - if ((*tok)->previous()->str() == "~") + if (destructor) tok1 = (*tok)->tokAt(-3); else tok1 = (*tok)->tokAt(-2); @@ -977,10 +979,8 @@ void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token * std::list::iterator func; for (func = scope1->functionList.begin(); func != scope1->functionList.end(); ++func) { - if (!func->hasBody) { - if (func->type == Function::eDestructor && - (*tok)->previous()->str() == "~" && - func->tokenDef->str() == (*tok)->str()) { + if (!func->hasBody && func->tokenDef->str() == (*tok)->str()) { + if (func->type == Function::eDestructor && destructor) { if (argsMatch(scope1, func->tokenDef->next(), (*tok)->next(), path, path_length)) { func->hasBody = true; func->token = *tok; @@ -990,7 +990,7 @@ void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token * start = start->next(); func->start = start; } - } else if (func->tokenDef->str() == (*tok)->str() && (*tok)->previous()->str() != "~") { + } else if (func->type != Function::eDestructor && !destructor) { if (argsMatch(scope1, func->tokenDef->next(), (*tok)->next(), path, path_length)) { // normal function? if (!func->retFuncPtr && (*tok)->next()->link()) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 72d6f1b5f..2e1413e2b 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -136,6 +136,7 @@ private: TEST_CASE(symboldatabase21); TEST_CASE(symboldatabase22); // ticket #3437 (segmentation fault) TEST_CASE(symboldatabase23); // ticket #3435 + TEST_CASE(symboldatabase24); // ticket #3508 (constructor, destructor) } void test_isVariableDeclarationCanHandleNull() { @@ -973,6 +974,48 @@ private: ASSERT_EQUALS(true, var.isClass()); } + // #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.. + const Scope *fredScope = NULL; + for (std::list::const_iterator scope = db->scopeList.begin(); scope != db->scopeList.end(); ++scope) { + if (scope->isClassOrStruct() && scope->className == "Fred") + fredScope = &(*scope); + } + ASSERT(fredScope != NULL); + if (fredScope == NULL) + 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::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); + + } + };