Fixed #3508 (Symbol database: mixing up constructors and destructors)

This commit is contained in:
Daniel Marjamäki 2012-01-22 19:34:53 +01:00
parent 5c68b36cbc
commit f81557da50
2 changed files with 49 additions and 6 deletions

View File

@ -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<Function>::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()) {

View File

@ -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<Scope>::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<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);
}
};