diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp | 4 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Marshallers.h | 10 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Parser.cpp | 50 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/VariantValue.cpp | 32 |
4 files changed, 81 insertions, 15 deletions
diff --git a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp index 787b780c424..9cddcf93cae 100644 --- a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp @@ -118,8 +118,8 @@ static StringRef errorTypeToFormatString(Diagnostics::ErrorType Type) { return "Malformed bind() expression."; case Diagnostics::ET_ParserTrailingCode: return "Expected end of code."; - case Diagnostics::ET_ParserUnsignedError: - return "Error parsing unsigned token: <$0>"; + case Diagnostics::ET_ParserNumberError: + return "Error parsing numeric literal: <$0>"; case Diagnostics::ET_ParserOverloadedType: return "Input value has unresolved overloaded type: $0"; diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 1d4ba037fde..c557ff16269 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -75,6 +75,16 @@ template <> struct ArgTypeTraits<bool> { } }; +template <> struct ArgTypeTraits<double> { + static bool is(const VariantValue &Value) { return Value.isDouble(); } + static double get(const VariantValue &Value) { + return Value.getDouble(); + } + static ArgKind getKind() { + return ArgKind(ArgKind::AK_Double); + } +}; + template <> struct ArgTypeTraits<unsigned> { static bool is(const VariantValue &Value) { return Value.isUnsigned(); } static unsigned get(const VariantValue &Value) { 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. diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp index a889e46fd6a..57858d00acb 100644 --- a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp +++ b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp @@ -26,6 +26,8 @@ std::string ArgKind::asString() const { return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str(); case AK_Boolean: return "boolean"; + case AK_Double: + return "double"; case AK_Unsigned: return "unsigned"; case AK_String: @@ -253,6 +255,10 @@ VariantValue::VariantValue(bool Boolean) : Type(VT_Nothing) { setBoolean(Boolean); } +VariantValue::VariantValue(double Double) : Type(VT_Nothing) { + setDouble(Double); +} + VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) { setUnsigned(Unsigned); } @@ -274,6 +280,9 @@ VariantValue &VariantValue::operator=(const VariantValue &Other) { case VT_Boolean: setBoolean(Other.getBoolean()); break; + case VT_Double: + setDouble(Other.getDouble()); + break; case VT_Unsigned: setUnsigned(Other.getUnsigned()); break; @@ -300,6 +309,7 @@ void VariantValue::reset() { break; // Cases that do nothing. case VT_Boolean: + case VT_Double: case VT_Unsigned: case VT_Nothing: break; @@ -322,6 +332,21 @@ void VariantValue::setBoolean(bool NewValue) { Value.Boolean = NewValue; } +bool VariantValue::isDouble() const { + return Type == VT_Double; +} + +double VariantValue::getDouble() const { + assert(isDouble()); + return Value.Double; +} + +void VariantValue::setDouble(double NewValue) { + reset(); + Type = VT_Double; + Value.Double = NewValue; +} + bool VariantValue::isUnsigned() const { return Type == VT_Unsigned; } @@ -375,6 +400,12 @@ bool VariantValue::isConvertibleTo(ArgKind Kind, unsigned *Specificity) const { *Specificity = 1; return true; + case ArgKind::AK_Double: + if (!isDouble()) + return false; + *Specificity = 1; + return true; + case ArgKind::AK_Unsigned: if (!isUnsigned()) return false; @@ -415,6 +446,7 @@ std::string VariantValue::getTypeAsString() const { case VT_String: return "String"; case VT_Matcher: return getMatcher().getTypeAsString(); case VT_Boolean: return "Boolean"; + case VT_Double: return "Double"; case VT_Unsigned: return "Unsigned"; case VT_Nothing: return "Nothing"; } |