2007-06-02 02:02:12 +08:00
|
|
|
//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-06-02 02:02:12 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This contains code to emit Expr nodes as LLVM code.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "CodeGenFunction.h"
|
2007-06-20 12:44:43 +08:00
|
|
|
#include "CodeGenModule.h"
|
2008-09-09 05:33:45 +08:00
|
|
|
#include "CGCall.h"
|
2010-03-31 09:09:11 +08:00
|
|
|
#include "CGRecordLayout.h"
|
2008-08-13 08:59:25 +08:00
|
|
|
#include "CGObjCRuntime.h"
|
2008-08-11 13:00:27 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2008-08-11 13:35:13 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2009-12-15 08:35:12 +08:00
|
|
|
#include "llvm/Intrinsics.h"
|
2010-06-16 07:19:56 +08:00
|
|
|
#include "clang/Frontend/CodeGenOptions.h"
|
2008-05-18 04:03:47 +08:00
|
|
|
#include "llvm/Target/TargetData.h"
|
2007-06-02 02:02:12 +08:00
|
|
|
using namespace clang;
|
|
|
|
using namespace CodeGen;
|
|
|
|
|
2007-06-03 03:33:17 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// Miscellaneous Helper Methods
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
2007-06-23 05:44:33 +08:00
|
|
|
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
|
|
|
|
/// block.
|
|
|
|
llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty,
|
2009-10-19 09:21:05 +08:00
|
|
|
const llvm::Twine &Name) {
|
2009-03-22 08:24:14 +08:00
|
|
|
if (!Builder.isNamePreserving())
|
2009-10-19 09:21:05 +08:00
|
|
|
return new llvm::AllocaInst(Ty, 0, "", AllocaInsertPt);
|
2009-10-13 06:29:02 +08:00
|
|
|
return new llvm::AllocaInst(Ty, 0, Name, AllocaInsertPt);
|
2007-06-23 05:44:33 +08:00
|
|
|
}
|
2007-06-06 04:53:16 +08:00
|
|
|
|
2010-04-22 09:10:34 +08:00
|
|
|
void CodeGenFunction::InitTempAlloca(llvm::AllocaInst *Var,
|
|
|
|
llvm::Value *Init) {
|
|
|
|
llvm::StoreInst *Store = new llvm::StoreInst(Init, Var);
|
|
|
|
llvm::BasicBlock *Block = AllocaInsertPt->getParent();
|
|
|
|
Block->getInstList().insertAfter(&*AllocaInsertPt, Store);
|
|
|
|
}
|
|
|
|
|
2010-02-17 03:44:13 +08:00
|
|
|
llvm::Value *CodeGenFunction::CreateIRTemp(QualType Ty,
|
|
|
|
const llvm::Twine &Name) {
|
|
|
|
llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertType(Ty), Name);
|
|
|
|
// FIXME: Should we prefer the preferred type alignment here?
|
|
|
|
CharUnits Align = getContext().getTypeAlignInChars(Ty);
|
|
|
|
Alloc->setAlignment(Align.getQuantity());
|
|
|
|
return Alloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Value *CodeGenFunction::CreateMemTemp(QualType Ty,
|
|
|
|
const llvm::Twine &Name) {
|
2010-02-09 10:48:28 +08:00
|
|
|
llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty), Name);
|
|
|
|
// FIXME: Should we prefer the preferred type alignment here?
|
|
|
|
CharUnits Align = getContext().getTypeAlignInChars(Ty);
|
|
|
|
Alloc->setAlignment(Align.getQuantity());
|
|
|
|
return Alloc;
|
|
|
|
}
|
|
|
|
|
2007-06-06 04:53:16 +08:00
|
|
|
/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
|
|
|
|
/// expression and compare the result against zero, returning an Int1Ty value.
|
2007-06-16 07:05:46 +08:00
|
|
|
llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
|
2007-08-27 00:46:58 +08:00
|
|
|
QualType BoolTy = getContext().BoolTy;
|
2009-12-11 17:26:29 +08:00
|
|
|
if (E->getType()->isMemberFunctionPointerType()) {
|
2010-02-06 03:38:31 +08:00
|
|
|
LValue LV = EmitAggExprToLValue(E);
|
2009-12-11 17:26:29 +08:00
|
|
|
|
|
|
|
// Get the pointer.
|
2010-02-06 03:38:31 +08:00
|
|
|
llvm::Value *FuncPtr = Builder.CreateStructGEP(LV.getAddress(), 0,
|
|
|
|
"src.ptr");
|
2009-12-11 17:26:29 +08:00
|
|
|
FuncPtr = Builder.CreateLoad(FuncPtr);
|
|
|
|
|
|
|
|
llvm::Value *IsNotNull =
|
|
|
|
Builder.CreateICmpNE(FuncPtr,
|
|
|
|
llvm::Constant::getNullValue(FuncPtr->getType()),
|
|
|
|
"tobool");
|
|
|
|
|
|
|
|
return IsNotNull;
|
|
|
|
}
|
2008-04-05 00:54:41 +08:00
|
|
|
if (!E->getType()->isAnyComplexType())
|
2007-08-27 00:46:58 +08:00
|
|
|
return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy);
|
2007-06-06 04:53:16 +08:00
|
|
|
|
2007-08-27 00:46:58 +08:00
|
|
|
return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(),BoolTy);
|
2007-06-03 03:33:17 +08:00
|
|
|
}
|
|
|
|
|
2007-09-01 06:49:20 +08:00
|
|
|
/// EmitAnyExpr - Emit code to compute the specified expression which can have
|
|
|
|
/// any type. The result is returned as an RValue struct. If this is an
|
2009-09-09 21:00:44 +08:00
|
|
|
/// aggregate expression, the aggloc/agglocvolatile arguments indicate where the
|
|
|
|
/// result should be returned.
|
|
|
|
RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc,
|
2009-08-16 15:36:22 +08:00
|
|
|
bool IsAggLocVolatile, bool IgnoreResult,
|
|
|
|
bool IsInitializer) {
|
2007-09-01 06:49:20 +08:00
|
|
|
if (!hasAggregateLLVMType(E->getType()))
|
2009-05-29 23:46:01 +08:00
|
|
|
return RValue::get(EmitScalarExpr(E, IgnoreResult));
|
2008-04-05 00:54:41 +08:00
|
|
|
else if (E->getType()->isAnyComplexType())
|
2009-05-29 23:46:01 +08:00
|
|
|
return RValue::getComplex(EmitComplexExpr(E, false, false,
|
|
|
|
IgnoreResult, IgnoreResult));
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-08-16 15:36:22 +08:00
|
|
|
EmitAggExpr(E, AggLoc, IsAggLocVolatile, IgnoreResult, IsInitializer);
|
|
|
|
return RValue::getAggregate(AggLoc, IsAggLocVolatile);
|
2007-09-01 06:49:20 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will
|
|
|
|
/// always be accessible even if no aggregate location is provided.
|
|
|
|
RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E,
|
2009-08-16 15:36:22 +08:00
|
|
|
bool IsAggLocVolatile,
|
|
|
|
bool IsInitializer) {
|
|
|
|
llvm::Value *AggLoc = 0;
|
2009-09-09 21:00:44 +08:00
|
|
|
|
|
|
|
if (hasAggregateLLVMType(E->getType()) &&
|
2008-09-09 09:06:48 +08:00
|
|
|
!E->getType()->isAnyComplexType())
|
2010-02-15 09:23:36 +08:00
|
|
|
AggLoc = CreateMemTemp(E->getType(), "agg.tmp");
|
2009-09-09 21:00:44 +08:00
|
|
|
return EmitAnyExpr(E, AggLoc, IsAggLocVolatile, /*IgnoreResult=*/false,
|
2009-08-16 15:36:22 +08:00
|
|
|
IsInitializer);
|
2008-09-09 09:06:48 +08:00
|
|
|
}
|
|
|
|
|
2010-04-21 18:05:39 +08:00
|
|
|
/// EmitAnyExprToMem - Evaluate an expression into a given memory
|
|
|
|
/// location.
|
|
|
|
void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
|
|
|
|
llvm::Value *Location,
|
|
|
|
bool IsLocationVolatile,
|
|
|
|
bool IsInit) {
|
|
|
|
if (E->getType()->isComplexType())
|
|
|
|
EmitComplexExprIntoAddr(E, Location, IsLocationVolatile);
|
|
|
|
else if (hasAggregateLLVMType(E->getType()))
|
|
|
|
EmitAggExpr(E, Location, IsLocationVolatile, /*Ignore*/ false, IsInit);
|
|
|
|
else {
|
|
|
|
RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false));
|
|
|
|
LValue LV = LValue::MakeAddr(Location, MakeQualifiers(E->getType()));
|
|
|
|
EmitStoreThroughLValue(RV, LV, E->getType());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
/// \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 } Kind;
|
|
|
|
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
const CXXBaseSpecifierArray *BasePath;
|
|
|
|
const CXXRecordDecl *DerivedClass;
|
|
|
|
} DerivedToBase;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
FieldDecl *Field;
|
|
|
|
unsigned CVRQualifiers;
|
|
|
|
} Field;
|
|
|
|
};
|
|
|
|
|
|
|
|
SubobjectAdjustment(const CXXBaseSpecifierArray *BasePath,
|
|
|
|
const CXXRecordDecl *DerivedClass)
|
|
|
|
: Kind(DerivedToBaseAdjustment)
|
|
|
|
{
|
|
|
|
DerivedToBase.BasePath = BasePath;
|
|
|
|
DerivedToBase.DerivedClass = DerivedClass;
|
|
|
|
}
|
|
|
|
|
|
|
|
SubobjectAdjustment(FieldDecl *Field, unsigned CVRQualifiers)
|
|
|
|
: Kind(FieldAdjustment)
|
|
|
|
{
|
|
|
|
this->Field.Field = Field;
|
|
|
|
this->Field.CVRQualifiers = CVRQualifiers;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2010-06-28 00:56:04 +08:00
|
|
|
static llvm::Value *
|
|
|
|
EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E,
|
|
|
|
llvm::Value *&ReferenceTemporary,
|
|
|
|
const CXXDestructorDecl *&ReferenceTemporaryDtor,
|
|
|
|
bool IsInitializer) {
|
2009-12-19 08:20:10 +08:00
|
|
|
if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E))
|
|
|
|
E = DAE->getExpr();
|
2010-06-28 00:56:04 +08:00
|
|
|
|
2009-10-15 08:51:46 +08:00
|
|
|
if (const CXXExprWithTemporaries *TE = dyn_cast<CXXExprWithTemporaries>(E)) {
|
2010-06-28 00:56:04 +08:00
|
|
|
CodeGenFunction::CXXTemporariesCleanupScope Scope(CGF);
|
|
|
|
|
|
|
|
return EmitExprForReferenceBinding(CGF, TE->getSubExpr(),
|
|
|
|
ReferenceTemporary,
|
|
|
|
ReferenceTemporaryDtor,
|
|
|
|
IsInitializer);
|
2009-10-15 08:51:46 +08:00
|
|
|
}
|
2010-06-28 00:56:04 +08:00
|
|
|
|
|
|
|
RValue RV;
|
|
|
|
if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid) {
|
|
|
|
// Emit the expression as an lvalue.
|
|
|
|
LValue LV = CGF.EmitLValue(E);
|
|
|
|
|
|
|
|
if (LV.isSimple())
|
|
|
|
return LV.getAddress();
|
2009-10-19 07:09:21 +08:00
|
|
|
|
2010-06-28 00:56:04 +08:00
|
|
|
// We have to load the lvalue.
|
|
|
|
RV = CGF.EmitLoadOfLValue(LV, E->getType());
|
2009-05-20 10:31:19 +08:00
|
|
|
} else {
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
QualType ResultTy = E->getType();
|
2010-06-28 00:56:04 +08:00
|
|
|
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
llvm::SmallVector<SubobjectAdjustment, 2> Adjustments;
|
2010-06-28 00:56:04 +08:00
|
|
|
while (true) {
|
2010-05-22 13:17:18 +08:00
|
|
|
if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
|
|
|
|
E = PE->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
|
|
|
|
if ((CE->getCastKind() == CastExpr::CK_DerivedToBase ||
|
|
|
|
CE->getCastKind() == CastExpr::CK_UncheckedDerivedToBase) &&
|
|
|
|
E->getType()->isRecordType()) {
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
E = CE->getSubExpr();
|
|
|
|
CXXRecordDecl *Derived
|
|
|
|
= cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
|
|
|
|
Adjustments.push_back(SubobjectAdjustment(&CE->getBasePath(),
|
|
|
|
Derived));
|
|
|
|
continue;
|
|
|
|
}
|
2010-05-22 13:17:18 +08:00
|
|
|
|
|
|
|
if (CE->getCastKind() == CastExpr::CK_NoOp) {
|
|
|
|
E = CE->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
|
2010-06-28 00:56:04 +08:00
|
|
|
if (ME->getBase()->isLvalue(CGF.getContext()) != Expr::LV_Valid &&
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
ME->getBase()->getType()->isRecordType()) {
|
|
|
|
if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
|
|
|
|
E = ME->getBase();
|
|
|
|
Adjustments.push_back(SubobjectAdjustment(Field,
|
|
|
|
E->getType().getCVRQualifiers()));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2009-10-15 08:51:46 +08:00
|
|
|
}
|
2010-05-22 13:17:18 +08:00
|
|
|
|
|
|
|
// Nothing changed.
|
|
|
|
break;
|
2010-06-28 00:56:04 +08:00
|
|
|
}
|
2009-10-19 07:09:21 +08:00
|
|
|
|
2010-06-28 00:56:04 +08:00
|
|
|
// Create a reference temporary if necessary.
|
|
|
|
if (CGF.hasAggregateLLVMType(E->getType()) &&
|
|
|
|
!E->getType()->isAnyComplexType())
|
|
|
|
ReferenceTemporary = CGF.CreateMemTemp(E->getType(), "ref.tmp");
|
|
|
|
RV = CGF.EmitAnyExpr(E, ReferenceTemporary, /*IsAggLocVolatile=*/false,
|
|
|
|
/*IgnoreResult=*/false, IsInitializer);
|
|
|
|
|
2009-08-17 01:54:29 +08:00
|
|
|
if (IsInitializer) {
|
2010-06-28 00:56:04 +08:00
|
|
|
// Get the destructor for the reference temporary.
|
2009-08-17 01:54:29 +08:00
|
|
|
if (const RecordType *RT = E->getType()->getAs<RecordType>()) {
|
2010-06-28 00:56:04 +08:00
|
|
|
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
|
|
|
|
if (!ClassDecl->hasTrivialDestructor())
|
|
|
|
ReferenceTemporaryDtor = ClassDecl->getDestructor(CGF.getContext());
|
2009-08-17 01:50:25 +08:00
|
|
|
}
|
|
|
|
}
|
2010-06-28 00:56:04 +08:00
|
|
|
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
// Check if need to perform derived-to-base casts and/or field accesses, to
|
|
|
|
// get from the temporary object we created (and, potentially, for which we
|
|
|
|
// extended the lifetime) to the subobject we're binding the reference to.
|
|
|
|
if (!Adjustments.empty()) {
|
2010-06-28 00:56:04 +08:00
|
|
|
llvm::Value *Object = RV.getAggregateAddr();
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
for (unsigned I = Adjustments.size(); I != 0; --I) {
|
|
|
|
SubobjectAdjustment &Adjustment = Adjustments[I-1];
|
|
|
|
switch (Adjustment.Kind) {
|
|
|
|
case SubobjectAdjustment::DerivedToBaseAdjustment:
|
2010-06-28 00:56:04 +08:00
|
|
|
Object =
|
|
|
|
CGF.GetAddressOfBaseClass(Object,
|
|
|
|
Adjustment.DerivedToBase.DerivedClass,
|
|
|
|
*Adjustment.DerivedToBase.BasePath,
|
|
|
|
/*NullCheckValue=*/false);
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SubobjectAdjustment::FieldAdjustment: {
|
|
|
|
unsigned CVR = Adjustment.Field.CVRQualifiers;
|
2010-06-28 00:56:04 +08:00
|
|
|
LValue LV =
|
|
|
|
CGF.EmitLValueForField(Object, Adjustment.Field.Field, CVR);
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
if (LV.isSimple()) {
|
|
|
|
Object = LV.getAddress();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// For non-simple lvalues, we actually have to create a copy of
|
|
|
|
// the object we're binding to.
|
|
|
|
QualType T = Adjustment.Field.Field->getType().getNonReferenceType()
|
|
|
|
.getUnqualifiedType();
|
2010-06-28 00:56:04 +08:00
|
|
|
Object = CGF.CreateTempAlloca(CGF.ConvertType(T), "lv");
|
|
|
|
LValue TempLV =
|
|
|
|
LValue::MakeAddr(Object, Qualifiers::fromCVRMask(CVR));
|
|
|
|
CGF.EmitStoreThroughLValue(CGF.EmitLoadOfLValue(LV, T), TempLV, T);
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
break;
|
|
|
|
}
|
2010-06-28 00:56:04 +08:00
|
|
|
|
Rework our handling of binding a reference to a temporary
subobject. Previously, we could only properly bind to a base class
subobject while extending the lifetime of the complete object (of a
derived type); for non-static data member subobjects, we could memcpy
(!) the result and bind to that, which is rather broken.
Now, we pull apart the expression that we're binding to, to figure out
which subobject we're accessing, then construct the temporary object
(adding a destruction if needed) and, finally, dig out the subobject
we actually meant to access.
This fixes yet another instance where we were memcpy'ing rather than
doing the right thing. However, note the FIXME in references.cpp:
there's more work to be done for binding to subobjects, since the AST
is incorrectly modeling some member accesses in base classes as
lvalues when they are really rvalues.
llvm-svn: 104219
2010-05-20 16:36:28 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-28 00:56:04 +08:00
|
|
|
const llvm::Type *ResultPtrTy = CGF.ConvertType(ResultTy)->getPointerTo();
|
|
|
|
return CGF.Builder.CreateBitCast(Object, ResultPtrTy, "temp");
|
2009-10-15 08:51:46 +08:00
|
|
|
}
|
2009-05-20 08:36:58 +08:00
|
|
|
}
|
2009-05-20 10:31:19 +08:00
|
|
|
|
2010-06-28 00:56:04 +08:00
|
|
|
if (RV.isAggregate())
|
|
|
|
return RV.getAggregateAddr();
|
|
|
|
|
2010-06-27 23:24:55 +08:00
|
|
|
// Create a temporary variable that we can bind the reference to.
|
2010-06-28 00:56:04 +08:00
|
|
|
ReferenceTemporary = CGF.CreateMemTemp(E->getType(), "ref.tmp");
|
|
|
|
if (RV.isScalar())
|
|
|
|
CGF.EmitStoreOfScalar(RV.getScalarVal(), ReferenceTemporary,
|
|
|
|
/*Volatile=*/false, E->getType());
|
2010-06-27 23:24:55 +08:00
|
|
|
else
|
2010-06-28 00:56:04 +08:00
|
|
|
CGF.StoreComplexToAddr(RV.getComplexVal(), ReferenceTemporary,
|
|
|
|
/*Volatile=*/false);
|
|
|
|
return ReferenceTemporary;
|
|
|
|
}
|
|
|
|
|
|
|
|
RValue
|
|
|
|
CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
|
|
|
|
const NamedDecl *InitializedDecl) {
|
|
|
|
llvm::Value *ReferenceTemporary = 0;
|
|
|
|
const CXXDestructorDecl *ReferenceTemporaryDtor = 0;
|
|
|
|
llvm::Value *Value = EmitExprForReferenceBinding(*this, E, ReferenceTemporary,
|
|
|
|
ReferenceTemporaryDtor,
|
|
|
|
InitializedDecl);
|
|
|
|
|
|
|
|
// Make sure to call the destructor for the reference temporary.
|
|
|
|
if (ReferenceTemporaryDtor) {
|
|
|
|
DelayedCleanupBlock Scope(*this);
|
|
|
|
EmitCXXDestructorCall(ReferenceTemporaryDtor, Dtor_Complete,
|
|
|
|
/*ForVirtualBase=*/false, ReferenceTemporary);
|
|
|
|
|
|
|
|
// Make sure to jump to the exit block.
|
|
|
|
EmitBranch(Scope.getCleanupExitBlock());
|
|
|
|
|
|
|
|
if (Exceptions) {
|
|
|
|
EHCleanupBlock Cleanup(*this);
|
|
|
|
EmitCXXDestructorCall(ReferenceTemporaryDtor, Dtor_Complete,
|
|
|
|
/*ForVirtualBase=*/false, ReferenceTemporary);
|
|
|
|
}
|
|
|
|
}
|
2010-06-27 23:24:55 +08:00
|
|
|
|
2010-06-28 00:56:04 +08:00
|
|
|
return RValue::get(Value);
|
2009-05-20 08:24:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
/// getAccessedFieldNo - Given an encoded value and a result number, return the
|
|
|
|
/// input field number being accessed.
|
|
|
|
unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
|
2008-05-22 08:50:06 +08:00
|
|
|
const llvm::Constant *Elts) {
|
|
|
|
if (isa<llvm::ConstantAggregateZero>(Elts))
|
|
|
|
return 0;
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2008-05-22 08:50:06 +08:00
|
|
|
return cast<llvm::ConstantInt>(Elts->getOperand(Idx))->getZExtValue();
|
|
|
|
}
|
|
|
|
|
2009-12-16 10:57:00 +08:00
|
|
|
void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {
|
|
|
|
if (!CatchUndefined)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Address = Builder.CreateBitCast(Address, PtrToInt8Ty);
|
|
|
|
|
2010-06-27 15:15:29 +08:00
|
|
|
const llvm::Type *IntPtrT = IntPtrTy;
|
|
|
|
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, &IntPtrT, 1);
|
|
|
|
const llvm::IntegerType *Int1Ty = llvm::Type::getInt1Ty(VMContext);
|
2010-04-11 02:34:14 +08:00
|
|
|
|
2009-12-16 10:57:00 +08:00
|
|
|
// In time, people may want to control this and use a 1 here.
|
2010-04-11 02:34:14 +08:00
|
|
|
llvm::Value *Arg = llvm::ConstantInt::get(Int1Ty, 0);
|
2009-12-16 10:57:00 +08:00
|
|
|
llvm::Value *C = Builder.CreateCall2(F, Address, Arg);
|
|
|
|
llvm::BasicBlock *Cont = createBasicBlock();
|
|
|
|
llvm::BasicBlock *Check = createBasicBlock();
|
2010-06-27 15:15:29 +08:00
|
|
|
llvm::Value *NegativeOne = llvm::ConstantInt::get(IntPtrTy, -1ULL);
|
2009-12-16 10:57:00 +08:00
|
|
|
Builder.CreateCondBr(Builder.CreateICmpEQ(C, NegativeOne), Cont, Check);
|
|
|
|
|
|
|
|
EmitBlock(Check);
|
|
|
|
Builder.CreateCondBr(Builder.CreateICmpUGE(C,
|
2010-06-27 15:15:29 +08:00
|
|
|
llvm::ConstantInt::get(IntPtrTy, Size)),
|
2009-12-16 10:57:00 +08:00
|
|
|
Cont, getTrapBB());
|
|
|
|
EmitBlock(Cont);
|
|
|
|
}
|
2007-09-01 06:49:20 +08:00
|
|
|
|
2010-01-10 05:40:03 +08:00
|
|
|
|
|
|
|
CodeGenFunction::ComplexPairTy CodeGenFunction::
|
|
|
|
EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
|
|
|
|
bool isInc, bool isPre) {
|
|
|
|
ComplexPairTy InVal = LoadComplexFromAddr(LV.getAddress(),
|
|
|
|
LV.isVolatileQualified());
|
|
|
|
|
|
|
|
llvm::Value *NextVal;
|
|
|
|
if (isa<llvm::IntegerType>(InVal.first->getType())) {
|
|
|
|
uint64_t AmountVal = isInc ? 1 : -1;
|
|
|
|
NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal, true);
|
|
|
|
|
|
|
|
// Add the inc/dec to the real part.
|
|
|
|
NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
|
|
|
|
} else {
|
|
|
|
QualType ElemTy = E->getType()->getAs<ComplexType>()->getElementType();
|
|
|
|
llvm::APFloat FVal(getContext().getFloatTypeSemantics(ElemTy), 1);
|
|
|
|
if (!isInc)
|
|
|
|
FVal.changeSign();
|
|
|
|
NextVal = llvm::ConstantFP::get(getLLVMContext(), FVal);
|
|
|
|
|
|
|
|
// Add the inc/dec to the real part.
|
|
|
|
NextVal = Builder.CreateFAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
|
|
|
|
}
|
|
|
|
|
|
|
|
ComplexPairTy IncVal(NextVal, InVal.second);
|
|
|
|
|
|
|
|
// Store the updated result through the lvalue.
|
|
|
|
StoreComplexToAddr(IncVal, LV.getAddress(), LV.isVolatileQualified());
|
|
|
|
|
|
|
|
// If this is a postinc, return the value read from memory, otherwise use the
|
|
|
|
// updated value.
|
|
|
|
return isPre ? IncVal : InVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-06-03 03:47:04 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2007-06-02 13:24:33 +08:00
|
|
|
// LValue Expression Emission
|
2007-06-03 03:47:04 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2007-06-02 13:24:33 +08:00
|
|
|
|
2009-02-05 15:09:07 +08:00
|
|
|
RValue CodeGenFunction::GetUndefRValue(QualType Ty) {
|
2009-10-29 01:39:19 +08:00
|
|
|
if (Ty->isVoidType())
|
2009-02-05 15:09:07 +08:00
|
|
|
return RValue::get(0);
|
2009-10-29 01:39:19 +08:00
|
|
|
|
|
|
|
if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
|
2009-01-10 04:09:28 +08:00
|
|
|
const llvm::Type *EltTy = ConvertType(CTy->getElementType());
|
2009-07-31 07:11:26 +08:00
|
|
|
llvm::Value *U = llvm::UndefValue::get(EltTy);
|
2009-01-10 04:09:28 +08:00
|
|
|
return RValue::getComplex(std::make_pair(U, U));
|
2009-10-29 01:39:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hasAggregateLLVMType(Ty)) {
|
2009-07-30 06:16:19 +08:00
|
|
|
const llvm::Type *LTy = llvm::PointerType::getUnqual(ConvertType(Ty));
|
2009-07-31 07:11:26 +08:00
|
|
|
return RValue::getAggregate(llvm::UndefValue::get(LTy));
|
2009-01-10 04:09:28 +08:00
|
|
|
}
|
2009-10-29 01:39:19 +08:00
|
|
|
|
|
|
|
return RValue::get(llvm::UndefValue::get(ConvertType(Ty)));
|
2009-01-10 00:50:52 +08:00
|
|
|
}
|
|
|
|
|
2009-02-05 15:09:07 +08:00
|
|
|
RValue CodeGenFunction::EmitUnsupportedRValue(const Expr *E,
|
|
|
|
const char *Name) {
|
|
|
|
ErrorUnsupported(E, Name);
|
|
|
|
return GetUndefRValue(E->getType());
|
|
|
|
}
|
|
|
|
|
2008-08-26 04:45:57 +08:00
|
|
|
LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
|
|
|
|
const char *Name) {
|
|
|
|
ErrorUnsupported(E, Name);
|
2009-07-30 06:16:19 +08:00
|
|
|
llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
|
2009-07-31 07:11:26 +08:00
|
|
|
return LValue::MakeAddr(llvm::UndefValue::get(Ty),
|
2009-09-25 03:53:00 +08:00
|
|
|
MakeQualifiers(E->getType()));
|
2008-08-26 04:45:57 +08:00
|
|
|
}
|
|
|
|
|
2009-12-16 10:57:00 +08:00
|
|
|
LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {
|
|
|
|
LValue LV = EmitLValue(E);
|
2010-04-06 05:36:35 +08:00
|
|
|
if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
|
2009-12-16 10:57:00 +08:00
|
|
|
EmitCheck(LV.getAddress(), getContext().getTypeSize(E->getType()) / 8);
|
|
|
|
return LV;
|
|
|
|
}
|
|
|
|
|
2007-06-06 04:53:16 +08:00
|
|
|
/// EmitLValue - Emit code to compute a designator that specifies the location
|
|
|
|
/// of the expression.
|
|
|
|
///
|
2009-09-09 21:00:44 +08:00
|
|
|
/// This can return one of two things: a simple address or a bitfield reference.
|
|
|
|
/// In either case, the LLVM Value* in the LValue structure is guaranteed to be
|
|
|
|
/// an LLVM pointer type.
|
2007-06-06 04:53:16 +08:00
|
|
|
///
|
2009-09-09 21:00:44 +08:00
|
|
|
/// If this returns a bitfield reference, nothing about the pointee type of the
|
|
|
|
/// LLVM value is known: For example, it may not be a pointer to an integer.
|
2007-06-06 04:53:16 +08:00
|
|
|
///
|
2009-09-09 21:00:44 +08:00
|
|
|
/// If this returns a normal address, and if the lvalue's C type is fixed size,
|
|
|
|
/// this method guarantees that the returned pointer type will point to an LLVM
|
|
|
|
/// type of the same size of the lvalue's type. If the lvalue has a variable
|
|
|
|
/// length type, this is not possible.
|
2007-06-06 04:53:16 +08:00
|
|
|
///
|
2007-06-02 13:24:33 +08:00
|
|
|
LValue CodeGenFunction::EmitLValue(const Expr *E) {
|
|
|
|
switch (E->getStmtClass()) {
|
2008-08-26 04:45:57 +08:00
|
|
|
default: return EmitUnsupportedLValue(E, "l-value expression");
|
2007-06-02 13:24:33 +08:00
|
|
|
|
2010-06-18 03:56:20 +08:00
|
|
|
case Expr::ObjCSelectorExprClass:
|
|
|
|
return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E));
|
2009-12-10 07:35:29 +08:00
|
|
|
case Expr::ObjCIsaExprClass:
|
|
|
|
return EmitObjCIsaExpr(cast<ObjCIsaExpr>(E));
|
2009-09-09 21:00:44 +08:00
|
|
|
case Expr::BinaryOperatorClass:
|
2008-09-04 11:20:13 +08:00
|
|
|
return EmitBinaryOperatorLValue(cast<BinaryOperator>(E));
|
2010-04-23 12:16:32 +08:00
|
|
|
case Expr::CompoundAssignOperatorClass:
|
|
|
|
return EmitCompoundAssignOperatorLValue(cast<CompoundAssignOperator>(E));
|
2009-09-09 21:00:44 +08:00
|
|
|
case Expr::CallExprClass:
|
2009-09-02 05:18:52 +08:00
|
|
|
case Expr::CXXMemberCallExprClass:
|
2008-11-15 00:09:21 +08:00
|
|
|
case Expr::CXXOperatorCallExprClass:
|
|
|
|
return EmitCallExprLValue(cast<CallExpr>(E));
|
2009-02-12 04:59:32 +08:00
|
|
|
case Expr::VAArgExprClass:
|
|
|
|
return EmitVAArgExprLValue(cast<VAArgExpr>(E));
|
2009-09-09 21:00:44 +08:00
|
|
|
case Expr::DeclRefExprClass:
|
2009-01-06 13:10:23 +08:00
|
|
|
return EmitDeclRefLValue(cast<DeclRefExpr>(E));
|
2007-06-05 11:59:43 +08:00
|
|
|
case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
|
2008-08-10 09:53:14 +08:00
|
|
|
case Expr::PredefinedExprClass:
|
|
|
|
return EmitPredefinedLValue(cast<PredefinedExpr>(E));
|
2007-06-06 12:54:52 +08:00
|
|
|
case Expr::StringLiteralClass:
|
|
|
|
return EmitStringLiteralLValue(cast<StringLiteral>(E));
|
2009-02-25 06:18:39 +08:00
|
|
|
case Expr::ObjCEncodeExprClass:
|
|
|
|
return EmitObjCEncodeExprLValue(cast<ObjCEncodeExpr>(E));
|
2008-03-31 07:03:07 +08:00
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
case Expr::BlockDeclRefExprClass:
|
2009-02-28 17:07:16 +08:00
|
|
|
return EmitBlockDeclRefLValue(cast<BlockDeclRefExpr>(E));
|
|
|
|
|
2009-05-31 07:23:33 +08:00
|
|
|
case Expr::CXXTemporaryObjectExprClass:
|
|
|
|
case Expr::CXXConstructExprClass:
|
2009-05-31 07:30:54 +08:00
|
|
|
return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));
|
|
|
|
case Expr::CXXBindTemporaryExprClass:
|
|
|
|
return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E));
|
2009-09-14 09:10:45 +08:00
|
|
|
case Expr::CXXExprWithTemporariesClass:
|
|
|
|
return EmitCXXExprWithTemporariesLValue(cast<CXXExprWithTemporaries>(E));
|
2009-11-14 09:51:50 +08:00
|
|
|
case Expr::CXXZeroInitValueExprClass:
|
|
|
|
return EmitNullInitializationLValue(cast<CXXZeroInitValueExpr>(E));
|
|
|
|
case Expr::CXXDefaultArgExprClass:
|
|
|
|
return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());
|
2009-11-15 16:09:41 +08:00
|
|
|
case Expr::CXXTypeidExprClass:
|
|
|
|
return EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E));
|
2009-05-31 07:30:54 +08:00
|
|
|
|
2008-08-23 18:51:21 +08:00
|
|
|
case Expr::ObjCMessageExprClass:
|
|
|
|
return EmitObjCMessageExprLValue(cast<ObjCMessageExpr>(E));
|
2009-09-09 21:00:44 +08:00
|
|
|
case Expr::ObjCIvarRefExprClass:
|
2008-03-31 07:03:07 +08:00
|
|
|
return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
|
2008-08-26 04:45:57 +08:00
|
|
|
case Expr::ObjCPropertyRefExprClass:
|
2008-08-29 16:11:39 +08:00
|
|
|
return EmitObjCPropertyRefLValue(cast<ObjCPropertyRefExpr>(E));
|
2009-08-21 01:02:02 +08:00
|
|
|
case Expr::ObjCImplicitSetterGetterRefExprClass:
|
|
|
|
return EmitObjCKVCRefLValue(cast<ObjCImplicitSetterGetterRefExpr>(E));
|
2008-11-04 22:56:14 +08:00
|
|
|
case Expr::ObjCSuperExprClass:
|
2009-04-26 03:35:26 +08:00
|
|
|
return EmitObjCSuperExprLValue(cast<ObjCSuperExpr>(E));
|
2008-11-04 22:56:14 +08:00
|
|
|
|
2009-04-26 03:35:26 +08:00
|
|
|
case Expr::StmtExprClass:
|
|
|
|
return EmitStmtExprLValue(cast<StmtExpr>(E));
|
2009-09-09 21:00:44 +08:00
|
|
|
case Expr::UnaryOperatorClass:
|
2007-06-06 04:53:16 +08:00
|
|
|
return EmitUnaryOpLValue(cast<UnaryOperator>(E));
|
2007-06-09 07:31:14 +08:00
|
|
|
case Expr::ArraySubscriptExprClass:
|
|
|
|
return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E));
|
2008-04-19 07:10:10 +08:00
|
|
|
case Expr::ExtVectorElementExprClass:
|
|
|
|
return EmitExtVectorElementExpr(cast<ExtVectorElementExpr>(E));
|
2009-09-09 21:00:44 +08:00
|
|
|
case Expr::MemberExprClass:
|
When a member reference expression includes a qualifier on the member
name, e.g.,
x->Base::f()
retain the qualifier (and its source range information) in a new
subclass of MemberExpr called CXXQualifiedMemberExpr. Provide
construction, transformation, profiling, printing, etc., for this new
expression type.
When a virtual function is called via a qualified name, don't emit a
virtual call. Instead, call that function directly. Mike, could you
add a CodeGen test for this, too?
llvm-svn: 80167
2009-08-27 06:36:53 +08:00
|
|
|
return EmitMemberExpr(cast<MemberExpr>(E));
|
2008-05-14 07:18:27 +08:00
|
|
|
case Expr::CompoundLiteralExprClass:
|
|
|
|
return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
|
2009-03-24 10:38:23 +08:00
|
|
|
case Expr::ConditionalOperatorClass:
|
2009-09-16 00:35:24 +08:00
|
|
|
return EmitConditionalOperatorLValue(cast<ConditionalOperator>(E));
|
2008-12-12 13:35:08 +08:00
|
|
|
case Expr::ChooseExprClass:
|
2009-03-04 13:52:32 +08:00
|
|
|
return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr(getContext()));
|
2009-03-18 12:02:57 +08:00
|
|
|
case Expr::ImplicitCastExprClass:
|
|
|
|
case Expr::CStyleCastExprClass:
|
|
|
|
case Expr::CXXFunctionalCastExprClass:
|
|
|
|
case Expr::CXXStaticCastExprClass:
|
|
|
|
case Expr::CXXDynamicCastExprClass:
|
|
|
|
case Expr::CXXReinterpretCastExprClass:
|
|
|
|
case Expr::CXXConstCastExprClass:
|
2009-03-19 02:28:57 +08:00
|
|
|
return EmitCastLValue(cast<CastExpr>(E));
|
2007-06-02 13:24:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-10 08:57:50 +08:00
|
|
|
llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
|
|
|
|
QualType Ty) {
|
2009-11-30 05:23:36 +08:00
|
|
|
llvm::LoadInst *Load = Builder.CreateLoad(Addr, "tmp");
|
|
|
|
if (Volatile)
|
|
|
|
Load->setVolatile(true);
|
2009-02-10 08:57:50 +08:00
|
|
|
|
2009-05-20 03:36:19 +08:00
|
|
|
// Bool can have different representation in memory than in registers.
|
2009-11-30 05:23:36 +08:00
|
|
|
llvm::Value *V = Load;
|
2009-02-10 08:57:50 +08:00
|
|
|
if (Ty->isBooleanType())
|
2009-08-14 05:57:51 +08:00
|
|
|
if (V->getType() != llvm::Type::getInt1Ty(VMContext))
|
|
|
|
V = Builder.CreateTrunc(V, llvm::Type::getInt1Ty(VMContext), "tobool");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-02-10 08:57:50 +08:00
|
|
|
return V;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
|
2009-05-20 02:50:41 +08:00
|
|
|
bool Volatile, QualType Ty) {
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-05-20 03:36:19 +08:00
|
|
|
if (Ty->isBooleanType()) {
|
|
|
|
// Bool can have different representation in memory than in registers.
|
|
|
|
const llvm::PointerType *DstPtr = cast<llvm::PointerType>(Addr->getType());
|
2009-12-02 06:31:51 +08:00
|
|
|
Value = Builder.CreateIntCast(Value, DstPtr->getElementType(), false);
|
2009-02-10 08:57:50 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
Builder.CreateStore(Value, Addr, Volatile);
|
2009-02-10 08:57:50 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
/// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
|
|
|
|
/// method emits the address of the lvalue, then loads the result as an rvalue,
|
|
|
|
/// returning the rvalue.
|
2007-06-30 00:31:29 +08:00
|
|
|
RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
|
2008-11-20 01:34:06 +08:00
|
|
|
if (LV.isObjCWeak()) {
|
2009-09-09 21:00:44 +08:00
|
|
|
// load of a __weak object.
|
2008-11-19 05:45:40 +08:00
|
|
|
llvm::Value *AddrWeakObj = LV.getAddress();
|
2009-10-29 01:39:19 +08:00
|
|
|
return RValue::get(CGM.getObjCRuntime().EmitObjCWeakRead(*this,
|
|
|
|
AddrWeakObj));
|
2008-11-19 05:45:40 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-07-11 05:17:59 +08:00
|
|
|
if (LV.isSimple()) {
|
|
|
|
llvm::Value *Ptr = LV.getAddress();
|
2010-02-06 05:10:36 +08:00
|
|
|
const llvm::Type *EltTy =
|
|
|
|
cast<llvm::PointerType>(Ptr->getType())->getElementType();
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-07-11 05:17:59 +08:00
|
|
|
// Simple scalar l-value.
|
2010-02-09 06:53:07 +08:00
|
|
|
//
|
|
|
|
// FIXME: We shouldn't have to use isSingleValueType here.
|
2010-02-06 05:10:36 +08:00
|
|
|
if (EltTy->isSingleValueType())
|
2009-09-09 21:00:44 +08:00
|
|
|
return RValue::get(EmitLoadOfScalar(Ptr, LV.isVolatileQualified(),
|
2009-02-10 08:57:50 +08:00
|
|
|
ExprType));
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-11 08:04:45 +08:00
|
|
|
assert(ExprType->isFunctionType() && "Unknown scalar value");
|
|
|
|
return RValue::get(Ptr);
|
2007-07-11 05:17:59 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-07-11 05:17:59 +08:00
|
|
|
if (LV.isVectorElt()) {
|
2008-06-14 07:01:12 +08:00
|
|
|
llvm::Value *Vec = Builder.CreateLoad(LV.getVectorAddr(),
|
|
|
|
LV.isVolatileQualified(), "tmp");
|
2007-07-11 05:17:59 +08:00
|
|
|
return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(),
|
|
|
|
"vecext"));
|
|
|
|
}
|
implement lvalue to rvalue conversion for ocuvector components. We can now compile stuff
like this:
typedef __attribute__(( ocu_vector_type(4) )) float float4;
float4 test1(float4 V) {
return V.wzyx+V;
}
to:
_test1:
pshufd $27, %xmm0, %xmm1
addps %xmm0, %xmm1
movaps %xmm1, %xmm0
ret
and:
_test1:
mfspr r2, 256
oris r3, r2, 4096
mtspr 256, r3
li r3, lo16(LCPI1_0)
lis r4, ha16(LCPI1_0)
lvx v3, r4, r3
vperm v3, v2, v2, v3
vaddfp v2, v3, v2
mtspr 256, r2
blr
llvm-svn: 40771
2007-08-03 08:16:29 +08:00
|
|
|
|
|
|
|
// If this is a reference to a subset of the elements of a vector, either
|
|
|
|
// shuffle the input or extract/insert them as appropriate.
|
2008-04-19 07:10:10 +08:00
|
|
|
if (LV.isExtVectorElt())
|
|
|
|
return EmitLoadOfExtVectorElementLValue(LV, ExprType);
|
2008-01-23 04:17:04 +08:00
|
|
|
|
2010-04-06 05:36:35 +08:00
|
|
|
if (LV.isBitField())
|
2008-01-23 04:17:04 +08:00
|
|
|
return EmitLoadOfBitfieldLValue(LV, ExprType);
|
|
|
|
|
2008-08-29 16:11:39 +08:00
|
|
|
if (LV.isPropertyRef())
|
|
|
|
return EmitLoadOfPropertyRefLValue(LV, ExprType);
|
|
|
|
|
2009-02-17 05:11:58 +08:00
|
|
|
assert(LV.isKVCRef() && "Unknown LValue type!");
|
|
|
|
return EmitLoadOfKVCRefLValue(LV, ExprType);
|
2007-08-04 00:18:34 +08:00
|
|
|
}
|
2007-08-03 23:52:31 +08:00
|
|
|
|
2008-01-23 04:17:04 +08:00
|
|
|
RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
|
|
|
|
QualType ExprType) {
|
2010-04-06 09:07:44 +08:00
|
|
|
const CGBitFieldInfo &Info = LV.getBitFieldInfo();
|
2008-01-23 04:17:04 +08:00
|
|
|
|
2010-04-14 07:34:15 +08:00
|
|
|
// Get the output type.
|
|
|
|
const llvm::Type *ResLTy = ConvertType(ExprType);
|
|
|
|
unsigned ResSizeInBits = CGM.getTargetData().getTypeSizeInBits(ResLTy);
|
|
|
|
|
|
|
|
// Compute the result as an OR of all of the individual component accesses.
|
|
|
|
llvm::Value *Res = 0;
|
|
|
|
for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
|
|
|
|
const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
|
|
|
|
|
|
|
|
// Get the field pointer.
|
|
|
|
llvm::Value *Ptr = LV.getBitFieldBaseAddr();
|
|
|
|
|
|
|
|
// Only offset by the field index if used, so that incoming values are not
|
|
|
|
// required to be structures.
|
|
|
|
if (AI.FieldIndex)
|
|
|
|
Ptr = Builder.CreateStructGEP(Ptr, AI.FieldIndex, "bf.field");
|
|
|
|
|
|
|
|
// Offset by the byte offset, if used.
|
|
|
|
if (AI.FieldByteOffset) {
|
|
|
|
const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
|
|
|
|
Ptr = Builder.CreateBitCast(Ptr, i8PTy);
|
|
|
|
Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cast to the access type.
|
|
|
|
const llvm::Type *PTy = llvm::Type::getIntNPtrTy(VMContext, AI.AccessWidth,
|
|
|
|
ExprType.getAddressSpace());
|
|
|
|
Ptr = Builder.CreateBitCast(Ptr, PTy);
|
|
|
|
|
|
|
|
// Perform the load.
|
|
|
|
llvm::LoadInst *Load = Builder.CreateLoad(Ptr, LV.isVolatileQualified());
|
|
|
|
if (AI.AccessAlignment)
|
|
|
|
Load->setAlignment(AI.AccessAlignment);
|
|
|
|
|
|
|
|
// Shift out unused low bits and mask out unused high bits.
|
|
|
|
llvm::Value *Val = Load;
|
|
|
|
if (AI.FieldBitStart)
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
Val = Builder.CreateLShr(Load, AI.FieldBitStart);
|
2010-04-14 07:34:15 +08:00
|
|
|
Val = Builder.CreateAnd(Val, llvm::APInt::getLowBitsSet(AI.AccessWidth,
|
|
|
|
AI.TargetBitWidth),
|
|
|
|
"bf.clear");
|
|
|
|
|
|
|
|
// Extend or truncate to the target size.
|
|
|
|
if (AI.AccessWidth < ResSizeInBits)
|
|
|
|
Val = Builder.CreateZExt(Val, ResLTy);
|
|
|
|
else if (AI.AccessWidth > ResSizeInBits)
|
|
|
|
Val = Builder.CreateTrunc(Val, ResLTy);
|
|
|
|
|
|
|
|
// Shift into place, and OR into the result.
|
|
|
|
if (AI.TargetBitOffset)
|
|
|
|
Val = Builder.CreateShl(Val, AI.TargetBitOffset);
|
|
|
|
Res = Res ? Builder.CreateOr(Res, Val) : Val;
|
2008-08-06 13:08:45 +08:00
|
|
|
}
|
2008-05-18 04:03:47 +08:00
|
|
|
|
2010-04-14 07:34:15 +08:00
|
|
|
// If the bit-field is signed, perform the sign-extension.
|
|
|
|
//
|
|
|
|
// FIXME: This can easily be folded into the load of the high bits, which
|
|
|
|
// could also eliminate the mask of high bits in some situations.
|
|
|
|
if (Info.isSigned()) {
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
unsigned ExtraBits = ResSizeInBits - Info.getSize();
|
2010-04-14 07:34:15 +08:00
|
|
|
if (ExtraBits)
|
|
|
|
Res = Builder.CreateAShr(Builder.CreateShl(Res, ExtraBits),
|
|
|
|
ExtraBits, "bf.val.sext");
|
|
|
|
}
|
2008-05-18 04:03:47 +08:00
|
|
|
|
2010-04-14 07:34:15 +08:00
|
|
|
return RValue::get(Res);
|
2008-01-23 04:17:04 +08:00
|
|
|
}
|
|
|
|
|
2008-08-29 16:11:39 +08:00
|
|
|
RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
|
|
|
|
QualType ExprType) {
|
|
|
|
return EmitObjCPropertyGet(LV.getPropertyRefExpr());
|
|
|
|
}
|
|
|
|
|
2008-11-23 06:30:21 +08:00
|
|
|
RValue CodeGenFunction::EmitLoadOfKVCRefLValue(LValue LV,
|
|
|
|
QualType ExprType) {
|
|
|
|
return EmitObjCPropertyGet(LV.getKVCRefExpr());
|
|
|
|
}
|
|
|
|
|
2009-01-18 14:42:49 +08:00
|
|
|
// If this is a reference to a subset of the elements of a vector, create an
|
|
|
|
// appropriate shufflevector.
|
2008-04-19 07:10:10 +08:00
|
|
|
RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
|
|
|
|
QualType ExprType) {
|
2008-06-14 07:01:12 +08:00
|
|
|
llvm::Value *Vec = Builder.CreateLoad(LV.getExtVectorAddr(),
|
|
|
|
LV.isVolatileQualified(), "tmp");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2008-05-09 14:41:27 +08:00
|
|
|
const llvm::Constant *Elts = LV.getExtVectorElts();
|
2009-09-09 21:00:44 +08:00
|
|
|
|
|
|
|
// If the result of the expression is a non-vector type, we must be extracting
|
|
|
|
// a single element. Just codegen as an extractelement.
|
2009-09-22 07:43:11 +08:00
|
|
|
const VectorType *ExprVT = ExprType->getAs<VectorType>();
|
2007-08-11 01:10:08 +08:00
|
|
|
if (!ExprVT) {
|
2008-05-22 08:50:06 +08:00
|
|
|
unsigned InIdx = getAccessedFieldNo(0, Elts);
|
2010-06-27 15:15:29 +08:00
|
|
|
llvm::Value *Elt = llvm::ConstantInt::get(Int32Ty, InIdx);
|
2007-08-04 00:18:34 +08:00
|
|
|
return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
|
|
|
|
}
|
2009-01-18 14:42:49 +08:00
|
|
|
|
|
|
|
// Always use shuffle vector to try to retain the original program structure
|
2007-08-11 01:10:08 +08:00
|
|
|
unsigned NumResultElts = ExprVT->getNumElements();
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-01-18 14:42:49 +08:00
|
|
|
llvm::SmallVector<llvm::Constant*, 4> Mask;
|
2007-08-04 00:18:34 +08:00
|
|
|
for (unsigned i = 0; i != NumResultElts; ++i) {
|
2008-05-22 08:50:06 +08:00
|
|
|
unsigned InIdx = getAccessedFieldNo(i, Elts);
|
2010-06-27 15:15:29 +08:00
|
|
|
Mask.push_back(llvm::ConstantInt::get(Int32Ty, InIdx));
|
2007-08-04 00:18:34 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-07-29 05:22:35 +08:00
|
|
|
llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
|
2009-01-18 14:42:49 +08:00
|
|
|
Vec = Builder.CreateShuffleVector(Vec,
|
2009-07-31 07:11:26 +08:00
|
|
|
llvm::UndefValue::get(Vec->getType()),
|
2009-01-18 14:42:49 +08:00
|
|
|
MaskV, "tmp");
|
|
|
|
return RValue::get(Vec);
|
2007-06-06 04:53:16 +08:00
|
|
|
}
|
|
|
|
|
2007-08-04 00:18:34 +08:00
|
|
|
|
2007-06-30 00:31:29 +08:00
|
|
|
|
2007-06-06 04:53:16 +08:00
|
|
|
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
|
|
|
|
/// lvalue, where both are guaranteed to the have the same type, and that type
|
|
|
|
/// is 'Ty'.
|
2009-09-09 21:00:44 +08:00
|
|
|
void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
|
2007-06-06 04:53:16 +08:00
|
|
|
QualType Ty) {
|
2007-08-04 00:28:33 +08:00
|
|
|
if (!Dst.isSimple()) {
|
|
|
|
if (Dst.isVectorElt()) {
|
|
|
|
// Read/modify/write the vector, inserting the new element.
|
2008-06-14 07:01:12 +08:00
|
|
|
llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddr(),
|
|
|
|
Dst.isVolatileQualified(), "tmp");
|
2007-09-01 06:49:20 +08:00
|
|
|
Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(),
|
2007-08-04 00:28:33 +08:00
|
|
|
Dst.getVectorIdx(), "vecins");
|
2008-06-14 07:01:12 +08:00
|
|
|
Builder.CreateStore(Vec, Dst.getVectorAddr(),Dst.isVolatileQualified());
|
2007-08-04 00:28:33 +08:00
|
|
|
return;
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2008-04-19 07:10:10 +08:00
|
|
|
// If this is an update of extended vector elements, insert them as
|
|
|
|
// appropriate.
|
|
|
|
if (Dst.isExtVectorElt())
|
|
|
|
return EmitStoreThroughExtVectorComponentLValue(Src, Dst, Ty);
|
2008-01-23 06:36:45 +08:00
|
|
|
|
2010-04-06 05:36:35 +08:00
|
|
|
if (Dst.isBitField())
|
2008-01-23 06:36:45 +08:00
|
|
|
return EmitStoreThroughBitfieldLValue(Src, Dst, Ty);
|
|
|
|
|
2008-08-29 16:11:39 +08:00
|
|
|
if (Dst.isPropertyRef())
|
|
|
|
return EmitStoreThroughPropertyRefLValue(Src, Dst, Ty);
|
|
|
|
|
2009-10-29 01:39:19 +08:00
|
|
|
assert(Dst.isKVCRef() && "Unknown LValue type");
|
|
|
|
return EmitStoreThroughKVCRefLValue(Src, Dst, Ty);
|
2007-08-04 00:28:33 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-02-21 08:30:43 +08:00
|
|
|
if (Dst.isObjCWeak() && !Dst.isNonGC()) {
|
2009-09-09 21:00:44 +08:00
|
|
|
// load of a __weak object.
|
2008-11-20 01:34:06 +08:00
|
|
|
llvm::Value *LvalueDst = Dst.getAddress();
|
|
|
|
llvm::Value *src = Src.getScalarVal();
|
2009-04-14 08:57:29 +08:00
|
|
|
CGM.getObjCRuntime().EmitObjCWeakAssign(*this, src, LvalueDst);
|
2008-11-20 01:34:06 +08:00
|
|
|
return;
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-02-21 08:30:43 +08:00
|
|
|
if (Dst.isObjCStrong() && !Dst.isNonGC()) {
|
2009-09-09 21:00:44 +08:00
|
|
|
// load of a __strong object.
|
2008-11-20 01:34:06 +08:00
|
|
|
llvm::Value *LvalueDst = Dst.getAddress();
|
|
|
|
llvm::Value *src = Src.getScalarVal();
|
2009-09-25 06:25:38 +08:00
|
|
|
if (Dst.isObjCIvar()) {
|
|
|
|
assert(Dst.getBaseIvarExp() && "BaseIvarExp is NULL");
|
|
|
|
const llvm::Type *ResultType = ConvertType(getContext().LongTy);
|
|
|
|
llvm::Value *RHS = EmitScalarExpr(Dst.getBaseIvarExp());
|
2009-09-25 08:00:20 +08:00
|
|
|
llvm::Value *dst = RHS;
|
2009-09-25 06:25:38 +08:00
|
|
|
RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
|
|
|
|
llvm::Value *LHS =
|
|
|
|
Builder.CreatePtrToInt(LvalueDst, ResultType, "sub.ptr.lhs.cast");
|
|
|
|
llvm::Value *BytesBetween = Builder.CreateSub(LHS, RHS, "ivar.offset");
|
2009-09-25 08:00:20 +08:00
|
|
|
CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, dst,
|
2009-09-25 06:25:38 +08:00
|
|
|
BytesBetween);
|
2009-10-29 01:39:19 +08:00
|
|
|
} else if (Dst.isGlobalObjCRef())
|
2009-05-05 07:27:20 +08:00
|
|
|
CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst);
|
|
|
|
else
|
|
|
|
CGM.getObjCRuntime().EmitObjCStrongCastAssign(*this, src, LvalueDst);
|
2008-11-20 01:34:06 +08:00
|
|
|
return;
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-11 08:04:45 +08:00
|
|
|
assert(Src.isScalar() && "Can't emit an agg store with this method");
|
2009-05-20 02:50:41 +08:00
|
|
|
EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(),
|
|
|
|
Dst.isVolatileQualified(), Ty);
|
2007-06-06 04:53:16 +08:00
|
|
|
}
|
|
|
|
|
2008-01-23 06:36:45 +08:00
|
|
|
void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
|
2009-09-09 21:00:44 +08:00
|
|
|
QualType Ty,
|
2008-11-19 17:36:46 +08:00
|
|
|
llvm::Value **Result) {
|
2010-04-06 09:07:44 +08:00
|
|
|
const CGBitFieldInfo &Info = Dst.getBitFieldInfo();
|
2008-01-23 06:36:45 +08:00
|
|
|
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
// Get the output type.
|
2010-04-18 05:52:22 +08:00
|
|
|
const llvm::Type *ResLTy = ConvertTypeForMem(Ty);
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
unsigned ResSizeInBits = CGM.getTargetData().getTypeSizeInBits(ResLTy);
|
2008-01-23 06:36:45 +08:00
|
|
|
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
// Get the source value, truncated to the width of the bit-field.
|
2008-11-19 17:36:46 +08:00
|
|
|
llvm::Value *SrcVal = Src.getScalarVal();
|
2010-04-18 05:52:22 +08:00
|
|
|
|
|
|
|
if (Ty->isBooleanType())
|
|
|
|
SrcVal = Builder.CreateIntCast(SrcVal, ResLTy, /*IsSigned=*/false);
|
|
|
|
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
SrcVal = Builder.CreateAnd(SrcVal, llvm::APInt::getLowBitsSet(ResSizeInBits,
|
|
|
|
Info.getSize()),
|
|
|
|
"bf.value");
|
2008-08-06 13:08:45 +08:00
|
|
|
|
2008-11-19 17:36:46 +08:00
|
|
|
// Return the new value of the bit-field, if requested.
|
|
|
|
if (Result) {
|
|
|
|
// Cast back to the proper type for result.
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
const llvm::Type *SrcTy = Src.getScalarVal()->getType();
|
|
|
|
llvm::Value *ReloadVal = Builder.CreateIntCast(SrcVal, SrcTy, false,
|
|
|
|
"bf.reload.val");
|
2008-11-19 17:36:46 +08:00
|
|
|
|
|
|
|
// Sign extend if necessary.
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
if (Info.isSigned()) {
|
|
|
|
unsigned ExtraBits = ResSizeInBits - Info.getSize();
|
|
|
|
if (ExtraBits)
|
|
|
|
ReloadVal = Builder.CreateAShr(Builder.CreateShl(ReloadVal, ExtraBits),
|
|
|
|
ExtraBits, "bf.reload.sext");
|
2008-11-19 17:36:46 +08:00
|
|
|
}
|
|
|
|
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
*Result = ReloadVal;
|
2008-11-19 17:36:46 +08:00
|
|
|
}
|
|
|
|
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 11:47:33 +08:00
|
|
|
// Iterate over the components, writing each piece to memory.
|
|
|
|
for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
|
|
|
|
const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
|
|
|
|
|
|
|
|
// Get the field pointer.
|
|
|
|
llvm::Value *Ptr = Dst.getBitFieldBaseAddr();
|
|
|
|
|
|
|
|
// Only offset by the field index if used, so that incoming values are not
|
|
|
|
// required to be structures.
|
|
|
|
if (AI.FieldIndex)
|
|
|
|
Ptr = Builder.CreateStructGEP(Ptr, AI.FieldIndex, "bf.field");
|
|
|
|
|
|
|
|
// Offset by the byte offset, if used.
|
|
|
|
if (AI.FieldByteOffset) {
|
|
|
|
const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
|
|
|
|
Ptr = Builder.CreateBitCast(Ptr, i8PTy);
|
|
|
|
Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cast to the access type.
|
|
|
|
const llvm::Type *PTy = llvm::Type::getIntNPtrTy(VMContext, AI.AccessWidth,
|
|
|
|
Ty.getAddressSpace());
|
|
|
|
Ptr = Builder.CreateBitCast(Ptr, PTy);
|
|
|
|
|
|
|
|
// Extract the piece of the bit-field value to write in this access, limited
|
|
|
|
// to the values that are part of this access.
|
|
|
|
llvm::Value *Val = SrcVal;
|
|
|
|
if (AI.TargetBitOffset)
|
|
|
|
Val = Builder.CreateLShr(Val, AI.TargetBitOffset);
|
|
|
|
Val = Builder.CreateAnd(Val, llvm::APInt::getLowBitsSet(ResSizeInBits,
|
|
|
|
AI.TargetBitWidth));
|
|
|
|
|
|
|
|
// Extend or truncate to the access size.
|
|
|
|
const llvm::Type *AccessLTy =
|
|
|
|
llvm::Type::getIntNTy(VMContext, AI.AccessWidth);
|
|
|
|
if (ResSizeInBits < AI.AccessWidth)
|
|
|
|
Val = Builder.CreateZExt(Val, AccessLTy);
|
|
|
|
else if (ResSizeInBits > AI.AccessWidth)
|
|
|
|
Val = Builder.CreateTrunc(Val, AccessLTy);
|
|
|
|
|
|
|
|
// Shift into the position in memory.
|
|
|
|
if (AI.FieldBitStart)
|
|
|
|
Val = Builder.CreateShl(Val, AI.FieldBitStart);
|
|
|
|
|
|
|
|
// If necessary, load and OR in bits that are outside of the bit-field.
|
|
|
|
if (AI.TargetBitWidth != AI.AccessWidth) {
|
|
|
|
llvm::LoadInst *Load = Builder.CreateLoad(Ptr, Dst.isVolatileQualified());
|
|
|
|
if (AI.AccessAlignment)
|
|
|
|
Load->setAlignment(AI.AccessAlignment);
|
|
|
|
|
|
|
|
// Compute the mask for zeroing the bits that are part of the bit-field.
|
|
|
|
llvm::APInt InvMask =
|
|
|
|
~llvm::APInt::getBitsSet(AI.AccessWidth, AI.FieldBitStart,
|
|
|
|
AI.FieldBitStart + AI.TargetBitWidth);
|
|
|
|
|
|
|
|
// Apply the mask and OR in to the value to write.
|
|
|
|
Val = Builder.CreateOr(Builder.CreateAnd(Load, InvMask), Val);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write the value.
|
|
|
|
llvm::StoreInst *Store = Builder.CreateStore(Val, Ptr,
|
|
|
|
Dst.isVolatileQualified());
|
|
|
|
if (AI.AccessAlignment)
|
|
|
|
Store->setAlignment(AI.AccessAlignment);
|
2008-08-06 13:08:45 +08:00
|
|
|
}
|
2008-01-23 06:36:45 +08:00
|
|
|
}
|
|
|
|
|
2008-08-29 16:11:39 +08:00
|
|
|
void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
|
|
|
|
LValue Dst,
|
|
|
|
QualType Ty) {
|
|
|
|
EmitObjCPropertySet(Dst.getPropertyRefExpr(), Src);
|
|
|
|
}
|
|
|
|
|
2008-11-23 06:30:21 +08:00
|
|
|
void CodeGenFunction::EmitStoreThroughKVCRefLValue(RValue Src,
|
|
|
|
LValue Dst,
|
|
|
|
QualType Ty) {
|
|
|
|
EmitObjCPropertySet(Dst.getKVCRefExpr(), Src);
|
|
|
|
}
|
|
|
|
|
2008-04-19 07:10:10 +08:00
|
|
|
void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
|
|
|
|
LValue Dst,
|
|
|
|
QualType Ty) {
|
2007-08-04 00:28:33 +08:00
|
|
|
// This access turns into a read/modify/write of the vector. Load the input
|
|
|
|
// value now.
|
2008-06-14 07:01:12 +08:00
|
|
|
llvm::Value *Vec = Builder.CreateLoad(Dst.getExtVectorAddr(),
|
|
|
|
Dst.isVolatileQualified(), "tmp");
|
2008-05-09 14:41:27 +08:00
|
|
|
const llvm::Constant *Elts = Dst.getExtVectorElts();
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-09-01 06:49:20 +08:00
|
|
|
llvm::Value *SrcVal = Src.getScalarVal();
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-09-22 07:43:11 +08:00
|
|
|
if (const VectorType *VTy = Ty->getAs<VectorType>()) {
|
2007-08-04 00:37:04 +08:00
|
|
|
unsigned NumSrcElts = VTy->getNumElements();
|
2009-01-18 14:42:49 +08:00
|
|
|
unsigned NumDstElts =
|
|
|
|
cast<llvm::VectorType>(Vec->getType())->getNumElements();
|
|
|
|
if (NumDstElts == NumSrcElts) {
|
2009-09-09 21:00:44 +08:00
|
|
|
// Use shuffle vector is the src and destination are the same number of
|
|
|
|
// elements and restore the vector mask since it is on the side it will be
|
|
|
|
// stored.
|
2009-06-27 05:12:50 +08:00
|
|
|
llvm::SmallVector<llvm::Constant*, 4> Mask(NumDstElts);
|
2009-01-18 14:42:49 +08:00
|
|
|
for (unsigned i = 0; i != NumSrcElts; ++i) {
|
|
|
|
unsigned InIdx = getAccessedFieldNo(i, Elts);
|
2010-06-27 15:15:29 +08:00
|
|
|
Mask[InIdx] = llvm::ConstantInt::get(Int32Ty, i);
|
2009-01-18 14:42:49 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-07-29 05:22:35 +08:00
|
|
|
llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
|
2009-01-18 14:42:49 +08:00
|
|
|
Vec = Builder.CreateShuffleVector(SrcVal,
|
2009-07-31 07:11:26 +08:00
|
|
|
llvm::UndefValue::get(Vec->getType()),
|
2009-01-18 14:42:49 +08:00
|
|
|
MaskV, "tmp");
|
2009-07-31 06:28:39 +08:00
|
|
|
} else if (NumDstElts > NumSrcElts) {
|
2009-01-18 14:42:49 +08:00
|
|
|
// Extended the source vector to the same length and then shuffle it
|
|
|
|
// into the destination.
|
|
|
|
// FIXME: since we're shuffling with undef, can we just use the indices
|
|
|
|
// into that? This could be simpler.
|
|
|
|
llvm::SmallVector<llvm::Constant*, 4> ExtMask;
|
|
|
|
unsigned i;
|
|
|
|
for (i = 0; i != NumSrcElts; ++i)
|
2009-10-29 01:39:19 +08:00
|
|
|
ExtMask.push_back(llvm::ConstantInt::get(Int32Ty, i));
|
2009-01-18 14:42:49 +08:00
|
|
|
for (; i != NumDstElts; ++i)
|
2009-10-29 01:39:19 +08:00
|
|
|
ExtMask.push_back(llvm::UndefValue::get(Int32Ty));
|
2009-07-29 05:22:35 +08:00
|
|
|
llvm::Value *ExtMaskV = llvm::ConstantVector::get(&ExtMask[0],
|
2009-01-18 14:42:49 +08:00
|
|
|
ExtMask.size());
|
2009-09-09 21:00:44 +08:00
|
|
|
llvm::Value *ExtSrcVal =
|
2009-02-18 02:31:04 +08:00
|
|
|
Builder.CreateShuffleVector(SrcVal,
|
2009-07-31 07:11:26 +08:00
|
|
|
llvm::UndefValue::get(SrcVal->getType()),
|
2009-02-18 02:31:04 +08:00
|
|
|
ExtMaskV, "tmp");
|
2009-01-18 14:42:49 +08:00
|
|
|
// build identity
|
|
|
|
llvm::SmallVector<llvm::Constant*, 4> Mask;
|
2009-10-29 01:39:19 +08:00
|
|
|
for (unsigned i = 0; i != NumDstElts; ++i)
|
|
|
|
Mask.push_back(llvm::ConstantInt::get(Int32Ty, i));
|
|
|
|
|
2009-01-18 14:42:49 +08:00
|
|
|
// modify when what gets shuffled in
|
|
|
|
for (unsigned i = 0; i != NumSrcElts; ++i) {
|
|
|
|
unsigned Idx = getAccessedFieldNo(i, Elts);
|
2009-10-29 01:39:19 +08:00
|
|
|
Mask[Idx] = llvm::ConstantInt::get(Int32Ty, i+NumDstElts);
|
2009-01-18 14:42:49 +08:00
|
|
|
}
|
2009-07-29 05:22:35 +08:00
|
|
|
llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
|
2009-01-18 14:42:49 +08:00
|
|
|
Vec = Builder.CreateShuffleVector(Vec, ExtSrcVal, MaskV, "tmp");
|
2009-07-31 06:28:39 +08:00
|
|
|
} else {
|
2009-01-18 14:42:49 +08:00
|
|
|
// We should never shorten the vector
|
|
|
|
assert(0 && "unexpected shorten vector length");
|
2007-08-04 00:37:04 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// If the Src is a scalar (not a vector) it must be updating one element.
|
2008-05-22 08:50:06 +08:00
|
|
|
unsigned InIdx = getAccessedFieldNo(0, Elts);
|
2009-10-29 01:39:19 +08:00
|
|
|
llvm::Value *Elt = llvm::ConstantInt::get(Int32Ty, InIdx);
|
2007-08-04 00:28:33 +08:00
|
|
|
Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt, "tmp");
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2008-06-14 07:01:12 +08:00
|
|
|
Builder.CreateStore(Vec, Dst.getExtVectorAddr(), Dst.isVolatileQualified());
|
2007-08-04 00:28:33 +08:00
|
|
|
}
|
|
|
|
|
2009-09-17 05:37:16 +08:00
|
|
|
// setObjCGCLValueClass - sets class of he lvalue for the purpose of
|
|
|
|
// generating write-barries API. It is currently a global, ivar,
|
|
|
|
// or neither.
|
2009-10-29 01:39:19 +08:00
|
|
|
static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
|
|
|
|
LValue &LV) {
|
2009-09-22 07:03:37 +08:00
|
|
|
if (Ctx.getLangOptions().getGCMode() == LangOptions::NonGC)
|
2009-09-17 05:37:16 +08:00
|
|
|
return;
|
|
|
|
|
2009-09-17 07:11:23 +08:00
|
|
|
if (isa<ObjCIvarRefExpr>(E)) {
|
|
|
|
LV.SetObjCIvar(LV, true);
|
2009-09-25 06:25:38 +08:00
|
|
|
ObjCIvarRefExpr *Exp = cast<ObjCIvarRefExpr>(const_cast<Expr*>(E));
|
|
|
|
LV.setBaseIvarExp(Exp->getBase());
|
2009-09-22 02:54:29 +08:00
|
|
|
LV.SetObjCArray(LV, E->getType()->isArrayType());
|
2009-09-17 07:11:23 +08:00
|
|
|
return;
|
|
|
|
}
|
2009-10-29 01:39:19 +08:00
|
|
|
|
2009-09-17 05:37:16 +08:00
|
|
|
if (const DeclRefExpr *Exp = dyn_cast<DeclRefExpr>(E)) {
|
|
|
|
if (const VarDecl *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
|
|
|
|
if ((VD->isBlockVarDecl() && !VD->hasLocalStorage()) ||
|
|
|
|
VD->isFileVarDecl())
|
|
|
|
LV.SetGlobalObjCRef(LV, true);
|
|
|
|
}
|
2009-09-22 02:54:29 +08:00
|
|
|
LV.SetObjCArray(LV, E->getType()->isArrayType());
|
2009-10-29 01:39:19 +08:00
|
|
|
return;
|
2009-09-17 05:37:16 +08:00
|
|
|
}
|
2009-10-29 01:39:19 +08:00
|
|
|
|
|
|
|
if (const UnaryOperator *Exp = dyn_cast<UnaryOperator>(E)) {
|
2009-09-17 05:37:16 +08:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
2009-10-29 01:39:19 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const ParenExpr *Exp = dyn_cast<ParenExpr>(E)) {
|
2009-09-17 05:37:16 +08:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
2009-10-01 01:10:29 +08:00
|
|
|
if (LV.isObjCIvar()) {
|
|
|
|
// If cast is to a structure pointer, follow gcc's behavior and make it
|
|
|
|
// a non-ivar write-barrier.
|
|
|
|
QualType ExpTy = E->getType();
|
|
|
|
if (ExpTy->isPointerType())
|
|
|
|
ExpTy = ExpTy->getAs<PointerType>()->getPointeeType();
|
|
|
|
if (ExpTy->isRecordType())
|
|
|
|
LV.SetObjCIvar(LV, false);
|
2009-10-29 01:39:19 +08:00
|
|
|
}
|
|
|
|
return;
|
2009-10-01 01:10:29 +08:00
|
|
|
}
|
2009-10-29 01:39:19 +08:00
|
|
|
if (const ImplicitCastExpr *Exp = dyn_cast<ImplicitCastExpr>(E)) {
|
2009-09-17 05:37:16 +08:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
2009-10-29 01:39:19 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const CStyleCastExpr *Exp = dyn_cast<CStyleCastExpr>(E)) {
|
2009-09-17 05:37:16 +08:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
2009-10-29 01:39:19 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const ArraySubscriptExpr *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
|
2009-09-17 05:37:16 +08:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
|
2009-09-22 02:54:29 +08:00
|
|
|
if (LV.isObjCIvar() && !LV.isObjCArray())
|
2009-09-18 08:04:00 +08:00
|
|
|
// Using array syntax to assigning to what an ivar points to is not
|
|
|
|
// same as assigning to the ivar itself. {id *Names;} Names[i] = 0;
|
|
|
|
LV.SetObjCIvar(LV, false);
|
2009-09-22 02:54:29 +08:00
|
|
|
else if (LV.isGlobalObjCRef() && !LV.isObjCArray())
|
|
|
|
// Using array syntax to assigning to what global points to is not
|
|
|
|
// same as assigning to the global itself. {id *G;} G[i] = 0;
|
|
|
|
LV.SetGlobalObjCRef(LV, false);
|
2009-10-29 01:39:19 +08:00
|
|
|
return;
|
2009-09-18 08:04:00 +08:00
|
|
|
}
|
2009-10-29 01:39:19 +08:00
|
|
|
|
|
|
|
if (const MemberExpr *Exp = dyn_cast<MemberExpr>(E)) {
|
2009-09-17 05:37:16 +08:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
|
2009-09-18 08:04:00 +08:00
|
|
|
// We don't know if member is an 'ivar', but this flag is looked at
|
|
|
|
// only in the context of LV.isObjCIvar().
|
2009-09-22 02:54:29 +08:00
|
|
|
LV.SetObjCArray(LV, E->getType()->isArrayType());
|
2009-10-29 01:39:19 +08:00
|
|
|
return;
|
2009-09-17 05:37:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-08 07:06:58 +08:00
|
|
|
static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
|
|
|
|
const Expr *E, const VarDecl *VD) {
|
2009-11-08 17:46:46 +08:00
|
|
|
assert((VD->hasExternalStorage() || VD->isFileVarDecl()) &&
|
2009-11-08 07:06:58 +08:00
|
|
|
"Var decl must have external storage or be a file var decl!");
|
|
|
|
|
|
|
|
llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
|
|
|
|
if (VD->getType()->isReferenceType())
|
|
|
|
V = CGF.Builder.CreateLoad(V, "tmp");
|
|
|
|
LValue LV = LValue::MakeAddr(V, CGF.MakeQualifiers(E->getType()));
|
|
|
|
setObjCGCLValueClass(CGF.getContext(), E, LV);
|
|
|
|
return LV;
|
|
|
|
}
|
|
|
|
|
2009-11-26 14:08:14 +08:00
|
|
|
static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
|
|
|
|
const Expr *E, const FunctionDecl *FD) {
|
|
|
|
llvm::Value* V = CGF.CGM.GetAddrOfFunction(FD);
|
|
|
|
if (!FD->hasPrototype()) {
|
|
|
|
if (const FunctionProtoType *Proto =
|
|
|
|
FD->getType()->getAs<FunctionProtoType>()) {
|
|
|
|
// Ugly case: for a K&R-style definition, the type of the definition
|
|
|
|
// isn't the same as the type of a use. Correct for this with a
|
|
|
|
// bitcast.
|
|
|
|
QualType NoProtoType =
|
|
|
|
CGF.getContext().getFunctionNoProtoType(Proto->getResultType());
|
|
|
|
NoProtoType = CGF.getContext().getPointerType(NoProtoType);
|
|
|
|
V = CGF.Builder.CreateBitCast(V, CGF.ConvertType(NoProtoType), "tmp");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return LValue::MakeAddr(V, CGF.MakeQualifiers(E->getType()));
|
|
|
|
}
|
|
|
|
|
2007-06-02 13:24:33 +08:00
|
|
|
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
2009-11-08 06:53:10 +08:00
|
|
|
const NamedDecl *ND = E->getDecl();
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2010-03-05 02:17:24 +08:00
|
|
|
if (ND->hasAttr<WeakRefAttr>()) {
|
|
|
|
const ValueDecl* VD = cast<ValueDecl>(ND);
|
|
|
|
llvm::Constant *Aliasee = CGM.GetWeakRefReference(VD);
|
|
|
|
|
|
|
|
Qualifiers Quals = MakeQualifiers(E->getType());
|
|
|
|
LValue LV = LValue::MakeAddr(Aliasee, Quals);
|
|
|
|
|
|
|
|
return LV;
|
|
|
|
}
|
|
|
|
|
2009-11-08 06:53:10 +08:00
|
|
|
if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
|
|
|
|
|
|
|
|
// Check if this is a global variable.
|
2009-11-08 07:06:58 +08:00
|
|
|
if (VD->hasExternalStorage() || VD->isFileVarDecl())
|
|
|
|
return EmitGlobalVarDeclLValue(*this, E, VD);
|
2009-11-08 06:43:34 +08:00
|
|
|
|
2009-11-08 06:46:42 +08:00
|
|
|
bool NonGCable = VD->hasLocalStorage() && !VD->hasAttr<BlocksAttr>();
|
2009-09-25 03:53:00 +08:00
|
|
|
|
2009-11-08 06:46:42 +08:00
|
|
|
llvm::Value *V = LocalDeclMap[VD];
|
2010-04-20 02:15:02 +08:00
|
|
|
if (!V && getContext().getLangOptions().CPlusPlus &&
|
|
|
|
VD->isStaticLocal())
|
|
|
|
V = CGM.getStaticLocalDeclAddress(VD);
|
2009-11-08 06:46:42 +08:00
|
|
|
assert(V && "DeclRefExpr not entered in LocalDeclMap?");
|
2009-09-25 03:53:00 +08:00
|
|
|
|
2009-11-08 06:46:42 +08:00
|
|
|
Qualifiers Quals = MakeQualifiers(E->getType());
|
|
|
|
// local variables do not get their gc attribute set.
|
|
|
|
// local static?
|
|
|
|
if (NonGCable) Quals.removeObjCGCAttr();
|
|
|
|
|
|
|
|
if (VD->hasAttr<BlocksAttr>()) {
|
|
|
|
V = Builder.CreateStructGEP(V, 1, "forwarding");
|
2009-11-30 05:23:36 +08:00
|
|
|
V = Builder.CreateLoad(V);
|
2009-11-08 06:46:42 +08:00
|
|
|
V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD),
|
|
|
|
VD->getNameAsString());
|
2008-02-17 06:30:38 +08:00
|
|
|
}
|
2009-11-08 06:46:42 +08:00
|
|
|
if (VD->getType()->isReferenceType())
|
|
|
|
V = Builder.CreateLoad(V, "tmp");
|
2009-11-08 07:06:58 +08:00
|
|
|
LValue LV = LValue::MakeAddr(V, Quals);
|
2009-11-08 06:46:42 +08:00
|
|
|
LValue::SetObjCNonGC(LV, NonGCable);
|
2009-09-17 05:37:16 +08:00
|
|
|
setObjCGCLValueClass(getContext(), E, LV);
|
2008-11-20 08:15:42 +08:00
|
|
|
return LV;
|
2009-10-29 01:39:19 +08:00
|
|
|
}
|
|
|
|
|
2009-11-26 14:08:14 +08:00
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
|
|
|
|
return EmitFunctionDeclLValue(*this, E, FD);
|
2009-10-29 01:39:19 +08:00
|
|
|
|
2010-02-02 11:37:46 +08:00
|
|
|
// FIXME: the qualifier check does not seem sufficient here
|
2009-10-29 01:39:19 +08:00
|
|
|
if (E->getQualifier()) {
|
2010-02-02 11:37:46 +08:00
|
|
|
const FieldDecl *FD = cast<FieldDecl>(ND);
|
|
|
|
llvm::Value *V = CGM.EmitPointerToDataMember(FD);
|
|
|
|
|
|
|
|
return LValue::MakeAddr(V, MakeQualifiers(FD->getType()));
|
2008-06-18 02:05:57 +08:00
|
|
|
}
|
2009-10-29 01:39:19 +08:00
|
|
|
|
2009-11-08 06:53:10 +08:00
|
|
|
assert(false && "Unhandled DeclRefExpr");
|
|
|
|
|
|
|
|
// an invalid LValue, but the assert will
|
|
|
|
// ensure that this point is never reached.
|
2007-09-17 03:23:47 +08:00
|
|
|
return LValue();
|
2007-06-02 13:24:33 +08:00
|
|
|
}
|
2007-06-02 02:02:12 +08:00
|
|
|
|
2009-02-28 17:07:16 +08:00
|
|
|
LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
|
2009-09-25 03:53:00 +08:00
|
|
|
return LValue::MakeAddr(GetAddrOfBlockDecl(E), MakeQualifiers(E->getType()));
|
2009-02-28 17:07:16 +08:00
|
|
|
}
|
|
|
|
|
2007-06-06 04:53:16 +08:00
|
|
|
LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
|
|
|
|
// __extension__ doesn't affect lvalue-ness.
|
|
|
|
if (E->getOpcode() == UnaryOperator::Extension)
|
|
|
|
return EmitLValue(E->getSubExpr());
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2008-07-27 06:37:01 +08:00
|
|
|
QualType ExprTy = getContext().getCanonicalType(E->getSubExpr()->getType());
|
2007-10-31 06:53:42 +08:00
|
|
|
switch (E->getOpcode()) {
|
|
|
|
default: assert(0 && "Unknown unary operator lvalue!");
|
2009-10-29 01:39:19 +08:00
|
|
|
case UnaryOperator::Deref: {
|
|
|
|
QualType T = E->getSubExpr()->getType()->getPointeeType();
|
|
|
|
assert(!T.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
|
|
|
|
|
|
|
|
Qualifiers Quals = MakeQualifiers(T);
|
|
|
|
Quals.setAddressSpace(ExprTy.getAddressSpace());
|
|
|
|
|
|
|
|
LValue LV = LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()), Quals);
|
|
|
|
// We should not generate __weak write barrier on indirect reference
|
|
|
|
// of a pointer to object; as in void foo (__weak id *param); *param = 0;
|
|
|
|
// But, we continue to generate __strong write barrier on indirect write
|
|
|
|
// into a pointer to object.
|
|
|
|
if (getContext().getLangOptions().ObjC1 &&
|
|
|
|
getContext().getLangOptions().getGCMode() != LangOptions::NonGC &&
|
|
|
|
LV.isObjCWeak())
|
|
|
|
LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
|
|
|
|
return LV;
|
|
|
|
}
|
2007-10-31 06:53:42 +08:00
|
|
|
case UnaryOperator::Real:
|
2009-11-09 12:20:47 +08:00
|
|
|
case UnaryOperator::Imag: {
|
2007-10-31 06:53:42 +08:00
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2008-03-19 13:19:41 +08:00
|
|
|
unsigned Idx = E->getOpcode() == UnaryOperator::Imag;
|
|
|
|
return LValue::MakeAddr(Builder.CreateStructGEP(LV.getAddress(),
|
2008-07-27 06:17:49 +08:00
|
|
|
Idx, "idx"),
|
2009-09-25 03:53:00 +08:00
|
|
|
MakeQualifiers(ExprTy));
|
2007-10-31 06:53:42 +08:00
|
|
|
}
|
2009-11-09 12:20:47 +08:00
|
|
|
case UnaryOperator::PreInc:
|
2010-01-10 05:44:40 +08:00
|
|
|
case UnaryOperator::PreDec: {
|
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
|
|
|
bool isInc = E->getOpcode() == UnaryOperator::PreInc;
|
|
|
|
|
|
|
|
if (E->getType()->isAnyComplexType())
|
|
|
|
EmitComplexPrePostIncDec(E, LV, isInc, true/*isPre*/);
|
|
|
|
else
|
|
|
|
EmitScalarPrePostIncDec(E, LV, isInc, true/*isPre*/);
|
|
|
|
return LV;
|
|
|
|
}
|
2009-11-09 12:20:47 +08:00
|
|
|
}
|
2007-06-06 04:53:16 +08:00
|
|
|
}
|
|
|
|
|
2007-06-06 12:54:52 +08:00
|
|
|
LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
|
2009-09-25 03:53:00 +08:00
|
|
|
return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromLiteral(E),
|
|
|
|
Qualifiers());
|
2007-06-06 12:54:52 +08:00
|
|
|
}
|
|
|
|
|
2009-02-25 06:18:39 +08:00
|
|
|
LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {
|
2009-09-25 03:53:00 +08:00
|
|
|
return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromObjCEncode(E),
|
|
|
|
Qualifiers());
|
2009-02-25 06:18:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-18 05:58:32 +08:00
|
|
|
LValue CodeGenFunction::EmitPredefinedFunctionName(unsigned Type) {
|
2007-07-21 13:21:51 +08:00
|
|
|
std::string GlobalVarName;
|
2008-10-18 05:58:32 +08:00
|
|
|
|
|
|
|
switch (Type) {
|
2009-10-29 01:39:19 +08:00
|
|
|
default: assert(0 && "Invalid type");
|
2009-02-25 06:18:39 +08:00
|
|
|
case PredefinedExpr::Func:
|
|
|
|
GlobalVarName = "__func__.";
|
|
|
|
break;
|
|
|
|
case PredefinedExpr::Function:
|
|
|
|
GlobalVarName = "__FUNCTION__.";
|
|
|
|
break;
|
|
|
|
case PredefinedExpr::PrettyFunction:
|
|
|
|
GlobalVarName = "__PRETTY_FUNCTION__.";
|
|
|
|
break;
|
2007-07-21 13:21:51 +08:00
|
|
|
}
|
2008-10-18 05:58:32 +08:00
|
|
|
|
2009-09-13 07:06:21 +08:00
|
|
|
llvm::StringRef FnName = CurFn->getName();
|
|
|
|
if (FnName.startswith("\01"))
|
|
|
|
FnName = FnName.substr(1);
|
|
|
|
GlobalVarName += FnName;
|
|
|
|
|
2009-09-09 02:24:21 +08:00
|
|
|
std::string FunctionName =
|
2010-02-12 02:20:28 +08:00
|
|
|
PredefinedExpr::ComputeName((PredefinedExpr::IdentType)Type, CurCodeDecl);
|
2008-10-18 05:58:32 +08:00
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
llvm::Constant *C =
|
2008-10-18 05:58:32 +08:00
|
|
|
CGM.GetAddrOfConstantCString(FunctionName, GlobalVarName.c_str());
|
2009-09-25 03:53:00 +08:00
|
|
|
return LValue::MakeAddr(C, Qualifiers());
|
2008-10-18 05:58:32 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
|
2008-10-18 05:58:32 +08:00
|
|
|
switch (E->getIdentType()) {
|
|
|
|
default:
|
|
|
|
return EmitUnsupportedLValue(E, "predefined expression");
|
|
|
|
case PredefinedExpr::Func:
|
|
|
|
case PredefinedExpr::Function:
|
|
|
|
case PredefinedExpr::PrettyFunction:
|
|
|
|
return EmitPredefinedFunctionName(E->getIdentType());
|
|
|
|
}
|
2007-07-21 13:21:51 +08:00
|
|
|
}
|
|
|
|
|
2009-12-15 09:22:35 +08:00
|
|
|
llvm::BasicBlock *CodeGenFunction::getTrapBB() {
|
2009-12-15 08:59:40 +08:00
|
|
|
const CodeGenOptions &GCO = CGM.getCodeGenOpts();
|
|
|
|
|
|
|
|
// If we are not optimzing, don't collapse all calls to trap in the function
|
|
|
|
// to the same call, that way, in the debugger they can see which operation
|
|
|
|
// did in fact fail. If we are optimizing, we collpase all call to trap down
|
|
|
|
// to just one per function to save on codesize.
|
|
|
|
if (GCO.OptimizationLevel
|
|
|
|
&& TrapBB)
|
2009-12-15 08:35:12 +08:00
|
|
|
return TrapBB;
|
2009-12-12 09:27:46 +08:00
|
|
|
|
|
|
|
llvm::BasicBlock *Cont = 0;
|
|
|
|
if (HaveInsertPoint()) {
|
|
|
|
Cont = createBasicBlock("cont");
|
|
|
|
EmitBranch(Cont);
|
|
|
|
}
|
2009-12-15 08:35:12 +08:00
|
|
|
TrapBB = createBasicBlock("trap");
|
|
|
|
EmitBlock(TrapBB);
|
|
|
|
|
|
|
|
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap, 0, 0);
|
|
|
|
llvm::CallInst *TrapCall = Builder.CreateCall(F);
|
|
|
|
TrapCall->setDoesNotReturn();
|
|
|
|
TrapCall->setDoesNotThrow();
|
2009-12-12 09:27:46 +08:00
|
|
|
Builder.CreateUnreachable();
|
|
|
|
|
|
|
|
if (Cont)
|
|
|
|
EmitBlock(Cont);
|
2009-12-15 08:35:12 +08:00
|
|
|
return TrapBB;
|
2009-12-12 09:27:46 +08:00
|
|
|
}
|
|
|
|
|
2010-06-27 07:03:20 +08:00
|
|
|
/// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an
|
|
|
|
/// array to pointer, return the array subexpression.
|
|
|
|
static const Expr *isSimpleArrayDecayOperand(const Expr *E) {
|
|
|
|
// If this isn't just an array->pointer decay, bail out.
|
|
|
|
const CastExpr *CE = dyn_cast<CastExpr>(E);
|
|
|
|
if (CE == 0 || CE->getCastKind() != CastExpr::CK_ArrayToPointerDecay)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// If this is a decay from variable width array, bail out.
|
|
|
|
const Expr *SubExpr = CE->getSubExpr();
|
|
|
|
if (SubExpr->getType()->isVariableArrayType())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return SubExpr;
|
|
|
|
}
|
|
|
|
|
2007-06-09 07:31:14 +08:00
|
|
|
LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
|
2007-08-21 00:18:38 +08:00
|
|
|
// The index must always be an integer, which is not an aggregate. Emit it.
|
2007-08-24 13:35:26 +08:00
|
|
|
llvm::Value *Idx = EmitScalarExpr(E->getIdx());
|
2009-06-07 03:09:26 +08:00
|
|
|
QualType IdxTy = E->getIdx()->getType();
|
|
|
|
bool IdxSigned = IdxTy->isSignedIntegerType();
|
|
|
|
|
2007-07-11 05:17:59 +08:00
|
|
|
// If the base is a vector type, then we are forming a vector element lvalue
|
|
|
|
// with this subscript.
|
2008-06-14 07:01:12 +08:00
|
|
|
if (E->getBase()->getType()->isVectorType()) {
|
2007-07-11 05:17:59 +08:00
|
|
|
// Emit the vector as an lvalue to get its address.
|
2008-06-14 07:01:12 +08:00
|
|
|
LValue LHS = EmitLValue(E->getBase());
|
2007-08-21 00:18:38 +08:00
|
|
|
assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
|
2010-06-27 15:15:29 +08:00
|
|
|
Idx = Builder.CreateIntCast(Idx, CGF.Int32Ty, IdxSigned, "vidx");
|
2008-06-14 07:01:12 +08:00
|
|
|
return LValue::MakeVectorElt(LHS.getAddress(), Idx,
|
2009-09-25 03:53:00 +08:00
|
|
|
E->getBase()->getType().getCVRQualifiers());
|
2007-07-11 05:17:59 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-21 00:18:38 +08:00
|
|
|
// Extend or truncate the index type to 32 or 64-bits.
|
2010-06-27 06:40:46 +08:00
|
|
|
if (!Idx->getType()->isIntegerTy(LLVMPointerWidth))
|
2010-06-27 15:15:29 +08:00
|
|
|
Idx = Builder.CreateIntCast(Idx, IntPtrTy,
|
2007-06-09 07:31:14 +08:00
|
|
|
IdxSigned, "idxprom");
|
2010-06-27 06:40:46 +08:00
|
|
|
|
2009-12-16 10:57:00 +08:00
|
|
|
// FIXME: As llvm implements the object size checking, this can come out.
|
2009-12-12 09:27:46 +08:00
|
|
|
if (CatchUndefined) {
|
2010-06-27 06:40:46 +08:00
|
|
|
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E->getBase())){
|
2009-12-12 09:27:46 +08:00
|
|
|
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
|
|
|
|
if (ICE->getCastKind() == CastExpr::CK_ArrayToPointerDecay) {
|
|
|
|
if (const ConstantArrayType *CAT
|
|
|
|
= getContext().getAsConstantArrayType(DRE->getType())) {
|
|
|
|
llvm::APInt Size = CAT->getSize();
|
|
|
|
llvm::BasicBlock *Cont = createBasicBlock("cont");
|
2009-12-15 06:14:31 +08:00
|
|
|
Builder.CreateCondBr(Builder.CreateICmpULE(Idx,
|
2009-12-12 09:27:46 +08:00
|
|
|
llvm::ConstantInt::get(Idx->getType(), Size)),
|
2009-12-15 08:35:12 +08:00
|
|
|
Cont, getTrapBB());
|
2009-12-15 04:52:00 +08:00
|
|
|
EmitBlock(Cont);
|
2009-12-12 09:27:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
// We know that the pointer points to a type of the correct size, unless the
|
|
|
|
// size is a VLA or Objective-C interface.
|
2009-04-25 13:08:32 +08:00
|
|
|
llvm::Value *Address = 0;
|
2009-09-09 21:00:44 +08:00
|
|
|
if (const VariableArrayType *VAT =
|
2008-12-21 08:11:23 +08:00
|
|
|
getContext().getAsVariableArrayType(E->getType())) {
|
2009-08-15 07:43:22 +08:00
|
|
|
llvm::Value *VLASize = GetVLASize(VAT);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2008-12-21 08:11:23 +08:00
|
|
|
Idx = Builder.CreateMul(Idx, VLASize);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2008-12-21 11:44:36 +08:00
|
|
|
QualType BaseType = getContext().getBaseElementType(VAT);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2010-01-12 01:06:35 +08:00
|
|
|
CharUnits BaseTypeSize = getContext().getTypeSizeInChars(BaseType);
|
2008-12-21 08:11:23 +08:00
|
|
|
Idx = Builder.CreateUDiv(Idx,
|
2009-09-09 21:00:44 +08:00
|
|
|
llvm::ConstantInt::get(Idx->getType(),
|
2010-01-12 01:06:35 +08:00
|
|
|
BaseTypeSize.getQuantity()));
|
2010-06-27 07:03:20 +08:00
|
|
|
|
|
|
|
// The base must be a pointer, which is not an aggregate. Emit it.
|
|
|
|
llvm::Value *Base = EmitScalarExpr(E->getBase());
|
|
|
|
|
2009-08-12 08:33:55 +08:00
|
|
|
Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
|
2010-06-27 07:03:20 +08:00
|
|
|
} else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
|
|
|
|
// Indexing over an interface, as in "NSString *P; P[4];"
|
2009-09-09 21:00:44 +08:00
|
|
|
llvm::Value *InterfaceSize =
|
2009-07-25 07:12:58 +08:00
|
|
|
llvm::ConstantInt::get(Idx->getType(),
|
2010-01-12 01:06:35 +08:00
|
|
|
getContext().getTypeSizeInChars(OIT).getQuantity());
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-04-25 13:08:32 +08:00
|
|
|
Idx = Builder.CreateMul(Idx, InterfaceSize);
|
|
|
|
|
2009-10-13 18:07:13 +08:00
|
|
|
const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
|
2010-06-27 07:03:20 +08:00
|
|
|
|
|
|
|
// The base must be a pointer, which is not an aggregate. Emit it.
|
|
|
|
llvm::Value *Base = EmitScalarExpr(E->getBase());
|
2009-08-12 08:33:55 +08:00
|
|
|
Address = Builder.CreateGEP(Builder.CreateBitCast(Base, i8PTy),
|
2009-04-25 13:08:32 +08:00
|
|
|
Idx, "arrayidx");
|
|
|
|
Address = Builder.CreateBitCast(Address, Base->getType());
|
2010-06-27 07:03:20 +08:00
|
|
|
} else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
|
|
|
|
// If this is A[i] where A is an array, the frontend will have decayed the
|
|
|
|
// base to be a ArrayToPointerDecay implicit cast. While correct, it is
|
|
|
|
// inefficient at -O0 to emit a "gep A, 0, 0" when codegen'ing it, then a
|
|
|
|
// "gep x, i" here. Emit one "gep A, 0, i".
|
|
|
|
assert(Array->getType()->isArrayType() &&
|
|
|
|
"Array to pointer decay must have array source type!");
|
|
|
|
llvm::Value *ArrayPtr = EmitLValue(Array).getAddress();
|
|
|
|
llvm::Value *Zero = llvm::ConstantInt::get(Int32Ty, 0);
|
|
|
|
llvm::Value *Args[] = { Zero, Idx };
|
|
|
|
|
|
|
|
Address = Builder.CreateInBoundsGEP(ArrayPtr, Args, Args+2, "arrayidx");
|
2009-04-25 13:08:32 +08:00
|
|
|
} else {
|
2010-06-27 07:03:20 +08:00
|
|
|
// The base must be a pointer, which is not an aggregate. Emit it.
|
|
|
|
llvm::Value *Base = EmitScalarExpr(E->getBase());
|
2009-08-12 08:33:55 +08:00
|
|
|
Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
|
2008-12-21 08:11:23 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-07-11 07:34:53 +08:00
|
|
|
QualType T = E->getBase()->getType()->getPointeeType();
|
2009-09-09 21:00:44 +08:00
|
|
|
assert(!T.isNull() &&
|
2009-07-11 07:34:53 +08:00
|
|
|
"CodeGenFunction::EmitArraySubscriptExpr(): Illegal base type");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-09-25 03:53:00 +08:00
|
|
|
Qualifiers Quals = MakeQualifiers(T);
|
|
|
|
Quals.setAddressSpace(E->getBase()->getType().getAddressSpace());
|
|
|
|
|
|
|
|
LValue LV = LValue::MakeAddr(Address, Quals);
|
2009-02-22 07:37:19 +08:00
|
|
|
if (getContext().getLangOptions().ObjC1 &&
|
2009-09-17 05:37:16 +08:00
|
|
|
getContext().getLangOptions().getGCMode() != LangOptions::NonGC) {
|
2009-06-02 05:29:32 +08:00
|
|
|
LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
|
2009-09-17 05:37:16 +08:00
|
|
|
setObjCGCLValueClass(getContext(), E, LV);
|
|
|
|
}
|
2009-02-22 07:37:19 +08:00
|
|
|
return LV;
|
2007-06-09 07:31:14 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
static
|
2009-07-15 07:10:40 +08:00
|
|
|
llvm::Constant *GenerateConstantVector(llvm::LLVMContext &VMContext,
|
|
|
|
llvm::SmallVector<unsigned, 4> &Elts) {
|
2009-12-24 05:31:11 +08:00
|
|
|
llvm::SmallVector<llvm::Constant*, 4> CElts;
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2010-06-27 15:15:29 +08:00
|
|
|
const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
|
2008-05-14 05:03:02 +08:00
|
|
|
for (unsigned i = 0, e = Elts.size(); i != e; ++i)
|
2010-06-27 15:15:29 +08:00
|
|
|
CElts.push_back(llvm::ConstantInt::get(Int32Ty, Elts[i]));
|
2008-05-14 05:03:02 +08:00
|
|
|
|
2009-07-29 05:22:35 +08:00
|
|
|
return llvm::ConstantVector::get(&CElts[0], CElts.size());
|
2008-05-14 05:03:02 +08:00
|
|
|
}
|
|
|
|
|
2007-08-03 07:37:31 +08:00
|
|
|
LValue CodeGenFunction::
|
2008-04-19 07:10:10 +08:00
|
|
|
EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
|
2007-08-03 07:37:31 +08:00
|
|
|
// Emit the base vector as an l-value.
|
2009-02-17 05:11:58 +08:00
|
|
|
LValue Base;
|
|
|
|
|
|
|
|
// ExtVectorElementExpr's base can either be a vector or pointer to vector.
|
2009-12-24 05:31:11 +08:00
|
|
|
if (E->isArrow()) {
|
|
|
|
// If it is a pointer to a vector, emit the address and form an lvalue with
|
|
|
|
// it.
|
2009-02-17 06:14:05 +08:00
|
|
|
llvm::Value *Ptr = EmitScalarExpr(E->getBase());
|
2009-12-24 05:31:11 +08:00
|
|
|
const PointerType *PT = E->getBase()->getType()->getAs<PointerType>();
|
2009-09-25 03:53:00 +08:00
|
|
|
Qualifiers Quals = MakeQualifiers(PT->getPointeeType());
|
|
|
|
Quals.removeObjCGCAttr();
|
|
|
|
Base = LValue::MakeAddr(Ptr, Quals);
|
2009-12-24 05:31:11 +08:00
|
|
|
} else if (E->getBase()->isLvalue(getContext()) == Expr::LV_Valid) {
|
|
|
|
// Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
|
|
|
|
// emit the base as an lvalue.
|
|
|
|
assert(E->getBase()->getType()->isVectorType());
|
|
|
|
Base = EmitLValue(E->getBase());
|
|
|
|
} else {
|
|
|
|
// Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such.
|
2010-01-05 02:02:28 +08:00
|
|
|
assert(E->getBase()->getType()->getAs<VectorType>() &&
|
|
|
|
"Result must be a vector");
|
2009-12-24 05:31:11 +08:00
|
|
|
llvm::Value *Vec = EmitScalarExpr(E->getBase());
|
|
|
|
|
2009-12-24 05:33:41 +08:00
|
|
|
// Store the vector to memory (because LValue wants an address).
|
2010-02-09 10:48:28 +08:00
|
|
|
llvm::Value *VecMem = CreateMemTemp(E->getBase()->getType());
|
2009-12-24 05:31:11 +08:00
|
|
|
Builder.CreateStore(Vec, VecMem);
|
2009-12-24 05:33:41 +08:00
|
|
|
Base = LValue::MakeAddr(VecMem, Qualifiers());
|
2009-02-17 05:11:58 +08:00
|
|
|
}
|
2009-12-24 05:31:11 +08:00
|
|
|
|
2008-05-14 05:03:02 +08:00
|
|
|
// Encode the element access list into a vector of unsigned indices.
|
|
|
|
llvm::SmallVector<unsigned, 4> Indices;
|
|
|
|
E->getEncodedElementAccess(Indices);
|
|
|
|
|
|
|
|
if (Base.isSimple()) {
|
2009-07-15 07:10:40 +08:00
|
|
|
llvm::Constant *CV = GenerateConstantVector(VMContext, Indices);
|
2008-06-14 07:01:12 +08:00
|
|
|
return LValue::MakeExtVectorElt(Base.getAddress(), CV,
|
2009-09-25 03:53:00 +08:00
|
|
|
Base.getVRQualifiers());
|
2008-05-09 14:41:27 +08:00
|
|
|
}
|
2008-05-14 05:03:02 +08:00
|
|
|
assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
|
|
|
|
|
|
|
|
llvm::Constant *BaseElts = Base.getExtVectorElts();
|
|
|
|
llvm::SmallVector<llvm::Constant *, 4> CElts;
|
2007-08-03 07:37:31 +08:00
|
|
|
|
2008-05-14 05:03:02 +08:00
|
|
|
for (unsigned i = 0, e = Indices.size(); i != e; ++i) {
|
|
|
|
if (isa<llvm::ConstantAggregateZero>(BaseElts))
|
2009-10-28 13:12:07 +08:00
|
|
|
CElts.push_back(llvm::ConstantInt::get(Int32Ty, 0));
|
2008-05-14 05:03:02 +08:00
|
|
|
else
|
2009-10-28 13:12:07 +08:00
|
|
|
CElts.push_back(cast<llvm::Constant>(BaseElts->getOperand(Indices[i])));
|
2008-05-14 05:03:02 +08:00
|
|
|
}
|
2009-07-29 05:22:35 +08:00
|
|
|
llvm::Constant *CV = llvm::ConstantVector::get(&CElts[0], CElts.size());
|
2008-06-14 07:01:12 +08:00
|
|
|
return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV,
|
2009-09-25 03:53:00 +08:00
|
|
|
Base.getVRQualifiers());
|
2007-08-03 07:37:31 +08:00
|
|
|
}
|
|
|
|
|
2007-10-24 04:28:39 +08:00
|
|
|
LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
|
2009-02-21 08:30:43 +08:00
|
|
|
bool isNonGC = false;
|
2007-10-25 06:26:28 +08:00
|
|
|
Expr *BaseExpr = E->getBase();
|
|
|
|
llvm::Value *BaseValue = NULL;
|
2009-09-25 03:53:00 +08:00
|
|
|
Qualifiers BaseQuals;
|
2008-06-14 07:01:12 +08:00
|
|
|
|
2007-12-03 02:52:07 +08:00
|
|
|
// If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
|
2007-12-12 05:33:16 +08:00
|
|
|
if (E->isArrow()) {
|
2007-12-03 02:52:07 +08:00
|
|
|
BaseValue = EmitScalarExpr(BaseExpr);
|
2009-09-09 21:00:44 +08:00
|
|
|
const PointerType *PTy =
|
2009-07-30 05:53:49 +08:00
|
|
|
BaseExpr->getType()->getAs<PointerType>();
|
2009-09-25 03:53:00 +08:00
|
|
|
BaseQuals = PTy->getPointeeType().getQualifiers();
|
2009-09-02 01:02:21 +08:00
|
|
|
} else if (isa<ObjCPropertyRefExpr>(BaseExpr->IgnoreParens()) ||
|
|
|
|
isa<ObjCImplicitSetterGetterRefExpr>(
|
|
|
|
BaseExpr->IgnoreParens())) {
|
2009-01-13 07:27:26 +08:00
|
|
|
RValue RV = EmitObjCPropertyGet(BaseExpr);
|
|
|
|
BaseValue = RV.getAggregateAddr();
|
2009-09-25 03:53:00 +08:00
|
|
|
BaseQuals = BaseExpr->getType().getQualifiers();
|
2009-02-17 06:25:49 +08:00
|
|
|
} else {
|
2007-10-25 06:26:28 +08:00
|
|
|
LValue BaseLV = EmitLValue(BaseExpr);
|
2009-02-21 08:30:43 +08:00
|
|
|
if (BaseLV.isNonGC())
|
|
|
|
isNonGC = true;
|
2007-12-03 02:52:07 +08:00
|
|
|
// FIXME: this isn't right for bitfields.
|
2007-10-25 06:26:28 +08:00
|
|
|
BaseValue = BaseLV.getAddress();
|
2009-07-29 08:44:13 +08:00
|
|
|
QualType BaseTy = BaseExpr->getType();
|
2009-09-25 03:53:00 +08:00
|
|
|
BaseQuals = BaseTy.getQualifiers();
|
2007-12-03 02:52:07 +08:00
|
|
|
}
|
2007-10-24 04:28:39 +08:00
|
|
|
|
2009-11-08 07:06:58 +08:00
|
|
|
NamedDecl *ND = E->getMemberDecl();
|
|
|
|
if (FieldDecl *Field = dyn_cast<FieldDecl>(ND)) {
|
2010-01-29 13:05:36 +08:00
|
|
|
LValue LV = EmitLValueForField(BaseValue, Field,
|
2009-11-08 07:06:58 +08:00
|
|
|
BaseQuals.getCVRQualifiers());
|
|
|
|
LValue::SetObjCNonGC(LV, isNonGC);
|
|
|
|
setObjCGCLValueClass(getContext(), E, LV);
|
|
|
|
return LV;
|
|
|
|
}
|
|
|
|
|
2009-11-08 07:16:50 +08:00
|
|
|
if (VarDecl *VD = dyn_cast<VarDecl>(ND))
|
|
|
|
return EmitGlobalVarDeclLValue(*this, E, VD);
|
2009-11-26 14:08:14 +08:00
|
|
|
|
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
|
|
|
|
return EmitFunctionDeclLValue(*this, E, FD);
|
|
|
|
|
2009-11-08 07:06:58 +08:00
|
|
|
assert(false && "Unhandled member declaration!");
|
|
|
|
return LValue();
|
2008-02-09 16:50:58 +08:00
|
|
|
}
|
2007-10-24 04:28:39 +08:00
|
|
|
|
2008-12-16 04:35:07 +08:00
|
|
|
LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
|
2009-11-17 11:57:07 +08:00
|
|
|
const FieldDecl* Field,
|
2009-02-04 03:03:09 +08:00
|
|
|
unsigned CVRQualifiers) {
|
2010-03-31 09:09:11 +08:00
|
|
|
const CGRecordLayout &RL =
|
|
|
|
CGM.getTypes().getCGRecordLayout(Field->getParent());
|
2010-04-06 00:20:44 +08:00
|
|
|
const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
|
2010-04-08 10:59:45 +08:00
|
|
|
return LValue::MakeBitfield(BaseValue, Info,
|
2010-04-06 05:36:35 +08:00
|
|
|
Field->getType().getCVRQualifiers()|CVRQualifiers);
|
2008-12-16 04:35:07 +08:00
|
|
|
}
|
|
|
|
|
2010-05-21 09:18:57 +08:00
|
|
|
/// EmitLValueForAnonRecordField - Given that the field is a member of
|
|
|
|
/// an anonymous struct or union buried inside a record, and given
|
|
|
|
/// that the base value is a pointer to the enclosing record, derive
|
|
|
|
/// an lvalue for the ultimate field.
|
|
|
|
LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue,
|
|
|
|
const FieldDecl *Field,
|
|
|
|
unsigned CVRQualifiers) {
|
|
|
|
llvm::SmallVector<const FieldDecl *, 8> Path;
|
|
|
|
Path.push_back(Field);
|
|
|
|
|
|
|
|
while (Field->getParent()->isAnonymousStructOrUnion()) {
|
|
|
|
const ValueDecl *VD = Field->getParent()->getAnonymousStructOrUnionObject();
|
|
|
|
if (!isa<FieldDecl>(VD)) break;
|
|
|
|
Field = cast<FieldDecl>(VD);
|
|
|
|
Path.push_back(Field);
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::SmallVectorImpl<const FieldDecl*>::reverse_iterator
|
|
|
|
I = Path.rbegin(), E = Path.rend();
|
|
|
|
while (true) {
|
|
|
|
LValue LV = EmitLValueForField(BaseValue, *I, CVRQualifiers);
|
|
|
|
if (++I == E) return LV;
|
|
|
|
|
|
|
|
assert(LV.isSimple());
|
|
|
|
BaseValue = LV.getAddress();
|
|
|
|
CVRQualifiers |= LV.getVRQualifiers();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-09 16:50:58 +08:00
|
|
|
LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
|
2009-11-17 11:57:07 +08:00
|
|
|
const FieldDecl* Field,
|
2009-09-09 23:08:12 +08:00
|
|
|
unsigned CVRQualifiers) {
|
2008-12-16 04:35:07 +08:00
|
|
|
if (Field->isBitField())
|
2009-02-04 03:03:09 +08:00
|
|
|
return EmitLValueForBitfield(BaseValue, Field, CVRQualifiers);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2010-03-31 09:09:11 +08:00
|
|
|
const CGRecordLayout &RL =
|
|
|
|
CGM.getTypes().getCGRecordLayout(Field->getParent());
|
|
|
|
unsigned idx = RL.getLLVMFieldNo(Field);
|
2008-12-16 04:35:07 +08:00
|
|
|
llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
|
2008-05-29 19:33:25 +08:00
|
|
|
|
2007-10-27 03:42:18 +08:00
|
|
|
// Match union field type.
|
2010-01-29 13:05:36 +08:00
|
|
|
if (Field->getParent()->isUnion()) {
|
2009-09-09 21:00:44 +08:00
|
|
|
const llvm::Type *FieldTy =
|
2008-06-14 07:01:12 +08:00
|
|
|
CGM.getTypes().ConvertTypeForMem(Field->getType());
|
2009-09-09 21:00:44 +08:00
|
|
|
const llvm::PointerType * BaseTy =
|
2007-10-31 04:59:40 +08:00
|
|
|
cast<llvm::PointerType>(BaseValue->getType());
|
2008-05-21 21:24:44 +08:00
|
|
|
unsigned AS = BaseTy->getAddressSpace();
|
2009-09-09 21:00:44 +08:00
|
|
|
V = Builder.CreateBitCast(V,
|
|
|
|
llvm::PointerType::get(FieldTy, AS),
|
2008-05-21 21:24:44 +08:00
|
|
|
"tmp");
|
2007-10-27 03:42:18 +08:00
|
|
|
}
|
2009-05-31 05:09:44 +08:00
|
|
|
if (Field->getType()->isReferenceType())
|
|
|
|
V = Builder.CreateLoad(V, "tmp");
|
2009-09-25 03:53:00 +08:00
|
|
|
|
|
|
|
Qualifiers Quals = MakeQualifiers(Field->getType());
|
|
|
|
Quals.addCVRQualifiers(CVRQualifiers);
|
2009-09-22 02:54:29 +08:00
|
|
|
// __weak attribute on a field is ignored.
|
2009-09-25 03:53:00 +08:00
|
|
|
if (Quals.getObjCGCAttr() == Qualifiers::Weak)
|
|
|
|
Quals.removeObjCGCAttr();
|
2009-09-22 02:54:29 +08:00
|
|
|
|
2009-09-25 03:53:00 +08:00
|
|
|
return LValue::MakeAddr(V, Quals);
|
2007-10-24 04:28:39 +08:00
|
|
|
}
|
|
|
|
|
2010-01-29 13:24:29 +08:00
|
|
|
LValue
|
|
|
|
CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value* BaseValue,
|
|
|
|
const FieldDecl* Field,
|
|
|
|
unsigned CVRQualifiers) {
|
|
|
|
QualType FieldType = Field->getType();
|
|
|
|
|
|
|
|
if (!FieldType->isReferenceType())
|
|
|
|
return EmitLValueForField(BaseValue, Field, CVRQualifiers);
|
|
|
|
|
2010-03-31 09:09:11 +08:00
|
|
|
const CGRecordLayout &RL =
|
|
|
|
CGM.getTypes().getCGRecordLayout(Field->getParent());
|
|
|
|
unsigned idx = RL.getLLVMFieldNo(Field);
|
2010-01-29 13:24:29 +08:00
|
|
|
llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
|
|
|
|
|
|
|
|
assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs");
|
|
|
|
|
|
|
|
return LValue::MakeAddr(V, MakeQualifiers(FieldType));
|
|
|
|
}
|
|
|
|
|
2009-03-19 02:28:57 +08:00
|
|
|
LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E){
|
2010-02-17 03:43:39 +08:00
|
|
|
llvm::Value *DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral");
|
2008-05-14 07:18:27 +08:00
|
|
|
const Expr* InitExpr = E->getInitializer();
|
2009-09-25 03:53:00 +08:00
|
|
|
LValue Result = LValue::MakeAddr(DeclPtr, MakeQualifiers(E->getType()));
|
2008-05-14 07:18:27 +08:00
|
|
|
|
2010-04-21 18:05:39 +08:00
|
|
|
EmitAnyExprToMem(InitExpr, DeclPtr, /*Volatile*/ false);
|
2008-05-14 07:18:27 +08:00
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2009-09-16 00:35:24 +08:00
|
|
|
LValue
|
|
|
|
CodeGenFunction::EmitConditionalOperatorLValue(const ConditionalOperator* E) {
|
|
|
|
if (E->isLvalue(getContext()) == Expr::LV_Valid) {
|
2009-12-25 13:29:40 +08:00
|
|
|
if (int Cond = ConstantFoldsToSimpleInteger(E->getCond())) {
|
|
|
|
Expr *Live = Cond == 1 ? E->getLHS() : E->getRHS();
|
|
|
|
if (Live)
|
|
|
|
return EmitLValue(Live);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!E->getLHS())
|
|
|
|
return EmitUnsupportedLValue(E, "conditional operator with missing LHS");
|
|
|
|
|
2009-09-16 00:35:24 +08:00
|
|
|
llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
|
|
|
|
llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
|
|
|
|
llvm::BasicBlock *ContBlock = createBasicBlock("cond.end");
|
|
|
|
|
2009-12-25 14:17:05 +08:00
|
|
|
EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
|
2009-09-16 00:35:24 +08:00
|
|
|
|
2010-02-05 01:26:01 +08:00
|
|
|
// Any temporaries created here are conditional.
|
|
|
|
BeginConditionalBranch();
|
2009-09-16 00:35:24 +08:00
|
|
|
EmitBlock(LHSBlock);
|
|
|
|
LValue LHS = EmitLValue(E->getLHS());
|
2010-02-05 01:26:01 +08:00
|
|
|
EndConditionalBranch();
|
|
|
|
|
2009-09-16 00:35:24 +08:00
|
|
|
if (!LHS.isSimple())
|
|
|
|
return EmitUnsupportedLValue(E, "conditional operator");
|
|
|
|
|
2010-02-09 10:48:28 +08:00
|
|
|
// FIXME: We shouldn't need an alloca for this.
|
2009-10-29 01:39:19 +08:00
|
|
|
llvm::Value *Temp = CreateTempAlloca(LHS.getAddress()->getType(),"condtmp");
|
2009-09-16 00:35:24 +08:00
|
|
|
Builder.CreateStore(LHS.getAddress(), Temp);
|
|
|
|
EmitBranch(ContBlock);
|
|
|
|
|
2010-02-05 01:26:01 +08:00
|
|
|
// Any temporaries created here are conditional.
|
|
|
|
BeginConditionalBranch();
|
2009-09-16 00:35:24 +08:00
|
|
|
EmitBlock(RHSBlock);
|
|
|
|
LValue RHS = EmitLValue(E->getRHS());
|
2010-02-05 01:26:01 +08:00
|
|
|
EndConditionalBranch();
|
2009-09-16 00:35:24 +08:00
|
|
|
if (!RHS.isSimple())
|
|
|
|
return EmitUnsupportedLValue(E, "conditional operator");
|
|
|
|
|
|
|
|
Builder.CreateStore(RHS.getAddress(), Temp);
|
|
|
|
EmitBranch(ContBlock);
|
|
|
|
|
|
|
|
EmitBlock(ContBlock);
|
|
|
|
|
|
|
|
Temp = Builder.CreateLoad(Temp, "lv");
|
2009-09-25 03:53:00 +08:00
|
|
|
return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
|
2009-09-16 00:35:24 +08:00
|
|
|
}
|
|
|
|
|
2009-03-24 10:38:23 +08:00
|
|
|
// ?: here should be an aggregate.
|
2009-09-09 21:00:44 +08:00
|
|
|
assert((hasAggregateLLVMType(E->getType()) &&
|
2009-03-24 10:38:23 +08:00
|
|
|
!E->getType()->isAnyComplexType()) &&
|
|
|
|
"Unexpected conditional operator!");
|
|
|
|
|
2010-02-06 03:38:31 +08:00
|
|
|
return EmitAggExprToLValue(E);
|
2009-03-24 10:38:23 +08:00
|
|
|
}
|
|
|
|
|
2009-11-16 14:50:58 +08:00
|
|
|
/// EmitCastLValue - Casts are never lvalues unless that cast is a dynamic_cast.
|
|
|
|
/// If the cast is a dynamic_cast, we can have the usual lvalue result,
|
|
|
|
/// otherwise if a cast is needed by the code generator in an lvalue context,
|
|
|
|
/// then it must mean that we need the address of an aggregate in order to
|
|
|
|
/// access one of its fields. This can happen for all the reasons that casts
|
|
|
|
/// are permitted with aggregate result, including noop aggregate casts, and
|
|
|
|
/// cast from scalar to union.
|
2009-03-19 02:28:57 +08:00
|
|
|
LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
|
2009-09-13 00:16:49 +08:00
|
|
|
switch (E->getCastKind()) {
|
|
|
|
default:
|
2009-11-16 13:48:01 +08:00
|
|
|
return EmitUnsupportedLValue(E, "unexpected cast lvalue");
|
|
|
|
|
2009-11-16 14:50:58 +08:00
|
|
|
case CastExpr::CK_Dynamic: {
|
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
|
|
|
llvm::Value *V = LV.getAddress();
|
|
|
|
const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(E);
|
|
|
|
return LValue::MakeAddr(EmitDynamicCast(V, DCE),
|
|
|
|
MakeQualifiers(E->getType()));
|
|
|
|
}
|
|
|
|
|
2010-05-11 06:57:35 +08:00
|
|
|
case CastExpr::CK_NoOp: {
|
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
|
|
|
if (LV.isPropertyRef()) {
|
2010-05-12 00:31:10 +08:00
|
|
|
QualType QT = E->getSubExpr()->getType();
|
|
|
|
RValue RV = EmitLoadOfPropertyRefLValue(LV, QT);
|
|
|
|
assert(!RV.isScalar() && "EmitCastLValue - scalar cast of property ref");
|
|
|
|
llvm::Value *V = RV.getAggregateAddr();
|
|
|
|
return LValue::MakeAddr(V, MakeQualifiers(QT));
|
2010-05-11 06:57:35 +08:00
|
|
|
}
|
|
|
|
return LV;
|
|
|
|
}
|
2009-09-13 00:16:49 +08:00
|
|
|
case CastExpr::CK_ConstructorConversion:
|
|
|
|
case CastExpr::CK_UserDefinedConversion:
|
2009-12-16 05:34:52 +08:00
|
|
|
case CastExpr::CK_AnyPointerToObjCPointerCast:
|
2009-03-19 02:28:57 +08:00
|
|
|
return EmitLValue(E->getSubExpr());
|
2009-09-13 00:16:49 +08:00
|
|
|
|
2010-03-31 07:58:03 +08:00
|
|
|
case CastExpr::CK_UncheckedDerivedToBase:
|
2009-09-13 00:16:49 +08:00
|
|
|
case CastExpr::CK_DerivedToBase: {
|
|
|
|
const RecordType *DerivedClassTy =
|
|
|
|
E->getSubExpr()->getType()->getAs<RecordType>();
|
|
|
|
CXXRecordDecl *DerivedClassDecl =
|
|
|
|
cast<CXXRecordDecl>(DerivedClassTy->getDecl());
|
|
|
|
|
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2010-06-18 07:00:29 +08:00
|
|
|
llvm::Value *This;
|
|
|
|
if (LV.isPropertyRef()) {
|
|
|
|
RValue RV = EmitLoadOfPropertyRefLValue(LV, E->getSubExpr()->getType());
|
|
|
|
assert (!RV.isScalar() && "EmitCastLValue");
|
|
|
|
This = RV.getAggregateAddr();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
This = LV.getAddress();
|
2009-09-13 00:16:49 +08:00
|
|
|
|
|
|
|
// Perform the derived-to-base conversion
|
|
|
|
llvm::Value *Base =
|
2010-06-18 07:00:29 +08:00
|
|
|
GetAddressOfBaseClass(This, DerivedClassDecl,
|
2010-04-25 05:12:55 +08:00
|
|
|
E->getBasePath(), /*NullCheckValue=*/false);
|
2009-09-13 00:16:49 +08:00
|
|
|
|
2009-09-25 03:53:00 +08:00
|
|
|
return LValue::MakeAddr(Base, MakeQualifiers(E->getType()));
|
2009-09-13 00:16:49 +08:00
|
|
|
}
|
2010-02-06 04:02:42 +08:00
|
|
|
case CastExpr::CK_ToUnion:
|
|
|
|
return EmitAggExprToLValue(E);
|
2009-11-16 13:48:01 +08:00
|
|
|
case CastExpr::CK_BaseToDerived: {
|
2009-11-24 01:57:54 +08:00
|
|
|
const RecordType *DerivedClassTy = E->getType()->getAs<RecordType>();
|
|
|
|
CXXRecordDecl *DerivedClassDecl =
|
|
|
|
cast<CXXRecordDecl>(DerivedClassTy->getDecl());
|
|
|
|
|
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
|
|
|
|
|
|
|
// Perform the base-to-derived conversion
|
|
|
|
llvm::Value *Derived =
|
2010-04-25 05:23:59 +08:00
|
|
|
GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl,
|
|
|
|
E->getBasePath(),/*NullCheckValue=*/false);
|
2009-11-24 01:57:54 +08:00
|
|
|
|
|
|
|
return LValue::MakeAddr(Derived, MakeQualifiers(E->getType()));
|
2009-11-16 13:48:01 +08:00
|
|
|
}
|
2009-11-15 05:21:42 +08:00
|
|
|
case CastExpr::CK_BitCast: {
|
2009-11-16 13:48:01 +08:00
|
|
|
// This must be a reinterpret_cast (or c-style equivalent).
|
|
|
|
const ExplicitCastExpr *CE = cast<ExplicitCastExpr>(E);
|
2009-11-15 05:21:42 +08:00
|
|
|
|
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
|
|
|
llvm::Value *V = Builder.CreateBitCast(LV.getAddress(),
|
|
|
|
ConvertType(CE->getTypeAsWritten()));
|
|
|
|
return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
|
|
|
|
}
|
2009-09-13 00:16:49 +08:00
|
|
|
}
|
2009-03-19 02:28:57 +08:00
|
|
|
}
|
|
|
|
|
2009-10-21 07:29:04 +08:00
|
|
|
LValue CodeGenFunction::EmitNullInitializationLValue(
|
|
|
|
const CXXZeroInitValueExpr *E) {
|
|
|
|
QualType Ty = E->getType();
|
2010-02-09 10:48:28 +08:00
|
|
|
LValue LV = LValue::MakeAddr(CreateMemTemp(Ty), MakeQualifiers(Ty));
|
2010-05-23 01:35:42 +08:00
|
|
|
EmitNullInitialization(LV.getAddress(), Ty);
|
2010-02-09 10:48:28 +08:00
|
|
|
return LV;
|
2009-10-21 07:29:04 +08:00
|
|
|
}
|
|
|
|
|
2007-06-02 02:02:12 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// Expression Emission
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
2007-08-21 06:37:10 +08:00
|
|
|
|
2009-12-25 04:40:36 +08:00
|
|
|
RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
|
|
|
|
ReturnValueSlot ReturnValue) {
|
2009-02-21 02:06:48 +08:00
|
|
|
// Builtins never have block type.
|
|
|
|
if (E->getCallee()->getType()->isBlockPointerType())
|
2009-12-25 05:13:40 +08:00
|
|
|
return EmitBlockCallExpr(E, ReturnValue);
|
2009-02-21 02:06:48 +08:00
|
|
|
|
2009-04-04 06:50:24 +08:00
|
|
|
if (const CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(E))
|
2009-12-25 05:13:40 +08:00
|
|
|
return EmitCXXMemberCallExpr(CE, ReturnValue);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-02-21 02:06:48 +08:00
|
|
|
const Decl *TargetDecl = 0;
|
2009-02-21 03:34:33 +08:00
|
|
|
if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E->getCallee())) {
|
|
|
|
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
|
|
|
|
TargetDecl = DRE->getDecl();
|
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(TargetDecl))
|
2009-09-12 08:22:50 +08:00
|
|
|
if (unsigned builtinID = FD->getBuiltinID())
|
2009-02-21 03:34:33 +08:00
|
|
|
return EmitBuiltinExpr(FD, builtinID, E);
|
2009-02-21 02:06:48 +08:00
|
|
|
}
|
|
|
|
}
|
2009-01-10 00:50:52 +08:00
|
|
|
|
2009-06-13 08:26:38 +08:00
|
|
|
if (const CXXOperatorCallExpr *CE = dyn_cast<CXXOperatorCallExpr>(E))
|
2009-05-27 12:18:27 +08:00
|
|
|
if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(TargetDecl))
|
2009-12-25 05:13:40 +08:00
|
|
|
return EmitCXXOperatorMemberCallExpr(CE, MD, ReturnValue);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-12-08 10:09:46 +08:00
|
|
|
if (isa<CXXPseudoDestructorExpr>(E->getCallee()->IgnoreParens())) {
|
2009-09-05 01:36:40 +08:00
|
|
|
// C++ [expr.pseudo]p1:
|
2009-09-09 21:00:44 +08:00
|
|
|
// The result shall only be used as the operand for the function call
|
2009-09-05 01:36:40 +08:00
|
|
|
// operator (), and the result of such a call has type void. The only
|
|
|
|
// effect is the evaluation of the postfix-expression before the dot or
|
|
|
|
// arrow.
|
|
|
|
EmitScalarExpr(E->getCallee());
|
|
|
|
return RValue::get(0);
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
llvm::Value *Callee = EmitScalarExpr(E->getCallee());
|
2009-12-25 04:40:36 +08:00
|
|
|
return EmitCall(E->getCallee()->getType(), Callee, ReturnValue,
|
2009-05-27 09:22:39 +08:00
|
|
|
E->arg_begin(), E->arg_end(), TargetDecl);
|
2007-08-31 12:44:06 +08:00
|
|
|
}
|
|
|
|
|
2008-09-04 11:20:13 +08:00
|
|
|
LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
|
2009-05-13 05:28:12 +08:00
|
|
|
// Comma expressions just emit their LHS then their RHS as an l-value.
|
|
|
|
if (E->getOpcode() == BinaryOperator::Comma) {
|
|
|
|
EmitAnyExpr(E->getLHS());
|
2009-12-08 04:18:11 +08:00
|
|
|
EnsureInsertPoint();
|
2009-05-13 05:28:12 +08:00
|
|
|
return EmitLValue(E->getRHS());
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-10-27 05:58:25 +08:00
|
|
|
if (E->getOpcode() == BinaryOperator::PtrMemD ||
|
|
|
|
E->getOpcode() == BinaryOperator::PtrMemI)
|
2009-10-23 06:57:31 +08:00
|
|
|
return EmitPointerToDataMemberBinaryExpr(E);
|
|
|
|
|
2008-09-04 11:20:13 +08:00
|
|
|
// Can only get l-value for binary operator expressions which are a
|
|
|
|
// simple assignment of aggregate type.
|
|
|
|
if (E->getOpcode() != BinaryOperator::Assign)
|
|
|
|
return EmitUnsupportedLValue(E, "binary l-value expression");
|
|
|
|
|
2009-10-20 02:28:22 +08:00
|
|
|
if (!hasAggregateLLVMType(E->getType())) {
|
|
|
|
// Emit the LHS as an l-value.
|
|
|
|
LValue LV = EmitLValue(E->getLHS());
|
|
|
|
|
|
|
|
llvm::Value *RHS = EmitScalarExpr(E->getRHS());
|
|
|
|
EmitStoreOfScalar(RHS, LV.getAddress(), LV.isVolatileQualified(),
|
|
|
|
E->getType());
|
|
|
|
return LV;
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:31 +08:00
|
|
|
return EmitAggExprToLValue(E);
|
2008-09-04 11:20:13 +08:00
|
|
|
}
|
|
|
|
|
2007-12-29 13:02:41 +08:00
|
|
|
LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
|
|
|
|
RValue RV = EmitCallExpr(E);
|
2009-05-27 09:45:47 +08:00
|
|
|
|
2009-10-29 01:39:19 +08:00
|
|
|
if (!RV.isScalar())
|
|
|
|
return LValue::MakeAddr(RV.getAggregateAddr(),MakeQualifiers(E->getType()));
|
|
|
|
|
|
|
|
assert(E->getCallReturnType()->isReferenceType() &&
|
|
|
|
"Can't have a scalar return unless the return type is a "
|
|
|
|
"reference type!");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-10-29 01:39:19 +08:00
|
|
|
return LValue::MakeAddr(RV.getScalarVal(), MakeQualifiers(E->getType()));
|
2007-12-29 13:02:41 +08:00
|
|
|
}
|
|
|
|
|
2009-02-12 04:59:32 +08:00
|
|
|
LValue CodeGenFunction::EmitVAArgExprLValue(const VAArgExpr *E) {
|
|
|
|
// FIXME: This shouldn't require another copy.
|
2010-02-06 03:38:31 +08:00
|
|
|
return EmitAggExprToLValue(E);
|
2009-02-12 04:59:32 +08:00
|
|
|
}
|
|
|
|
|
2009-05-31 07:23:33 +08:00
|
|
|
LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
|
2010-02-09 10:48:28 +08:00
|
|
|
llvm::Value *Temp = CreateMemTemp(E->getType(), "tmp");
|
2009-05-31 07:23:33 +08:00
|
|
|
EmitCXXConstructExpr(Temp, E);
|
2009-09-25 03:53:00 +08:00
|
|
|
return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
|
2009-05-31 07:23:33 +08:00
|
|
|
}
|
|
|
|
|
2009-11-15 16:09:41 +08:00
|
|
|
LValue
|
|
|
|
CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {
|
|
|
|
llvm::Value *Temp = EmitCXXTypeidExpr(E);
|
|
|
|
return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
|
|
|
|
}
|
|
|
|
|
2009-05-31 07:30:54 +08:00
|
|
|
LValue
|
|
|
|
CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
|
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2009-05-31 08:34:10 +08:00
|
|
|
PushCXXTemporary(E->getTemporary(), LV.getAddress());
|
2009-05-31 07:30:54 +08:00
|
|
|
return LV;
|
|
|
|
}
|
|
|
|
|
2008-08-23 18:51:21 +08:00
|
|
|
LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
|
|
|
|
RValue RV = EmitObjCMessageExpr(E);
|
2010-06-22 04:59:55 +08:00
|
|
|
|
|
|
|
if (!RV.isScalar())
|
|
|
|
return LValue::MakeAddr(RV.getAggregateAddr(),
|
|
|
|
MakeQualifiers(E->getType()));
|
|
|
|
|
|
|
|
assert(E->getMethodDecl()->getResultType()->isReferenceType() &&
|
|
|
|
"Can't have a scalar return unless the return type is a "
|
|
|
|
"reference type!");
|
|
|
|
|
|
|
|
return LValue::MakeAddr(RV.getScalarVal(), MakeQualifiers(E->getType()));
|
2008-08-23 18:51:21 +08:00
|
|
|
}
|
|
|
|
|
2010-06-18 03:56:20 +08:00
|
|
|
LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) {
|
|
|
|
llvm::Value *V =
|
|
|
|
CGM.getObjCRuntime().GetSelector(Builder, E->getSelector(), true);
|
|
|
|
return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
|
|
|
|
}
|
|
|
|
|
2009-04-22 13:08:15 +08:00
|
|
|
llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface,
|
2008-09-24 12:00:38 +08:00
|
|
|
const ObjCIvarDecl *Ivar) {
|
2009-02-11 03:02:04 +08:00
|
|
|
return CGM.getObjCRuntime().EmitIvarOffset(*this, Interface, Ivar);
|
2008-09-24 12:00:38 +08:00
|
|
|
}
|
2008-08-25 09:53:23 +08:00
|
|
|
|
2009-02-03 08:09:52 +08:00
|
|
|
LValue CodeGenFunction::EmitLValueForIvar(QualType ObjectTy,
|
|
|
|
llvm::Value *BaseValue,
|
2008-09-24 12:00:38 +08:00
|
|
|
const ObjCIvarDecl *Ivar,
|
|
|
|
unsigned CVRQualifiers) {
|
2009-04-18 01:44:48 +08:00
|
|
|
return CGM.getObjCRuntime().EmitObjCValueForIvar(*this, ObjectTy, BaseValue,
|
2009-04-21 09:19:28 +08:00
|
|
|
Ivar, CVRQualifiers);
|
2008-09-24 12:00:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
|
2008-08-25 09:53:23 +08:00
|
|
|
// FIXME: A lot of the code below could be shared with EmitMemberExpr.
|
|
|
|
llvm::Value *BaseValue = 0;
|
|
|
|
const Expr *BaseExpr = E->getBase();
|
2009-09-25 03:53:00 +08:00
|
|
|
Qualifiers BaseQuals;
|
2009-02-03 08:09:52 +08:00
|
|
|
QualType ObjectTy;
|
2008-08-25 09:53:23 +08:00
|
|
|
if (E->isArrow()) {
|
|
|
|
BaseValue = EmitScalarExpr(BaseExpr);
|
2009-07-11 07:34:53 +08:00
|
|
|
ObjectTy = BaseExpr->getType()->getPointeeType();
|
2009-09-25 03:53:00 +08:00
|
|
|
BaseQuals = ObjectTy.getQualifiers();
|
2008-08-25 09:53:23 +08:00
|
|
|
} else {
|
|
|
|
LValue BaseLV = EmitLValue(BaseExpr);
|
|
|
|
// FIXME: this isn't right for bitfields.
|
|
|
|
BaseValue = BaseLV.getAddress();
|
2009-02-03 08:09:52 +08:00
|
|
|
ObjectTy = BaseExpr->getType();
|
2009-09-25 03:53:00 +08:00
|
|
|
BaseQuals = ObjectTy.getQualifiers();
|
2008-08-25 09:53:23 +08:00
|
|
|
}
|
2008-09-24 12:00:38 +08:00
|
|
|
|
2009-09-17 07:11:23 +08:00
|
|
|
LValue LV =
|
2009-09-25 03:53:00 +08:00
|
|
|
EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(),
|
|
|
|
BaseQuals.getCVRQualifiers());
|
2009-09-17 07:11:23 +08:00
|
|
|
setObjCGCLValueClass(getContext(), E, LV);
|
|
|
|
return LV;
|
2008-03-31 07:03:07 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
LValue
|
2008-08-29 16:11:39 +08:00
|
|
|
CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
|
2009-09-09 21:00:44 +08:00
|
|
|
// This is a special l-value that just issues sends when we load or store
|
|
|
|
// through it.
|
2008-08-29 16:11:39 +08:00
|
|
|
return LValue::MakePropertyRef(E, E->getType().getCVRQualifiers());
|
|
|
|
}
|
|
|
|
|
2009-10-29 01:39:19 +08:00
|
|
|
LValue CodeGenFunction::EmitObjCKVCRefLValue(
|
2009-08-21 01:02:02 +08:00
|
|
|
const ObjCImplicitSetterGetterRefExpr *E) {
|
2009-09-09 21:00:44 +08:00
|
|
|
// This is a special l-value that just issues sends when we load or store
|
|
|
|
// through it.
|
2008-11-23 06:30:21 +08:00
|
|
|
return LValue::MakeKVCRef(E, E->getType().getCVRQualifiers());
|
|
|
|
}
|
|
|
|
|
2009-10-29 01:39:19 +08:00
|
|
|
LValue CodeGenFunction::EmitObjCSuperExprLValue(const ObjCSuperExpr *E) {
|
2008-11-04 22:56:14 +08:00
|
|
|
return EmitUnsupportedLValue(E, "use of super");
|
|
|
|
}
|
|
|
|
|
2009-04-26 03:35:26 +08:00
|
|
|
LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {
|
|
|
|
// Can only get l-value for message expression returning aggregate type
|
|
|
|
RValue RV = EmitAnyExprToTemp(E);
|
2009-09-25 03:53:00 +08:00
|
|
|
return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
|
2009-04-26 03:35:26 +08:00
|
|
|
}
|
|
|
|
|
2009-12-25 03:08:58 +08:00
|
|
|
RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
|
2009-12-25 04:40:36 +08:00
|
|
|
ReturnValueSlot ReturnValue,
|
2009-05-27 09:22:39 +08:00
|
|
|
CallExpr::const_arg_iterator ArgBeg,
|
|
|
|
CallExpr::const_arg_iterator ArgEnd,
|
|
|
|
const Decl *TargetDecl) {
|
2009-09-09 21:00:44 +08:00
|
|
|
// Get the actual function type. The callee type will always be a pointer to
|
|
|
|
// function type or a block pointer type.
|
|
|
|
assert(CalleeType->isFunctionPointerType() &&
|
2009-04-08 02:53:02 +08:00
|
|
|
"Call must have function pointer type!");
|
|
|
|
|
2009-10-23 16:22:42 +08:00
|
|
|
CalleeType = getContext().getCanonicalType(CalleeType);
|
|
|
|
|
2010-02-06 05:31:56 +08:00
|
|
|
const FunctionType *FnType
|
|
|
|
= cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType());
|
|
|
|
QualType ResultType = FnType->getResultType();
|
2008-08-30 11:02:31 +08:00
|
|
|
|
|
|
|
CallArgList Args;
|
2009-10-23 16:22:42 +08:00
|
|
|
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);
|
2008-08-30 11:02:31 +08:00
|
|
|
|
2010-02-06 05:31:56 +08:00
|
|
|
return EmitCall(CGM.getTypes().getFunctionInfo(Args, FnType),
|
2009-12-25 04:40:36 +08:00
|
|
|
Callee, ReturnValue, Args, TargetDecl);
|
2008-08-23 11:46:30 +08:00
|
|
|
}
|
2009-10-23 06:57:31 +08:00
|
|
|
|
2009-10-29 01:39:19 +08:00
|
|
|
LValue CodeGenFunction::
|
|
|
|
EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
|
2009-11-18 13:01:17 +08:00
|
|
|
llvm::Value *BaseV;
|
2009-10-27 05:58:25 +08:00
|
|
|
if (E->getOpcode() == BinaryOperator::PtrMemI)
|
2009-11-18 13:01:17 +08:00
|
|
|
BaseV = EmitScalarExpr(E->getLHS());
|
|
|
|
else
|
|
|
|
BaseV = EmitLValue(E->getLHS()).getAddress();
|
2009-10-23 06:57:31 +08:00
|
|
|
const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(getLLVMContext());
|
|
|
|
BaseV = Builder.CreateBitCast(BaseV, i8Ty);
|
2009-11-18 13:01:17 +08:00
|
|
|
llvm::Value *OffsetV = EmitScalarExpr(E->getRHS());
|
2009-10-23 06:57:31 +08:00
|
|
|
llvm::Value *AddV = Builder.CreateInBoundsGEP(BaseV, OffsetV, "add.ptr");
|
2009-10-29 01:39:19 +08:00
|
|
|
|
2009-10-23 06:57:31 +08:00
|
|
|
QualType Ty = E->getRHS()->getType();
|
2009-10-29 01:39:19 +08:00
|
|
|
Ty = Ty->getAs<MemberPointerType>()->getPointeeType();
|
|
|
|
|
|
|
|
const llvm::Type *PType = ConvertType(getContext().getPointerType(Ty));
|
2009-10-23 06:57:31 +08:00
|
|
|
AddV = Builder.CreateBitCast(AddV, PType);
|
2009-10-29 01:39:19 +08:00
|
|
|
return LValue::MakeAddr(AddV, MakeQualifiers(Ty));
|
2009-10-23 06:57:31 +08:00
|
|
|
}
|
|
|
|
|