aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--lib/CodeGen/CGExprScalar.cpp133
1 files changed, 104 insertions, 29 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index d1c0f8dc3d73..984968802382 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -133,6 +133,7 @@ public:
CGF.getContext().typesAreCompatible(
E->getArgType1(), E->getArgType2()));
}
+ Value *VisitOffsetOfExpr(const OffsetOfExpr *E);
Value *VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
@@ -242,7 +243,7 @@ public:
return Visit(E->getSubExpr());
}
Value *VisitUnaryOffsetOf(const UnaryOperator *E);
-
+
// C++
Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
return Visit(DAE->getExpr());
@@ -314,6 +315,10 @@ public:
}
BinOpInfo EmitBinOps(const BinaryOperator *E);
+ LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
+ Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
+ Value *&BitFieldResult);
+
Value *EmitCompoundAssign(const CompoundAssignOperator *E,
Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
@@ -818,16 +823,12 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
return Visit(const_cast<Expr*>(E));
case CastExpr::CK_BaseToDerived: {
- const CXXRecordDecl *BaseClassDecl =
- E->getType()->getCXXRecordDeclForPointerType();
const CXXRecordDecl *DerivedClassDecl =
DestTy->getCXXRecordDeclForPointerType();
- Value *Src = Visit(const_cast<Expr*>(E));
-
- bool NullCheckValue = ShouldNullCheckClassCastValue(CE);
- return CGF.GetAddressOfDerivedClass(Src, BaseClassDecl, DerivedClassDecl,
- NullCheckValue);
+ return CGF.GetAddressOfDerivedClass(Visit(E), DerivedClassDecl,
+ CE->getBasePath(),
+ ShouldNullCheckClassCastValue(CE));
}
case CastExpr::CK_UncheckedDerivedToBase:
case CastExpr::CK_DerivedToBase: {
@@ -836,15 +837,9 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
CXXRecordDecl *DerivedClassDecl =
cast<CXXRecordDecl>(DerivedClassTy->getDecl());
- const RecordType *BaseClassTy =
- DestTy->getAs<PointerType>()->getPointeeType()->getAs<RecordType>();
- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseClassTy->getDecl());
-
- Value *Src = Visit(const_cast<Expr*>(E));
-
- bool NullCheckValue = ShouldNullCheckClassCastValue(CE);
- return CGF.GetAddressOfBaseClass(Src, DerivedClassDecl, BaseClassDecl,
- NullCheckValue);
+ return CGF.GetAddressOfBaseClass(Visit(E), DerivedClassDecl,
+ CE->getBasePath(),
+ ShouldNullCheckClassCastValue(CE));
}
case CastExpr::CK_Dynamic: {
Value *V = Visit(const_cast<Expr*>(E));
@@ -894,7 +889,8 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
std::swap(DerivedDecl, BaseDecl);
if (llvm::Constant *Adj =
- CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, BaseDecl)) {
+ CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
+ CE->getBasePath())) {
if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
Src = Builder.CreateSub(Src, Adj, "adj");
else
@@ -1035,6 +1031,21 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext");
}
+Value *ScalarExprEmitter::VisitOffsetOfExpr(const OffsetOfExpr *E) {
+ Expr::EvalResult Result;
+ if(E->Evaluate(Result, CGF.getContext()))
+ return llvm::ConstantInt::get(VMContext, Result.Val.getInt());
+
+ // FIXME: Cannot support code generation for non-constant offsetof.
+ unsigned DiagID = CGF.CGM.getDiags().getCustomDiagID(Diagnostic::Error,
+ "cannot compile non-constant __builtin_offsetof");
+ CGF.CGM.getDiags().Report(CGF.getContext().getFullLoc(E->getLocStart()),
+ DiagID)
+ << E->getSourceRange();
+
+ return llvm::Constant::getNullValue(ConvertType(E->getType()));
+}
+
/// VisitSizeOfAlignOfExpr - Return the size or alignment of the type of
/// argument of the sizeof expression as an integer.
Value *
@@ -1103,22 +1114,24 @@ BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
return Result;
}
-Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
- Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
- bool Ignore = TestAndClearIgnoreResultAssign();
+LValue ScalarExprEmitter::EmitCompoundAssignLValue(
+ const CompoundAssignOperator *E,
+ Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
+ Value *&BitFieldResult) {
QualType LHSTy = E->getLHS()->getType();
-
+ BitFieldResult = 0;
BinOpInfo OpInfo;
-
+
if (E->getComputationResultType()->isAnyComplexType()) {
// This needs to go through the complex expression emitter, but it's a tad
// complicated to do that... I'm leaving it out for now. (Note that we do
// actually need the imaginary part of the RHS for multiplication and
// division.)
CGF.ErrorUnsupported(E, "complex compound assignment");
- return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
+ llvm::UndefValue::get(CGF.ConvertType(E->getType()));
+ return LValue();
}
-
+
// Emit the RHS first. __block variables need to have the rhs evaluated
// first, plus this should improve codegen a little.
OpInfo.RHS = Visit(E->getRHS());
@@ -1129,13 +1142,13 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
E->getComputationLHSType());
-
+
// Expand the binary operator.
Value *Result = (this->*Func)(OpInfo);
-
+
// Convert the result back to the LHS type.
Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy);
-
+
// Store the result value into the LHS lvalue. Bit-fields are handled
// specially because the result is altered by the store, i.e., [C99 6.5.16p1]
// 'An assignment expression has the value of the left operand after the
@@ -1144,11 +1157,23 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
if (!LHSLV.isVolatileQualified()) {
CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy,
&Result);
- return Result;
+ BitFieldResult = Result;
+ return LHSLV;
} else
CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy);
} else
CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV, LHSTy);
+ return LHSLV;
+}
+
+Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
+ Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
+ bool Ignore = TestAndClearIgnoreResultAssign();
+ Value *BitFieldResult;
+ LValue LHSLV = EmitCompoundAssignLValue(E, Func, BitFieldResult);
+ if (BitFieldResult)
+ return BitFieldResult;
+
if (Ignore)
return 0;
return EmitLoadOfLValue(LHSLV, E->getType());
@@ -1914,3 +1939,53 @@ LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
return LV;
}
+
+LValue CodeGenFunction::EmitCompoundAssignOperatorLValue(
+ const CompoundAssignOperator *E) {
+ ScalarExprEmitter Scalar(*this);
+ Value *BitFieldResult = 0;
+ switch (E->getOpcode()) {
+#define COMPOUND_OP(Op) \
+ case BinaryOperator::Op##Assign: \
+ return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
+ BitFieldResult)
+ COMPOUND_OP(Mul);
+ COMPOUND_OP(Div);
+ COMPOUND_OP(Rem);
+ COMPOUND_OP(Add);
+ COMPOUND_OP(Sub);
+ COMPOUND_OP(Shl);
+ COMPOUND_OP(Shr);
+ COMPOUND_OP(And);
+ COMPOUND_OP(Xor);
+ COMPOUND_OP(Or);
+#undef COMPOUND_OP
+
+ case BinaryOperator::PtrMemD:
+ case BinaryOperator::PtrMemI:
+ case BinaryOperator::Mul:
+ case BinaryOperator::Div:
+ case BinaryOperator::Rem:
+ case BinaryOperator::Add:
+ case BinaryOperator::Sub:
+ case BinaryOperator::Shl:
+ case BinaryOperator::Shr:
+ case BinaryOperator::LT:
+ case BinaryOperator::GT:
+ case BinaryOperator::LE:
+ case BinaryOperator::GE:
+ case BinaryOperator::EQ:
+ case BinaryOperator::NE:
+ case BinaryOperator::And:
+ case BinaryOperator::Xor:
+ case BinaryOperator::Or:
+ case BinaryOperator::LAnd:
+ case BinaryOperator::LOr:
+ case BinaryOperator::Assign:
+ case BinaryOperator::Comma:
+ assert(false && "Not valid compound assignment operators");
+ break;
+ }
+
+ llvm_unreachable("Unhandled compound assignment operator");
+}