]> granicus.if.org Git - clang/commitdiff
When transforming CXXExprWithTemporaries and CXXBindTemporaryExpr
authorDouglas Gregor <dgregor@apple.com>
Thu, 24 Dec 2009 18:51:59 +0000 (18:51 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 24 Dec 2009 18:51:59 +0000 (18:51 +0000)
expressions (e.g., for template instantiation), just transform the
subexpressions and return those, since the temporary-related nodes
will be implicitly regenerated. Fixes PR5867, but I said that
before...

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92135 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaTemplateInstantiate.cpp
lib/Sema/TreeTransform.h
test/CodeGenCXX/temporaries.cpp

index 06f8e7aed8818f947c73096094973348f1dbe94c..5f723f92146d1453cf93e4613730922d126e5c7a 100644 (file)
@@ -2096,6 +2096,8 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
   if (!Context.getLangOptions().CPlusPlus)
     return Owned(E);
 
+  assert(!isa<CXXBindTemporaryExpr>(E) && "Double-bound temporary?");
+
   const RecordType *RT = E->getType()->getAs<RecordType>();
   if (!RT)
     return Owned(E);
index d65b2465677f14e7d5a1aeb2cd16b05b7980ac08..d974f89bc6095517e73483ff48ab43dda7343033 100644 (file)
@@ -554,7 +554,6 @@ namespace {
 
     Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E);
     Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E);
-
     Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
 
     /// \brief Transforms a template type parameter type by performing
index e062a37f8ef2f9386d206695130ad20e8d54cc85..cf424aa8c11c3031b1569c4be6bf1506b3bf5a97 100644 (file)
@@ -4757,37 +4757,24 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
 
 /// \brief Transform a C++ temporary-binding expression.
 ///
-/// The transformation of a temporary-binding expression always attempts to
-/// bind a new temporary variable to its subexpression, even if the
-/// subexpression itself did not change, because the temporary variable itself
-/// must be unique.
+/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
+/// transform the subexpression and return that.
 template<typename Derived>
 Sema::OwningExprResult
 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
-  if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
-
-  return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
+  return getDerived().TransformExpr(E->getSubExpr());
 }
 
 /// \brief Transform a C++ expression that contains temporaries that should
 /// be destroyed after the expression is evaluated.
 ///
-/// The transformation of a full expression always attempts to build a new
-/// CXXExprWithTemporaries expression, even if the
-/// subexpression itself did not change, because it will need to capture the
-/// the new temporary variables introduced in the subexpression.
+/// Since CXXExprWithTemporaries nodes are implicitly generated, we
+/// just transform the subexpression and return that.
 template<typename Derived>
 Sema::OwningExprResult
 TreeTransform<Derived>::TransformCXXExprWithTemporaries(
-                                                      CXXExprWithTemporaries *E) {
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
-  if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
-
-  return SemaRef.Owned(
-           SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>()));
+                                                    CXXExprWithTemporaries *E) {
+  return getDerived().TransformExpr(E->getSubExpr());
 }
 
 template<typename Derived>
index 3fd7cfec78678b41cef36876bcd20f21a57a3bd6..611781886b3ec31a22cc4d55b83a5681b5f9d132 100644 (file)
@@ -234,4 +234,18 @@ namespace PR5867 {
     // CHECK-NEXT: ret void
     (f)(S(), 0);
   }
+
+  // CHECK: define linkonce_odr void @_ZN6PR58672g2IiEEvT_
+  template<typename T>
+  void g2(T) {
+    // CHECK: call void @_ZN6PR58671SC1Ev
+    // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
+    // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
+    // CHECK-NEXT: ret void
+    (f)(S(), 0);
+  }
+
+  void h() {
+    g2(17);
+  }
 }