@@ -7789,6 +7789,8 @@ static const Function* getFunction(const Token* tok) {
77897789 return nullptr ;
77907790 if (tok->function () && tok->function ()->retDef )
77917791 return tok->function ();
7792+ if (tok->str () == " )" && tok->link () && Token::simpleMatch (tok->link ()->previous (), " _Generic (" ))
7793+ return tok->link ()->function ();
77927794 if (const Variable* lvar = tok->variable ()) { // lambda
77937795 const Function* lambda{};
77947796 if (Token::Match (lvar->nameToken ()->next (), " ; %varid% = [" , lvar->declarationId ()))
@@ -7842,6 +7844,66 @@ static int getIntegerConstantMacroWidth(const Token* tok) {
78427844 return intnum;
78437845}
78447846
7847+ void SymbolDatabase::setGenericValueType (Token *par)
7848+ {
7849+ const Token *tok = par->astOperand2 ();
7850+ std::vector<const Token*> stack;
7851+
7852+ while (tok && tok->str () == " ," ) {
7853+ stack.push_back (tok);
7854+ tok = tok->astOperand1 ();
7855+ }
7856+
7857+ if (!tok)
7858+ return ;
7859+
7860+ const ValueType *controlVt = tok->valueType ();
7861+
7862+ if (!controlVt)
7863+ return ;
7864+
7865+ const Token *selected = nullptr ;
7866+
7867+ const auto matchVt = [](const ValueType *control, const ValueType *type) {
7868+ // Strip top level qualifiers of controlling expression
7869+ const nonneg int controlMask = ~(1 << control->pointer );
7870+ return control->isTypeEqual (type) &&
7871+ control->sign == type->sign &&
7872+ (control->constness & controlMask) == type->constness &&
7873+ (control->volatileness & controlMask) == type->volatileness ;
7874+ };
7875+
7876+ while (!stack.empty ()) {
7877+ const Token *comma = stack.back ();
7878+ stack.pop_back ();
7879+
7880+ const Token *type = comma->next ();
7881+ const Token *expr = comma->astOperand2 ();
7882+
7883+ if (type->str () == " default" ) {
7884+ if (!selected)
7885+ selected = expr;
7886+ } else {
7887+ ValueType typeVt;
7888+ parsedecl (type, &typeVt, mDefaultSignedness , mSettings );
7889+
7890+ if (matchVt (controlVt, &typeVt)) {
7891+ selected = expr;
7892+ break ;
7893+ }
7894+ }
7895+ }
7896+
7897+ if (!selected)
7898+ return ;
7899+
7900+ if (selected->valueType ())
7901+ setValueType (par, *selected->valueType ());
7902+
7903+ if (selected->function ())
7904+ par->function (selected->function ());
7905+ }
7906+
78457907void SymbolDatabase::setValueTypeInTokenList (bool reportDebugWarnings, Token *tokens)
78467908{
78477909 if (!tokens)
@@ -7850,7 +7912,18 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
78507912 for (Token *tok = tokens; tok; tok = tok->next ())
78517913 tok->setValueType (nullptr );
78527914
7915+ std::vector<Token*> genericClosingParens;
7916+
78537917 for (Token *tok = tokens; tok; tok = tok->next ()) {
7918+ if (Token::simpleMatch (tok, " _Generic (" )) {
7919+ genericClosingParens.push_back (tok->linkAt (1 ));
7920+ continue ;
7921+ }
7922+ if (!genericClosingParens.empty () && tok == genericClosingParens.back ()) {
7923+ setGenericValueType (tok->link ());
7924+ genericClosingParens.pop_back ();
7925+ continue ;
7926+ }
78547927 if (tok->isNumber ()) {
78557928 if (MathLib::isFloat (tok->str ())) {
78567929 ValueType::Type type = ValueType::Type::DOUBLE ;
0 commit comments