@@ -743,6 +743,122 @@ CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
743743 return lv;
744744}
745745
746+ // / Casts are never lvalues unless that cast is to a reference type. If the cast
747+ // / is to a reference, we can have the usual lvalue result, otherwise if a cast
748+ // / is needed by the code generator in an lvalue context, then it must mean that
749+ // / we need the address of an aggregate in order to access one of its members.
750+ // / This can happen for all the reasons that casts are permitted with aggregate
751+ // / result, including noop aggregate casts, and cast from scalar to union.
752+ LValue CIRGenFunction::emitCastLValue (const CastExpr *e) {
753+ switch (e->getCastKind ()) {
754+ case CK_ToVoid:
755+ case CK_BitCast:
756+ case CK_LValueToRValueBitCast:
757+ case CK_ArrayToPointerDecay:
758+ case CK_FunctionToPointerDecay:
759+ case CK_NullToMemberPointer:
760+ case CK_NullToPointer:
761+ case CK_IntegralToPointer:
762+ case CK_PointerToIntegral:
763+ case CK_PointerToBoolean:
764+ case CK_IntegralCast:
765+ case CK_BooleanToSignedIntegral:
766+ case CK_IntegralToBoolean:
767+ case CK_IntegralToFloating:
768+ case CK_FloatingToIntegral:
769+ case CK_FloatingToBoolean:
770+ case CK_FloatingCast:
771+ case CK_FloatingRealToComplex:
772+ case CK_FloatingComplexToReal:
773+ case CK_FloatingComplexToBoolean:
774+ case CK_FloatingComplexCast:
775+ case CK_FloatingComplexToIntegralComplex:
776+ case CK_IntegralRealToComplex:
777+ case CK_IntegralComplexToReal:
778+ case CK_IntegralComplexToBoolean:
779+ case CK_IntegralComplexCast:
780+ case CK_IntegralComplexToFloatingComplex:
781+ case CK_DerivedToBaseMemberPointer:
782+ case CK_BaseToDerivedMemberPointer:
783+ case CK_MemberPointerToBoolean:
784+ case CK_ReinterpretMemberPointer:
785+ case CK_AnyPointerToBlockPointerCast:
786+ case CK_ARCProduceObject:
787+ case CK_ARCConsumeObject:
788+ case CK_ARCReclaimReturnedObject:
789+ case CK_ARCExtendBlockObject:
790+ case CK_CopyAndAutoreleaseBlockObject:
791+ case CK_IntToOCLSampler:
792+ case CK_FloatingToFixedPoint:
793+ case CK_FixedPointToFloating:
794+ case CK_FixedPointCast:
795+ case CK_FixedPointToBoolean:
796+ case CK_FixedPointToIntegral:
797+ case CK_IntegralToFixedPoint:
798+ case CK_MatrixCast:
799+ case CK_HLSLVectorTruncation:
800+ case CK_HLSLArrayRValue:
801+ case CK_HLSLElementwiseCast:
802+ case CK_HLSLAggregateSplatCast:
803+ llvm_unreachable (" unexpected cast lvalue" );
804+
805+ case CK_Dependent:
806+ llvm_unreachable (" dependent cast kind in IR gen!" );
807+
808+ case CK_BuiltinFnToFnPtr:
809+ llvm_unreachable (" builtin functions are handled elsewhere" );
810+
811+ // These are never l-values; just use the aggregate emission code.
812+ case CK_NonAtomicToAtomic:
813+ case CK_AtomicToNonAtomic:
814+ case CK_Dynamic:
815+ case CK_UncheckedDerivedToBase:
816+ case CK_DerivedToBase:
817+ case CK_ToUnion:
818+ case CK_BaseToDerived:
819+ case CK_LValueBitCast:
820+ case CK_AddressSpaceConversion:
821+ case CK_ObjCObjectLValueCast:
822+ case CK_VectorSplat:
823+ case CK_ConstructorConversion:
824+ case CK_UserDefinedConversion:
825+ case CK_CPointerToObjCPointerCast:
826+ case CK_BlockPointerToObjCPointerCast:
827+ case CK_LValueToRValue: {
828+ cgm.errorNYI (e->getSourceRange (),
829+ std::string (" emitCastLValue for unhandled cast kind: " ) +
830+ e->getCastKindName ());
831+
832+ return {};
833+ }
834+
835+ case CK_NoOp: {
836+ // CK_NoOp can model a qualification conversion, which can remove an array
837+ // bound and change the IR type.
838+ LValue lv = emitLValue (e->getSubExpr ());
839+ // Propagate the volatile qualifier to LValue, if exists in e.
840+ if (e->changesVolatileQualification ())
841+ cgm.errorNYI (e->getSourceRange (),
842+ " emitCastLValue: NoOp changes volatile qual" );
843+ if (lv.isSimple ()) {
844+ Address v = lv.getAddress ();
845+ if (v.isValid ()) {
846+ mlir::Type ty = convertTypeForMem (e->getType ());
847+ if (v.getElementType () != ty)
848+ cgm.errorNYI (e->getSourceRange (),
849+ " emitCastLValue: NoOp needs bitcast" );
850+ }
851+ }
852+ return lv;
853+ }
854+
855+ case CK_ZeroToOCLOpaqueType:
856+ llvm_unreachable (" NULL to OpenCL opaque type lvalue cast is not valid" );
857+ }
858+
859+ llvm_unreachable (" Invalid cast kind" );
860+ }
861+
746862LValue CIRGenFunction::emitMemberExpr (const MemberExpr *e) {
747863 if (isa<VarDecl>(e->getMemberDecl ())) {
748864 cgm.errorNYI (e->getSourceRange (), " emitMemberExpr: VarDecl" );
@@ -785,6 +901,21 @@ LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {
785901 llvm_unreachable (" Unhandled member declaration!" );
786902}
787903
904+ LValue CIRGenFunction::emitCallExprLValue (const CallExpr *e) {
905+ RValue rv = emitCallExpr (e);
906+
907+ if (!rv.isScalar ()) {
908+ cgm.errorNYI (e->getSourceRange (), " emitCallExprLValue: non-scalar return" );
909+ return {};
910+ }
911+
912+ assert (e->getCallReturnType (getContext ())->isReferenceType () &&
913+ " Can't have a scalar return unless the return type is a "
914+ " reference type!" );
915+
916+ return makeNaturalAlignPointeeAddrLValue (rv.getScalarVal (), e->getType ());
917+ }
918+
788919LValue CIRGenFunction::emitBinaryOperatorLValue (const BinaryOperator *e) {
789920 // Comma expressions just emit their LHS then their RHS as an l-value.
790921 if (e->getOpcode () == BO_Comma) {
@@ -983,10 +1114,14 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
9831114 }
9841115
9851116 if (const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(e)) {
986- if (isa_and_nonnull<CXXMethodDecl>(operatorCall->getCalleeDecl ())) {
987- cgm.errorNYI (e->getSourceRange (), " call to member operator" );
988- return RValue::get (nullptr );
989- }
1117+ // If the callee decl is a CXXMethodDecl, we need to emit this as a C++
1118+ // operator member call.
1119+ if (const CXXMethodDecl *md =
1120+ dyn_cast_or_null<CXXMethodDecl>(operatorCall->getCalleeDecl ()))
1121+ return emitCXXOperatorMemberCallExpr (operatorCall, md, returnValue);
1122+ // A CXXOperatorCallExpr is created even for explicit object methods, but
1123+ // these should be treated like static function calls. Fall through to do
1124+ // that.
9901125 }
9911126
9921127 CIRGenCallee callee = emitCallee (e->getCallee ());
0 commit comments