[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-13 Thread Dmitri Gribenko via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL363262: Added AST matcher for ignoring elidable constructors 
(authored by gribozavr, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D63149?vs=204447=204522#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  cfe/trunk/docs/LibASTMatchersReference.html
  cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
  cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
  cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h

Index: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -320,6 +320,7 @@
   REGISTER_MATCHER(hasUnqualifiedDesugaredType);
   REGISTER_MATCHER(hasValueType);
   REGISTER_MATCHER(ifStmt);
+  REGISTER_MATCHER(ignoringElidableConstructorCall);
   REGISTER_MATCHER(ignoringImpCasts);
   REGISTER_MATCHER(ignoringImplicit);
   REGISTER_MATCHER(ignoringParenCasts);
Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,74 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(B(1));"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableConstructorCall(callExpr()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(1);"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
+ integerLiteral()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(matches(
+  "struct H {};"
+  "H G();"
+  "void f() {"
+  "  H D = G();"
+  "}",
+  varDecl(hasInitializer(anyOf(
+  ignoringElidableConstructorCall(callExpr()),
+  exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())),
+  LanguageMode::Cxx11OrLater));
+}
+
+TEST(Matcher, IgnoresElidableInReturn) {
+  auto matcher = expr(ignoringElidableConstructorCall(declRefExpr()));
+  EXPECT_TRUE(matches("struct H {};"
+  "H f() {"
+  "  H g;"
+  "  return g;"
+  "}",
+  matcher, LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(notMatches("struct H {};"
+ "H f() {"
+ "  return H();"
+ "}",
+ matcher, LanguageMode::Cxx11OrLater));
+}
+
+TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
+  EXPECT_TRUE(matches("struct H {};"
+  "void f() {"
+  "  H D;"
+  "}",
+  varDecl(hasInitializer(
+  ignoringElidableConstructorCall(cxxConstructExpr(,
+  LanguageMode::Cxx11OrLater));
+}
+
+TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
+  EXPECT_TRUE(matches("void f() {"
+  "  int D = 10;"
+  "}",
+  expr(ignoringElidableConstructorCall(integerLiteral())),
+  LanguageMode::Cxx11OrLater));
+}
+
 TEST(Matcher, BindTheSameNameInAlternatives) {
   StatementMatcher matcher = anyOf(
 binaryOperator(hasOperatorName("+"),
@@ -914,10 +982,10 @@
   varDecl(hasName("foo"), isConstexpr(;
   EXPECT_TRUE(matches("constexpr int bar();",
   functionDecl(hasName("bar"), isConstexpr(;
-  EXPECT_TRUE(matchesConditionally("void baz() { if constexpr(1 > 0) {} }",
-   ifStmt(isConstexpr()), true, "-std=c++17"));
-  EXPECT_TRUE(matchesConditionally("void baz() { if (1 > 0) {} }",
-   ifStmt(isConstexpr()), false, "-std=c++17"));
+  EXPECT_TRUE(matches("void baz() { if constexpr(1 > 0) {} }",
+  ifStmt(isConstexpr()), LanguageMode::Cxx17OrLater));
+  EXPECT_TRUE(notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConstexpr()),
+ 

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-13 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom marked an inline comment as done.
jvikstrom added inline comments.



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:153
+  case LanguageMode::Cxx2aOrLater:
+LangModes = {LanguageMode::Cxx2a};
+  }

hokein wrote:
> nit: add a llvm_unreachable for `default`.
But the switch covers all enum values so that would give warnings


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-13 Thread Haojian Wu via Phabricator via cfe-commits
hokein accepted this revision.
hokein added a comment.
This revision is now accepted and ready to land.

thanks, looks good to me. I'll commit for you. @gribozavr do you want to take 
another look on the patch?




Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:153
+  case LanguageMode::Cxx2aOrLater:
+LangModes = {LanguageMode::Cxx2a};
+  }

hokein wrote:
> nit: add a llvm_unreachable for `default`.
this is not done?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-13 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204447.
jvikstrom marked 3 inline comments as done.
jvikstrom added a comment.

- Removed unnecessary return


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTest.h

Index: clang/unittests/ASTMatchers/ASTMatchersTest.h
===
--- clang/unittests/ASTMatchers/ASTMatchersTest.h
+++ clang/unittests/ASTMatchers/ASTMatchersTest.h
@@ -57,6 +57,17 @@
   const std::unique_ptr FindResultReviewer;
 };
 
+enum class LanguageMode {
+  Cxx11,
+  Cxx14,
+  Cxx17,
+  Cxx2a,
+  Cxx11OrLater,
+  Cxx14OrLater,
+  Cxx17OrLater,
+  Cxx2aOrLater
+};
+
 template 
 testing::AssertionResult matchesConditionally(
 const std::string , const T , bool ExpectMatch,
@@ -116,14 +127,71 @@
 }
 
 template 
-testing::AssertionResult matches(const std::string , const T ) {
-  return matchesConditionally(Code, AMatcher, true, "-std=c++11");
+testing::AssertionResult
+matchesConditionally(const std::string , const T ,
+ bool ExpectMatch, const LanguageMode ) {
+  std::vector LangModes;
+  switch (Mode) {
+  case LanguageMode::Cxx11:
+  case LanguageMode::Cxx14:
+  case LanguageMode::Cxx17:
+  case LanguageMode::Cxx2a:
+LangModes = {Mode};
+break;
+  case LanguageMode::Cxx11OrLater:
+LangModes = {LanguageMode::Cxx11, LanguageMode::Cxx14, LanguageMode::Cxx17,
+ LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx14OrLater:
+LangModes = {LanguageMode::Cxx14, LanguageMode::Cxx17, LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx17OrLater:
+LangModes = {LanguageMode::Cxx17, LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx2aOrLater:
+LangModes = {LanguageMode::Cxx2a};
+  }
+
+  for (auto Mode : LangModes) {
+std::string LangModeArg;
+switch (Mode) {
+case LanguageMode::Cxx11:
+  LangModeArg = "-std=c++11";
+  break;
+case LanguageMode::Cxx14:
+  LangModeArg = "-std=c++14";
+  break;
+case LanguageMode::Cxx17:
+  LangModeArg = "-std=c++17";
+  break;
+case LanguageMode::Cxx2a:
+  LangModeArg = "-std=c++2a";
+  break;
+default:
+  llvm_unreachable("Invalid language mode");
+}
+
+auto Result =
+matchesConditionally(Code, AMatcher, ExpectMatch, LangModeArg);
+if (!Result)
+  return Result;
+  }
+
+  return testing::AssertionSuccess();
+}
+
+template 
+testing::AssertionResult
+matches(const std::string , const T ,
+const LanguageMode  = LanguageMode::Cxx11) {
+  return matchesConditionally(Code, AMatcher, true, Modes);
 }
 
 template 
-testing::AssertionResult notMatches(const std::string ,
-const T ) {
-  return matchesConditionally(Code, AMatcher, false, "-std=c++11");
+testing::AssertionResult
+notMatches(const std::string , const T ,
+   const LanguageMode  = LanguageMode::Cxx11) {
+  return matchesConditionally(Code, AMatcher, false, Modes);
 }
 
 template 
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,74 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(B(1));"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableConstructorCall(callExpr()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(1);"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
+ integerLiteral()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(matches(
+  "struct H {};"
+  "H G();"
+  "void f() {"
+  "  H D = G();"
+  "}",
+  varDecl(hasInitializer(anyOf(
+  ignoringElidableConstructorCall(callExpr()),
+  exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())),
+  LanguageMode::Cxx11OrLater));
+}
+
+TEST(Matcher, IgnoresElidableInReturn) {
+  auto matcher = 

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-13 Thread Haojian Wu via Phabricator via cfe-commits
hokein added a comment.

looks most good to me, a few nits.




Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6488
+  }
+  return InnerMatcher.matches(*CtorExpr, Finder, Builder);
+}

This `return` statement is not needed.



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:16
 #include "gtest/gtest.h"
+#include 
 

looks like the `include` is not used?



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:153
+  case LanguageMode::Cxx2aOrLater:
+LangModes = {LanguageMode::Cxx2a};
+  }

nit: add a llvm_unreachable for `default`.



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:177
+matchesConditionally(Code, AMatcher, ExpectMatch, LangModeArg);
+if (!Result) {
+  return Result;

nit: no `{}` needed for a single-statement body.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-13 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204443.
jvikstrom marked an inline comment as done.
jvikstrom added a comment.

- Removed dependency on unordered map


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTest.h

Index: clang/unittests/ASTMatchers/ASTMatchersTest.h
===
--- clang/unittests/ASTMatchers/ASTMatchersTest.h
+++ clang/unittests/ASTMatchers/ASTMatchersTest.h
@@ -57,6 +57,17 @@
   const std::unique_ptr FindResultReviewer;
 };
 
+enum class LanguageMode {
+  Cxx11,
+  Cxx14,
+  Cxx17,
+  Cxx2a,
+  Cxx11OrLater,
+  Cxx14OrLater,
+  Cxx17OrLater,
+  Cxx2aOrLater
+};
+
 template 
 testing::AssertionResult matchesConditionally(
 const std::string , const T , bool ExpectMatch,
@@ -116,14 +127,72 @@
 }
 
 template 
-testing::AssertionResult matches(const std::string , const T ) {
-  return matchesConditionally(Code, AMatcher, true, "-std=c++11");
+testing::AssertionResult
+matchesConditionally(const std::string , const T ,
+ bool ExpectMatch, const LanguageMode ) {
+  std::vector LangModes;
+  switch (Mode) {
+  case LanguageMode::Cxx11:
+  case LanguageMode::Cxx14:
+  case LanguageMode::Cxx17:
+  case LanguageMode::Cxx2a:
+LangModes = {Mode};
+break;
+  case LanguageMode::Cxx11OrLater:
+LangModes = {LanguageMode::Cxx11, LanguageMode::Cxx14, LanguageMode::Cxx17,
+ LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx14OrLater:
+LangModes = {LanguageMode::Cxx14, LanguageMode::Cxx17, LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx17OrLater:
+LangModes = {LanguageMode::Cxx17, LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx2aOrLater:
+LangModes = {LanguageMode::Cxx2a};
+  }
+
+  for (auto Mode : LangModes) {
+std::string LangModeArg;
+switch (Mode) {
+case LanguageMode::Cxx11:
+  LangModeArg = "-std=c++11";
+  break;
+case LanguageMode::Cxx14:
+  LangModeArg = "-std=c++14";
+  break;
+case LanguageMode::Cxx17:
+  LangModeArg = "-std=c++17";
+  break;
+case LanguageMode::Cxx2a:
+  LangModeArg = "-std=c++2a";
+  break;
+default:
+  llvm_unreachable("Invalid language mode");
+}
+
+auto Result =
+matchesConditionally(Code, AMatcher, ExpectMatch, LangModeArg);
+if (!Result) {
+  return Result;
+}
+  }
+
+  return testing::AssertionSuccess();
 }
 
 template 
-testing::AssertionResult notMatches(const std::string ,
-const T ) {
-  return matchesConditionally(Code, AMatcher, false, "-std=c++11");
+testing::AssertionResult
+matches(const std::string , const T ,
+const LanguageMode  = LanguageMode::Cxx11) {
+  return matchesConditionally(Code, AMatcher, true, Modes);
+}
+
+template 
+testing::AssertionResult
+notMatches(const std::string , const T ,
+   const LanguageMode  = LanguageMode::Cxx11) {
+  return matchesConditionally(Code, AMatcher, false, Modes);
 }
 
 template 
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,74 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(B(1));"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableConstructorCall(callExpr()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(1);"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
+ integerLiteral()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(matches(
+  "struct H {};"
+  "H G();"
+  "void f() {"
+  "  H D = G();"
+  "}",
+  varDecl(hasInitializer(anyOf(
+  ignoringElidableConstructorCall(callExpr()),
+  exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())),
+  LanguageMode::Cxx11OrLater));
+}
+
+TEST(Matcher, IgnoresElidableInReturn) {
+  auto matcher = 

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-13 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204442.
jvikstrom added a comment.

- Updated outdated docs


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTest.h

Index: clang/unittests/ASTMatchers/ASTMatchersTest.h
===
--- clang/unittests/ASTMatchers/ASTMatchersTest.h
+++ clang/unittests/ASTMatchers/ASTMatchersTest.h
@@ -13,6 +13,7 @@
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
+#include 
 
 namespace clang {
 namespace ast_matchers {
@@ -57,6 +58,17 @@
   const std::unique_ptr FindResultReviewer;
 };
 
+enum class LanguageMode {
+  Cxx11,
+  Cxx14,
+  Cxx17,
+  Cxx2a,
+  Cxx11OrLater,
+  Cxx14OrLater,
+  Cxx17OrLater,
+  Cxx2aOrLater
+};
+
 template 
 testing::AssertionResult matchesConditionally(
 const std::string , const T , bool ExpectMatch,
@@ -116,14 +128,72 @@
 }
 
 template 
-testing::AssertionResult matches(const std::string , const T ) {
-  return matchesConditionally(Code, AMatcher, true, "-std=c++11");
+testing::AssertionResult
+matchesConditionally(const std::string , const T ,
+ bool ExpectMatch, const LanguageMode ) {
+  std::vector LangModes;
+  switch (Mode) {
+  case LanguageMode::Cxx11:
+  case LanguageMode::Cxx14:
+  case LanguageMode::Cxx17:
+  case LanguageMode::Cxx2a:
+LangModes = {Mode};
+break;
+  case LanguageMode::Cxx11OrLater:
+LangModes = {LanguageMode::Cxx11, LanguageMode::Cxx14, LanguageMode::Cxx17,
+ LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx14OrLater:
+LangModes = {LanguageMode::Cxx14, LanguageMode::Cxx17, LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx17OrLater:
+LangModes = {LanguageMode::Cxx17, LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx2aOrLater:
+LangModes = {LanguageMode::Cxx2a};
+  }
+
+  for (auto Mode : LangModes) {
+std::string LangModeArg;
+switch (Mode) {
+case LanguageMode::Cxx11:
+  LangModeArg = "-std=c++11";
+  break;
+case LanguageMode::Cxx14:
+  LangModeArg = "-std=c++14";
+  break;
+case LanguageMode::Cxx17:
+  LangModeArg = "-std=c++17";
+  break;
+case LanguageMode::Cxx2a:
+  LangModeArg = "-std=c++2a";
+  break;
+default:
+  llvm_unreachable("Invalid language mode");
+}
+
+auto Result =
+matchesConditionally(Code, AMatcher, ExpectMatch, LangModeArg);
+if (!Result) {
+  return Result;
+}
+  }
+
+  return testing::AssertionSuccess();
 }
 
 template 
-testing::AssertionResult notMatches(const std::string ,
-const T ) {
-  return matchesConditionally(Code, AMatcher, false, "-std=c++11");
+testing::AssertionResult
+matches(const std::string , const T ,
+const LanguageMode  = LanguageMode::Cxx11) {
+  return matchesConditionally(Code, AMatcher, true, Modes);
+}
+
+template 
+testing::AssertionResult
+notMatches(const std::string , const T ,
+   const LanguageMode  = LanguageMode::Cxx11) {
+  return matchesConditionally(Code, AMatcher, false, Modes);
 }
 
 template 
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,74 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(B(1));"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableConstructorCall(callExpr()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(1);"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
+ integerLiteral()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(matches(
+  "struct H {};"
+  "H G();"
+  "void f() {"
+  "  H D = G();"
+  "}",
+  varDecl(hasInitializer(anyOf(
+  ignoringElidableConstructorCall(callExpr()),
+  exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())),
+  

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-13 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204437.
jvikstrom marked an inline comment as done.
jvikstrom added a comment.

- Added default to switch for language modes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTest.h

Index: clang/unittests/ASTMatchers/ASTMatchersTest.h
===
--- clang/unittests/ASTMatchers/ASTMatchersTest.h
+++ clang/unittests/ASTMatchers/ASTMatchersTest.h
@@ -13,6 +13,7 @@
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
+#include 
 
 namespace clang {
 namespace ast_matchers {
@@ -57,6 +58,17 @@
   const std::unique_ptr FindResultReviewer;
 };
 
+enum class LanguageMode {
+  Cxx11,
+  Cxx14,
+  Cxx17,
+  Cxx2a,
+  Cxx11OrLater,
+  Cxx14OrLater,
+  Cxx17OrLater,
+  Cxx2aOrLater
+};
+
 template 
 testing::AssertionResult matchesConditionally(
 const std::string , const T , bool ExpectMatch,
@@ -116,14 +128,72 @@
 }
 
 template 
-testing::AssertionResult matches(const std::string , const T ) {
-  return matchesConditionally(Code, AMatcher, true, "-std=c++11");
+testing::AssertionResult
+matchesConditionally(const std::string , const T ,
+ bool ExpectMatch, const LanguageMode ) {
+  std::vector LangModes;
+  switch (Mode) {
+  case LanguageMode::Cxx11:
+  case LanguageMode::Cxx14:
+  case LanguageMode::Cxx17:
+  case LanguageMode::Cxx2a:
+LangModes = {Mode};
+break;
+  case LanguageMode::Cxx11OrLater:
+LangModes = {LanguageMode::Cxx11, LanguageMode::Cxx14, LanguageMode::Cxx17,
+ LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx14OrLater:
+LangModes = {LanguageMode::Cxx14, LanguageMode::Cxx17, LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx17OrLater:
+LangModes = {LanguageMode::Cxx17, LanguageMode::Cxx2a};
+break;
+  case LanguageMode::Cxx2aOrLater:
+LangModes = {LanguageMode::Cxx2a};
+  }
+
+  for (auto Mode : LangModes) {
+std::string LangModeArg;
+switch (Mode) {
+case LanguageMode::Cxx11:
+  LangModeArg = "-std=c++11";
+  break;
+case LanguageMode::Cxx14:
+  LangModeArg = "-std=c++14";
+  break;
+case LanguageMode::Cxx17:
+  LangModeArg = "-std=c++17";
+  break;
+case LanguageMode::Cxx2a:
+  LangModeArg = "-std=c++2a";
+  break;
+default:
+  llvm_unreachable("Invalid language mode");
+}
+
+auto Result =
+matchesConditionally(Code, AMatcher, ExpectMatch, LangModeArg);
+if (!Result) {
+  return Result;
+}
+  }
+
+  return testing::AssertionSuccess();
 }
 
 template 
-testing::AssertionResult notMatches(const std::string ,
-const T ) {
-  return matchesConditionally(Code, AMatcher, false, "-std=c++11");
+testing::AssertionResult
+matches(const std::string , const T ,
+const LanguageMode  = LanguageMode::Cxx11) {
+  return matchesConditionally(Code, AMatcher, true, Modes);
+}
+
+template 
+testing::AssertionResult
+notMatches(const std::string , const T ,
+   const LanguageMode  = LanguageMode::Cxx11) {
+  return matchesConditionally(Code, AMatcher, false, Modes);
 }
 
 template 
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,74 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(B(1));"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableConstructorCall(callExpr()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(1);"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
+ integerLiteral()),
+  LanguageMode::Cxx11OrLater));
+  EXPECT_TRUE(matches(
+  "struct H {};"
+  "H G();"
+  "void f() {"
+  "  H D = G();"
+  "}",
+  varDecl(hasInitializer(anyOf(
+  ignoringElidableConstructorCall(callExpr()),
+  

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr added inline comments.



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:69
+  CXX17OrLater,
+  CXX2AOrLater
+};

Cxx2aOrLater?

(no need to uppercase things)



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:159
+switch (Mode) {
+case LanguageMode::CXX11OrLater:
+case LanguageMode::CXX11:

The "orlater" variants should not appear here, please use "default: 
llvm_unreachable()".


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204282.
jvikstrom marked 7 inline comments as done.
jvikstrom added a comment.

- Using switch for choosing language standard


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTest.h

Index: clang/unittests/ASTMatchers/ASTMatchersTest.h
===
--- clang/unittests/ASTMatchers/ASTMatchersTest.h
+++ clang/unittests/ASTMatchers/ASTMatchersTest.h
@@ -13,6 +13,7 @@
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
+#include 
 
 namespace clang {
 namespace ast_matchers {
@@ -57,6 +58,17 @@
   const std::unique_ptr FindResultReviewer;
 };
 
+enum class LanguageMode {
+  CXX11,
+  CXX14,
+  CXX17,
+  CXX2A,
+  CXX11OrLater,
+  CXX14OrLater,
+  CXX17OrLater,
+  CXX2AOrLater
+};
+
 template 
 testing::AssertionResult matchesConditionally(
 const std::string , const T , bool ExpectMatch,
@@ -116,14 +128,73 @@
 }
 
 template 
-testing::AssertionResult matches(const std::string , const T ) {
-  return matchesConditionally(Code, AMatcher, true, "-std=c++11");
+testing::AssertionResult
+matchesConditionally(const std::string , const T ,
+ bool ExpectMatch, const LanguageMode ) {
+  std::vector LangModes;
+  switch (Mode) {
+  case LanguageMode::CXX11:
+  case LanguageMode::CXX14:
+  case LanguageMode::CXX17:
+  case LanguageMode::CXX2A:
+LangModes = {Mode};
+break;
+  case LanguageMode::CXX11OrLater:
+LangModes = {LanguageMode::CXX11, LanguageMode::CXX14, LanguageMode::CXX17,
+ LanguageMode::CXX2A};
+break;
+  case LanguageMode::CXX14OrLater:
+LangModes = {LanguageMode::CXX14, LanguageMode::CXX17, LanguageMode::CXX2A};
+break;
+  case LanguageMode::CXX17OrLater:
+LangModes = {LanguageMode::CXX17, LanguageMode::CXX2A};
+break;
+  case LanguageMode::CXX2AOrLater:
+LangModes = {LanguageMode::CXX2A};
+  }
+
+  for (auto Mode : LangModes) {
+std::string LangModeArg;
+switch (Mode) {
+case LanguageMode::CXX11OrLater:
+case LanguageMode::CXX11:
+  LangModeArg = "-std=c++11";
+  break;
+case LanguageMode::CXX14OrLater:
+case LanguageMode::CXX14:
+  LangModeArg = "-std=c++14";
+  break;
+case LanguageMode::CXX17OrLater:
+case LanguageMode::CXX17:
+  LangModeArg = "-std=c++17";
+  break;
+case LanguageMode::CXX2AOrLater:
+case LanguageMode::CXX2A:
+  LangModeArg = "-std=c++2a";
+}
+
+auto Result =
+matchesConditionally(Code, AMatcher, ExpectMatch, LangModeArg);
+if (!Result) {
+  return Result;
+}
+  }
+
+  return testing::AssertionSuccess();
 }
 
 template 
-testing::AssertionResult notMatches(const std::string ,
-const T ) {
-  return matchesConditionally(Code, AMatcher, false, "-std=c++11");
+testing::AssertionResult
+matches(const std::string , const T ,
+const LanguageMode  = LanguageMode::CXX11) {
+  return matchesConditionally(Code, AMatcher, true, Modes);
+}
+
+template 
+testing::AssertionResult
+notMatches(const std::string , const T ,
+   const LanguageMode  = LanguageMode::CXX11) {
+  return matchesConditionally(Code, AMatcher, false, Modes);
 }
 
 template 
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,74 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(B(1));"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableConstructorCall(callExpr()),
+  LanguageMode::CXX11OrLater));
+  EXPECT_TRUE(
+  matches("struct H {};"
+  "template H B(T A);"
+  "void f() {"
+  "  H D1;"
+  "  D1 = B(1);"
+  "}",
+  cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
+ integerLiteral()),
+  LanguageMode::CXX11OrLater));
+  EXPECT_TRUE(matches(
+  "struct H {};"
+  "H G();"
+  "void f() {"
+  "  H D = G();"
+  "}",
+  varDecl(hasInitializer(anyOf(
+  

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr added inline comments.



Comment at: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp:600
+  EXPECT_TRUE(matches(code2, matcher2, LanguageMode::CXX11OrLater));
+  EXPECT_TRUE(matches(code3, matcher3, LanguageMode::CXX11OrLater));
+}

Please inline the variables that are used once.



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:61
+enum class LanguageMode : int {
+  CXX11 = 0,
+  CXX14 = 1,

Please drop the explicit values.



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:64
+  CXX17 = 2,
+  CXX20 = 3,
+  CXX11OrLater,

2a



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:68
+  CXX17OrLater,
+  CXX20OrLater
+};

"2a" (we don't know the year yet)



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:144
+  case LanguageMode::CXX11OrLater:
+LangModes = {LanguageMode::CXX11, LanguageMode::CXX14, 
LanguageMode::CXX17, LanguageMode::CXX20};
+break;

80 columns.



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:154
+LangModes = {LanguageMode::CXX20};
+  };
+

No need for semicolon.



Comment at: clang/unittests/ASTMatchers/ASTMatchersTest.h:157
+  for (auto Mode : LangModes) {
+auto LangModeArg = LangModeStrings[static_cast(Mode)];
+auto Result =

I'd say it is too clever, and suggest to write an explicit switch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204277.
jvikstrom marked 10 inline comments as done.
jvikstrom added a comment.

- Fixed wrong formatting in test code


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTest.h

Index: clang/unittests/ASTMatchers/ASTMatchersTest.h
===
--- clang/unittests/ASTMatchers/ASTMatchersTest.h
+++ clang/unittests/ASTMatchers/ASTMatchersTest.h
@@ -57,6 +57,17 @@
   const std::unique_ptr FindResultReviewer;
 };
 
+enum class LanguageMode : int {
+  CXX11 = 0,
+  CXX14 = 1,
+  CXX17 = 2,
+  CXX20 = 3,
+  CXX11OrLater,
+  CXX14OrLater,
+  CXX17OrLater,
+  CXX20OrLater
+};
+
 template 
 testing::AssertionResult matchesConditionally(
 const std::string , const T , bool ExpectMatch,
@@ -116,14 +127,56 @@
 }
 
 template 
-testing::AssertionResult matches(const std::string , const T ) {
-  return matchesConditionally(Code, AMatcher, true, "-std=c++11");
+testing::AssertionResult
+matchesConditionally(const std::string , const T ,
+ bool ExpectMatch, const LanguageMode ) {
+  std::vector LangModeStrings{"-std=c++11", "-std=c++14",
+   "-std=c++17", "-std=c++20"};
+  std::vector LangModes;
+  switch (Mode) {
+  case LanguageMode::CXX11:
+  case LanguageMode::CXX14:
+  case LanguageMode::CXX17:
+  case LanguageMode::CXX20:
+LangModes = {Mode};
+break;
+  case LanguageMode::CXX11OrLater:
+LangModes = {LanguageMode::CXX11, LanguageMode::CXX14, LanguageMode::CXX17, LanguageMode::CXX20};
+break;
+  case LanguageMode::CXX14OrLater:
+LangModes = {LanguageMode::CXX14, LanguageMode::CXX17, LanguageMode::CXX20};
+break;
+  case LanguageMode::CXX17OrLater:
+LangModes = {LanguageMode::CXX17, LanguageMode::CXX20};
+break;
+  case LanguageMode::CXX20OrLater:
+LangModes = {LanguageMode::CXX20};
+  };
+
+  for (auto Mode : LangModes) {
+auto LangModeArg = LangModeStrings[static_cast(Mode)];
+auto Result =
+matchesConditionally(Code, AMatcher, ExpectMatch, LangModeArg);
+if (!Result) {
+  return Result;
+}
+  }
+
+  return testing::AssertionSuccess();
 }
 
 template 
-testing::AssertionResult notMatches(const std::string ,
-const T ) {
-  return matchesConditionally(Code, AMatcher, false, "-std=c++11");
+testing::AssertionResult
+matches(const std::string , const T ,
+const LanguageMode  = LanguageMode::CXX11) {
+  return matchesConditionally(Code, AMatcher, true, Modes);
+}
+
+template 
+testing::AssertionResult
+notMatches(const std::string , const T ,
+   const LanguageMode  = LanguageMode::CXX11) {
+  return matchesConditionally(Code, AMatcher, false, Modes);
 }
 
 template 
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,73 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  auto matcher1 = cxxOperatorCallExpr(hasArgument(
+  1,
+  callExpr(hasArgument(0, ignoringElidableConstructorCall(callExpr());
+  auto matcher2 = cxxOperatorCallExpr(
+  hasArgument(1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
+ integerLiteral());
+  auto matcher3 = varDecl(hasInitializer(anyOf(
+  ignoringElidableConstructorCall(callExpr()),
+  exprWithCleanups(has(ignoringElidableConstructorCall(callExpr()));
+
+  auto code1 = "struct H {};"
+   "template H B(T A);"
+   "void f() {"
+   "  H D1;"
+   "  D1 = B(B(1));"
+   "}";
+  auto code2 = "struct H {};"
+   "template H B(T A);"
+   "void f() {"
+   "  H D1;"
+   "  D1 = B(1);"
+   "}";
+  auto code3 = "struct H {};"
+   "H G();"
+   "void f() {"
+   "  H D = G();"
+   "}";
+
+  EXPECT_TRUE(matches(code1, matcher1, LanguageMode::CXX11OrLater));
+  EXPECT_TRUE(matches(code2, matcher2, LanguageMode::CXX11OrLater));
+  EXPECT_TRUE(matches(code3, matcher3, LanguageMode::CXX11OrLater));
+}
+
+TEST(Matcher, IgnoresElidableInReturn) {
+  auto matcher = expr(ignoringElidableConstructorCall(declRefExpr()));
+  EXPECT_TRUE(matches("struct H {};"
+  "H f() {"
+  "  H g;"
+  "  return g;"
+  "}",

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204269.
jvikstrom marked 3 inline comments as done.
jvikstrom added a comment.

- Added match conditionally overload to control in what language standard a 
match should run in


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTest.h

Index: clang/unittests/ASTMatchers/ASTMatchersTest.h
===
--- clang/unittests/ASTMatchers/ASTMatchersTest.h
+++ clang/unittests/ASTMatchers/ASTMatchersTest.h
@@ -57,6 +57,17 @@
   const std::unique_ptr FindResultReviewer;
 };
 
+enum class LanguageMode : int {
+  CXX11 = 0,
+  CXX14 = 1,
+  CXX17 = 2,
+  CXX20 = 3,
+  CXX11OrLater,
+  CXX14OrLater,
+  CXX17OrLater,
+  CXX20OrLater
+};
+
 template 
 testing::AssertionResult matchesConditionally(
 const std::string , const T , bool ExpectMatch,
@@ -116,14 +127,56 @@
 }
 
 template 
-testing::AssertionResult matches(const std::string , const T ) {
-  return matchesConditionally(Code, AMatcher, true, "-std=c++11");
+testing::AssertionResult
+matchesConditionally(const std::string , const T ,
+ bool ExpectMatch, const LanguageMode ) {
+  std::vector LangModeStrings{"-std=c++11", "-std=c++14",
+   "-std=c++17", "-std=c++20"};
+  std::vector LangModes;
+  switch (Mode) {
+  case LanguageMode::CXX11:
+  case LanguageMode::CXX14:
+  case LanguageMode::CXX17:
+  case LanguageMode::CXX20:
+LangModes = {Mode};
+break;
+  case LanguageMode::CXX11OrLater:
+LangModes = {LanguageMode::CXX11, LanguageMode::CXX14, LanguageMode::CXX17, LanguageMode::CXX20};
+break;
+  case LanguageMode::CXX14OrLater:
+LangModes = {LanguageMode::CXX14, LanguageMode::CXX17, LanguageMode::CXX20};
+break;
+  case LanguageMode::CXX17OrLater:
+LangModes = {LanguageMode::CXX17, LanguageMode::CXX20};
+break;
+  case LanguageMode::CXX20OrLater:
+LangModes = {LanguageMode::CXX20};
+  };
+
+  for (auto Mode : LangModes) {
+auto LangModeArg = LangModeStrings[static_cast(Mode)];
+auto Result =
+matchesConditionally(Code, AMatcher, ExpectMatch, LangModeArg);
+if (!Result) {
+  return Result;
+}
+  }
+
+  return testing::AssertionSuccess();
 }
 
 template 
-testing::AssertionResult notMatches(const std::string ,
-const T ) {
-  return matchesConditionally(Code, AMatcher, false, "-std=c++11");
+testing::AssertionResult
+matches(const std::string , const T ,
+const LanguageMode  = LanguageMode::CXX11) {
+  return matchesConditionally(Code, AMatcher, true, Modes);
+}
+
+template 
+testing::AssertionResult
+notMatches(const std::string , const T ,
+   const LanguageMode  = LanguageMode::CXX11) {
+  return matchesConditionally(Code, AMatcher, false, Modes);
 }
 
 template 
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,76 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  auto matcher1 = cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableConstructorCall(callExpr());
+  auto matcher2 = cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
+ integerLiteral());
+  auto matcher3 =
+  varDecl(hasInitializer(
+anyOf(
+ignoringElidableConstructorCall(callExpr()),
+exprWithCleanups(has(ignoringElidableConstructorCall(callExpr(
+)));
+
+  auto code1 = "struct H {};"
+   "template H B(T A);"
+   "void f() {"
+   "  H D1;"
+   "  D1 = B(B(1));"
+   "}";
+  auto code2 = "struct H {};"
+   "template H B(T A);"
+   "void f() {"
+   "  H D1;"
+   "  D1 = B(1);"
+   "}";
+  auto code3 = "struct H {};"
+   "H G();"
+   "void f() {"
+   "  H D = G();"
+   "}";
+
+  EXPECT_TRUE(matches(code1, matcher1, LanguageMode::CXX11OrLater));
+  EXPECT_TRUE(matches(code2, matcher2, LanguageMode::CXX11OrLater));
+  EXPECT_TRUE(matches(code3, matcher3, LanguageMode::CXX11OrLater));
+}
+
+TEST(Matcher, IgnoresElidableInReturn) {
+  auto matcher = expr(ignoringElidableConstructorCall(declRefExpr()));
+  EXPECT_TRUE(matches("struct H{};"
+  "H f() {"
+ 

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204245.
jvikstrom added a comment.

- Using CamelCase and also renamed ignoringElidableMoveConstructorCall to 
ignoringElidableConstructorCall


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,81 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  auto matcher1 = cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableMoveConstructorCall(callExpr().bind("c"));
+  auto matcher2 = cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableMoveConstructorCall(
+ integerLiteral().bind("c"));
+  auto matcher3 =
+  varDecl(hasInitializer(ignoringElidableMoveConstructorCall(callExpr(;
+
+  auto code1 = "struct H {};"
+   "template H B(T A);"
+   "void f(){"
+   "H D1;"
+   "D1=B(B(1));"
+   "}";
+  auto code2 = "struct H {};"
+   "template H B(T A);"
+   "void f(){"
+   "H D1;"
+   "D1=B(1);"
+   "}";
+  auto code3 = "struct H {};"
+   "H G();"
+   "void f(){"
+   "H D = G();"
+   "}";
+
+  EXPECT_TRUE(matchesConditionally(code1, matcher1, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code1, matcher1, true, "-std=c++17"));
+
+  EXPECT_TRUE(matchesConditionally(code2, matcher2, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code2, matcher2, true, "-std=c++17"));
+
+  EXPECT_TRUE(matchesConditionally(code3, matcher3, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code3, matcher3, true, "-std=c++17"));
+}
+
+TEST(Matcher, IgnoresElidableInReturn) {
+  auto matcher = expr(ignoringElidableMoveConstructorCall(declRefExpr()));
+  auto code1 = "struct H{};"
+   "H f(){"
+   "H g;"
+   "return g;"
+   "}";
+  auto code2 = "struct H{};"
+   "H f(){"
+   "return H();"
+   "}";
+  EXPECT_TRUE(matchesConditionally(code1, matcher, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code1, matcher, true, "-std=c++17"));
+  EXPECT_TRUE(matchesConditionally(code2, matcher, false, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code2, matcher, false, "-std=c++17"));
+}
+
+TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
+  auto matcher = varDecl(
+  hasInitializer(ignoringElidableMoveConstructorCall(cxxConstructExpr(;
+  auto code = "struct H {};"
+  "void f(){"
+  "H D;"
+  "}";
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++17"));
+};
+
+TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
+  auto matcher = expr(ignoringElidableMoveConstructorCall(integerLiteral()));
+  auto code = "void f(){"
+  "int D = 10;"
+  "}";
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++17"));
+}
+
 TEST(Matcher, BindTheSameNameInAlternatives) {
   StatementMatcher matcher = anyOf(
 binaryOperator(hasOperatorName("+"),
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -320,6 +320,7 @@
   REGISTER_MATCHER(hasUnqualifiedDesugaredType);
   REGISTER_MATCHER(hasValueType);
   REGISTER_MATCHER(ifStmt);
+  REGISTER_MATCHER(ignoringElidableMoveConstructorCall);
   REGISTER_MATCHER(ignoringImpCasts);
   REGISTER_MATCHER(ignoringImplicit);
   REGISTER_MATCHER(ignoringParenCasts);
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6452,6 +6452,56 @@
   return false;
 }
 
+/// Matches expressions that match InnerMatcher that are possibly wrapped in an
+/// elidable constructor.
+///
+/// In C++17 copy elidable constructors are no longer being
+/// generated in the AST as it is not permitted by the standard. They are
+/// however part of the AST in C++14 and earlier. Therefore, to write a 

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204244.
jvikstrom marked an inline comment as done.
jvikstrom added a comment.

- Updated example and fixed edge case in ignoringElidableConstructorCall


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,81 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  auto matcher1 = cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableMoveConstructorCall(callExpr().bind("c"));
+  auto matcher2 = cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableMoveConstructorCall(
+ integerLiteral().bind("c"));
+  auto matcher3 =
+  varDecl(hasInitializer(ignoringElidableMoveConstructorCall(callExpr(;
+
+  auto code1 = "struct H {};"
+   "template H B(T A);"
+   "void f(){"
+   "H D1;"
+   "D1=B(B(1));"
+   "}";
+  auto code2 = "struct H {};"
+   "template H B(T A);"
+   "void f(){"
+   "H D1;"
+   "D1=B(1);"
+   "}";
+  auto code3 = "struct H {};"
+   "H G();"
+   "void f(){"
+   "H D = G();"
+   "}";
+
+  EXPECT_TRUE(matchesConditionally(code1, matcher1, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code1, matcher1, true, "-std=c++17"));
+
+  EXPECT_TRUE(matchesConditionally(code2, matcher2, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code2, matcher2, true, "-std=c++17"));
+
+  EXPECT_TRUE(matchesConditionally(code3, matcher3, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code3, matcher3, true, "-std=c++17"));
+}
+
+TEST(Matcher, IgnoresElidableInReturn) {
+  auto matcher = expr(ignoringElidableMoveConstructorCall(declRefExpr()));
+  auto code1 = "struct H{};"
+   "H f(){"
+   "H g;"
+   "return g;"
+   "}";
+  auto code2 = "struct H{};"
+   "H f(){"
+   "return H();"
+   "}";
+  EXPECT_TRUE(matchesConditionally(code1, matcher, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code1, matcher, true, "-std=c++17"));
+  EXPECT_TRUE(matchesConditionally(code2, matcher, false, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code2, matcher, false, "-std=c++17"));
+}
+
+TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
+  auto matcher = varDecl(
+  hasInitializer(ignoringElidableMoveConstructorCall(cxxConstructExpr(;
+  auto code = "struct H {};"
+  "void f(){"
+  "H D;"
+  "}";
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++17"));
+};
+
+TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
+  auto matcher = expr(ignoringElidableMoveConstructorCall(integerLiteral()));
+  auto code = "void f(){"
+  "int D = 10;"
+  "}";
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++17"));
+}
+
 TEST(Matcher, BindTheSameNameInAlternatives) {
   StatementMatcher matcher = anyOf(
 binaryOperator(hasOperatorName("+"),
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -320,6 +320,7 @@
   REGISTER_MATCHER(hasUnqualifiedDesugaredType);
   REGISTER_MATCHER(hasValueType);
   REGISTER_MATCHER(ifStmt);
+  REGISTER_MATCHER(ignoringElidableMoveConstructorCall);
   REGISTER_MATCHER(ignoringImpCasts);
   REGISTER_MATCHER(ignoringImplicit);
   REGISTER_MATCHER(ignoringParenCasts);
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6452,6 +6452,56 @@
   return false;
 }
 
+/// Matches expressions that match InnerMatcher that are possibly wrapped in an
+/// elidable constructor.
+///
+/// In C++17 copy elidable constructors are no longer being
+/// generated in the AST as it is not permitted by the standard. They are
+/// however part of the AST in C++14 and earlier. Therefore, to 

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Haojian Wu via Phabricator via cfe-commits
hokein added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6477
+/// matches ``D1 = B(B(1))``
+AST_MATCHER_P(Expr, ignoringElidableMoveConstructorCall,
+  ast_matchers::internal::Matcher, InnerMatcher) {

Is the matcher only strict to **move** constructor? looks like the matcher 
implementation is for general constructors, just 
`ignoringElidableConstructorCall`? we may have elidable copy constructor.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6479
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  if (const auto *cxx_construct_expr = dyn_cast()) {
+if (cxx_construct_expr->isElidable()) {

nit: 
[LLVM](https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly)
 uses `CamelCase` style. 



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6486
+  }
+  return InnerMatcher.matches(*cxx_construct_expr, Finder, Builder);
+}

I think this return is unnecessary, since we will fall through at line 6489.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6455
 
+/// Matches expressions that match InnerMatcher after any elidable constructor
+/// are stripped off. In C++17 copy elidable constructors are no longer being

"Matches expressions that match InnerMatcher that are possibly wrapped in an 
elidable constructor."

Then a blank line, and the rest of the explanation.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6458
+/// generated in the AST as it is not permitted by the standard. They are
+/// however part of the C++14 AST. This means that there are cases where it is
+/// needed to use ``anyOf(cxxConstructorExpr(Inner), Inner)`` to match for both

part of the AST in C++14 and earlier.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6460
+/// needed to use ``anyOf(cxxConstructorExpr(Inner), Inner)`` to match for both
+/// the C++14 and C++17 AST. Instead of doing this, this matcher can be used as
+/// ``ignoringElidableMoveConstructorCall(Inner)``.

Therefore, to write a matcher that works in all language modes, the matcher has 
to skip elidable constructor AST nodes if they appear in the AST.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6467
+/// struct H {};
+/// template H B(T A);
+/// void f() {

Can this sample be simplified? For example, B does not need to be a template (I 
think), and f() can be simplified to not call B twice.



Comment at: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp:628
+  EXPECT_TRUE(matches(
+"void f(){"
+"int D = 10;"

gribozavr wrote:
> Need a space before the open brace, and indentation in the function body (in 
> every test).
Not done? I was talking about the code in the code snippet.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-12 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom updated this revision to Diff 204229.
jvikstrom added a comment.

- Made ignoreElidable also ignore materializeTemporaryExpr and reformatted code


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,71 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  StatementMatcher matcher1 = cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(
+ 0, ignoringElidableMoveConstructorCall(callExpr().bind("c"));
+  StatementMatcher matcher2 = cxxOperatorCallExpr(hasArgument(
+  1, callExpr(hasArgument(0, ignoringElidableMoveConstructorCall(
+ integerLiteral().bind("c"));
+
+  auto code1 = "struct H {};"
+   "template H B(T A);"
+   "void f(){"
+   "H D1;"
+   "D1=B(B(1));"
+   "}";
+  auto code2 = "struct H {};"
+   "template H B(T A);"
+   "void f(){"
+   "H D1;"
+   "D1=B(1);"
+   "}";
+
+  EXPECT_TRUE(matchesConditionally(code1, matcher1, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code1, matcher1, true, "-std=c++17"));
+
+  EXPECT_TRUE(matchesConditionally(code2, matcher2, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code2, matcher2, true, "-std=c++17"));
+}
+
+TEST(Matcher, IgnoresElidableInReturn) {
+  auto matcher = expr(ignoringElidableMoveConstructorCall(declRefExpr()));
+  auto code1 = "struct H{};"
+   "H f(){"
+   "H g;"
+   "return g;"
+   "}";
+  auto code2 = "struct H{};"
+   "H f(){"
+   "return H();"
+   "}";
+  EXPECT_TRUE(matchesConditionally(code1, matcher, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code1, matcher, true, "-std=c++17"));
+  EXPECT_TRUE(matchesConditionally(code2, matcher, false, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code2, matcher, false, "-std=c++17"));
+}
+
+TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
+  auto matcher = varDecl(
+  hasInitializer(ignoringElidableMoveConstructorCall(cxxConstructExpr(;
+  auto code = "struct H {};"
+  "void f(){"
+  "H D;"
+  "}";
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++17"));
+};
+
+TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
+  auto matcher = expr(ignoringElidableMoveConstructorCall(integerLiteral()));
+  auto code = "void f(){"
+  "int D = 10;"
+  "}";
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++14"));
+  EXPECT_TRUE(matchesConditionally(code, matcher, true, "-std=c++17"));
+}
+
 TEST(Matcher, BindTheSameNameInAlternatives) {
   StatementMatcher matcher = anyOf(
 binaryOperator(hasOperatorName("+"),
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -320,6 +320,7 @@
   REGISTER_MATCHER(hasUnqualifiedDesugaredType);
   REGISTER_MATCHER(hasValueType);
   REGISTER_MATCHER(ifStmt);
+  REGISTER_MATCHER(ignoringElidableMoveConstructorCall);
   REGISTER_MATCHER(ignoringImpCasts);
   REGISTER_MATCHER(ignoringImplicit);
   REGISTER_MATCHER(ignoringParenCasts);
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6452,6 +6452,43 @@
   return false;
 }
 
+/// Matches expressions that match InnerMatcher after any elidable constructor
+/// are stripped off. In C++17 copy elidable constructors are no longer being
+/// generated in the AST as it is not permitted by the standard. They are
+/// however part of the C++14 AST. This means that there are cases where it is
+/// needed to use ``anyOf(cxxConstructorExpr(Inner), Inner)`` to match for both
+/// the C++14 and C++17 AST. Instead of doing this, this matcher can be used as
+/// ``ignoringElidableMoveConstructorCall(Inner)``.
+///
+/// Given
+///
+/// \code
+/// struct H {};
+/// template H B(T A);
+/// void f() {
+///   H D1;
+///   D1 = B(B(1));
+/// }
+/// \endcode
+///
+/// 

[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-11 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6455
 
+/// Matches expressions that match InnerMatcher after any elidable constructor 
are stripped off.
+///

80 columns



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6455
 
+/// Matches expressions that match InnerMatcher after any elidable constructor 
are stripped off.
+///

gribozavr wrote:
> 80 columns
It would help if you described why a user would want to skip the elidable 
constructor using this matcher rather than hardcoding the presence of such an 
AST node.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6457
+///
+/// Example matches the entire D1 = ... (matcher = 
cxxOperatorCallExpr(hasArgument(1, callExpr(hasArgument(0, 
ignoringElidableMoveConstructorCall(ignoringParenImpCasts(callExpr(
+/// \code

I'd suggest to rephrase the example using the "Given:" format (see other 
comments around), and wrap the code to 80 columns.



Comment at: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp:575
+
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+"struct H {};"

Can you run these tests in both C++14 and C++17 modes?



Comment at: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp:628
+  EXPECT_TRUE(matches(
+"void f(){"
+"int D = 10;"

Need a space before the open brace, and indentation in the function body (in 
every test).



Comment at: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp:631
+"}"
+  , matcher));
+}

Please clang-format.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63149/new/

https://reviews.llvm.org/D63149



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63149: Added AST matcher for ignoring elidable constructors

2019-06-11 Thread Johan Vikström via Phabricator via cfe-commits
jvikstrom created this revision.
jvikstrom added reviewers: hokein, gribozavr.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Added AST matcher for ignoring elidable move constructors


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D63149

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -566,6 +566,71 @@
llvm::make_unique>("x")));
 }
 
+TEST(Matcher, IgnoresElidableConstructors) {
+  StatementMatcher matcher = cxxOperatorCallExpr(
+hasArgument(1, callExpr(hasArgument(0, 
+ignoringElidableMoveConstructorCall(
+  ignoringParenImpCasts(expr().bind("c")));
+
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+"struct H {};"
+"template H B(T A);"
+"void f(){"
+"H D1;"
+"D1=B(B(1));"
+"}"
+, matcher, llvm::make_unique>("c")));
+
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+"struct H {};"
+"template H B(T A);"
+"void f(){"
+"H D1;"
+"D1=B(1);"
+"}"
+, matcher, llvm::make_unique>("c")));
+}
+
+TEST(Matcher, IgnoresElidableInReturn) {
+  auto matcher = expr(ignoringElidableMoveConstructorCall(declRefExpr()));
+
+  EXPECT_TRUE(matches(
+"struct H{};"
+"H f(){"
+"H g;"
+"return g;"
+"}"
+, matcher));
+
+  EXPECT_FALSE(matches(
+"struct H{};"
+"H f(){"
+"return H();"
+"}"
+, matcher
+  ));
+}
+
+TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
+  auto matcher = varDecl(hasInitializer(ignoringElidableMoveConstructorCall(cxxConstructExpr(;
+  EXPECT_TRUE(matches(
+"struct H {};"
+"void f(){"
+"H D;"
+"}"
+  , matcher));
+
+};
+
+TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
+  auto matcher = expr(ignoringElidableMoveConstructorCall(integerLiteral()));
+  EXPECT_TRUE(matches(
+"void f(){"
+"int D = 10;"
+"}"
+  , matcher));
+}
+
 TEST(Matcher, BindTheSameNameInAlternatives) {
   StatementMatcher matcher = anyOf(
 binaryOperator(hasOperatorName("+"),
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -320,6 +320,7 @@
   REGISTER_MATCHER(hasUnqualifiedDesugaredType);
   REGISTER_MATCHER(hasValueType);
   REGISTER_MATCHER(ifStmt);
+  REGISTER_MATCHER(ignoringElidableMoveConstructorCall);
   REGISTER_MATCHER(ignoringImpCasts);
   REGISTER_MATCHER(ignoringImplicit);
   REGISTER_MATCHER(ignoringParenCasts);
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6452,6 +6452,31 @@
   return false;
 }
 
+/// Matches expressions that match InnerMatcher after any elidable constructor are stripped off.
+///
+/// Example matches the entire D1 = ... (matcher = cxxOperatorCallExpr(hasArgument(1, callExpr(hasArgument(0, ignoringElidableMoveConstructorCall(ignoringParenImpCasts(callExpr(
+/// \code
+/// struct H {};
+/// template H B(T A);
+/// void f() {
+///   H D1;
+///   D1 = B(B(1));
+/// }
+/// \endcode
+AST_MATCHER_P(Expr, ignoringElidableMoveConstructorCall,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  if (const auto* cxx_construct_expr = dyn_cast()) {
+if (cxx_construct_expr->isElidable()) {
+  if (const auto* materialize_temp = dyn_cast(
+  cxx_construct_expr->getArg(0))) {
+return InnerMatcher.matches(*materialize_temp, Finder, Builder);
+  }
+  return InnerMatcher.matches(*cxx_construct_expr, Finder, Builder);
+}
+  }
+  return InnerMatcher.matches(Node, Finder, Builder);
+}
+
 ////
 // OpenMP handling.
 ////
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -5728,6 +5728,19 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Expr.html;>ExprignoringElidableMoveConstructorCallast_matchers::Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr InnerMatcher
+Matches expressions that match InnerMatcher after any elidable constructor are stripped off.
+
+Example matches the entire D1 = ...