Skip to content

Commit 905f79c

Browse files
committed
hash hash
1 parent 80d58d4 commit 905f79c

3 files changed

Lines changed: 45 additions & 9 deletions

File tree

preprocessor.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,27 @@ class Macro {
106106
for (const Token *tok = valueToken; tok != endToken;) {
107107
if (tok->op == '#') {
108108
tok = tok->next;
109-
110-
TokenList tokenListHash;
111-
tok = expandToken(&tokenListHash, loc, tok, macros, expandedmacros1, expandedmacros, parametertokens);
112-
113-
std::string s;
114-
for (const Token *hashtok = tokenListHash.cbegin(); hashtok; hashtok = hashtok->next)
115-
s += hashtok->str;
116-
output->push_back(newMacroToken('\"' + s + '\"', loc));
109+
if (tok->op == '#') {
110+
// A##B => AB
111+
Token *A = output->end();
112+
if (!A)
113+
throw std::runtime_error("invalid ##");
114+
tok = expandToken(output, loc, tok->next, macros, expandedmacros1, expandedmacros, parametertokens);
115+
Token *next = A->next;
116+
if (!next)
117+
throw std::runtime_error("invalid ##");
118+
A->str = A->str + A->next->str;
119+
A->flags();
120+
output->deleteToken(A->next);
121+
} else {
122+
// #123 => "123"
123+
TokenList tokenListHash;
124+
tok = expandToken(&tokenListHash, loc, tok, macros, expandedmacros1, expandedmacros, parametertokens);
125+
std::string s;
126+
for (const Token *hashtok = tokenListHash.cbegin(); hashtok; hashtok = hashtok->next)
127+
s += hashtok->str;
128+
output->push_back(newMacroToken('\"' + s + '\"', loc));
129+
}
117130
} else {
118131
tok = expandToken(output, loc, tok, macros, expandedmacros1, expandedmacros, parametertokens);
119132
}

preprocessor.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ class TokenList {
7575
const Token *cend() const {
7676
return last;
7777
}
78+
79+
void deleteToken(Token *tok) {
80+
if (!tok)
81+
return;
82+
Token *prev = tok->previous;
83+
Token *next = tok->next;
84+
if (prev)
85+
prev->next = next;
86+
if (next)
87+
next->previous = prev;
88+
if (first == tok)
89+
first = next;
90+
if (last == tok)
91+
last = prev;
92+
delete tok;
93+
}
7894
private:
7995
Token *first;
8096
Token *last;

test.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,15 @@ void hash() {
9797
const char code[] = "#define a(x) #x\n"
9898
"a(1)\n"
9999
"a(2+3)";
100-
ASSERT_EQUALS(" \"1\"\n \"2+3\"", preprocess(code));
100+
ASSERT_EQUALS(" \"1\"\n"
101+
" \"2+3\"", preprocess(code));
101102
}
102103

104+
void hashhash() { // #4703
105+
const char code[] = "#define MACRO( A, B, C ) class A##B##C##Creator {};\n"
106+
"MACRO( B\t, U , G )";
107+
ASSERT_EQUALS(" class BUGCreator { } ;", preprocess(code));
108+
}
103109

104110
void ifdef1() {
105111
const char code[] = "#ifdef A\n"
@@ -152,6 +158,7 @@ int main() {
152158
define4();
153159
define5();
154160
hash();
161+
hashhash();
155162
ifdef1();
156163
ifdef2();
157164
tokenMacro1();

0 commit comments

Comments
 (0)