@@ -743,6 +743,122 @@ CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
743
743
return lv;
744
744
}
745
745
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
+
746
862
LValue CIRGenFunction::emitMemberExpr (const MemberExpr *e) {
747
863
if (isa<VarDecl>(e->getMemberDecl ())) {
748
864
cgm.errorNYI (e->getSourceRange (), " emitMemberExpr: VarDecl" );
@@ -785,6 +901,21 @@ LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {
785
901
llvm_unreachable (" Unhandled member declaration!" );
786
902
}
787
903
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
+
788
919
LValue CIRGenFunction::emitBinaryOperatorLValue (const BinaryOperator *e) {
789
920
// Comma expressions just emit their LHS then their RHS as an l-value.
790
921
if (e->getOpcode () == BO_Comma) {
@@ -983,10 +1114,14 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
983
1114
}
984
1115
985
1116
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.
990
1125
}
991
1126
992
1127
CIRGenCallee callee = emitCallee (e->getCallee ());
0 commit comments