Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -473,6 +473,22 @@ Stmt, CXXBindTemporaryExpr> bindTemporaryExpression; +/// \brief Matches nodes where temporaries are materialized. +/// +/// Example: Given +/// struct T {void func()}; +/// T f(); +/// void g(T); +/// materializeTempExpr() matches 'f()' in these statements +/// T u(f()); +/// g(f()); +/// but does not match +/// f(); +/// f().func(); +const internal::VariadicDynCastAllOfMatcher< + Stmt, + MaterializeTemporaryExpr> materializeTempExpr; + /// \brief Matches new expressions. /// /// Given Index: unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -1249,6 +1249,43 @@ TempExpression)); } +TEST(MaterializeTempExpr, MatchesTemporary) { + StatementMatcher MaterializeTemp = materializeTempExpr(); + + std::string ClassString = + "class string { public: string(); int length(); }; "; + + EXPECT_TRUE( + matches(ClassString + + "string GetStringByValue();" + "void FunctionTakesString(string s);" + "void run() { FunctionTakesString(GetStringByValue()); }", + MaterializeTemp)); + + EXPECT_TRUE( + notMatches(ClassString + + "string* GetStringPointer(); " + "void FunctionTakesStringPtr(string* s);" + "void run() {" + " string* s = GetStringPointer();" + " FunctionTakesStringPtr(GetStringPointer());" + " FunctionTakesStringPtr(s);" + "}", + MaterializeTemp)); + + EXPECT_TRUE( + notMatches(ClassString + + "string GetStringByValue();" + "void run() { int k = GetStringByValue().length(); }", + MaterializeTemp)); + + EXPECT_TRUE( + notMatches(ClassString + + "string GetStringByValue();" + "void run() { GetStringByValue(); }", + MaterializeTemp)); +} + TEST(ConstructorDeclaration, SimpleCase) { EXPECT_TRUE(matches("class Foo { Foo(int i); };", constructor(ofClass(hasName("Foo")))));