[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