@@ -7842,6 +7842,78 @@ static int getIntegerConstantMacroWidth(const Token* tok) {
78427842 return intnum;
78437843}
78447844
7845+ void SymbolDatabase::setGenericValueType (Token *par)
7846+ {
7847+ if (!par)
7848+ return ;
7849+
7850+ const Token *tok = par->astOperand2 ();
7851+ std::vector<const Token*> stack;
7852+
7853+ while (tok && tok->str () == " ," ) {
7854+ stack.push_back (tok);
7855+ tok = tok->astOperand1 ();
7856+ }
7857+
7858+ if (!tok)
7859+ return ;
7860+
7861+ const ValueType *controlVt = tok->valueType ();
7862+
7863+ if (!controlVt)
7864+ return ;
7865+
7866+ const Token *selected = nullptr ;
7867+
7868+ const auto matchVt = [](const ValueType *control, const ValueType *type) {
7869+ // Strip top level qualifiers of controlling expression
7870+ const unsigned int controlMask = ~(1U << control->pointer );
7871+ return control->isTypeEqual (type) &&
7872+ control->sign == type->sign &&
7873+ (static_cast <unsigned int >(control->constness ) & controlMask) == static_cast <unsigned int >(type->constness ) &&
7874+ (static_cast <unsigned int >(control->volatileness ) & controlMask) == static_cast <unsigned int >(type->volatileness );
7875+ };
7876+
7877+ while (!stack.empty ()) {
7878+ const Token *comma = stack.back ();
7879+ stack.pop_back ();
7880+
7881+ const Token *type = comma->next ();
7882+ const Token *expr = comma->astOperand2 ();
7883+
7884+ if (type->str () == " default" ) {
7885+ if (!selected)
7886+ selected = expr;
7887+ } else {
7888+ ValueType typeVt;
7889+
7890+ if (!parsedecl (type, &typeVt, mDefaultSignedness , mSettings ))
7891+ continue ;
7892+
7893+ if (matchVt (controlVt, &typeVt)) {
7894+ selected = expr;
7895+ break ;
7896+ }
7897+ }
7898+ }
7899+
7900+ if (!selected)
7901+ return ;
7902+
7903+ if (selected->valueType ()) {
7904+ setValueType (par, *selected->valueType ());
7905+ } else {
7906+ const Function *f = selected->function ();
7907+ Token *parent = par->astParent ();
7908+
7909+ if (f && f->retDef && parent && parent->str () == " (" ) {
7910+ ValueType returnVt;
7911+ if (parsedecl (f->retDef , &returnVt, mDefaultSignedness , mSettings ))
7912+ setValueType (parent, returnVt);
7913+ }
7914+ }
7915+ }
7916+
78457917void SymbolDatabase::setValueTypeInTokenList (bool reportDebugWarnings, Token *tokens)
78467918{
78477919 if (!tokens)
@@ -7850,7 +7922,18 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
78507922 for (Token *tok = tokens; tok; tok = tok->next ())
78517923 tok->setValueType (nullptr );
78527924
7925+ std::vector<Token*> genericClosingParens;
7926+
78537927 for (Token *tok = tokens; tok; tok = tok->next ()) {
7928+ if (Token::simpleMatch (tok, " _Generic (" )) {
7929+ genericClosingParens.push_back (tok->linkAt (1 ));
7930+ continue ;
7931+ }
7932+ if (!genericClosingParens.empty () && tok == genericClosingParens.back ()) {
7933+ setGenericValueType (tok->link ());
7934+ genericClosingParens.pop_back ();
7935+ continue ;
7936+ }
78547937 if (tok->isNumber ()) {
78557938 if (MathLib::isFloat (tok->str ())) {
78567939 ValueType::Type type = ValueType::Type::DOUBLE ;
0 commit comments