Add some overloads so that floating point literals can be AST matched properly.
authorDaniel Jasper <djasper@google.com>
Mon, 2 Feb 2015 23:04:00 +0000 (23:04 +0000)
committerDaniel Jasper <djasper@google.com>
Mon, 2 Feb 2015 23:04:00 +0000 (23:04 +0000)
I am not entirely sure whether the implemented sematics are ideal. In
particular, should floatLiteral(equals(0.5)) match "0.5f" and should
floatLiteral(equals(0.5f)) match "0.5". With the overloads in this
patch, the answer to both questions is yes, but I am happy to change
that.

llvm-svn: 227892

clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/unittests/ASTMatchers/ASTMatchersTest.cpp

index ebe5cdd..bc979b2 100644 (file)
@@ -1456,6 +1456,32 @@ private:
   const ValueT ExpectedValue;
 };
 
+template <>
+bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
+    const FloatingLiteral &Node) const {
+  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
+    return Node.getValue().convertToFloat() == ExpectedValue;
+  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
+    return Node.getValue().convertToDouble() == ExpectedValue;
+  return false;
+}
+
+template <>
+bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
+    const FloatingLiteral &Node) const {
+  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
+    return Node.getValue().convertToFloat() == ExpectedValue;
+  if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
+    return Node.getValue().convertToDouble() == ExpectedValue;
+  return false;
+}
+
+template <>
+bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
+    const FloatingLiteral &Node) const {
+  return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
+}
+
 /// \brief A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
 /// variadic functor that takes a number of Matcher<TargetT> and returns a
 /// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
index d2e9ee1..9cc011d 100644 (file)
@@ -2104,8 +2104,16 @@ TEST(Matcher, FloatLiterals) {
   EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
   EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
   EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
+  EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));
+  EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));
+  EXPECT_TRUE(
+      matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));
 
   EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
+  EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));
+  EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));
+  EXPECT_TRUE(
+      notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));
 }
 
 TEST(Matcher, NullPtrLiteral) {