Initialize Function::start when the function is implemented, not when its defined. (Fixes #3826)

This commit is contained in:
PKEuS 2012-05-22 12:30:10 -07:00
parent 77e9106ec0
commit 26f5f08614
3 changed files with 20 additions and 13 deletions

View File

@ -429,7 +429,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
} }
// save function prototype in database // save function prototype in database
if (newFunc) if (newFunc)
addGlobalFunctionDecl(scope, tok, argStart, funcStart); addGlobalFunctionDecl(scope, argStart, funcStart);
tok = argStart->link()->next(); tok = argStart->link()->next();
continue; continue;
@ -445,7 +445,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
} }
// save function prototype in database // save function prototype in database
if (newFunc) { if (newFunc) {
Function* func = addGlobalFunctionDecl(scope, tok, argStart, funcStart); Function* func = addGlobalFunctionDecl(scope, argStart, funcStart);
func->retFuncPtr = true; func->retFuncPtr = true;
} }
@ -934,12 +934,19 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
function = &*i; function = &*i;
} }
if (!function) if (!function)
function = addGlobalFunctionDecl(scope, tok, argStart, funcStart); function = addGlobalFunctionDecl(scope, argStart, funcStart);
function->arg = argStart; function->arg = argStart;
function->token = funcStart; function->token = funcStart;
function->hasBody = true; function->hasBody = true;
// find start of function '{'
const Token *start = tok;
while (start && start->str() != "{")
start = start->next();
// save start of function
function->start = start;
addNewFunction(&scope, &tok); addNewFunction(&scope, &tok);
if (scope) { if (scope) {
@ -950,7 +957,7 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
return 0; return 0;
} }
Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart) Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token *argStart, const Token* funcStart)
{ {
Function function; Function function;
@ -967,14 +974,6 @@ Function* SymbolDatabase::addGlobalFunctionDecl(Scope*& scope, const Token*& tok
function.hasBody = false; function.hasBody = false;
function.type = Function::eFunction; function.type = Function::eFunction;
// find start of function '{'
const Token *start = tok;
while (start && start->str() != "{")
start = start->next();
// save start of function
function.start = start;
scope->functionList.push_back(function); scope->functionList.push_back(function);
return &scope->functionList.back(); return &scope->functionList.back();
} }

View File

@ -585,7 +585,7 @@ private:
friend class Scope; friend class Scope;
void addClassFunction(Scope **info, const Token **tok, const Token *argStart); void addClassFunction(Scope **info, const Token **tok, const Token *argStart);
Function* addGlobalFunctionDecl(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart); Function* addGlobalFunctionDecl(Scope*& scope, const Token *argStart, const Token* funcStart);
Function* addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart); Function* addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart);
void addNewFunction(Scope **info, const Token **tok); void addNewFunction(Scope **info, const Token **tok);
bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart) const; bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart) const;

View File

@ -102,6 +102,7 @@ private:
TEST_CASE(classWithFriend); TEST_CASE(classWithFriend);
TEST_CASE(parseFunctionCorrect); TEST_CASE(parseFunctionCorrect);
TEST_CASE(parseFunctionDeclarationCorrect);
TEST_CASE(hasGlobalVariables1); TEST_CASE(hasGlobalVariables1);
TEST_CASE(hasGlobalVariables2); TEST_CASE(hasGlobalVariables2);
@ -692,6 +693,13 @@ private:
ASSERT(tokenizer.getFunctionTokenByName("if") == NULL); ASSERT(tokenizer.getFunctionTokenByName("if") == NULL);
} }
void parseFunctionDeclarationCorrect() {
GET_SYMBOL_DB("void func();\n"
"int bar() {}\n"
"void func() {}")
ASSERT_EQUALS(3, db->findScopeByName("func")->function->start->linenr());
}
void hasGlobalVariables1() { void hasGlobalVariables1() {
GET_SYMBOL_DB("int i;\n") GET_SYMBOL_DB("int i;\n")