aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenExpr.cpp')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExpr.cpp79
1 files changed, 71 insertions, 8 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 51da48d..1f64801 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -333,13 +333,12 @@ mlir::Value CIRGenFunction::emitStoreThroughBitfieldLValue(RValue src,
Address ptr = dst.getBitFieldAddress();
assert(!cir::MissingFeatures::armComputeVolatileBitfields());
- const bool useVolatile = false;
mlir::Value dstAddr = dst.getAddress().getPointer();
- return builder.createSetBitfield(dstAddr.getLoc(), resLTy, dstAddr,
+ return builder.createSetBitfield(dstAddr.getLoc(), resLTy, ptr,
ptr.getElementType(), src.getValue(), info,
- dst.isVolatileQualified(), useVolatile);
+ dst.isVolatileQualified());
}
RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) {
@@ -352,8 +351,7 @@ RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) {
assert(!cir::MissingFeatures::armComputeVolatileBitfields());
mlir::Value field = builder.createGetBitfield(
- getLoc(loc), resLTy, ptr.getPointer(), ptr.getElementType(), info,
- lv.isVolatile(), false);
+ getLoc(loc), resLTy, ptr, ptr.getElementType(), info, lv.isVolatile());
assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck() && "NYI");
return RValue::get(field);
}
@@ -366,7 +364,10 @@ Address CIRGenFunction::getAddrOfBitFieldStorage(LValue base,
cir::PointerType fieldPtr = cir::PointerType::get(fieldType);
cir::GetMemberOp sea = getBuilder().createGetMember(
loc, fieldPtr, base.getPointer(), field->getName(), index);
- return Address(sea, CharUnits::One());
+ auto rec = cast<cir::RecordType>(base.getAddress().getElementType());
+ CharUnits offset = CharUnits::fromQuantity(
+ rec.getElementOffset(cgm.getDataLayout().layout, index));
+ return Address(sea, base.getAlignment().alignmentAtOffset(offset));
}
LValue CIRGenFunction::emitLValueForBitField(LValue base,
@@ -662,7 +663,8 @@ LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {
}
case UO_PreInc:
case UO_PreDec: {
- bool isInc = e->isIncrementOp();
+ cir::UnaryOpKind kind =
+ e->isIncrementOp() ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec;
LValue lv = emitLValue(e->getSubExpr());
assert(e->isPrefix() && "Prefix operator in unexpected state!");
@@ -671,7 +673,7 @@ LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {
cgm.errorNYI(e->getSourceRange(), "UnaryOp complex inc/dec");
lv = LValue();
} else {
- emitScalarPrePostIncDec(e, lv, isInc, /*isPre=*/true);
+ emitScalarPrePostIncDec(e, lv, kind, /*isPre=*/true);
}
return lv;
@@ -1053,6 +1055,67 @@ LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {
llvm_unreachable("Unhandled member declaration!");
}
+/// Evaluate an expression into a given memory location.
+void CIRGenFunction::emitAnyExprToMem(const Expr *e, Address location,
+ Qualifiers quals, bool isInit) {
+ // FIXME: This function should take an LValue as an argument.
+ switch (getEvaluationKind(e->getType())) {
+ case cir::TEK_Complex: {
+ LValue lv = makeAddrLValue(location, e->getType());
+ emitComplexExprIntoLValue(e, lv, isInit);
+ return;
+ }
+
+ case cir::TEK_Aggregate: {
+ emitAggExpr(e, AggValueSlot::forAddr(location, quals,
+ AggValueSlot::IsDestructed_t(isInit),
+ AggValueSlot::IsAliased_t(!isInit),
+ AggValueSlot::MayOverlap));
+ return;
+ }
+
+ case cir::TEK_Scalar: {
+ RValue rv = RValue::get(emitScalarExpr(e));
+ LValue lv = makeAddrLValue(location, e->getType());
+ emitStoreThroughLValue(rv, lv);
+ return;
+ }
+ }
+
+ llvm_unreachable("bad evaluation kind");
+}
+
+LValue CIRGenFunction::emitCompoundLiteralLValue(const CompoundLiteralExpr *e) {
+ if (e->isFileScope()) {
+ cgm.errorNYI(e->getSourceRange(), "emitCompoundLiteralLValue: FileScope");
+ return {};
+ }
+
+ if (e->getType()->isVariablyModifiedType()) {
+ cgm.errorNYI(e->getSourceRange(),
+ "emitCompoundLiteralLValue: VariablyModifiedType");
+ return {};
+ }
+
+ Address declPtr = createMemTemp(e->getType(), getLoc(e->getSourceRange()),
+ ".compoundliteral");
+ const Expr *initExpr = e->getInitializer();
+ LValue result = makeAddrLValue(declPtr, e->getType(), AlignmentSource::Decl);
+
+ emitAnyExprToMem(initExpr, declPtr, e->getType().getQualifiers(),
+ /*Init*/ true);
+
+ // Block-scope compound literals are destroyed at the end of the enclosing
+ // scope in C.
+ if (!getLangOpts().CPlusPlus && e->getType().isDestructedType()) {
+ cgm.errorNYI(e->getSourceRange(),
+ "emitCompoundLiteralLValue: non C++ DestructedType");
+ return {};
+ }
+
+ return result;
+}
+
LValue CIRGenFunction::emitCallExprLValue(const CallExpr *e) {
RValue rv = emitCallExpr(e);