Merge pull request #924 from IOBYTE/master

Fixed #6985 (SymbolDatabase: Function pointer not set when calling bas…
This commit is contained in:
Daniel Marjamäki 2017-07-16 14:04:25 +02:00 committed by GitHub
commit fabe07ffd6
2 changed files with 96 additions and 23 deletions

View File

@ -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;
}
}
}
}
} }
} }
@ -4405,14 +4405,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) == "::") {
@ -4420,14 +4422,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

View File

@ -270,6 +270,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);
@ -2799,6 +2800,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;");