@@ -974,6 +974,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
974974 bool isFixedPointConstant = isFixedPointLiteral ();
975975 bool isFPConstant = isFloatingLiteral ();
976976 bool HasSize = false ;
977+ bool DoubleUnderscore = false ;
977978
978979 // Loop over all of the characters of the suffix. If we see something bad,
979980 // we break out of the loop.
@@ -1117,6 +1118,31 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
11171118 if (isImaginary) break ; // Cannot be repeated.
11181119 isImaginary = true ;
11191120 continue ; // Success.
1121+ case ' _' :
1122+ if (isFPConstant)
1123+ break ; // Invalid for floats
1124+ if (HasSize)
1125+ break ;
1126+ if (DoubleUnderscore)
1127+ break ; // Cannot be repeated.
1128+ if (LangOpts.CPlusPlus && s + 2 < ThisTokEnd &&
1129+ s[1 ] == ' _' ) { // s + 2 < ThisTokEnd to ensure some character exists
1130+ // after __
1131+ DoubleUnderscore = true ;
1132+ s += 2 ; // Skip both '_'
1133+ if (s + 1 < ThisTokEnd &&
1134+ (*s == ' u' || *s == ' U' )) { // Ensure some character after 'u'/'U'
1135+ isUnsigned = true ;
1136+ ++s;
1137+ }
1138+ if (s + 1 < ThisTokEnd &&
1139+ ((*s == ' w' && *(++s) == ' b' ) || (*s == ' W' && *(++s) == ' B' ))) {
1140+ isBitInt = true ;
1141+ HasSize = true ;
1142+ continue ;
1143+ }
1144+ }
1145+ break ;
11201146 case ' w' :
11211147 case ' W' :
11221148 if (isFPConstant)
@@ -1127,9 +1153,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
11271153 // wb and WB are allowed, but a mixture of cases like Wb or wB is not. We
11281154 // explicitly do not support the suffix in C++ as an extension because a
11291155 // library-based UDL that resolves to a library type may be more
1130- // appropriate there.
1131- if (!LangOpts.CPlusPlus && ((s[ 0 ] == ' w ' && s[ 1 ] == ' b ' ) ||
1132- (s[0 ] == ' W' && s[1 ] == ' B' ))) {
1156+ // appropriate there. The same rules apply for __wb/__WB.
1157+ if (( !LangOpts.CPlusPlus || DoubleUnderscore) && s + 1 < ThisTokEnd &&
1158+ ((s[ 0 ] == ' w ' && s[ 1 ] == ' b ' ) || ( s[0 ] == ' W' && s[1 ] == ' B' ))) {
11331159 isBitInt = true ;
11341160 HasSize = true ;
11351161 ++s; // Skip both characters (2nd char skipped on continue).
@@ -1241,7 +1267,9 @@ bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts,
12411267 return false ;
12421268
12431269 // By C++11 [lex.ext]p10, ud-suffixes starting with an '_' are always valid.
1244- if (Suffix[0 ] == ' _' )
1270+ // Suffixes starting with '__' (double underscore) are for use by
1271+ // the implementation.
1272+ if (Suffix.starts_with (" _" ) && !Suffix.starts_with (" __" ))
12451273 return true ;
12461274
12471275 // In C++11, there are no library suffixes.
0 commit comments