@@ -226,17 +226,47 @@ static BNNameType GetNameType(char elm1, char elm2)
226226 }
227227}
228228
229- static int8_t HexToDec (char c)
229+
230+
231+
232+ // Decode a big-endian hex string into a float or double.
233+ // Returns the decimal string representation, or the raw hex with a type
234+ // prefix if decoding fails or the result is NaN/Inf.
235+ static string DecodeHexFloat (const string& hex, size_t byteCount)
230236{
231- if (isdigit (c))
237+ if (hex.size () != byteCount * 2 )
238+ return hex;
239+
240+ // Parse big-endian hex into an integer, then reinterpret as float/double
241+ uint64_t bits = 0 ;
242+ for (size_t i = 0 ; i < hex.size (); i++)
243+ {
244+ char c = hex[i];
245+ uint64_t nibble;
246+ if (c >= ' 0' && c <= ' 9' ) nibble = c - ' 0' ;
247+ else if (c >= ' a' && c <= ' f' ) nibble = c - ' a' + 10 ;
248+ else if (c >= ' A' && c <= ' F' ) nibble = c - ' A' + 10 ;
249+ else return hex;
250+ bits = (bits << 4 ) | nibble;
251+ }
252+
253+ if (byteCount == 4 )
232254 {
233- return c - ' 0' ;
255+ union { uint32_t i; float f; } u;
256+ u.i = (uint32_t )bits;
257+ if (std::isnan (u.f ) || std::isinf (u.f ))
258+ return " (float)" + hex;
259+ return to_string (u.f );
234260 }
235- else if ( islower (c) && c <= ' f ' )
261+ else if (byteCount == 8 )
236262 {
237- return c - ' a' + 10 ;
263+ union { uint64_t i; double d; } u;
264+ u.i = bits;
265+ if (std::isnan (u.d ) || std::isinf (u.d ))
266+ return " (double)" + hex;
267+ return to_string (u.d );
238268 }
239- return - 1 ;
269+ return hex ;
240270}
241271
242272
@@ -994,8 +1024,6 @@ string DemangleGNU3::DemanglePrimaryExpression()
9941024 char elm1 = ' \0 ' ;
9951025 string out;
9961026 QualifiedName tmpList;
997- string valueString;
998- float f; double d; long double ld;
9991027 bool oldTopLevel;
10001028 // expr-primary
10011029 if (m_reader.PeekString (2 ) == " _Z" )
@@ -1042,41 +1070,17 @@ string DemangleGNU3::DemanglePrimaryExpression()
10421070 else
10431071 throw DemangleException ();
10441072 break ;
1045- case ' d' : // double
1046- valueString = m_reader.ReadString (8 );
1047-
1048- for (size_t i = 0 ; i < valueString.size (); i+=2 )
1049- {
1050- ((unsigned char *)&d)[i/2 ] = (HexToDec (valueString[i]) << 16 ) + HexToDec (valueString[i+1 ]);
1051- }
1052- out += to_string (d);
1073+ case ' d' : // double (16 hex chars = 8 bytes)
1074+ out += DecodeHexFloat (m_reader.ReadString (16 ), 8 );
10531075 break ;
1054- case ' e' : // long double
1055- valueString = m_reader.ReadString (10 );
1056-
1057- for (size_t i = 0 ; i < valueString.size (); i+=2 )
1058- {
1059- ((unsigned char *)&ld)[i/2 ] = (HexToDec (valueString[i]) << 16 ) + HexToDec (valueString[i+1 ]);
1060- }
1061- out += to_string (ld);
1076+ case ' e' : // long double (20 hex chars = 10 bytes, platform-dependent layout)
1077+ out += " (long double)" + m_reader.ReadString (20 );
10621078 break ;
1063- case ' f' : // float
1064- valueString = m_reader.ReadString (4 );
1065-
1066- for (size_t i = 0 ; i < valueString.size (); i+=2 )
1067- {
1068- ((unsigned char *)&f)[i/2 ] = (HexToDec (valueString[i]) << 16 ) + HexToDec (valueString[i+1 ]);
1069- }
1070- out += to_string (f);
1079+ case ' f' : // float (8 hex chars = 4 bytes)
1080+ out += DecodeHexFloat (m_reader.ReadString (8 ), 4 );
10711081 break ;
1072- case ' g' : // float_128
1073- valueString = m_reader.ReadString (16 ); // We read 16 but then just throw away
1074-
1075- for (size_t i = 0 ; i < 10 ; i+=2 )
1076- {
1077- ((unsigned char *)&ld)[i/2 ] = (HexToDec (valueString[i]) << 16 ) + HexToDec (valueString[i+1 ]);
1078- }
1079- out += to_string (ld);
1082+ case ' g' : // float_128 (32 hex chars = 16 bytes)
1083+ out += " (__float128)" + m_reader.ReadString (32 );
10801084 break ;
10811085 case ' l' : out = DemangleNumberAsString () + " l" ; break ; // long
10821086 case ' x' : out = DemangleNumberAsString () + " ll" ; break ; // long long
0 commit comments