summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGExprAgg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExprAgg.cpp')
-rw-r--r--lib/CodeGen/CGExprAgg.cpp86
1 files changed, 55 insertions, 31 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index c852d65..97455c7 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -118,7 +118,7 @@ public:
void VisitVAArgExpr(VAArgExpr *E);
- void EmitInitializationToLValue(Expr *E, LValue Address);
+ void EmitInitializationToLValue(Expr *E, LValue Address, QualType T);
void EmitNullInitializationToLValue(LValue Address, QualType T);
// case Expr::ChooseExprClass:
void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
@@ -147,7 +147,7 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
return;
// If the source is volatile, we must read from it; to do that, we need
// some place to put it.
- DestPtr = CGF.CreateTempAlloca(CGF.ConvertType(E->getType()), "agg.tmp");
+ DestPtr = CGF.CreateMemTemp(E->getType(), "agg.tmp");
}
if (RequiresGCollection) {
@@ -188,7 +188,8 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
CGF.ConvertType(PtrTy));
EmitInitializationToLValue(E->getSubExpr(),
- LValue::MakeAddr(CastPtr, Qualifiers()));
+ LValue::MakeAddr(CastPtr, Qualifiers()),
+ E->getType());
break;
}
@@ -227,8 +228,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
case CastExpr::CK_BaseToDerivedMemberPointer: {
QualType SrcType = E->getSubExpr()->getType();
- llvm::Value *Src = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(SrcType),
- "tmp");
+ llvm::Value *Src = CGF.CreateMemTemp(SrcType, "tmp");
CGF.EmitAggExpr(E->getSubExpr(), Src, SrcType.isVolatileQualified());
llvm::Value *SrcPtr = Builder.CreateStructGEP(Src, 0, "src.ptr");
@@ -252,8 +252,8 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
std::swap(DerivedDecl, BaseDecl);
- llvm::Constant *Adj = CGF.CGM.GetCXXBaseClassOffset(DerivedDecl, BaseDecl);
- if (Adj) {
+ if (llvm::Constant *Adj =
+ CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, BaseDecl)) {
if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj");
else
@@ -326,10 +326,18 @@ void AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) {
int64_t Index =
CGF.CGM.getVtableInfo().getMethodVtableIndex(MD);
- FuncPtr = llvm::ConstantInt::get(PtrDiffTy, Index + 1);
+ // Itanium C++ ABI 2.3:
+ // For a non-virtual function, this field is a simple function pointer.
+ // For a virtual function, it is 1 plus the virtual table offset
+ // (in bytes) of the function, represented as a ptrdiff_t.
+ FuncPtr = llvm::ConstantInt::get(PtrDiffTy, (Index * 8) + 1);
} else {
- FuncPtr = llvm::ConstantExpr::getPtrToInt(CGF.CGM.GetAddrOfFunction(MD),
- PtrDiffTy);
+ const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+ const llvm::Type *Ty =
+ CGF.CGM.getTypes().GetFunctionType(CGF.CGM.getTypes().getFunctionInfo(MD),
+ FPT->isVariadic());
+ llvm::Constant *Fn = CGF.CGM.GetAddrOfFunction(MD, Ty);
+ FuncPtr = llvm::ConstantExpr::getPtrToInt(Fn, PtrDiffTy);
}
Builder.CreateStore(FuncPtr, DstPtr, VolatileDest);
@@ -371,14 +379,14 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
if (LHS.isPropertyRef()) {
llvm::Value *AggLoc = DestPtr;
if (!AggLoc)
- AggLoc = CGF.CreateTempAlloca(CGF.ConvertType(E->getRHS()->getType()));
+ AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
RValue::getAggregate(AggLoc, VolatileDest));
} else if (LHS.isKVCRef()) {
llvm::Value *AggLoc = DestPtr;
if (!AggLoc)
- AggLoc = CGF.CreateTempAlloca(CGF.ConvertType(E->getRHS()->getType()));
+ AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
RValue::getAggregate(AggLoc, VolatileDest));
@@ -408,21 +416,21 @@ void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
- CGF.StartConditionalBranch();
+ CGF.BeginConditionalBranch();
CGF.EmitBlock(LHSBlock);
// Handle the GNU extension for missing LHS.
assert(E->getLHS() && "Must have LHS for aggregate value");
Visit(E->getLHS());
- CGF.FinishConditionalBranch();
+ CGF.EndConditionalBranch();
CGF.EmitBranch(ContBlock);
- CGF.StartConditionalBranch();
+ CGF.BeginConditionalBranch();
CGF.EmitBlock(RHSBlock);
Visit(E->getRHS());
- CGF.FinishConditionalBranch();
+ CGF.EndConditionalBranch();
CGF.EmitBranch(ContBlock);
CGF.EmitBlock(ContBlock);
@@ -449,7 +457,7 @@ void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
// FIXME: volatile
CGF.EmitAggExpr(E->getSubExpr(), Val, false);
@@ -467,7 +475,7 @@ AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
}
if (E->requiresZeroInitialization())
@@ -484,7 +492,7 @@ void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
}
CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer);
}
@@ -494,7 +502,7 @@ void AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
}
LValue LV = LValue::MakeAddr(Val, Qualifiers());
EmitNullInitializationToLValue(LV, E->getType());
@@ -505,23 +513,27 @@ void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
if (!Val) {
// Create a temporary variable.
- Val = CGF.CreateTempAlloca(CGF.ConvertTypeForMem(E->getType()), "tmp");
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
}
LValue LV = LValue::MakeAddr(Val, Qualifiers());
EmitNullInitializationToLValue(LV, E->getType());
}
-void AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
+void
+AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) {
// FIXME: Ignore result?
// FIXME: Are initializers affected by volatile?
if (isa<ImplicitValueInitExpr>(E)) {
- EmitNullInitializationToLValue(LV, E->getType());
- } else if (E->getType()->isComplexType()) {
+ EmitNullInitializationToLValue(LV, T);
+ } else if (T->isReferenceType()) {
+ RValue RV = CGF.EmitReferenceBindingToExpr(E, /*IsInitializer=*/false);
+ CGF.EmitStoreThroughLValue(RV, LV, T);
+ } else if (T->isAnyComplexType()) {
CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
- } else if (CGF.hasAggregateLLVMType(E->getType())) {
+ } else if (CGF.hasAggregateLLVMType(T)) {
CGF.EmitAnyExpr(E, LV.getAddress(), false);
} else {
- CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(E), LV, E->getType());
+ CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(E), LV, T);
}
}
@@ -590,7 +602,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
if (i < NumInitElements)
EmitInitializationToLValue(E->getInit(i),
- LValue::MakeAddr(NextVal, Quals));
+ LValue::MakeAddr(NextVal, Quals),
+ ElementType);
else
EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, Quals),
ElementType);
@@ -627,11 +640,11 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
// FIXME: volatility
FieldDecl *Field = E->getInitializedFieldInUnion();
- LValue FieldLoc = CGF.EmitLValueForField(DestPtr, Field, true, 0);
+ LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
if (NumInitElements) {
// Store the initializer into the field
- EmitInitializationToLValue(E->getInit(0), FieldLoc);
+ EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType());
} else {
// Default-initialize to null
EmitNullInitializationToLValue(FieldLoc, Field->getType());
@@ -653,12 +666,13 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
continue;
// FIXME: volatility
- LValue FieldLoc = CGF.EmitLValueForField(DestPtr, *Field, false, 0);
+ LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0);
// We never generate write-barries for initialized fields.
LValue::SetObjCNonGC(FieldLoc, true);
if (CurInitVal < NumInitElements) {
// Store the initializer into the field
- EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc);
+ EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
+ Field->getType());
} else {
// We're out of initalizers; default-initialize to null
EmitNullInitializationToLValue(FieldLoc, Field->getType());
@@ -674,6 +688,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
/// type. The result is computed into DestPtr. Note that if DestPtr is null,
/// the value of the aggregate expression is not needed. If VolatileDest is
/// true, DestPtr cannot be 0.
+//
+// FIXME: Take Qualifiers object.
void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
bool VolatileDest, bool IgnoreResult,
bool IsInitializer,
@@ -688,6 +704,14 @@ void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
.Visit(const_cast<Expr*>(E));
}
+LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
+ assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
+ Qualifiers Q = MakeQualifiers(E->getType());
+ llvm::Value *Temp = CreateMemTemp(E->getType());
+ EmitAggExpr(E, Temp, Q.hasVolatile());
+ return LValue::MakeAddr(Temp, Q);
+}
+
void CodeGenFunction::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) {
assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
OpenPOWER on IntegriCloud