Commit d95724454c

Evan Haas <evan@lagerdata.com>
2021-01-02 08:13:15
Allow dollar sign $ in identifiers in translate-c
In strictly conforming C, identifiers cannot container dollar signs. However GCC and Clang allow them by default, so translate-c should handle them. See http://gcc.gnu.org/onlinedocs/cpp/Tokenization.html I encountered this in the wild in windows.h Fixes #7585
1 parent 819f2a0
Changed files (2)
lib/std/c/tokenizer.zig
@@ -446,7 +446,7 @@ pub const Tokenizer = struct {
                     'L' => {
                         state = .L;
                     },
-                    'a'...'t', 'v'...'z', 'A'...'K', 'M'...'T', 'V'...'Z', '_' => {
+                    'a'...'t', 'v'...'z', 'A'...'K', 'M'...'T', 'V'...'Z', '_', '$' => {
                         state = .Identifier;
                     },
                     '=' => {
@@ -776,7 +776,7 @@ pub const Tokenizer = struct {
                     },
                 },
                 .Identifier => switch (c) {
-                    'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
+                    'a'...'z', 'A'...'Z', '_', '0'...'9', '$' => {},
                     else => {
                         result.id = Token.getKeyword(self.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier;
                         if (self.prev_tok_id == .Hash)
test/run_translated_c.zig
@@ -687,4 +687,20 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
         \\    return 0;
         \\}
     , "");
+
+    cases.add("dollar sign in identifiers",
+        \\#include <stdlib.h>
+        \\#define $FOO 2
+        \\#define $foo bar$
+        \\#define $baz($x) ($x + $FOO)
+        \\int $$$(int $x$) { return $x$ + $FOO; }
+        \\int main() {
+        \\    int bar$ = 42;
+        \\    if ($foo != 42) abort();
+        \\    if (bar$ != 42) abort();
+        \\    if ($baz(bar$) != 44) abort();
+        \\    if ($$$(bar$) != 44) abort();
+        \\    return 0;
+        \\}
+    , "");
 }