summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/CGExprComplex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGExprComplex.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGExprComplex.cpp142
1 files changed, 75 insertions, 67 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExprComplex.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExprComplex.cpp
index 27d1c68..ccdb532 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExprComplex.cpp
@@ -83,12 +83,12 @@ public:
/// specified value pointer.
void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit);
- /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
+ /// Emit a cast from complex value Val to DestType.
ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
- QualType DestType);
- /// EmitComplexToComplexCast - Emit a cast from scalar value Val to DestType.
+ QualType DestType, SourceLocation Loc);
+ /// Emit a cast from scalar value Val to DestType.
ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType,
- QualType DestType);
+ QualType DestType, SourceLocation Loc);
//===--------------------------------------------------------------------===//
// Visitor Methods
@@ -154,6 +154,8 @@ public:
return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
}
ComplexPairTy VisitCastExpr(CastExpr *E) {
+ if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
+ CGF.CGM.EmitExplicitCastExprType(ECE, &CGF);
return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
}
ComplexPairTy VisitCallExpr(const CallExpr *E);
@@ -298,6 +300,19 @@ public:
// Utilities
//===----------------------------------------------------------------------===//
+Address CodeGenFunction::emitAddrOfRealComponent(Address addr,
+ QualType complexType) {
+ CharUnits offset = CharUnits::Zero();
+ return Builder.CreateStructGEP(addr, 0, offset, addr.getName() + ".realp");
+}
+
+Address CodeGenFunction::emitAddrOfImagComponent(Address addr,
+ QualType complexType) {
+ QualType eltType = complexType->castAs<ComplexType>()->getElementType();
+ CharUnits offset = getContext().getTypeSizeInChars(eltType);
+ return Builder.CreateStructGEP(addr, 1, offset, addr.getName() + ".imagp");
+}
+
/// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to
/// load the real and imaginary pieces, returning them as Real/Imag.
ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue,
@@ -306,29 +321,21 @@ ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue,
if (lvalue.getType()->isAtomicType())
return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal();
- llvm::Value *SrcPtr = lvalue.getAddress();
+ Address SrcPtr = lvalue.getAddress();
bool isVolatile = lvalue.isVolatileQualified();
- unsigned AlignR = lvalue.getAlignment().getQuantity();
- ASTContext &C = CGF.getContext();
- QualType ComplexTy = lvalue.getType();
- unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity();
- unsigned AlignI = std::min(AlignR, ComplexAlign);
- llvm::Value *Real=nullptr, *Imag=nullptr;
+ llvm::Value *Real = nullptr, *Imag = nullptr;
if (!IgnoreReal || isVolatile) {
- llvm::Value *RealP = Builder.CreateStructGEP(nullptr, SrcPtr, 0,
- SrcPtr->getName() + ".realp");
- Real = Builder.CreateAlignedLoad(RealP, AlignR, isVolatile,
- SrcPtr->getName() + ".real");
+ Address RealP = CGF.emitAddrOfRealComponent(SrcPtr, lvalue.getType());
+ Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.getName() + ".real");
}
if (!IgnoreImag || isVolatile) {
- llvm::Value *ImagP = Builder.CreateStructGEP(nullptr, SrcPtr, 1,
- SrcPtr->getName() + ".imagp");
- Imag = Builder.CreateAlignedLoad(ImagP, AlignI, isVolatile,
- SrcPtr->getName() + ".imag");
+ Address ImagP = CGF.emitAddrOfImagComponent(SrcPtr, lvalue.getType());
+ Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.getName() + ".imag");
}
+
return ComplexPairTy(Real, Imag);
}
@@ -340,19 +347,12 @@ void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue,
(!isInit && CGF.LValueIsSuitableForInlineAtomic(lvalue)))
return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit);
- llvm::Value *Ptr = lvalue.getAddress();
- llvm::Value *RealPtr = Builder.CreateStructGEP(nullptr, Ptr, 0, "real");
- llvm::Value *ImagPtr = Builder.CreateStructGEP(nullptr, Ptr, 1, "imag");
- unsigned AlignR = lvalue.getAlignment().getQuantity();
- ASTContext &C = CGF.getContext();
- QualType ComplexTy = lvalue.getType();
- unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity();
- unsigned AlignI = std::min(AlignR, ComplexAlign);
-
- Builder.CreateAlignedStore(Val.first, RealPtr, AlignR,
- lvalue.isVolatileQualified());
- Builder.CreateAlignedStore(Val.second, ImagPtr, AlignI,
- lvalue.isVolatileQualified());
+ Address Ptr = lvalue.getAddress();
+ Address RealPtr = CGF.emitAddrOfRealComponent(Ptr, lvalue.getType());
+ Address ImagPtr = CGF.emitAddrOfImagComponent(Ptr, lvalue.getType());
+
+ Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified());
+ Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified());
}
@@ -385,16 +385,17 @@ ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
CodeGenFunction::StmtExprEvaluation eval(CGF);
- llvm::Value *RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true);
- assert(RetAlloca && "Expected complex return value");
+ Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true);
+ assert(RetAlloca.isValid() && "Expected complex return value");
return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()),
E->getExprLoc());
}
-/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
+/// Emit a cast from complex value Val to DestType.
ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
QualType SrcType,
- QualType DestType) {
+ QualType DestType,
+ SourceLocation Loc) {
// Get the src/dest element type.
SrcType = SrcType->castAs<ComplexType>()->getElementType();
DestType = DestType->castAs<ComplexType>()->getElementType();
@@ -402,17 +403,18 @@ ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
// C99 6.3.1.6: When a value of complex type is converted to another
// complex type, both the real and imaginary parts follow the conversion
// rules for the corresponding real types.
- Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
- Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
+ Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType, Loc);
+ Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType, Loc);
return Val;
}
ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
QualType SrcType,
- QualType DestType) {
+ QualType DestType,
+ SourceLocation Loc) {
// Convert the input element to the element type of the complex.
DestType = DestType->castAs<ComplexType>()->getElementType();
- Val = CGF.EmitScalarConversion(Val, SrcType, DestType);
+ Val = CGF.EmitScalarConversion(Val, SrcType, DestType, Loc);
// Return (realval, 0).
return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
@@ -434,12 +436,9 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
case CK_LValueBitCast: {
LValue origLV = CGF.EmitLValue(Op);
- llvm::Value *V = origLV.getAddress();
- V = Builder.CreateBitCast(V,
- CGF.ConvertType(CGF.getContext().getPointerType(DestTy)));
- return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy,
- origLV.getAlignment()),
- Op->getExprLoc());
+ Address V = origLV.getAddress();
+ V = Builder.CreateElementBitCast(V, CGF.ConvertType(DestTy));
+ return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy), Op->getExprLoc());
}
case CK_BitCast:
@@ -488,14 +487,15 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
case CK_FloatingRealToComplex:
case CK_IntegralRealToComplex:
- return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op),
- Op->getType(), DestTy);
+ return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), Op->getType(),
+ DestTy, Op->getExprLoc());
case CK_FloatingComplexCast:
case CK_FloatingComplexToIntegralComplex:
case CK_IntegralComplexCast:
case CK_IntegralComplexToFloatingComplex:
- return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
+ return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy,
+ Op->getExprLoc());
}
llvm_unreachable("unknown cast resulting in complex value");
@@ -585,19 +585,25 @@ ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
// We *must* use the full CG function call building logic here because the
// complex type has special ABI handling. We also should not forget about
// special calling convention which may be used for compiler builtins.
- const CGFunctionInfo &FuncInfo =
- CGF.CGM.getTypes().arrangeFreeFunctionCall(
- Op.Ty, Args, FunctionType::ExtInfo(/* No CC here - will be added later */),
- RequiredArgs::All);
+
+ // We create a function qualified type to state that this call does not have
+ // any exceptions.
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI = EPI.withExceptionSpec(
+ FunctionProtoType::ExceptionSpecInfo(EST_BasicNoexcept));
+ SmallVector<QualType, 4> ArgsQTys(
+ 4, Op.Ty->castAs<ComplexType>()->getElementType());
+ QualType FQTy = CGF.getContext().getFunctionType(Op.Ty, ArgsQTys, EPI);
+ const CGFunctionInfo &FuncInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall(
+ Args, cast<FunctionType>(FQTy.getTypePtr()), false);
+
llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Constant *Func = CGF.CGM.CreateBuiltinFunction(FTy, LibCallName);
llvm::Instruction *Call;
RValue Res = CGF.EmitCall(FuncInfo, Func, ReturnValueSlot(), Args,
- nullptr, &Call);
+ FQTy->getAs<FunctionProtoType>(), &Call);
cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getBuiltinCC());
- cast<llvm::CallInst>(Call)->setDoesNotThrow();
-
return Res.getComplexVal();
}
@@ -846,19 +852,20 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
LValue LHS = CGF.EmitLValue(E->getLHS());
// Load from the l-value and convert it.
+ SourceLocation Loc = E->getExprLoc();
if (LHSTy->isAnyComplexType()) {
- ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, E->getExprLoc());
- OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
+ ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc);
+ OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
} else {
- llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, E->getExprLoc());
+ llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, Loc);
// For floating point real operands we can directly pass the scalar form
// to the binary operator emission and potentially get more efficient code.
if (LHSTy->isRealFloatingType()) {
if (!CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, LHSTy))
- LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy);
+ LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy, Loc);
OpInfo.LHS = ComplexPairTy(LHSVal, nullptr);
} else {
- OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
+ OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
}
}
@@ -867,12 +874,13 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
// Truncate the result and store it into the LHS lvalue.
if (LHSTy->isAnyComplexType()) {
- ComplexPairTy ResVal = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
+ ComplexPairTy ResVal =
+ EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy, Loc);
EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false);
Val = RValue::getComplex(ResVal);
} else {
llvm::Value *ResVal =
- CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy);
+ CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy, Loc);
CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false);
Val = RValue::get(ResVal);
}
@@ -1011,10 +1019,10 @@ ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
}
ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
- llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr());
- llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType());
+ Address ArgValue = Address::invalid();
+ Address ArgPtr = CGF.EmitVAArg(E, ArgValue);
- if (!ArgPtr) {
+ if (!ArgPtr.isValid()) {
CGF.ErrorUnsupported(E, "complex va_arg expression");
llvm::Type *EltTy =
CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType());
@@ -1022,7 +1030,7 @@ ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
return ComplexPairTy(U, U);
}
- return EmitLoadOfLValue(CGF.MakeNaturalAlignAddrLValue(ArgPtr, E->getType()),
+ return EmitLoadOfLValue(CGF.MakeAddrLValue(ArgPtr, E->getType()),
E->getExprLoc());
}
OpenPOWER on IntegriCloud