[PATCH] D22128: Make CastExpr::getSubExprAsWritten look through implicit temporary under CK_ConstructorConversion

2017-06-27 Thread Stephan Bergmann via Phabricator via cfe-commits
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::function OnExplicitCast;
+
+  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

2017-06-21 Thread Stephan Bergmann via Phabricator via cfe-commits
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::function OnExplicitCast;
+
+  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

2016-07-08 Thread Stephan Bergmann via cfe-commits
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

2016-07-08 Thread Stephan Bergmann via cfe-commits
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