Skip to content

Commit bf832fb

Browse files
committed
skip type tokens in generic selection
1 parent a18d104 commit bf832fb

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

lib/tokenlist.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ namespace {
451451
bool cpp;
452452
int assign{};
453453
bool inCase{}; // true from case to :
454+
bool inGeneric{};
454455
bool stopAtColon{}; // help to properly parse ternary operators
455456
const Token* functionCallEndPar{};
456457
explicit AST_state(bool cpp) : cpp(cpp) {}
@@ -706,11 +707,31 @@ static void compileUnaryOp(Token *&tok, AST_state& state, void (*f)(Token *&tok,
706707
state.op.push(unaryop);
707708
}
708709

710+
static void skipGenericType(Token *&tok)
711+
{
712+
Token *skip = tok;
713+
while (skip && !Token::Match(skip, ",|)")) {
714+
if (Token::simpleMatch(skip, "(")) {
715+
skip = skip->link()->next();
716+
continue;
717+
}
718+
if (Token::simpleMatch(skip, ":")) {
719+
tok = skip->next();
720+
return;
721+
}
722+
skip = skip->next();
723+
}
724+
}
725+
709726
static void compileBinOp(Token *&tok, AST_state& state, void (*f)(Token *&tok, AST_state& state))
710727
{
711728
Token *binop = tok;
712729
if (f) {
713730
tok = tok->next();
731+
if (Token::simpleMatch(binop, ",") && state.inGeneric)
732+
skipGenericType(tok);
733+
bool inGenericSaved = state.inGeneric;
734+
state.inGeneric = false;
714735
if (Token::Match(binop, "::|. ~"))
715736
tok = tok->next();
716737
state.depth++;
@@ -719,6 +740,7 @@ static void compileBinOp(Token *&tok, AST_state& state, void (*f)(Token *&tok, A
719740
if (state.depth > AST_MAX_DEPTH)
720741
throw InternalError(tok, "maximum AST depth exceeded", InternalError::AST);
721742
state.depth--;
743+
state.inGeneric = inGenericSaved;
722744
}
723745

724746
// TODO: Should we check if op is empty.
@@ -1048,6 +1070,9 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
10481070
continue;
10491071
} else if (tok->str() == "(" &&
10501072
(!iscast(tok, state.cpp) || Token::Match(tok->previous(), "if|while|for|switch|catch"))) {
1073+
bool inGenericSaved = state.inGeneric;
1074+
if (Token::simpleMatch(tok->previous(), "_Generic"))
1075+
state.inGeneric = true;
10511076
Token* tok2 = tok;
10521077
tok = tok->next();
10531078
const bool opPrevTopSquare = !state.op.empty() && state.op.top() && state.op.top()->str() == "[";
@@ -1066,6 +1091,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
10661091
else
10671092
compileUnaryOp(tok, state, nullptr);
10681093
}
1094+
state.inGeneric = inGenericSaved;
10691095
tok = tok->link()->next();
10701096
if (Token::simpleMatch(tok, "::"))
10711097
compileBinOp(tok, state, compileTerm);

test/testtokenize.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -8394,7 +8394,7 @@ class TestTokenizer : public TestFixture {
83948394

83958395
void genericInIf() { // #13561
83968396
const char code[] = " if (_Generic(s, char * : 1, const float * : 2, volatile int * : 3, default : 0)) {}";
8397-
const char ast[] = "(( if (( _Generic (, (, (, (, s (: char 1)) (: float 2)) (: int 3)) (: default 0))))";
8397+
const char ast[] = "(( if (( _Generic (, (, (, (, s 1) 2) 3) 0)))";
83988398
ASSERT_EQUALS(ast, testAst(code, AstStyle::Z3));
83998399
}
84008400
};

0 commit comments

Comments
 (0)