Skip to content

Commit 127340e

Browse files
committed
TokenList::combineOperators: dont combine &= for anonymous reference parameter
1 parent 81499d9 commit 127340e

2 files changed

Lines changed: 64 additions & 2 deletions

File tree

simplecpp.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,26 @@ static bool isFloatSuffix(const simplecpp::Token *tok)
658658

659659
void simplecpp::TokenList::combineOperators()
660660
{
661+
std::stack<bool> executableScope;
662+
executableScope.push(false);
661663
for (Token *tok = front(); tok; tok = tok->next) {
664+
if (tok->op == '{') {
665+
if (executableScope.top()) {
666+
executableScope.push(true);
667+
continue;
668+
}
669+
const Token *prev = tok->previous;
670+
while (prev && prev->isOneOf(";{}()"))
671+
prev = prev->previous;
672+
executableScope.push(prev && prev->op == ')');
673+
continue;
674+
}
675+
if (tok->op == '}') {
676+
if (executableScope.size() > 1)
677+
executableScope.pop();
678+
continue;
679+
}
680+
662681
if (tok->op == '.') {
663682
if (tok->previous && tok->previous->op == '.')
664683
continue;
@@ -694,6 +713,39 @@ void simplecpp::TokenList::combineOperators()
694713
continue;
695714

696715
if (tok->next->op == '=' && tok->isOneOf("=!<>+-*/%&|^")) {
716+
if (tok->op == '&' && !executableScope.top()) {
717+
// don't combine &= if it is a anonymous reference parameter with default value:
718+
// void f(x&=2)
719+
int indentlevel = 0;
720+
const Token *start = tok;
721+
while (indentlevel >= 0 && start) {
722+
if (start->op == ')')
723+
++indentlevel;
724+
else if (start->op == '(')
725+
--indentlevel;
726+
else if (start->isOneOf(";{}"))
727+
break;
728+
start = start->previous;
729+
}
730+
if (indentlevel == -1 && start) {
731+
const Token *ftok = start;
732+
bool isFuncDecl = ftok->name;
733+
while (isFuncDecl) {
734+
if (!start->name && start->str != "::" && start->op != '*' && start->op != '&')
735+
isFuncDecl = false;
736+
if (!start->previous)
737+
break;
738+
if (start->previous->isOneOf(";{}:"))
739+
break;
740+
start = start->previous;
741+
}
742+
isFuncDecl &= start != ftok && start->name;
743+
if (isFuncDecl) {
744+
// TODO: we could loop through the parameters here and check if they are correct.
745+
continue;
746+
}
747+
}
748+
}
697749
tok->setstr(tok->str + "=");
698750
deleteToken(tok->next);
699751
} else if ((tok->op == '|' || tok->op == '&') && tok->op == tok->next->op) {

test.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ static void combineOperators_coloncolon()
168168
ASSERT_EQUALS("x ? y : :: z", preprocess("x ? y : ::z"));
169169
}
170170

171+
static void combineOperators_andequal()
172+
{
173+
ASSERT_EQUALS("x &= 2 ;", preprocess("x &= 2;"));
174+
ASSERT_EQUALS("void f ( x & = 2 ) ;", preprocess("void f(x &= 2);"));
175+
ASSERT_EQUALS("f ( x &= 2 ) ;", preprocess("f(x &= 2);"));
176+
}
177+
171178
static void comment()
172179
{
173180
ASSERT_EQUALS("// abc", readfile("// abc"));
@@ -612,7 +619,8 @@ static void hashhash8()
612619
ASSERT_EQUALS("\nxy = 123 ;", preprocess(code));
613620
}
614621

615-
static void hashhash_invalid_1() {
622+
static void hashhash_invalid_1()
623+
{
616624
std::istringstream istr("#define f(a) (##x)\nf(1)");
617625
std::vector<std::string> files;
618626
std::map<std::string, simplecpp::TokenList*> filedata;
@@ -622,7 +630,8 @@ static void hashhash_invalid_1() {
622630
ASSERT_EQUALS("file0,1,syntax_error,failed to expand 'f', Invalid ## usage when expanding 'f'.\n", toString(outputList));
623631
}
624632

625-
static void hashhash_invalid_2() {
633+
static void hashhash_invalid_2()
634+
{
626635
std::istringstream istr("#define f(a) (x##)\nf(1)");
627636
std::vector<std::string> files;
628637
std::map<std::string, simplecpp::TokenList*> filedata;
@@ -1484,6 +1493,7 @@ int main(int argc, char **argv)
14841493
TEST_CASE(combineOperators_floatliteral);
14851494
TEST_CASE(combineOperators_increment);
14861495
TEST_CASE(combineOperators_coloncolon);
1496+
TEST_CASE(combineOperators_andequal);
14871497

14881498
TEST_CASE(comment);
14891499
TEST_CASE(comment_multiline);

0 commit comments

Comments
 (0)