[cfe-commits] r166853 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/Expr.cpp lib/CodeGen/CGExpr.cpp

Rafael Espindola rafael.espindola at gmail.com
Fri Oct 26 18:03:43 PDT 2012


Author: rafael
Date: Fri Oct 26 20:03:43 2012
New Revision: 166853

URL: http://llvm.org/viewvc/llvm-project?rev=166853&view=rev
Log:
Move two helper functions to AST so that sema can use them.

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=166853&r1=166852&r2=166853&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Oct 26 20:03:43 2012
@@ -34,6 +34,7 @@
 namespace clang {
   class ASTContext;
   class APValue;
+  class CastExpr;
   class Decl;
   class IdentifierInfo;
   class ParmVarDecl;
@@ -42,6 +43,7 @@
   class BlockDecl;
   class CXXBaseSpecifier;
   class CXXOperatorCallExpr;
+  class MaterializeTemporaryExpr;
   class CXXMemberCallExpr;
   class ObjCPropertyRefExpr;
   class OpaqueValueExpr;
@@ -49,6 +51,48 @@
 /// \brief A simple array of base specifiers.
 typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
 
+/// \brief An adjustment to be made to the temporary created when emitting a
+/// reference binding, which accesses a particular subobject of that temporary.
+struct SubobjectAdjustment {
+  enum {
+    DerivedToBaseAdjustment,
+    FieldAdjustment,
+    MemberPointerAdjustment
+  } Kind;
+
+   union {
+    struct {
+      const CastExpr *BasePath;
+      const CXXRecordDecl *DerivedClass;
+    } DerivedToBase;
+
+    FieldDecl *Field;
+
+    struct {
+      const MemberPointerType *MPT;
+      Expr *RHS;
+    } Ptr;
+  };
+
+  SubobjectAdjustment(const CastExpr *BasePath,
+                      const CXXRecordDecl *DerivedClass)
+    : Kind(DerivedToBaseAdjustment) {
+    DerivedToBase.BasePath = BasePath;
+    DerivedToBase.DerivedClass = DerivedClass;
+  }
+
+  SubobjectAdjustment(FieldDecl *Field)
+    : Kind(FieldAdjustment) {
+    this->Field = Field;
+  }
+
+  SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS)
+    : Kind(MemberPointerAdjustment) {
+    this->Ptr.MPT = MPT;
+    this->Ptr.RHS = RHS;
+  }
+};
+
 /// Expr - This represents one expression.  Note that Expr's are subclasses of
 /// Stmt.  This allows an expression to be transparently used any place a Stmt
 /// is required.
@@ -695,6 +739,18 @@
   /// behavior if the object isn't dynamically of the derived type.
   const CXXRecordDecl *getBestDynamicClassType() const;
 
+  /// Walk outwards from an expression we want to bind a reference to and
+  /// find the expression whose lifetime needs to be extended. Record
+  /// the adjustments needed along the path.
+  const Expr *
+  skipRValueSubobjectAdjustments(
+                       SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
+
+  /// Skip irrelevant expressions to find what should be materialize for
+  /// binding with a reference.
+  const Expr *
+  findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const;
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() >= firstExprConstant &&
            T->getStmtClass() <= lastExprConstant;

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=166853&r1=166852&r2=166853&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Oct 26 20:03:43 2012
@@ -48,6 +48,75 @@
   return cast<CXXRecordDecl>(D);
 }
 
+const Expr *
+Expr::skipRValueSubobjectAdjustments(
+                     SmallVectorImpl<SubobjectAdjustment> &Adjustments) const  {
+  const Expr *E = this;
+  while (true) {
+    E = E->IgnoreParens();
+
+    if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
+      if ((CE->getCastKind() == CK_DerivedToBase ||
+           CE->getCastKind() == CK_UncheckedDerivedToBase) &&
+          E->getType()->isRecordType()) {
+        E = CE->getSubExpr();
+        CXXRecordDecl *Derived
+          = cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
+        Adjustments.push_back(SubobjectAdjustment(CE, Derived));
+        continue;
+      }
+
+      if (CE->getCastKind() == CK_NoOp) {
+        E = CE->getSubExpr();
+        continue;
+      }
+    } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+      if (!ME->isArrow() && ME->getBase()->isRValue()) {
+        assert(ME->getBase()->getType()->isRecordType());
+        if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
+          E = ME->getBase();
+          Adjustments.push_back(SubobjectAdjustment(Field));
+          continue;
+        }
+      }
+    } else if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
+      if (BO->isPtrMemOp()) {
+        assert(BO->getLHS()->isRValue());
+        E = BO->getLHS();
+        const MemberPointerType *MPT =
+          BO->getRHS()->getType()->getAs<MemberPointerType>();
+        Adjustments.push_back(SubobjectAdjustment(MPT, BO->getRHS()));
+      }
+    }
+
+    // Nothing changed.
+    break;
+  }
+  return E;
+}
+
+const Expr *
+Expr::findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const {
+  const Expr *E = this;
+  // Look through single-element init lists that claim to be lvalues. They're
+  // just syntactic wrappers in this case.
+  if (const InitListExpr *ILE = dyn_cast<InitListExpr>(E)) {
+    if (ILE->getNumInits() == 1 && ILE->isGLValue())
+      E = ILE->getInit(0);
+  }
+
+  // Look through expressions for materialized temporaries (for now).
+  if (const MaterializeTemporaryExpr *M
+      = dyn_cast<MaterializeTemporaryExpr>(E)) {
+    MTE = M;
+    E = M->GetTemporaryExpr();
+  }
+
+  if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E))
+    E = DAE->getExpr();
+  return E;
+}
+
 /// isKnownToHaveBooleanValue - Return true if this is an integer expression
 /// that is known to return 0 or 1.  This happens for _Bool/bool expressions
 /// but also int expressions which are produced by things like comparisons in

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=166853&r1=166852&r2=166853&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Oct 26 20:03:43 2012
@@ -157,50 +157,6 @@
   }
 }
 
