[PATCH] D22128: Make CastExpr::getSubExprAsWritten look through implicit temporary under CK_ConstructorConversion
This revision was automatically updated to reflect the committed changes. Closed by commit rL306377: Make CastExpr::getSubExprAsWritten look through implicit temporary under… (authored by sberg). Changed prior to commit: https://reviews.llvm.org/D22128?vs=103449=104104#toc Repository: rL LLVM https://reviews.llvm.org/D22128 Files: cfe/trunk/lib/AST/Expr.cpp cfe/trunk/unittests/Tooling/CMakeLists.txt cfe/trunk/unittests/Tooling/CastExprTest.cpp Index: cfe/trunk/lib/AST/Expr.cpp === --- cfe/trunk/lib/AST/Expr.cpp +++ cfe/trunk/lib/AST/Expr.cpp @@ -1641,25 +1641,32 @@ llvm_unreachable("Unhandled cast kind!"); } +namespace { + Expr *skipImplicitTemporary(Expr *expr) { +// Skip through reference binding to temporary. +if (MaterializeTemporaryExpr *Materialize + = dyn_cast(expr)) + expr = Materialize->GetTemporaryExpr(); + +// Skip any temporary bindings; they're implicit. +if (CXXBindTemporaryExpr *Binder = dyn_cast(expr)) + expr = Binder->getSubExpr(); + +return expr; + } +} + Expr *CastExpr::getSubExprAsWritten() { Expr *SubExpr = nullptr; CastExpr *E = this; do { -SubExpr = E->getSubExpr(); +SubExpr = skipImplicitTemporary(E->getSubExpr()); -// Skip through reference binding to temporary. -if (MaterializeTemporaryExpr *Materialize - = dyn_cast(SubExpr)) - SubExpr = Materialize->GetTemporaryExpr(); - -// Skip any temporary bindings; they're implicit. -if (CXXBindTemporaryExpr *Binder = dyn_cast(SubExpr)) - SubExpr = Binder->getSubExpr(); - // Conversions by constructor and conversion functions have a // subexpression describing the call; strip it off. if (E->getCastKind() == CK_ConstructorConversion) - SubExpr = cast(SubExpr)->getArg(0); + SubExpr = +skipImplicitTemporary(cast(SubExpr)->getArg(0)); else if (E->getCastKind() == CK_UserDefinedConversion) { assert((isa(SubExpr) || isa(SubExpr)) && Index: cfe/trunk/unittests/Tooling/CMakeLists.txt === --- cfe/trunk/unittests/Tooling/CMakeLists.txt +++ cfe/trunk/unittests/Tooling/CMakeLists.txt @@ -11,6 +11,7 @@ endif() add_clang_unittest(ToolingTests + CastExprTest.cpp CommentHandlerTest.cpp CompilationDatabaseTest.cpp FixItTest.cpp Index: cfe/trunk/unittests/Tooling/CastExprTest.cpp === --- cfe/trunk/unittests/Tooling/CastExprTest.cpp +++ cfe/trunk/unittests/Tooling/CastExprTest.cpp @@ -0,0 +1,38 @@ +//===- unittest/Tooling/CastExprTest.cpp --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +struct CastExprVisitor : TestVisitor { + std::functionOnExplicitCast; + + bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) { +if (OnExplicitCast) + OnExplicitCast(Expr); +return true; + } +}; + +TEST(CastExprTest, GetSubExprAsWrittenThroughMaterializedTemporary) { +CastExprVisitor Visitor; +Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) { + auto Sub = Expr->getSubExprAsWritten(); + EXPECT_TRUE(isa(Sub)) +<< "Expected DeclRefExpr, but saw " << Sub->getStmtClassName(); +}; +Visitor.runOver("struct S1 {};\n" +"struct S2 { operator S1(); };\n" +"S1 f(S2 s) { return static_cast(s); }\n"); +} + +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D22128: Make CastExpr::getSubExprAsWritten look through implicit temporary under CK_ConstructorConversion
sberg updated this revision to Diff 103449. sberg added a comment. Herald added subscribers: kristof.beyls, mgorny, klimek. added test https://reviews.llvm.org/D22128 Files: lib/AST/Expr.cpp unittests/Tooling/CMakeLists.txt unittests/Tooling/CastExprTest.cpp Index: unittests/Tooling/CastExprTest.cpp === --- /dev/null +++ unittests/Tooling/CastExprTest.cpp @@ -0,0 +1,38 @@ +//===- unittest/Tooling/CastExprTest.cpp --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +struct CastExprVisitor : TestVisitor { + std::functionOnExplicitCast; + + bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) { +if (OnExplicitCast) + OnExplicitCast(Expr); +return true; + } +}; + +TEST(CastExprTest, GetSubExprAsWrittenThroughMaterializedTemporary) { +CastExprVisitor Visitor; +Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) { + auto Sub = Expr->getSubExprAsWritten(); + EXPECT_TRUE(isa(Sub)) +<< "Expected DeclRefExpr, but saw " << Sub->getStmtClassName(); +}; +Visitor.runOver("struct S1 {};\n" +"struct S2 { operator S1(); };\n" +"S1 f(S2 s) { return static_cast(s); }\n"); +} + +} Index: unittests/Tooling/CMakeLists.txt === --- unittests/Tooling/CMakeLists.txt +++ unittests/Tooling/CMakeLists.txt @@ -11,6 +11,7 @@ endif() add_clang_unittest(ToolingTests + CastExprTest.cpp CommentHandlerTest.cpp CompilationDatabaseTest.cpp FixItTest.cpp Index: lib/AST/Expr.cpp === --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -1641,25 +1641,32 @@ llvm_unreachable("Unhandled cast kind!"); } +namespace { + Expr *skipImplicitTemporary(Expr *expr) { +// Skip through reference binding to temporary. +if (MaterializeTemporaryExpr *Materialize + = dyn_cast(expr)) + expr = Materialize->GetTemporaryExpr(); + +// Skip any temporary bindings; they're implicit. +if (CXXBindTemporaryExpr *Binder = dyn_cast(expr)) + expr = Binder->getSubExpr(); + +return expr; + } +} + Expr *CastExpr::getSubExprAsWritten() { Expr *SubExpr = nullptr; CastExpr *E = this; do { -SubExpr = E->getSubExpr(); +SubExpr = skipImplicitTemporary(E->getSubExpr()); -// Skip through reference binding to temporary. -if (MaterializeTemporaryExpr *Materialize - = dyn_cast(SubExpr)) - SubExpr = Materialize->GetTemporaryExpr(); - -// Skip any temporary bindings; they're implicit. -if (CXXBindTemporaryExpr *Binder = dyn_cast(SubExpr)) - SubExpr = Binder->getSubExpr(); - // Conversions by constructor and conversion functions have a // subexpression describing the call; strip it off. if (E->getCastKind() == CK_ConstructorConversion) - SubExpr = cast(SubExpr)->getArg(0); + SubExpr = +skipImplicitTemporary(cast(SubExpr)->getArg(0)); else if (E->getCastKind() == CK_UserDefinedConversion) { assert((isa(SubExpr) || isa(SubExpr)) && ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D22128: Make CastExpr::getSubExprAsWritten look through implicit temporary under CK_ConstructorConversion
sberg added a comment. (I'm not sure where and how to add a test for this?) http://reviews.llvm.org/D22128 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D22128: Make CastExpr::getSubExprAsWritten look through implicit temporary under CK_ConstructorConversion
sberg created this revision. sberg added a reviewer: rsmith. sberg added a subscriber: cfe-commits. Herald added a subscriber: aemerson. With > struct S1 {}; > struct S2 { operator S1(); }; > S1 f(S2 s) { return static_cast(s); } the static_cast expr is > CXXStaticCastExpr 0x... 'struct S1' static_cast > > `-CXXConstructExpr 0x... 'struct S1' 'void (struct S1 &&) noexcept' elidable > `-MaterializeTemporaryExpr 0x... 'struct S1' xvalue > `-ImplicitCastExpr 0x... 'struct S1' > `-CXXMemberCallExpr 0x... 'struct S1' > `-MemberExpr 0x... '' .operator S1 0x... > `-DeclRefExpr 0x... 'struct S2' lvalue ParmVar 0x... 's' 'struct S2' getSubExprAsWritten used to return the MaterializeTemporaryExpr (of type S1) under the CXXConstructExpr, instead of unwinding further to the DeclRefExpr (of type S2) at the bottom. http://reviews.llvm.org/D22128 Files: lib/AST/Expr.cpp Index: lib/AST/Expr.cpp === --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -1602,25 +1602,32 @@ llvm_unreachable("Unhandled cast kind!"); } +namespace { + Expr *skipImplicitTemporary(Expr *expr) { +// Skip through reference binding to temporary. +if (MaterializeTemporaryExpr *Materialize + = dyn_cast(expr)) + expr = Materialize->GetTemporaryExpr(); + +// Skip any temporary bindings; they're implicit. +if (CXXBindTemporaryExpr *Binder = dyn_cast(expr)) + expr = Binder->getSubExpr(); + +return expr; + } +} + Expr *CastExpr::getSubExprAsWritten() { Expr *SubExpr = nullptr; CastExpr *E = this; do { -SubExpr = E->getSubExpr(); +SubExpr = skipImplicitTemporary(E->getSubExpr()); -// Skip through reference binding to temporary. -if (MaterializeTemporaryExpr *Materialize - = dyn_cast(SubExpr)) - SubExpr = Materialize->GetTemporaryExpr(); - -// Skip any temporary bindings; they're implicit. -if (CXXBindTemporaryExpr *Binder = dyn_cast(SubExpr)) - SubExpr = Binder->getSubExpr(); - // Conversions by constructor and conversion functions have a // subexpression describing the call; strip it off. if (E->getCastKind() == CK_ConstructorConversion) - SubExpr = cast(SubExpr)->getArg(0); + SubExpr = +skipImplicitTemporary(cast(SubExpr)->getArg(0)); else if (E->getCastKind() == CK_UserDefinedConversion) { assert((isa(SubExpr) || isa(SubExpr)) && Index: lib/AST/Expr.cpp === --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -1602,25 +1602,32 @@ llvm_unreachable("Unhandled cast kind!"); } +namespace { + Expr *skipImplicitTemporary(Expr *expr) { +// Skip through reference binding to temporary. +if (MaterializeTemporaryExpr *Materialize + = dyn_cast(expr)) + expr = Materialize->GetTemporaryExpr(); + +// Skip any temporary bindings; they're implicit. +if (CXXBindTemporaryExpr *Binder = dyn_cast(expr)) + expr = Binder->getSubExpr(); + +return expr; + } +} + Expr *CastExpr::getSubExprAsWritten() { Expr *SubExpr = nullptr; CastExpr *E = this; do { -SubExpr = E->getSubExpr(); +SubExpr = skipImplicitTemporary(E->getSubExpr()); -// Skip through reference binding to temporary. -if (MaterializeTemporaryExpr *Materialize - = dyn_cast(SubExpr)) - SubExpr = Materialize->GetTemporaryExpr(); - -// Skip any temporary bindings; they're implicit. -if (CXXBindTemporaryExpr *Binder = dyn_cast(SubExpr)) - SubExpr = Binder->getSubExpr(); - // Conversions by constructor and conversion functions have a // subexpression describing the call; strip it off. if (E->getCastKind() == CK_ConstructorConversion) - SubExpr = cast(SubExpr)->getArg(0); + SubExpr = +skipImplicitTemporary(cast(SubExpr)->getArg(0)); else if (E->getCastKind() == CK_UserDefinedConversion) { assert((isa(SubExpr) || isa(SubExpr)) && ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits