diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-10-27 01:03:43 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-10-27 01:03:43 +0000 |
commit | 0a7dd835184343ec9149277b668ecdc5d49fe8b0 (patch) | |
tree | 7087b62506c82f0b9a6a747ea61b0d224e5be55b /lib | |
parent | 034653c867d2369c05a286fffe3182190a999f7b (diff) |
Move two helper functions to AST so that sema can use them.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166853 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Expr.cpp | 69 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 115 |
2 files changed, 71 insertions, 113 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 6f4c8e2637..4a8033f878 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -48,6 +48,75 @@ const CXXRecordDecl *Expr::getBestDynamicClassType() const { 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 diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index d5d3a68b97..a26a0aa28a 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -157,50 +157,6 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E, } } -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 @@ CreateReferenceTemporary(CodeGenFunction &CGF, QualType Type, 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 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, 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 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, } 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(); |