Change hasAggregateLLVMType, which conflates complex and
aggregate types in a profoundly wrong way that has to be
worked around in every call site, to getEvaluationKind,
which classifies and distinguishes between all of these
cases.
Also, normalize the API for loading and storing complexes.
I'm working on a larger patch and wanted to pull these
changes out, but it would have be annoying to detangle
them from each other.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176656 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 842eaf1..9e7ddfb 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -741,7 +741,9 @@
} else if (RV.isAggregate()) {
EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty);
} else {
- StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false);
+ EmitStoreOfComplex(RV.getComplexVal(),
+ MakeNaturalAlignAddrLValue(ReturnValue, Ty),
+ /*init*/ true);
}
EmitBranchThroughCleanup(ReturnBlock);
}
@@ -788,16 +790,26 @@
// rather than the value.
RValue Result = EmitReferenceBindingToExpr(RV, /*InitializedDecl=*/0);
Builder.CreateStore(Result.getScalarVal(), ReturnValue);
- } else if (!hasAggregateLLVMType(RV->getType())) {
- Builder.CreateStore(EmitScalarExpr(RV), ReturnValue);
- } else if (RV->getType()->isAnyComplexType()) {
- EmitComplexExprIntoAddr(RV, ReturnValue, false);
} else {
- CharUnits Alignment = getContext().getTypeAlignInChars(RV->getType());
- EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Alignment, Qualifiers(),
- AggValueSlot::IsDestructed,
- AggValueSlot::DoesNotNeedGCBarriers,
- AggValueSlot::IsNotAliased));
+ switch (getEvaluationKind(RV->getType())) {
+ case TEK_Scalar:
+ Builder.CreateStore(EmitScalarExpr(RV), ReturnValue);
+ break;
+ case TEK_Complex:
+ EmitComplexExprIntoLValue(RV,
+ MakeNaturalAlignAddrLValue(ReturnValue, RV->getType()),
+ /*isInit*/ true);
+ break;
+ case TEK_Aggregate: {
+ CharUnits Alignment = getContext().getTypeAlignInChars(RV->getType());
+ EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Alignment,
+ Qualifiers(),
+ AggValueSlot::IsDestructed,
+ AggValueSlot::DoesNotNeedGCBarriers,
+ AggValueSlot::IsNotAliased));
+ break;
+ }
+ }
}
cleanupScope.ForceCleanup();
@@ -1355,7 +1367,7 @@
std::string &ConstraintStr) {
llvm::Value *Arg;
if (Info.allowsRegister() || !Info.allowsMemory()) {
- if (!CodeGenFunction::hasAggregateLLVMType(InputType)) {
+ if (CodeGenFunction::hasScalarEvaluationKind(InputType)) {
Arg = EmitLoadOfLValue(InputValue).getScalarVal();
} else {
llvm::Type *Ty = ConvertType(InputType);
@@ -1384,7 +1396,7 @@
const Expr *InputExpr,
std::string &ConstraintStr) {
if (Info.allowsRegister() || !Info.allowsMemory())
- if (!CodeGenFunction::hasAggregateLLVMType(InputExpr->getType()))
+ if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType()))
return EmitScalarExpr(InputExpr);
InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
@@ -1479,7 +1491,7 @@
// If this is a register output, then make the inline asm return it
// by-value. If this is a memory result, return the value by-reference.
- if (!Info.allowsMemory() && !hasAggregateLLVMType(OutExpr->getType())) {
+ if (!Info.allowsMemory() && hasScalarEvaluationKind(OutExpr->getType())) {
Constraints += "=" + OutputConstraint;
ResultRegQualTys.push_back(OutExpr->getType());
ResultRegDests.push_back(Dest);