-namespace {
-/// \brief An adjustment to be made to the temporary created when emitting a
-/// reference binding, which accesses a particular subobject of that temporary.
-  struct SubobjectAdjustment {
-    enum {
-      DerivedToBaseAdjustment,
-      FieldAdjustment,
-      MemberPointerAdjustment
-    } Kind;
-
-    union {
-      struct {
-        const CastExpr *BasePath;
-        const CXXRecordDecl *DerivedClass;
-      } DerivedToBase;
-
-      FieldDecl *Field;
-
-      struct {
-        const MemberPointerType *MPT;
-        Expr *RHS;
-      } Ptr;
-    };
-
-    SubobjectAdjustment(const CastExpr *BasePath,
-                        const CXXRecordDecl *DerivedClass)
-      : Kind(DerivedToBaseAdjustment) {
-      DerivedToBase.BasePath = BasePath;
-      DerivedToBase.DerivedClass = DerivedClass;
-    }
-
-    SubobjectAdjustment(FieldDecl *Field)
-      : Kind(FieldAdjustment) {
-      this->Field = Field;
-    }
-
-    SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS)
-      : Kind(MemberPointerAdjustment) {
-      this->Ptr.MPT = MPT;
-      this->Ptr.RHS = RHS;
-    }
-  };
-}
-
 static llvm::Value *
 CreateReferenceTemporary(CodeGenFunction &CGF, QualType Type,
                          const NamedDecl *InitializedDecl) {
@@ -227,73 +183,6 @@
   return CGF.CreateMemTemp(Type, "ref.tmp");
 }
 
-static const Expr *
-findMaterializedTemporary(const Expr *E, const MaterializeTemporaryExpr *&MTE) {
-  // Look through single-element init lists that claim to be lvalues. They're
-  // just syntactic wrappers in this case.
-  if (const InitListExpr *ILE = dyn_cast<InitListExpr>(E)) {
-    if (ILE->getNumInits() == 1 && ILE->isGLValue())
-      E = ILE->getInit(0);
-  }
-
-  // Look through expressions for materialized temporaries (for now).
-  if (const MaterializeTemporaryExpr *M
-      = dyn_cast<MaterializeTemporaryExpr>(E)) {
-    MTE = M;
-    E = M->GetTemporaryExpr();
-  }
-
-  if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E))
-    E = DAE->getExpr();
-  return E;
-}
-
-static const Expr *
-skipRValueSubobjectAdjustments(const Expr *E,
-                            SmallVectorImpl<SubobjectAdjustment> &Adjustments) {
-  while (true) {
-    E = E->IgnoreParens();
-
-    if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
-      if ((CE->getCastKind() == CK_DerivedToBase ||
-           CE->getCastKind() == CK_UncheckedDerivedToBase) &&
-          E->getType()->isRecordType()) {
-        E = CE->getSubExpr();
-        CXXRecordDecl *Derived
-          = cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
-        Adjustments.push_back(SubobjectAdjustment(CE, Derived));
-        continue;
-      }
-
-      if (CE->getCastKind() == CK_NoOp) {
-        E = CE->getSubExpr();
-        continue;
-      }
-    } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
-      if (!ME->isArrow() && ME->getBase()->isRValue()) {
-        assert(ME->getBase()->getType()->isRecordType());
-        if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
-          E = ME->getBase();
-          Adjustments.push_back(SubobjectAdjustment(Field));
-          continue;
-        }
-      }
-    } else if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
-      if (BO->isPtrMemOp()) {
-        assert(BO->getLHS()->isRValue());
-        E = BO->getLHS();
-        const MemberPointerType *MPT =
-          BO->getRHS()->getType()->getAs<MemberPointerType>();
-        Adjustments.push_back(SubobjectAdjustment(MPT, BO->getRHS()));
-      }
-    }
-
-    // Nothing changed.
-    break;
-  }
-  return E;
-}
-
 static llvm::Value *
 EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
                             llvm::Value *&ReferenceTemporary,
@@ -301,7 +190,7 @@
                             QualType &ObjCARCReferenceLifetimeType,
                             const NamedDecl *InitializedDecl) {
   const MaterializeTemporaryExpr *M = NULL;
-  E = findMaterializedTemporary(E, M);
+  E = E->findMaterializedTemporary(M);
   // Objective-C++ ARC:
   //   If we are binding a reference to a temporary that has ownership, we
   //   need to perform retain/release operations on the temporary.
@@ -391,7 +280,7 @@
     }
 
     SmallVector<SubobjectAdjustment, 2> Adjustments;
-    E = skipRValueSubobjectAdjustments(E, Adjustments);
+    E = E->skipRValueSubobjectAdjustments(Adjustments);
     if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E))
       if (opaque->getType()->isRecordType())
         return CGF.EmitOpaqueValueLValue(opaque).getAddress();





More information about the cfe-commits mailing list