diff --git a/clang/Lex/LiteralSupport.cpp b/clang/Lex/LiteralSupport.cpp index 21ead21bfece4adafe06f2fc2ed2bae22a8ce1bf..ebc66271dbd36409ad278592a84b8ba9f585ff87 100644 --- a/clang/Lex/LiteralSupport.cpp +++ b/clang/Lex/LiteralSupport.cpp @@ -410,17 +410,27 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } llvm::APFloat NumericLiteralParser:: -GetFloatValue(const llvm::fltSemantics &Format) { +GetFloatValue(const llvm::fltSemantics &Format, bool* isExact) { + using llvm::APFloat; + char floatChars[256]; strncpy(floatChars, ThisTokBegin, ThisTokEnd-ThisTokBegin); floatChars[ThisTokEnd-ThisTokBegin] = '\0'; -#if 0 - // This doesn't work yet. - return llvm::APFloat(Format, floatChars); + +#if 1 + APFloat V (Format, APFloat::fcZero, false); + + APFloat::opStatus status; + status = V.convertFromString(floatChars,APFloat::rmTowardZero); + + if (isExact) + *isExact = status == APFloat::opOK; + + return V; #else // FIXME: this is horrible! - llvm::APFloat V(strtod(floatChars, 0)); - V.convert(Format, llvm::APFloat::rmTowardZero); + APFloat V(strtod(floatChars, 0)); + V.convert(Format, APFloat::rmTowardZero); return V; #endif } diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index e8650fc8fa70139e1355329ce4a4729cc458feb6..2555660076900f2fee36b4454bbba1bba00a5dbf 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -77,8 +77,11 @@ public: /// GetFloatValue - Convert this numeric literal to a floating value, using /// the specified APFloat fltSemantics (specifying float, double, etc). - /// - llvm::APFloat GetFloatValue(const llvm::fltSemantics &Format); + /// The optional bool isExact (passed-by-reference) has its value + /// set to true if the returned APFloat can represent the number in the + /// literal exactly, and false otherwise. + llvm::APFloat GetFloatValue(const llvm::fltSemantics &Format, + bool* isExact = NULL); private: void Diag(SourceLocation Loc, unsigned DiagID,