@@ -1928,12 +1928,18 @@ static void collate_id_const(char **writeBufferWriteP, char *lhs, char **rhsP) {
19281928 * rhsP = rhs ; /* Update rhs position after consuming */
19291929}
19301930
1931- /* Collate CONSTANT ## IDENTIFIER -> identifier with constant prepended
1931+ /* Collate CONSTANT ## IDENTIFIER -> constant with suffix, or identifier
19321932 *
19331933 * C99/C11 6.10.3.3: The token resulting from pasting is formed by textual
19341934 * concatenation. For a numeric constant on the left and an identifier on the
1935- * right, the numeric text (including suffix where applicable) precedes the
1936- * identifier text.
1935+ * right, the result depends on whether the identifier is a valid numeric suffix.
1936+ *
1937+ * Common cases:
1938+ * - 42 ## L → 42L (LONG_CONSTANT)
1939+ * - 42 ## U → 42U (CONSTANT, unsigned)
1940+ * - 42 ## UL → 42UL (LONG_CONSTANT, unsigned)
1941+ * - 42 ## LL → 42LL (LONG_CONSTANT, long long)
1942+ * - 42 ## foo → 42foo (IDENTIFIER)
19371943 */
19381944static void collate_const_id (char * * writeBufferWriteP , char * * lhsP , char * * rhsP , LexemCode leftHandLexem ) {
19391945 char * lhs = * lhsP ;
@@ -1945,15 +1951,38 @@ static void collate_const_id(char **writeBufferWriteP, char **lhsP, char **rhsP,
19451951 getLexemCodeAndAdvance (& lhs );
19461952 getExtraLexemInformationFor (leftHandLexem , & lhs , NULL , NULL , & position , NULL , & leftText , false);
19471953
1948- /* Re-write to an IDENTIFIER */
1949- putLexemCodeAndAdvance (IDENTIFIER , & leftHandLexemStart );
1950- * writeBufferWriteP = leftHandLexemStart ; /* We want to write the id next */
1951-
19521954 char * rhs = * rhsP ;
19531955 LexemCode lexem = getLexemCodeAndAdvance (& rhs );
19541956 char * rightHandLexemString = rhs ; /* For an ID the string follows, then the position */
19551957 skipExtraLexemInformationFor (lexem , & rhs );
19561958
1959+ /* Check if the identifier is a numeric suffix (L, U, UL, LL, ULL, etc.) */
1960+ bool isNumericSuffix = (strcmp (rightHandLexemString , "L" ) == 0 ||
1961+ strcmp (rightHandLexemString , "U" ) == 0 ||
1962+ strcmp (rightHandLexemString , "UL" ) == 0 ||
1963+ strcmp (rightHandLexemString , "LU" ) == 0 ||
1964+ strcmp (rightHandLexemString , "LL" ) == 0 ||
1965+ strcmp (rightHandLexemString , "ULL" ) == 0 ||
1966+ strcmp (rightHandLexemString , "LLU" ) == 0 );
1967+
1968+ /* Determine result token type */
1969+ LexemCode resultLexem ;
1970+ if (isNumericSuffix ) {
1971+ /* Suffixes with L or LL make it a LONG_CONSTANT */
1972+ if (strchr (rightHandLexemString , 'L' ) != NULL ) {
1973+ resultLexem = LONG_CONSTANT ;
1974+ } else {
1975+ resultLexem = CONSTANT ; /* Just U suffix */
1976+ }
1977+ } else {
1978+ /* Not a standard suffix, register result as an identifier, altough it's not.. */
1979+ resultLexem = IDENTIFIER ;
1980+ }
1981+
1982+ /* Re-write to the appropriate token type */
1983+ putLexemCodeAndAdvance (resultLexem , & leftHandLexemStart );
1984+ * writeBufferWriteP = leftHandLexemStart ;
1985+
19571986 /* Calculate where RHS starts in the concatenated result */
19581987 int leftPartLength = strlen (leftText );
19591988
0 commit comments