diff options
Diffstat (limited to 'clang/lib/ASTMatchers/Dynamic/Parser.cpp')
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Parser.cpp | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/clang/lib/ASTMatchers/Dynamic/Parser.cpp b/clang/lib/ASTMatchers/Dynamic/Parser.cpp index 967da8ac322..ff5c5fb657c 100644 --- a/clang/lib/ASTMatchers/Dynamic/Parser.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Parser.cpp @@ -130,8 +130,8 @@ private: case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - // Parse an unsigned literal. - consumeUnsignedLiteral(&Result); + // Parse an unsigned and float literal. + consumeNumberLiteral(&Result); break; default: @@ -176,8 +176,9 @@ private: return Result; } - /// \brief Consume an unsigned literal. - void consumeUnsignedLiteral(TokenInfo *Result) { + /// \brief Consume an unsigned and float literal. + void consumeNumberLiteral(TokenInfo *Result) { + bool isFloatingLiteral = false; unsigned Length = 1; if (Code.size() > 1) { // Consume the 'x' or 'b' radix modifier, if present. @@ -188,20 +189,43 @@ private: while (Length < Code.size() && isHexDigit(Code[Length])) ++Length; + // Try to recognize a floating point literal. + while (Length < Code.size()) { + char c = Code[Length]; + if (c == '-' || c == '+' || c == '.' || isHexDigit(c)) { + isFloatingLiteral = true; + Length++; + } else { + break; + } + } + Result->Text = Code.substr(0, Length); Code = Code.drop_front(Length); - unsigned Value; - if (!Result->Text.getAsInteger(0, Value)) { - Result->Kind = TokenInfo::TK_Literal; - Result->Value = Value; + if (isFloatingLiteral) { + char *end; + errno = 0; + double doubleValue = strtod(Result->Text.str().c_str(), &end); + if (*end == 0 && errno == 0) { + Result->Kind = TokenInfo::TK_Literal; + Result->Value = doubleValue; + return; + } } else { - SourceRange Range; - Range.Start = Result->Range.Start; - Range.End = currentLocation(); - Error->addError(Range, Error->ET_ParserUnsignedError) << Result->Text; - Result->Kind = TokenInfo::TK_Error; + unsigned Value; + if (!Result->Text.getAsInteger(0, Value)) { + Result->Kind = TokenInfo::TK_Literal; + Result->Value = Value; + return; + } } + + SourceRange Range; + Range.Start = Result->Range.Start; + Range.End = currentLocation(); + Error->addError(Range, Error->ET_ParserNumberError) << Result->Text; + Result->Kind = TokenInfo::TK_Error; } /// \brief Consume a string literal. |