SymbolDatabase: fix problem where definition coudn't find forward declaration in class (#1190)
This commit is contained in:
parent
deaafd59d7
commit
fac851192a
|
@ -2240,7 +2240,7 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To
|
||||||
while (scope2 && count > 0) {
|
while (scope2 && count > 0) {
|
||||||
count--;
|
count--;
|
||||||
tok1 = tok1->tokAt(2);
|
tok1 = tok1->tokAt(2);
|
||||||
scope2 = scope2->findInNestedList(tok1->str());
|
scope2 = scope2->findRecordInNestedList(tok1->str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 0 && scope2) {
|
if (count == 0 && scope2) {
|
||||||
|
@ -4470,6 +4470,12 @@ const Scope *Scope::findRecordInNestedList(const std::string & name) const
|
||||||
if ((*it)->className == name && (*it)->type != eFunction)
|
if ((*it)->className == name && (*it)->type != eFunction)
|
||||||
return (*it);
|
return (*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Type * nested_type = findType(name);
|
||||||
|
|
||||||
|
if (nested_type)
|
||||||
|
return nested_type->classScope;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,7 @@ private:
|
||||||
TEST_CASE(symboldatabase61);
|
TEST_CASE(symboldatabase61);
|
||||||
TEST_CASE(symboldatabase62);
|
TEST_CASE(symboldatabase62);
|
||||||
TEST_CASE(symboldatabase63);
|
TEST_CASE(symboldatabase63);
|
||||||
|
TEST_CASE(symboldatabase64);
|
||||||
|
|
||||||
TEST_CASE(enum1);
|
TEST_CASE(enum1);
|
||||||
TEST_CASE(enum2);
|
TEST_CASE(enum2);
|
||||||
|
@ -3001,6 +3002,332 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void symboldatabase64() {
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("class Fred { struct impl; };\n"
|
||||||
|
"struct Fred::impl {\n"
|
||||||
|
" impl() { }\n"
|
||||||
|
" ~impl() { }\n"
|
||||||
|
" impl(const impl &) { }\n"
|
||||||
|
"};\n");
|
||||||
|
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
ASSERT(db && db->scopeList.size() == 6);
|
||||||
|
ASSERT(db && db->classAndStructScopes.size() == 2);
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->functionScopes.size() == 3);
|
||||||
|
|
||||||
|
const Token * functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 3 &&
|
||||||
|
functionToken->function()->token->linenr() == 3);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "~ impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->next()->function() &&
|
||||||
|
functionToken->next()->function()->functionScope &&
|
||||||
|
functionToken->next()->function()->tokenDef->linenr() == 4 &&
|
||||||
|
functionToken->next()->function()->token->linenr() == 4);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( const impl & ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 5 &&
|
||||||
|
functionToken->function()->token->linenr() == 5);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("class Fred { struct impl; };\n"
|
||||||
|
"struct Fred::impl {\n"
|
||||||
|
" impl();\n"
|
||||||
|
" ~impl();\n"
|
||||||
|
" impl(const impl &);\n"
|
||||||
|
"};\n"
|
||||||
|
"Fred::impl::impl() { }\n"
|
||||||
|
"Fred::impl::~impl() { }\n"
|
||||||
|
"Fred::impl::impl(const Fred::impl &) { }");
|
||||||
|
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
ASSERT(db && db->scopeList.size() == 6);
|
||||||
|
ASSERT(db && db->classAndStructScopes.size() == 2);
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->functionScopes.size() == 3);
|
||||||
|
|
||||||
|
const Token * functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 3 &&
|
||||||
|
functionToken->function()->token->linenr() == 7);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "~ impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->next()->function() &&
|
||||||
|
functionToken->next()->function()->functionScope &&
|
||||||
|
functionToken->next()->function()->tokenDef->linenr() == 4 &&
|
||||||
|
functionToken->next()->function()->token->linenr() == 8);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( const Fred :: impl & ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 5 &&
|
||||||
|
functionToken->function()->token->linenr() == 9);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("namespace NS {\n"
|
||||||
|
" class Fred { struct impl; };\n"
|
||||||
|
" struct Fred::impl {\n"
|
||||||
|
" impl() { }\n"
|
||||||
|
" ~impl() { }\n"
|
||||||
|
" impl(const impl &) { }\n"
|
||||||
|
" };\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
ASSERT(db && db->scopeList.size() == 7);
|
||||||
|
ASSERT(db && db->classAndStructScopes.size() == 2);
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->functionScopes.size() == 3);
|
||||||
|
|
||||||
|
const Token * functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 4 &&
|
||||||
|
functionToken->function()->token->linenr() == 4);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "~ impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->next()->function() &&
|
||||||
|
functionToken->next()->function()->functionScope &&
|
||||||
|
functionToken->next()->function()->tokenDef->linenr() == 5 &&
|
||||||
|
functionToken->next()->function()->token->linenr() == 5);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( const impl & ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 6 &&
|
||||||
|
functionToken->function()->token->linenr() == 6);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("namespace NS {\n"
|
||||||
|
" class Fred { struct impl; };\n"
|
||||||
|
" struct Fred::impl {\n"
|
||||||
|
" impl();\n"
|
||||||
|
" ~impl();\n"
|
||||||
|
" impl(const impl &);\n"
|
||||||
|
" };\n"
|
||||||
|
" Fred::impl::impl() { }\n"
|
||||||
|
" Fred::impl::~impl() { }\n"
|
||||||
|
" Fred::impl::impl(const Fred::impl &) { }\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
ASSERT(db && db->scopeList.size() == 7);
|
||||||
|
ASSERT(db && db->classAndStructScopes.size() == 2);
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->functionScopes.size() == 3);
|
||||||
|
|
||||||
|
const Token * functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 4 &&
|
||||||
|
functionToken->function()->token->linenr() == 8);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "~ impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->next()->function() &&
|
||||||
|
functionToken->next()->function()->functionScope &&
|
||||||
|
functionToken->next()->function()->tokenDef->linenr() == 5 &&
|
||||||
|
functionToken->next()->function()->token->linenr() == 9);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( const Fred :: impl & ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 6 &&
|
||||||
|
functionToken->function()->token->linenr() == 10);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("namespace NS {\n"
|
||||||
|
" class Fred { struct impl; };\n"
|
||||||
|
" struct Fred::impl {\n"
|
||||||
|
" impl();\n"
|
||||||
|
" ~impl();\n"
|
||||||
|
" impl(const impl &);\n"
|
||||||
|
" };\n"
|
||||||
|
"}\n"
|
||||||
|
"NS::Fred::impl::impl() { }\n"
|
||||||
|
"NS::Fred::impl::~impl() { }\n"
|
||||||
|
"NS::Fred::impl::impl(const NS::Fred::impl &) { }\n");
|
||||||
|
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
ASSERT(db && db->scopeList.size() == 7);
|
||||||
|
ASSERT(db && db->classAndStructScopes.size() == 2);
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->functionScopes.size() == 3);
|
||||||
|
|
||||||
|
const Token * functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 4 &&
|
||||||
|
functionToken->function()->token->linenr() == 9);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "~ impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->next()->function() &&
|
||||||
|
functionToken->next()->function()->functionScope &&
|
||||||
|
functionToken->next()->function()->tokenDef->linenr() == 5 &&
|
||||||
|
functionToken->next()->function()->token->linenr() == 10);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( const NS :: Fred :: impl & ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 6 &&
|
||||||
|
functionToken->function()->token->linenr() == 11);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("namespace NS {\n"
|
||||||
|
" class Fred { struct impl; };\n"
|
||||||
|
"}\n"
|
||||||
|
"struct NS::Fred::impl {\n"
|
||||||
|
" impl() { }\n"
|
||||||
|
" ~impl() { }\n"
|
||||||
|
" impl(const impl &) { }\n"
|
||||||
|
"};");
|
||||||
|
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
ASSERT(db && db->scopeList.size() == 7);
|
||||||
|
ASSERT(db && db->classAndStructScopes.size() == 2);
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->functionScopes.size() == 3);
|
||||||
|
|
||||||
|
const Token * functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 5 &&
|
||||||
|
functionToken->function()->token->linenr() == 5);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "~ impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->next()->function() &&
|
||||||
|
functionToken->next()->function()->functionScope &&
|
||||||
|
functionToken->next()->function()->tokenDef->linenr() == 6 &&
|
||||||
|
functionToken->next()->function()->token->linenr() == 6);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( const impl & ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 7 &&
|
||||||
|
functionToken->function()->token->linenr() == 7);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("namespace NS {\n"
|
||||||
|
" class Fred { struct impl; };\n"
|
||||||
|
"}\n"
|
||||||
|
"struct NS::Fred::impl {\n"
|
||||||
|
" impl();\n"
|
||||||
|
" ~impl();\n"
|
||||||
|
" impl(const impl &);\n"
|
||||||
|
"};\n"
|
||||||
|
"NS::Fred::impl::impl() { }\n"
|
||||||
|
"NS::Fred::impl::~impl() { }\n"
|
||||||
|
"NS::Fred::impl::impl(const NS::Fred::impl &) { }");
|
||||||
|
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
ASSERT(db && db->scopeList.size() == 7);
|
||||||
|
ASSERT(db && db->classAndStructScopes.size() == 2);
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->functionScopes.size() == 3);
|
||||||
|
|
||||||
|
const Token * functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 5 &&
|
||||||
|
functionToken->function()->token->linenr() == 9);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "~ impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->next()->function() &&
|
||||||
|
functionToken->next()->function()->functionScope &&
|
||||||
|
functionToken->next()->function()->tokenDef->linenr() == 6 &&
|
||||||
|
functionToken->next()->function()->token->linenr() == 10);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( const NS :: Fred :: impl & ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 7 &&
|
||||||
|
functionToken->function()->token->linenr() == 11);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("namespace NS {\n"
|
||||||
|
" class Fred { struct impl; };\n"
|
||||||
|
"}\n"
|
||||||
|
"struct NS::Fred::impl {\n"
|
||||||
|
" impl();\n"
|
||||||
|
" ~impl();\n"
|
||||||
|
" impl(const impl &);\n"
|
||||||
|
"};\n"
|
||||||
|
"namespace NS {\n"
|
||||||
|
" Fred::impl::impl() { }\n"
|
||||||
|
" Fred::impl::~impl() { }\n"
|
||||||
|
" Fred::impl::impl(const Fred::impl &) { }\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
ASSERT(db && db->scopeList.size() == 7);
|
||||||
|
ASSERT(db && db->classAndStructScopes.size() == 2);
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->functionScopes.size() == 3);
|
||||||
|
|
||||||
|
const Token * functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 5 &&
|
||||||
|
functionToken->function()->token->linenr() == 10);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "~ impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->next()->function() &&
|
||||||
|
functionToken->next()->function()->functionScope &&
|
||||||
|
functionToken->next()->function()->tokenDef->linenr() == 6 &&
|
||||||
|
functionToken->next()->function()->token->linenr() == 11);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( const Fred :: impl & ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 7 &&
|
||||||
|
functionToken->function()->token->linenr() == 12);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("namespace NS {\n"
|
||||||
|
" class Fred { struct impl; };\n"
|
||||||
|
"}\n"
|
||||||
|
"struct NS::Fred::impl {\n"
|
||||||
|
" impl();\n"
|
||||||
|
" ~impl();\n"
|
||||||
|
" impl(const impl &);\n"
|
||||||
|
"};\n"
|
||||||
|
"using namespace NS;\n"
|
||||||
|
"Fred::impl::impl() { }\n"
|
||||||
|
"Fred::impl::~impl() { }\n"
|
||||||
|
"Fred::impl::impl(const Fred::impl &) { }");
|
||||||
|
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
ASSERT(db && db->scopeList.size() == 7);
|
||||||
|
ASSERT(db && db->classAndStructScopes.size() == 2);
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->functionScopes.size() == 3);
|
||||||
|
|
||||||
|
const Token * functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 5 &&
|
||||||
|
functionToken->function()->token->linenr() == 10);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "~ impl ( ) { }");
|
||||||
|
ASSERT(db && functionToken && functionToken->next()->function() &&
|
||||||
|
functionToken->next()->function()->functionScope &&
|
||||||
|
functionToken->next()->function()->tokenDef->linenr() == 6 &&
|
||||||
|
functionToken->next()->function()->token->linenr() == 11);
|
||||||
|
|
||||||
|
functionToken = Token::findsimplematch(tokenizer.tokens(), "impl ( const Fred :: impl & ) { }");
|
||||||
|
TODO_ASSERT(db && functionToken && functionToken->function() &&
|
||||||
|
functionToken->function()->functionScope &&
|
||||||
|
functionToken->function()->tokenDef->linenr() == 7 &&
|
||||||
|
functionToken->function()->token->linenr() == 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void enum1() {
|
void enum1() {
|
||||||
GET_SYMBOL_DB("enum BOOL { FALSE, TRUE }; enum BOOL b;");
|
GET_SYMBOL_DB("enum BOOL { FALSE, TRUE }; enum BOOL b;");
|
||||||
|
|
||||||
|
@ -4154,7 +4481,6 @@ private:
|
||||||
|
|
||||||
f = Token::findsimplematch(tokenizer.tokens(), "copy ( * f ) ;");
|
f = Token::findsimplematch(tokenizer.tokens(), "copy ( * f ) ;");
|
||||||
ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 12);
|
ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 12);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \
|
#define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \
|
||||||
|
|
Loading…
Reference in New Issue