Fixed #6985(SymbolDatabase: Function pointer not set when calling base class function)
Use using namespace when looking up types.
This commit is contained in:
parent
e2bfe1c0ec
commit
b0aec042a6
|
@ -844,6 +844,22 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
||||||
void SymbolDatabase::createSymbolDatabaseClassInfo()
|
void SymbolDatabase::createSymbolDatabaseClassInfo()
|
||||||
{
|
{
|
||||||
if (!_tokenizer->isC()) {
|
if (!_tokenizer->isC()) {
|
||||||
|
// fill in using info
|
||||||
|
for (std::list<Scope>::iterator it = scopeList.begin(); it != scopeList.end(); ++it) {
|
||||||
|
for (std::list<Scope::UsingInfo>::iterator i = it->usingList.begin(); i != it->usingList.end(); ++i) {
|
||||||
|
// only find if not already found
|
||||||
|
if (i->scope == nullptr) {
|
||||||
|
// check scope for match
|
||||||
|
Scope *scope = findScope(i->start->tokAt(2), &(*it));
|
||||||
|
if (scope) {
|
||||||
|
// set found scope
|
||||||
|
i->scope = scope;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// fill in base class info
|
// fill in base class info
|
||||||
for (std::list<Type>::iterator it = typeList.begin(); it != typeList.end(); ++it) {
|
for (std::list<Type>::iterator it = typeList.begin(); it != typeList.end(); ++it) {
|
||||||
// finish filling in base class info
|
// finish filling in base class info
|
||||||
|
@ -864,22 +880,6 @@ void SymbolDatabase::createSymbolDatabaseClassInfo()
|
||||||
i->type = findType(i->nameStart, it->enclosingScope);
|
i->type = findType(i->nameStart, it->enclosingScope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill in using info
|
|
||||||
for (std::list<Scope>::iterator it = scopeList.begin(); it != scopeList.end(); ++it) {
|
|
||||||
for (std::list<Scope::UsingInfo>::iterator i = it->usingList.begin(); i != it->usingList.end(); ++i) {
|
|
||||||
// only find if not already found
|
|
||||||
if (i->scope == nullptr) {
|
|
||||||
// check scope for match
|
|
||||||
Scope *scope = findScope(i->start->tokAt(2), &(*it));
|
|
||||||
if (scope) {
|
|
||||||
// set found scope
|
|
||||||
i->scope = scope;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4401,14 +4401,16 @@ const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startSc
|
||||||
if (startTok->str() == startScope->className && startScope->isClassOrStruct() && startTok->strAt(1) != "::")
|
if (startTok->str() == startScope->className && startScope->isClassOrStruct() && startTok->strAt(1) != "::")
|
||||||
return startScope->definedType;
|
return startScope->definedType;
|
||||||
|
|
||||||
|
const Scope* start_scope = startScope;
|
||||||
|
|
||||||
// absolute path - directly start in global scope
|
// absolute path - directly start in global scope
|
||||||
if (startTok->str() == "::") {
|
if (startTok->str() == "::") {
|
||||||
startTok = startTok->next();
|
startTok = startTok->next();
|
||||||
startScope = &scopeList.front();
|
start_scope = &scopeList.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token* tok = startTok;
|
const Token* tok = startTok;
|
||||||
const Scope* scope = startScope;
|
const Scope* scope = start_scope;
|
||||||
|
|
||||||
while (scope && tok && tok->isName()) {
|
while (scope && tok && tok->isName()) {
|
||||||
if (tok->strAt(1) == "::") {
|
if (tok->strAt(1) == "::") {
|
||||||
|
@ -4416,14 +4418,51 @@ const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startSc
|
||||||
if (scope) {
|
if (scope) {
|
||||||
tok = tok->tokAt(2);
|
tok = tok->tokAt(2);
|
||||||
} else {
|
} else {
|
||||||
startScope = startScope->nestedIn;
|
start_scope = start_scope->nestedIn;
|
||||||
if (!startScope)
|
if (!start_scope)
|
||||||
break;
|
break;
|
||||||
scope = startScope;
|
scope = start_scope;
|
||||||
tok = startTok;
|
tok = startTok;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
return scope->findType(tok->str());
|
const Type * type = scope->findType(tok->str());
|
||||||
|
if (type)
|
||||||
|
return type;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check using namespaces
|
||||||
|
while (startScope) {
|
||||||
|
for (std::list<Scope::UsingInfo>::const_iterator it = startScope->usingList.begin();
|
||||||
|
it != startScope->usingList.end(); ++it) {
|
||||||
|
tok = startTok;
|
||||||
|
scope = it->scope;
|
||||||
|
start_scope = startScope;
|
||||||
|
|
||||||
|
while (scope && tok && tok->isName()) {
|
||||||
|
if (tok->strAt(1) == "::") {
|
||||||
|
scope = scope->findRecordInNestedList(tok->str());
|
||||||
|
if (scope) {
|
||||||
|
tok = tok->tokAt(2);
|
||||||
|
} else {
|
||||||
|
start_scope = start_scope->nestedIn;
|
||||||
|
if (!start_scope)
|
||||||
|
break;
|
||||||
|
scope = start_scope;
|
||||||
|
tok = startTok;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const Type * type = scope->findType(tok->str());
|
||||||
|
if (type)
|
||||||
|
return type;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startScope = startScope->nestedIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not a valid path
|
// not a valid path
|
||||||
|
|
|
@ -255,6 +255,7 @@ private:
|
||||||
TEST_CASE(symboldatabase55); // #7767 (return unknown macro)
|
TEST_CASE(symboldatabase55); // #7767 (return unknown macro)
|
||||||
TEST_CASE(symboldatabase56); // #7909
|
TEST_CASE(symboldatabase56); // #7909
|
||||||
TEST_CASE(symboldatabase57);
|
TEST_CASE(symboldatabase57);
|
||||||
|
TEST_CASE(symboldatabase58); // #6985 (using namespace type lookup)
|
||||||
|
|
||||||
TEST_CASE(enum1);
|
TEST_CASE(enum1);
|
||||||
TEST_CASE(enum2);
|
TEST_CASE(enum2);
|
||||||
|
@ -2778,6 +2779,39 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void symboldatabase58() { // #6985 (using namespace type lookup)
|
||||||
|
GET_SYMBOL_DB("namespace N2\n"
|
||||||
|
"{\n"
|
||||||
|
"class B { };\n"
|
||||||
|
"}\n"
|
||||||
|
"using namespace N2;\n"
|
||||||
|
"class C {\n"
|
||||||
|
" class A : public B\n"
|
||||||
|
" {\n"
|
||||||
|
" };\n"
|
||||||
|
"};");
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
if (db) {
|
||||||
|
ASSERT(db->typeList.size() == 3U);
|
||||||
|
if (db->typeList.size() == 3U) {
|
||||||
|
std::list<Type>::const_iterator it = db->typeList.begin();
|
||||||
|
const Type * classB = &(*it);
|
||||||
|
const Type * classC = &(*(++it));
|
||||||
|
const Type * classA = &(*(++it));
|
||||||
|
ASSERT(classA->name() == "A" && classB->name() == "B" && classC->name() == "C");
|
||||||
|
if (classA->name() == "A" && classB->name() == "B" && classC->name() == "C") {
|
||||||
|
ASSERT(classA->derivedFrom.size() == 1U);
|
||||||
|
if (classA->derivedFrom.size() == 1) {
|
||||||
|
ASSERT(classA->derivedFrom[0].type);
|
||||||
|
if (classA->derivedFrom[0].type) {
|
||||||
|
ASSERT(classA->derivedFrom[0].type == classB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void enum1() {
|
void enum1() {
|
||||||
GET_SYMBOL_DB("enum BOOL { FALSE, TRUE }; enum BOOL b;");
|
GET_SYMBOL_DB("enum BOOL { FALSE, TRUE }; enum BOOL b;");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue