+98
−0
+101
−21
+4
−4
Loading
Translate used the preprocessor's #if evaluator to assign a value to every object-like constant macro, and that evaluator treats each identifier it meets, sizeof included, as 0: sizeof(T)*N came out as 0, (N-8)/sizeof(T) as N-8, an enumeration constant or a cast as 0 and a floating point expression as 0. ccgo then emitted const WALINDEX_PGSZ = 0 and const M_PI = 0 for SQLite, and const SQLITE_PRIVATE = 0 for a macro that is not an expression at all. The macro-expanded replacement list is now parsed and type checked as a C expression in the file scope of the translation unit, with everything the unit declares visible, so sizeof, casts, enumeration constants and typedef names have their C meaning. A macro whose expansion is not a constant expression gets no value; there is no fallback to the #if evaluator any more. Anything the throwaway parse declares lands in a child scope, the file scope itself is not touched. AST.check returns its context so that Translate can check the expressions against the unit. On the 3.53.4 amalgamation 3809 of the 4691 object-like macros get a value (1645 had one from their use sites before), for no measurable cost on top of the 2.6 s translation. In the ccgo output for SQLite this changes 235 exported constants: 70 zeros become the right number, 41 constants appear (casts, sizeof, enumeration constants), 19 bogus values disappear (RESERVED_BYTE, errno, INFINITY, ...), 97 macros that merely name another identifier fall back to ccgo's alias string form, and 8 numbers change: three sizeof fixes and pointer casts like ((void*)-1), which are all-ones now instead of -1. Found by hazyhaar while working on sqlite#221 (libsqlite3!4). Co-Authored-By:Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DPoSMckkK9hLqU8t3ATQHr