SymbolDatabase: Add support for functions in unions. (#973)

This commit is contained in:
IOBYTE 2017-10-15 05:49:36 -04:00 committed by Daniel Marjamäki
parent 51eb4ffe9b
commit 352fd7a381
3 changed files with 28 additions and 5 deletions

View File

@ -162,11 +162,11 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
if (tok->str() == "class") if (tok->str() == "class")
access[new_scope] = Private; access[new_scope] = Private;
else if (tok->str() == "struct") else if (tok->str() == "struct" || tok->str() == "union")
access[new_scope] = Public; access[new_scope] = Public;
// fill typeList... // fill typeList...
if (new_scope->isClassOrStruct() || new_scope->type == Scope::eUnion || new_scope->type == Scope::eEnum) { if (new_scope->isClassOrStructOrUnion() || new_scope->type == Scope::eEnum) {
Type* new_type = findType(tok->next(), scope); Type* new_type = findType(tok->next(), scope);
if (!new_type) { if (!new_type) {
typeList.push_back(Type(new_scope->classDef, new_scope, scope)); typeList.push_back(Type(new_scope->classDef, new_scope, scope));
@ -358,8 +358,8 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
continue; continue;
} }
// check if in class or structure // check if in class or structure or union
else if (scope->type == Scope::eClass || scope->type == Scope::eStruct) { else if (scope->isClassOrStructOrUnion()) {
const Token *funcStart = nullptr; const Token *funcStart = nullptr;
const Token *argStart = nullptr; const Token *argStart = nullptr;
const Token *declEnd = nullptr; const Token *declEnd = nullptr;
@ -1522,7 +1522,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
// regular function? // regular function?
else if (Token::Match(tok, "%name% (") && !isReservedName(tok->str()) && tok->previous() && else if (Token::Match(tok, "%name% (") && !isReservedName(tok->str()) && tok->previous() &&
(Token::Match(tok->previous(), "%name%|>|&|*|::|~") || // Either a return type or scope qualifier in front of tok (Token::Match(tok->previous(), "%name%|>|&|*|::|~") || // Either a return type or scope qualifier in front of tok
outerScope->isClassOrStruct())) { // or a ctor/dtor outerScope->isClassOrStructOrUnion())) { // or a ctor/dtor
const Token* tok1 = tok->previous(); const Token* tok1 = tok->previous();
const Token* tok2 = tok->next()->link()->next(); const Token* tok2 = tok->next()->link()->next();

View File

@ -927,6 +927,10 @@ public:
return (type == eClass || type == eStruct); return (type == eClass || type == eStruct);
} }
bool isClassOrStructOrUnion() const {
return (type == eClass || type == eStruct || type == eUnion);
}
bool isExecutable() const { bool isExecutable() const {
return type != eClass && type != eStruct && type != eUnion && type != eGlobal && type != eNamespace && type != eEnum; return type != eClass && type != eStruct && type != eUnion && type != eGlobal && type != eNamespace && type != eEnum;
} }

View File

@ -347,6 +347,8 @@ private:
TEST_CASE(auto8); TEST_CASE(auto8);
TEST_CASE(auto9); // #8044 (segmentation fault) TEST_CASE(auto9); // #8044 (segmentation fault)
TEST_CASE(auto10); // #8020 TEST_CASE(auto10); // #8020
TEST_CASE(unionWithConstructor);
} }
void array() { void array() {
@ -5252,6 +5254,23 @@ private:
} }
} }
void unionWithConstructor() {
GET_SYMBOL_DB("union Fred {\n"
" Fred(int x) : i(x) { }\n"
" Fred(float x) : f(x) { }\n"
" int i;\n"
" int f;\n"
"};");
ASSERT_EQUALS("", errout.str());
const Token *f = Token::findsimplematch(tokenizer.tokens(), "Fred ( int");
ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 2);
f = Token::findsimplematch(tokenizer.tokens(), "Fred ( float");
ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 3);
}
}; };
REGISTER_TEST(TestSymbolDatabase) REGISTER_TEST(TestSymbolDatabase)