xref: /freebsd/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenExpr.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric //
9*700637cbSDimitry Andric // This contains code to emit Expr nodes as CIR code.
10*700637cbSDimitry Andric //
11*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
12*700637cbSDimitry Andric 
13*700637cbSDimitry Andric #include "Address.h"
14*700637cbSDimitry Andric #include "CIRGenConstantEmitter.h"
15*700637cbSDimitry Andric #include "CIRGenFunction.h"
16*700637cbSDimitry Andric #include "CIRGenModule.h"
17*700637cbSDimitry Andric #include "CIRGenValue.h"
18*700637cbSDimitry Andric #include "mlir/IR/BuiltinAttributes.h"
19*700637cbSDimitry Andric #include "mlir/IR/Value.h"
20*700637cbSDimitry Andric #include "clang/AST/Attr.h"
21*700637cbSDimitry Andric #include "clang/AST/CharUnits.h"
22*700637cbSDimitry Andric #include "clang/AST/Decl.h"
23*700637cbSDimitry Andric #include "clang/AST/Expr.h"
24*700637cbSDimitry Andric #include "clang/AST/ExprCXX.h"
25*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIRDialect.h"
26*700637cbSDimitry Andric #include "clang/CIR/MissingFeatures.h"
27*700637cbSDimitry Andric #include <optional>
28*700637cbSDimitry Andric 
29*700637cbSDimitry Andric using namespace clang;
30*700637cbSDimitry Andric using namespace clang::CIRGen;
31*700637cbSDimitry Andric using namespace cir;
32*700637cbSDimitry Andric 
33*700637cbSDimitry Andric /// Get the address of a zero-sized field within a record. The resulting address
34*700637cbSDimitry Andric /// doesn't necessarily have the right type.
emitAddrOfFieldStorage(Address base,const FieldDecl * field,llvm::StringRef fieldName,unsigned fieldIndex)35*700637cbSDimitry Andric Address CIRGenFunction::emitAddrOfFieldStorage(Address base,
36*700637cbSDimitry Andric                                                const FieldDecl *field,
37*700637cbSDimitry Andric                                                llvm::StringRef fieldName,
38*700637cbSDimitry Andric                                                unsigned fieldIndex) {
39*700637cbSDimitry Andric   if (field->isZeroSize(getContext())) {
40*700637cbSDimitry Andric     cgm.errorNYI(field->getSourceRange(),
41*700637cbSDimitry Andric                  "emitAddrOfFieldStorage: zero-sized field");
42*700637cbSDimitry Andric     return Address::invalid();
43*700637cbSDimitry Andric   }
44*700637cbSDimitry Andric 
45*700637cbSDimitry Andric   mlir::Location loc = getLoc(field->getLocation());
46*700637cbSDimitry Andric 
47*700637cbSDimitry Andric   mlir::Type fieldType = convertType(field->getType());
48*700637cbSDimitry Andric   auto fieldPtr = cir::PointerType::get(fieldType);
49*700637cbSDimitry Andric   // For most cases fieldName is the same as field->getName() but for lambdas,
50*700637cbSDimitry Andric   // which do not currently carry the name, so it can be passed down from the
51*700637cbSDimitry Andric   // CaptureStmt.
52*700637cbSDimitry Andric   cir::GetMemberOp memberAddr = builder.createGetMember(
53*700637cbSDimitry Andric       loc, fieldPtr, base.getPointer(), fieldName, fieldIndex);
54*700637cbSDimitry Andric 
55*700637cbSDimitry Andric   // Retrieve layout information, compute alignment and return the final
56*700637cbSDimitry Andric   // address.
57*700637cbSDimitry Andric   const RecordDecl *rec = field->getParent();
58*700637cbSDimitry Andric   const CIRGenRecordLayout &layout = cgm.getTypes().getCIRGenRecordLayout(rec);
59*700637cbSDimitry Andric   unsigned idx = layout.getCIRFieldNo(field);
60*700637cbSDimitry Andric   CharUnits offset = CharUnits::fromQuantity(
61*700637cbSDimitry Andric       layout.getCIRType().getElementOffset(cgm.getDataLayout().layout, idx));
62*700637cbSDimitry Andric   return Address(memberAddr, base.getAlignment().alignmentAtOffset(offset));
63*700637cbSDimitry Andric }
64*700637cbSDimitry Andric 
65*700637cbSDimitry Andric /// Given an expression of pointer type, try to
66*700637cbSDimitry Andric /// derive a more accurate bound on the alignment of the pointer.
emitPointerWithAlignment(const Expr * expr,LValueBaseInfo * baseInfo)67*700637cbSDimitry Andric Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
68*700637cbSDimitry Andric                                                  LValueBaseInfo *baseInfo) {
69*700637cbSDimitry Andric   // We allow this with ObjC object pointers because of fragile ABIs.
70*700637cbSDimitry Andric   assert(expr->getType()->isPointerType() ||
71*700637cbSDimitry Andric          expr->getType()->isObjCObjectPointerType());
72*700637cbSDimitry Andric   expr = expr->IgnoreParens();
73*700637cbSDimitry Andric 
74*700637cbSDimitry Andric   // Casts:
75*700637cbSDimitry Andric   if (auto const *ce = dyn_cast<CastExpr>(expr)) {
76*700637cbSDimitry Andric     if (isa<ExplicitCastExpr>(ce)) {
77*700637cbSDimitry Andric       cgm.errorNYI(expr->getSourceRange(),
78*700637cbSDimitry Andric                    "emitPointerWithAlignment: explicit cast");
79*700637cbSDimitry Andric       return Address::invalid();
80*700637cbSDimitry Andric     }
81*700637cbSDimitry Andric 
82*700637cbSDimitry Andric     switch (ce->getCastKind()) {
83*700637cbSDimitry Andric     // Non-converting casts (but not C's implicit conversion from void*).
84*700637cbSDimitry Andric     case CK_BitCast:
85*700637cbSDimitry Andric     case CK_NoOp:
86*700637cbSDimitry Andric     case CK_AddressSpaceConversion: {
87*700637cbSDimitry Andric       cgm.errorNYI(expr->getSourceRange(),
88*700637cbSDimitry Andric                    "emitPointerWithAlignment: noop cast");
89*700637cbSDimitry Andric       return Address::invalid();
90*700637cbSDimitry Andric     } break;
91*700637cbSDimitry Andric 
92*700637cbSDimitry Andric     // Array-to-pointer decay. TODO(cir): BaseInfo and TBAAInfo.
93*700637cbSDimitry Andric     case CK_ArrayToPointerDecay: {
94*700637cbSDimitry Andric       cgm.errorNYI(expr->getSourceRange(),
95*700637cbSDimitry Andric                    "emitPointerWithAlignment: array-to-pointer decay");
96*700637cbSDimitry Andric       return Address::invalid();
97*700637cbSDimitry Andric     }
98*700637cbSDimitry Andric 
99*700637cbSDimitry Andric     case CK_UncheckedDerivedToBase:
100*700637cbSDimitry Andric     case CK_DerivedToBase: {
101*700637cbSDimitry Andric       assert(!cir::MissingFeatures::opTBAA());
102*700637cbSDimitry Andric       assert(!cir::MissingFeatures::addressIsKnownNonNull());
103*700637cbSDimitry Andric       Address addr = emitPointerWithAlignment(ce->getSubExpr(), baseInfo);
104*700637cbSDimitry Andric       const CXXRecordDecl *derived =
105*700637cbSDimitry Andric           ce->getSubExpr()->getType()->getPointeeCXXRecordDecl();
106*700637cbSDimitry Andric       return getAddressOfBaseClass(addr, derived, ce->path(),
107*700637cbSDimitry Andric                                    shouldNullCheckClassCastValue(ce),
108*700637cbSDimitry Andric                                    ce->getExprLoc());
109*700637cbSDimitry Andric     }
110*700637cbSDimitry Andric 
111*700637cbSDimitry Andric     case CK_AnyPointerToBlockPointerCast:
112*700637cbSDimitry Andric     case CK_BaseToDerived:
113*700637cbSDimitry Andric     case CK_BaseToDerivedMemberPointer:
114*700637cbSDimitry Andric     case CK_BlockPointerToObjCPointerCast:
115*700637cbSDimitry Andric     case CK_BuiltinFnToFnPtr:
116*700637cbSDimitry Andric     case CK_CPointerToObjCPointerCast:
117*700637cbSDimitry Andric     case CK_DerivedToBaseMemberPointer:
118*700637cbSDimitry Andric     case CK_Dynamic:
119*700637cbSDimitry Andric     case CK_FunctionToPointerDecay:
120*700637cbSDimitry Andric     case CK_IntegralToPointer:
121*700637cbSDimitry Andric     case CK_LValueToRValue:
122*700637cbSDimitry Andric     case CK_LValueToRValueBitCast:
123*700637cbSDimitry Andric     case CK_NullToMemberPointer:
124*700637cbSDimitry Andric     case CK_NullToPointer:
125*700637cbSDimitry Andric     case CK_ReinterpretMemberPointer:
126*700637cbSDimitry Andric       // Common pointer conversions, nothing to do here.
127*700637cbSDimitry Andric       // TODO: Is there any reason to treat base-to-derived conversions
128*700637cbSDimitry Andric       // specially?
129*700637cbSDimitry Andric       break;
130*700637cbSDimitry Andric 
131*700637cbSDimitry Andric     case CK_ARCConsumeObject:
132*700637cbSDimitry Andric     case CK_ARCExtendBlockObject:
133*700637cbSDimitry Andric     case CK_ARCProduceObject:
134*700637cbSDimitry Andric     case CK_ARCReclaimReturnedObject:
135*700637cbSDimitry Andric     case CK_AtomicToNonAtomic:
136*700637cbSDimitry Andric     case CK_BooleanToSignedIntegral:
137*700637cbSDimitry Andric     case CK_ConstructorConversion:
138*700637cbSDimitry Andric     case CK_CopyAndAutoreleaseBlockObject:
139*700637cbSDimitry Andric     case CK_Dependent:
140*700637cbSDimitry Andric     case CK_FixedPointCast:
141*700637cbSDimitry Andric     case CK_FixedPointToBoolean:
142*700637cbSDimitry Andric     case CK_FixedPointToFloating:
143*700637cbSDimitry Andric     case CK_FixedPointToIntegral:
144*700637cbSDimitry Andric     case CK_FloatingCast:
145*700637cbSDimitry Andric     case CK_FloatingComplexCast:
146*700637cbSDimitry Andric     case CK_FloatingComplexToBoolean:
147*700637cbSDimitry Andric     case CK_FloatingComplexToIntegralComplex:
148*700637cbSDimitry Andric     case CK_FloatingComplexToReal:
149*700637cbSDimitry Andric     case CK_FloatingRealToComplex:
150*700637cbSDimitry Andric     case CK_FloatingToBoolean:
151*700637cbSDimitry Andric     case CK_FloatingToFixedPoint:
152*700637cbSDimitry Andric     case CK_FloatingToIntegral:
153*700637cbSDimitry Andric     case CK_HLSLAggregateSplatCast:
154*700637cbSDimitry Andric     case CK_HLSLArrayRValue:
155*700637cbSDimitry Andric     case CK_HLSLElementwiseCast:
156*700637cbSDimitry Andric     case CK_HLSLVectorTruncation:
157*700637cbSDimitry Andric     case CK_IntToOCLSampler:
158*700637cbSDimitry Andric     case CK_IntegralCast:
159*700637cbSDimitry Andric     case CK_IntegralComplexCast:
160*700637cbSDimitry Andric     case CK_IntegralComplexToBoolean:
161*700637cbSDimitry Andric     case CK_IntegralComplexToFloatingComplex:
162*700637cbSDimitry Andric     case CK_IntegralComplexToReal:
163*700637cbSDimitry Andric     case CK_IntegralRealToComplex:
164*700637cbSDimitry Andric     case CK_IntegralToBoolean:
165*700637cbSDimitry Andric     case CK_IntegralToFixedPoint:
166*700637cbSDimitry Andric     case CK_IntegralToFloating:
167*700637cbSDimitry Andric     case CK_LValueBitCast:
168*700637cbSDimitry Andric     case CK_MatrixCast:
169*700637cbSDimitry Andric     case CK_MemberPointerToBoolean:
170*700637cbSDimitry Andric     case CK_NonAtomicToAtomic:
171*700637cbSDimitry Andric     case CK_ObjCObjectLValueCast:
172*700637cbSDimitry Andric     case CK_PointerToBoolean:
173*700637cbSDimitry Andric     case CK_PointerToIntegral:
174*700637cbSDimitry Andric     case CK_ToUnion:
175*700637cbSDimitry Andric     case CK_ToVoid:
176*700637cbSDimitry Andric     case CK_UserDefinedConversion:
177*700637cbSDimitry Andric     case CK_VectorSplat:
178*700637cbSDimitry Andric     case CK_ZeroToOCLOpaqueType:
179*700637cbSDimitry Andric       llvm_unreachable("unexpected cast for emitPointerWithAlignment");
180*700637cbSDimitry Andric     }
181*700637cbSDimitry Andric   }
182*700637cbSDimitry Andric 
183*700637cbSDimitry Andric   // Unary &
184*700637cbSDimitry Andric   if (const UnaryOperator *uo = dyn_cast<UnaryOperator>(expr)) {
185*700637cbSDimitry Andric     // TODO(cir): maybe we should use cir.unary for pointers here instead.
186*700637cbSDimitry Andric     if (uo->getOpcode() == UO_AddrOf) {
187*700637cbSDimitry Andric       cgm.errorNYI(expr->getSourceRange(), "emitPointerWithAlignment: unary &");
188*700637cbSDimitry Andric       return Address::invalid();
189*700637cbSDimitry Andric     }
190*700637cbSDimitry Andric   }
191*700637cbSDimitry Andric 
192*700637cbSDimitry Andric   // std::addressof and variants.
193*700637cbSDimitry Andric   if (auto const *call = dyn_cast<CallExpr>(expr)) {
194*700637cbSDimitry Andric     switch (call->getBuiltinCallee()) {
195*700637cbSDimitry Andric     default:
196*700637cbSDimitry Andric       break;
197*700637cbSDimitry Andric     case Builtin::BIaddressof:
198*700637cbSDimitry Andric     case Builtin::BI__addressof:
199*700637cbSDimitry Andric     case Builtin::BI__builtin_addressof: {
200*700637cbSDimitry Andric       cgm.errorNYI(expr->getSourceRange(),
201*700637cbSDimitry Andric                    "emitPointerWithAlignment: builtin addressof");
202*700637cbSDimitry Andric       return Address::invalid();
203*700637cbSDimitry Andric     }
204*700637cbSDimitry Andric     }
205*700637cbSDimitry Andric   }
206*700637cbSDimitry Andric 
207*700637cbSDimitry Andric   // Otherwise, use the alignment of the type.
208*700637cbSDimitry Andric   return makeNaturalAddressForPointer(
209*700637cbSDimitry Andric       emitScalarExpr(expr), expr->getType()->getPointeeType(), CharUnits(),
210*700637cbSDimitry Andric       /*forPointeeType=*/true, baseInfo);
211*700637cbSDimitry Andric }
212*700637cbSDimitry Andric 
emitStoreThroughLValue(RValue src,LValue dst,bool isInit)213*700637cbSDimitry Andric void CIRGenFunction::emitStoreThroughLValue(RValue src, LValue dst,
214*700637cbSDimitry Andric                                             bool isInit) {
215*700637cbSDimitry Andric   if (!dst.isSimple()) {
216*700637cbSDimitry Andric     if (dst.isVectorElt()) {
217*700637cbSDimitry Andric       // Read/modify/write the vector, inserting the new element
218*700637cbSDimitry Andric       const mlir::Location loc = dst.getVectorPointer().getLoc();
219*700637cbSDimitry Andric       const mlir::Value vector =
220*700637cbSDimitry Andric           builder.createLoad(loc, dst.getVectorAddress());
221*700637cbSDimitry Andric       const mlir::Value newVector = builder.create<cir::VecInsertOp>(
222*700637cbSDimitry Andric           loc, vector, src.getValue(), dst.getVectorIdx());
223*700637cbSDimitry Andric       builder.createStore(loc, newVector, dst.getVectorAddress());
224*700637cbSDimitry Andric       return;
225*700637cbSDimitry Andric     }
226*700637cbSDimitry Andric 
227*700637cbSDimitry Andric     assert(dst.isBitField() && "Unknown LValue type");
228*700637cbSDimitry Andric     emitStoreThroughBitfieldLValue(src, dst);
229*700637cbSDimitry Andric     return;
230*700637cbSDimitry Andric 
231*700637cbSDimitry Andric     cgm.errorNYI(dst.getPointer().getLoc(),
232*700637cbSDimitry Andric                  "emitStoreThroughLValue: non-simple lvalue");
233*700637cbSDimitry Andric     return;
234*700637cbSDimitry Andric   }
235*700637cbSDimitry Andric 
236*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opLoadStoreObjC());
237*700637cbSDimitry Andric 
238*700637cbSDimitry Andric   assert(src.isScalar() && "Can't emit an aggregate store with this method");
239*700637cbSDimitry Andric   emitStoreOfScalar(src.getValue(), dst, isInit);
240*700637cbSDimitry Andric }
241*700637cbSDimitry Andric 
emitGlobalVarDeclLValue(CIRGenFunction & cgf,const Expr * e,const VarDecl * vd)242*700637cbSDimitry Andric static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e,
243*700637cbSDimitry Andric                                       const VarDecl *vd) {
244*700637cbSDimitry Andric   QualType t = e->getType();
245*700637cbSDimitry Andric 
246*700637cbSDimitry Andric   // If it's thread_local, emit a call to its wrapper function instead.
247*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opGlobalThreadLocal());
248*700637cbSDimitry Andric   if (vd->getTLSKind() == VarDecl::TLS_Dynamic)
249*700637cbSDimitry Andric     cgf.cgm.errorNYI(e->getSourceRange(),
250*700637cbSDimitry Andric                      "emitGlobalVarDeclLValue: thread_local variable");
251*700637cbSDimitry Andric 
252*700637cbSDimitry Andric   // Check if the variable is marked as declare target with link clause in
253*700637cbSDimitry Andric   // device codegen.
254*700637cbSDimitry Andric   if (cgf.getLangOpts().OpenMP)
255*700637cbSDimitry Andric     cgf.cgm.errorNYI(e->getSourceRange(), "emitGlobalVarDeclLValue: OpenMP");
256*700637cbSDimitry Andric 
257*700637cbSDimitry Andric   // Traditional LLVM codegen handles thread local separately, CIR handles
258*700637cbSDimitry Andric   // as part of getAddrOfGlobalVar.
259*700637cbSDimitry Andric   mlir::Value v = cgf.cgm.getAddrOfGlobalVar(vd);
260*700637cbSDimitry Andric 
261*700637cbSDimitry Andric   assert(!cir::MissingFeatures::addressSpace());
262*700637cbSDimitry Andric   mlir::Type realVarTy = cgf.convertTypeForMem(vd->getType());
263*700637cbSDimitry Andric   cir::PointerType realPtrTy = cgf.getBuilder().getPointerTo(realVarTy);
264*700637cbSDimitry Andric   if (realPtrTy != v.getType())
265*700637cbSDimitry Andric     v = cgf.getBuilder().createBitcast(v.getLoc(), v, realPtrTy);
266*700637cbSDimitry Andric 
267*700637cbSDimitry Andric   CharUnits alignment = cgf.getContext().getDeclAlign(vd);
268*700637cbSDimitry Andric   Address addr(v, realVarTy, alignment);
269*700637cbSDimitry Andric   LValue lv;
270*700637cbSDimitry Andric   if (vd->getType()->isReferenceType())
271*700637cbSDimitry Andric     cgf.cgm.errorNYI(e->getSourceRange(),
272*700637cbSDimitry Andric                      "emitGlobalVarDeclLValue: reference type");
273*700637cbSDimitry Andric   else
274*700637cbSDimitry Andric     lv = cgf.makeAddrLValue(addr, t, AlignmentSource::Decl);
275*700637cbSDimitry Andric   assert(!cir::MissingFeatures::setObjCGCLValueClass());
276*700637cbSDimitry Andric   return lv;
277*700637cbSDimitry Andric }
278*700637cbSDimitry Andric 
emitStoreOfScalar(mlir::Value value,Address addr,bool isVolatile,QualType ty,bool isInit,bool isNontemporal)279*700637cbSDimitry Andric void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
280*700637cbSDimitry Andric                                        bool isVolatile, QualType ty,
281*700637cbSDimitry Andric                                        bool isInit, bool isNontemporal) {
282*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
283*700637cbSDimitry Andric 
284*700637cbSDimitry Andric   if (const auto *clangVecTy = ty->getAs<clang::VectorType>()) {
285*700637cbSDimitry Andric     // Boolean vectors use `iN` as storage type.
286*700637cbSDimitry Andric     if (clangVecTy->isExtVectorBoolType())
287*700637cbSDimitry Andric       cgm.errorNYI(addr.getPointer().getLoc(),
288*700637cbSDimitry Andric                    "emitStoreOfScalar ExtVectorBoolType");
289*700637cbSDimitry Andric 
290*700637cbSDimitry Andric     // Handle vectors of size 3 like size 4 for better performance.
291*700637cbSDimitry Andric     const mlir::Type elementType = addr.getElementType();
292*700637cbSDimitry Andric     const auto vecTy = cast<cir::VectorType>(elementType);
293*700637cbSDimitry Andric 
294*700637cbSDimitry Andric     // TODO(CIR): Use `ABIInfo::getOptimalVectorMemoryType` once it upstreamed
295*700637cbSDimitry Andric     if (vecTy.getSize() == 3 && !getLangOpts().PreserveVec3Type)
296*700637cbSDimitry Andric       cgm.errorNYI(addr.getPointer().getLoc(),
297*700637cbSDimitry Andric                    "emitStoreOfScalar Vec3 & PreserveVec3Type disabled");
298*700637cbSDimitry Andric   }
299*700637cbSDimitry Andric 
300*700637cbSDimitry Andric   value = emitToMemory(value, ty);
301*700637cbSDimitry Andric 
302*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opLoadStoreAtomic());
303*700637cbSDimitry Andric 
304*700637cbSDimitry Andric   // Update the alloca with more info on initialization.
305*700637cbSDimitry Andric   assert(addr.getPointer() && "expected pointer to exist");
306*700637cbSDimitry Andric   auto srcAlloca =
307*700637cbSDimitry Andric       dyn_cast_or_null<cir::AllocaOp>(addr.getPointer().getDefiningOp());
308*700637cbSDimitry Andric   if (currVarDecl && srcAlloca) {
309*700637cbSDimitry Andric     const VarDecl *vd = currVarDecl;
310*700637cbSDimitry Andric     assert(vd && "VarDecl expected");
311*700637cbSDimitry Andric     if (vd->hasInit())
312*700637cbSDimitry Andric       srcAlloca.setInitAttr(mlir::UnitAttr::get(&getMLIRContext()));
313*700637cbSDimitry Andric   }
314*700637cbSDimitry Andric 
315*700637cbSDimitry Andric   assert(currSrcLoc && "must pass in source location");
316*700637cbSDimitry Andric   builder.createStore(*currSrcLoc, value, addr /*, isVolatile*/);
317*700637cbSDimitry Andric 
318*700637cbSDimitry Andric   if (isNontemporal) {
319*700637cbSDimitry Andric     cgm.errorNYI(addr.getPointer().getLoc(), "emitStoreOfScalar nontemporal");
320*700637cbSDimitry Andric     return;
321*700637cbSDimitry Andric   }
322*700637cbSDimitry Andric 
323*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opTBAA());
324*700637cbSDimitry Andric }
325*700637cbSDimitry Andric 
emitStoreThroughBitfieldLValue(RValue src,LValue dst)326*700637cbSDimitry Andric mlir::Value CIRGenFunction::emitStoreThroughBitfieldLValue(RValue src,
327*700637cbSDimitry Andric                                                            LValue dst) {
328*700637cbSDimitry Andric 
329*700637cbSDimitry Andric   assert(!cir::MissingFeatures::armComputeVolatileBitfields());
330*700637cbSDimitry Andric 
331*700637cbSDimitry Andric   const CIRGenBitFieldInfo &info = dst.getBitFieldInfo();
332*700637cbSDimitry Andric   mlir::Type resLTy = convertTypeForMem(dst.getType());
333*700637cbSDimitry Andric   Address ptr = dst.getBitFieldAddress();
334*700637cbSDimitry Andric 
335*700637cbSDimitry Andric   assert(!cir::MissingFeatures::armComputeVolatileBitfields());
336*700637cbSDimitry Andric   const bool useVolatile = false;
337*700637cbSDimitry Andric 
338*700637cbSDimitry Andric   mlir::Value dstAddr = dst.getAddress().getPointer();
339*700637cbSDimitry Andric 
340*700637cbSDimitry Andric   return builder.createSetBitfield(dstAddr.getLoc(), resLTy, dstAddr,
341*700637cbSDimitry Andric                                    ptr.getElementType(), src.getValue(), info,
342*700637cbSDimitry Andric                                    dst.isVolatileQualified(), useVolatile);
343*700637cbSDimitry Andric }
344*700637cbSDimitry Andric 
emitLoadOfBitfieldLValue(LValue lv,SourceLocation loc)345*700637cbSDimitry Andric RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) {
346*700637cbSDimitry Andric   const CIRGenBitFieldInfo &info = lv.getBitFieldInfo();
347*700637cbSDimitry Andric 
348*700637cbSDimitry Andric   // Get the output type.
349*700637cbSDimitry Andric   mlir::Type resLTy = convertType(lv.getType());
350*700637cbSDimitry Andric   Address ptr = lv.getBitFieldAddress();
351*700637cbSDimitry Andric 
352*700637cbSDimitry Andric   assert(!cir::MissingFeatures::armComputeVolatileBitfields());
353*700637cbSDimitry Andric 
354*700637cbSDimitry Andric   mlir::Value field = builder.createGetBitfield(
355*700637cbSDimitry Andric       getLoc(loc), resLTy, ptr.getPointer(), ptr.getElementType(), info,
356*700637cbSDimitry Andric       lv.isVolatile(), false);
357*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck() && "NYI");
358*700637cbSDimitry Andric   return RValue::get(field);
359*700637cbSDimitry Andric }
360*700637cbSDimitry Andric 
getAddrOfBitFieldStorage(LValue base,const FieldDecl * field,mlir::Type fieldType,unsigned index)361*700637cbSDimitry Andric Address CIRGenFunction::getAddrOfBitFieldStorage(LValue base,
362*700637cbSDimitry Andric                                                  const FieldDecl *field,
363*700637cbSDimitry Andric                                                  mlir::Type fieldType,
364*700637cbSDimitry Andric                                                  unsigned index) {
365*700637cbSDimitry Andric   mlir::Location loc = getLoc(field->getLocation());
366*700637cbSDimitry Andric   cir::PointerType fieldPtr = cir::PointerType::get(fieldType);
367*700637cbSDimitry Andric   cir::GetMemberOp sea = getBuilder().createGetMember(
368*700637cbSDimitry Andric       loc, fieldPtr, base.getPointer(), field->getName(), index);
369*700637cbSDimitry Andric   return Address(sea, CharUnits::One());
370*700637cbSDimitry Andric }
371*700637cbSDimitry Andric 
emitLValueForBitField(LValue base,const FieldDecl * field)372*700637cbSDimitry Andric LValue CIRGenFunction::emitLValueForBitField(LValue base,
373*700637cbSDimitry Andric                                              const FieldDecl *field) {
374*700637cbSDimitry Andric   LValueBaseInfo baseInfo = base.getBaseInfo();
375*700637cbSDimitry Andric   const CIRGenRecordLayout &layout =
376*700637cbSDimitry Andric       cgm.getTypes().getCIRGenRecordLayout(field->getParent());
377*700637cbSDimitry Andric   const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);
378*700637cbSDimitry Andric   assert(!cir::MissingFeatures::armComputeVolatileBitfields());
379*700637cbSDimitry Andric   assert(!cir::MissingFeatures::preservedAccessIndexRegion());
380*700637cbSDimitry Andric   unsigned idx = layout.getCIRFieldNo(field);
381*700637cbSDimitry Andric 
382*700637cbSDimitry Andric   Address addr = getAddrOfBitFieldStorage(base, field, info.storageType, idx);
383*700637cbSDimitry Andric 
384*700637cbSDimitry Andric   mlir::Location loc = getLoc(field->getLocation());
385*700637cbSDimitry Andric   if (addr.getElementType() != info.storageType)
386*700637cbSDimitry Andric     addr = builder.createElementBitCast(loc, addr, info.storageType);
387*700637cbSDimitry Andric 
388*700637cbSDimitry Andric   QualType fieldType =
389*700637cbSDimitry Andric       field->getType().withCVRQualifiers(base.getVRQualifiers());
390*700637cbSDimitry Andric   // TODO(cir): Support TBAA for bit fields.
391*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opTBAA());
392*700637cbSDimitry Andric   LValueBaseInfo fieldBaseInfo(baseInfo.getAlignmentSource());
393*700637cbSDimitry Andric   return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo);
394*700637cbSDimitry Andric }
395*700637cbSDimitry Andric 
emitLValueForField(LValue base,const FieldDecl * field)396*700637cbSDimitry Andric LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
397*700637cbSDimitry Andric   LValueBaseInfo baseInfo = base.getBaseInfo();
398*700637cbSDimitry Andric 
399*700637cbSDimitry Andric   if (field->isBitField())
400*700637cbSDimitry Andric     return emitLValueForBitField(base, field);
401*700637cbSDimitry Andric 
402*700637cbSDimitry Andric   QualType fieldType = field->getType();
403*700637cbSDimitry Andric   const RecordDecl *rec = field->getParent();
404*700637cbSDimitry Andric   AlignmentSource baseAlignSource = baseInfo.getAlignmentSource();
405*700637cbSDimitry Andric   LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(baseAlignSource));
406*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opTBAA());
407*700637cbSDimitry Andric 
408*700637cbSDimitry Andric   Address addr = base.getAddress();
409*700637cbSDimitry Andric   if (auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {
410*700637cbSDimitry Andric     if (cgm.getCodeGenOpts().StrictVTablePointers &&
411*700637cbSDimitry Andric         classDecl->isDynamicClass()) {
412*700637cbSDimitry Andric       cgm.errorNYI(field->getSourceRange(),
413*700637cbSDimitry Andric                    "emitLValueForField: strict vtable for dynamic class");
414*700637cbSDimitry Andric     }
415*700637cbSDimitry Andric   }
416*700637cbSDimitry Andric 
417*700637cbSDimitry Andric   unsigned recordCVR = base.getVRQualifiers();
418*700637cbSDimitry Andric 
419*700637cbSDimitry Andric   llvm::StringRef fieldName = field->getName();
420*700637cbSDimitry Andric   unsigned fieldIndex;
421*700637cbSDimitry Andric   assert(!cir::MissingFeatures::lambdaFieldToName());
422*700637cbSDimitry Andric 
423*700637cbSDimitry Andric   if (rec->isUnion())
424*700637cbSDimitry Andric     fieldIndex = field->getFieldIndex();
425*700637cbSDimitry Andric   else {
426*700637cbSDimitry Andric     const CIRGenRecordLayout &layout =
427*700637cbSDimitry Andric         cgm.getTypes().getCIRGenRecordLayout(field->getParent());
428*700637cbSDimitry Andric     fieldIndex = layout.getCIRFieldNo(field);
429*700637cbSDimitry Andric   }
430*700637cbSDimitry Andric 
431*700637cbSDimitry Andric   addr = emitAddrOfFieldStorage(addr, field, fieldName, fieldIndex);
432*700637cbSDimitry Andric   assert(!cir::MissingFeatures::preservedAccessIndexRegion());
433*700637cbSDimitry Andric 
434*700637cbSDimitry Andric   // If this is a reference field, load the reference right now.
435*700637cbSDimitry Andric   if (fieldType->isReferenceType()) {
436*700637cbSDimitry Andric     cgm.errorNYI(field->getSourceRange(), "emitLValueForField: reference type");
437*700637cbSDimitry Andric     return LValue();
438*700637cbSDimitry Andric   }
439*700637cbSDimitry Andric 
440*700637cbSDimitry Andric   if (field->hasAttr<AnnotateAttr>()) {
441*700637cbSDimitry Andric     cgm.errorNYI(field->getSourceRange(), "emitLValueForField: AnnotateAttr");
442*700637cbSDimitry Andric     return LValue();
443*700637cbSDimitry Andric   }
444*700637cbSDimitry Andric 
445*700637cbSDimitry Andric   LValue lv = makeAddrLValue(addr, fieldType, fieldBaseInfo);
446*700637cbSDimitry Andric   lv.getQuals().addCVRQualifiers(recordCVR);
447*700637cbSDimitry Andric 
448*700637cbSDimitry Andric   // __weak attribute on a field is ignored.
449*700637cbSDimitry Andric   if (lv.getQuals().getObjCGCAttr() == Qualifiers::Weak) {
450*700637cbSDimitry Andric     cgm.errorNYI(field->getSourceRange(),
451*700637cbSDimitry Andric                  "emitLValueForField: __weak attribute");
452*700637cbSDimitry Andric     return LValue();
453*700637cbSDimitry Andric   }
454*700637cbSDimitry Andric 
455*700637cbSDimitry Andric   return lv;
456*700637cbSDimitry Andric }
457*700637cbSDimitry Andric 
emitLValueForFieldInitialization(LValue base,const clang::FieldDecl * field,llvm::StringRef fieldName)458*700637cbSDimitry Andric LValue CIRGenFunction::emitLValueForFieldInitialization(
459*700637cbSDimitry Andric     LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName) {
460*700637cbSDimitry Andric   QualType fieldType = field->getType();
461*700637cbSDimitry Andric 
462*700637cbSDimitry Andric   if (!fieldType->isReferenceType())
463*700637cbSDimitry Andric     return emitLValueForField(base, field);
464*700637cbSDimitry Andric 
465*700637cbSDimitry Andric   const CIRGenRecordLayout &layout =
466*700637cbSDimitry Andric       cgm.getTypes().getCIRGenRecordLayout(field->getParent());
467*700637cbSDimitry Andric   unsigned fieldIndex = layout.getCIRFieldNo(field);
468*700637cbSDimitry Andric 
469*700637cbSDimitry Andric   Address v =
470*700637cbSDimitry Andric       emitAddrOfFieldStorage(base.getAddress(), field, fieldName, fieldIndex);
471*700637cbSDimitry Andric 
472*700637cbSDimitry Andric   // Make sure that the address is pointing to the right type.
473*700637cbSDimitry Andric   mlir::Type memTy = convertTypeForMem(fieldType);
474*700637cbSDimitry Andric   v = builder.createElementBitCast(getLoc(field->getSourceRange()), v, memTy);
475*700637cbSDimitry Andric 
476*700637cbSDimitry Andric   // TODO: Generate TBAA information that describes this access as a structure
477*700637cbSDimitry Andric   // member access and not just an access to an object of the field's type. This
478*700637cbSDimitry Andric   // should be similar to what we do in EmitLValueForField().
479*700637cbSDimitry Andric   LValueBaseInfo baseInfo = base.getBaseInfo();
480*700637cbSDimitry Andric   AlignmentSource fieldAlignSource = baseInfo.getAlignmentSource();
481*700637cbSDimitry Andric   LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(fieldAlignSource));
482*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opTBAA());
483*700637cbSDimitry Andric   return makeAddrLValue(v, fieldType, fieldBaseInfo);
484*700637cbSDimitry Andric }
485*700637cbSDimitry Andric 
emitToMemory(mlir::Value value,QualType ty)486*700637cbSDimitry Andric mlir::Value CIRGenFunction::emitToMemory(mlir::Value value, QualType ty) {
487*700637cbSDimitry Andric   // Bool has a different representation in memory than in registers,
488*700637cbSDimitry Andric   // but in ClangIR, it is simply represented as a cir.bool value.
489*700637cbSDimitry Andric   // This function is here as a placeholder for possible future changes.
490*700637cbSDimitry Andric   return value;
491*700637cbSDimitry Andric }
492*700637cbSDimitry Andric 
emitStoreOfScalar(mlir::Value value,LValue lvalue,bool isInit)493*700637cbSDimitry Andric void CIRGenFunction::emitStoreOfScalar(mlir::Value value, LValue lvalue,
494*700637cbSDimitry Andric                                        bool isInit) {
495*700637cbSDimitry Andric   if (lvalue.getType()->isConstantMatrixType()) {
496*700637cbSDimitry Andric     assert(0 && "NYI: emitStoreOfScalar constant matrix type");
497*700637cbSDimitry Andric     return;
498*700637cbSDimitry Andric   }
499*700637cbSDimitry Andric 
500*700637cbSDimitry Andric   emitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
501*700637cbSDimitry Andric                     lvalue.getType(), isInit, /*isNontemporal=*/false);
502*700637cbSDimitry Andric }
503*700637cbSDimitry Andric 
emitLoadOfScalar(LValue lvalue,SourceLocation loc)504*700637cbSDimitry Andric mlir::Value CIRGenFunction::emitLoadOfScalar(LValue lvalue,
505*700637cbSDimitry Andric                                              SourceLocation loc) {
506*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
507*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck());
508*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opLoadBooleanRepresentation());
509*700637cbSDimitry Andric 
510*700637cbSDimitry Andric   Address addr = lvalue.getAddress();
511*700637cbSDimitry Andric   mlir::Type eltTy = addr.getElementType();
512*700637cbSDimitry Andric 
513*700637cbSDimitry Andric   if (mlir::isa<cir::VoidType>(eltTy))
514*700637cbSDimitry Andric     cgm.errorNYI(loc, "emitLoadOfScalar: void type");
515*700637cbSDimitry Andric 
516*700637cbSDimitry Andric   mlir::Value loadOp = builder.createLoad(getLoc(loc), addr);
517*700637cbSDimitry Andric 
518*700637cbSDimitry Andric   return loadOp;
519*700637cbSDimitry Andric }
520*700637cbSDimitry Andric 
521*700637cbSDimitry Andric /// Given an expression that represents a value lvalue, this
522*700637cbSDimitry Andric /// method emits the address of the lvalue, then loads the result as an rvalue,
523*700637cbSDimitry Andric /// returning the rvalue.
emitLoadOfLValue(LValue lv,SourceLocation loc)524*700637cbSDimitry Andric RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) {
525*700637cbSDimitry Andric   assert(!lv.getType()->isFunctionType());
526*700637cbSDimitry Andric   assert(!(lv.getType()->isConstantMatrixType()) && "not implemented");
527*700637cbSDimitry Andric 
528*700637cbSDimitry Andric   if (lv.isBitField())
529*700637cbSDimitry Andric     return emitLoadOfBitfieldLValue(lv, loc);
530*700637cbSDimitry Andric 
531*700637cbSDimitry Andric   if (lv.isSimple())
532*700637cbSDimitry Andric     return RValue::get(emitLoadOfScalar(lv, loc));
533*700637cbSDimitry Andric 
534*700637cbSDimitry Andric   if (lv.isVectorElt()) {
535*700637cbSDimitry Andric     const mlir::Value load =
536*700637cbSDimitry Andric         builder.createLoad(getLoc(loc), lv.getVectorAddress());
537*700637cbSDimitry Andric     return RValue::get(builder.create<cir::VecExtractOp>(getLoc(loc), load,
538*700637cbSDimitry Andric                                                          lv.getVectorIdx()));
539*700637cbSDimitry Andric   }
540*700637cbSDimitry Andric 
541*700637cbSDimitry Andric   cgm.errorNYI(loc, "emitLoadOfLValue");
542*700637cbSDimitry Andric   return RValue::get(nullptr);
543*700637cbSDimitry Andric }
544*700637cbSDimitry Andric 
emitDeclRefLValue(const DeclRefExpr * e)545*700637cbSDimitry Andric LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) {
546*700637cbSDimitry Andric   const NamedDecl *nd = e->getDecl();
547*700637cbSDimitry Andric   QualType ty = e->getType();
548*700637cbSDimitry Andric 
549*700637cbSDimitry Andric   assert(e->isNonOdrUse() != NOUR_Unevaluated &&
550*700637cbSDimitry Andric          "should not emit an unevaluated operand");
551*700637cbSDimitry Andric 
552*700637cbSDimitry Andric   if (const auto *vd = dyn_cast<VarDecl>(nd)) {
553*700637cbSDimitry Andric     // Checks for omitted feature handling
554*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opAllocaStaticLocal());
555*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opAllocaNonGC());
556*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opAllocaImpreciseLifetime());
557*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opAllocaTLS());
558*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opAllocaOpenMPThreadPrivate());
559*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opAllocaEscapeByReference());
560*700637cbSDimitry Andric 
561*700637cbSDimitry Andric     // Check if this is a global variable
562*700637cbSDimitry Andric     if (vd->hasLinkage() || vd->isStaticDataMember())
563*700637cbSDimitry Andric       return emitGlobalVarDeclLValue(*this, e, vd);
564*700637cbSDimitry Andric 
565*700637cbSDimitry Andric     Address addr = Address::invalid();
566*700637cbSDimitry Andric 
567*700637cbSDimitry Andric     // The variable should generally be present in the local decl map.
568*700637cbSDimitry Andric     auto iter = localDeclMap.find(vd);
569*700637cbSDimitry Andric     if (iter != localDeclMap.end()) {
570*700637cbSDimitry Andric       addr = iter->second;
571*700637cbSDimitry Andric     } else {
572*700637cbSDimitry Andric       // Otherwise, it might be static local we haven't emitted yet for some
573*700637cbSDimitry Andric       // reason; most likely, because it's in an outer function.
574*700637cbSDimitry Andric       cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: static local");
575*700637cbSDimitry Andric     }
576*700637cbSDimitry Andric 
577*700637cbSDimitry Andric     // Drill into reference types.
578*700637cbSDimitry Andric     LValue lv =
579*700637cbSDimitry Andric         vd->getType()->isReferenceType()
580*700637cbSDimitry Andric             ? emitLoadOfReferenceLValue(addr, getLoc(e->getSourceRange()),
581*700637cbSDimitry Andric                                         vd->getType(), AlignmentSource::Decl)
582*700637cbSDimitry Andric             : makeAddrLValue(addr, ty, AlignmentSource::Decl);
583*700637cbSDimitry Andric     return lv;
584*700637cbSDimitry Andric   }
585*700637cbSDimitry Andric 
586*700637cbSDimitry Andric   cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: unhandled decl type");
587*700637cbSDimitry Andric   return LValue();
588*700637cbSDimitry Andric }
589*700637cbSDimitry Andric 
evaluateExprAsBool(const Expr * e)590*700637cbSDimitry Andric mlir::Value CIRGenFunction::evaluateExprAsBool(const Expr *e) {
591*700637cbSDimitry Andric   QualType boolTy = getContext().BoolTy;
592*700637cbSDimitry Andric   SourceLocation loc = e->getExprLoc();
593*700637cbSDimitry Andric 
594*700637cbSDimitry Andric   assert(!cir::MissingFeatures::pgoUse());
595*700637cbSDimitry Andric   if (e->getType()->getAs<MemberPointerType>()) {
596*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(),
597*700637cbSDimitry Andric                  "evaluateExprAsBool: member pointer type");
598*700637cbSDimitry Andric     return createDummyValue(getLoc(loc), boolTy);
599*700637cbSDimitry Andric   }
600*700637cbSDimitry Andric 
601*700637cbSDimitry Andric   assert(!cir::MissingFeatures::cgFPOptionsRAII());
602*700637cbSDimitry Andric   if (!e->getType()->isAnyComplexType())
603*700637cbSDimitry Andric     return emitScalarConversion(emitScalarExpr(e), e->getType(), boolTy, loc);
604*700637cbSDimitry Andric 
605*700637cbSDimitry Andric   cgm.errorNYI(e->getSourceRange(), "evaluateExprAsBool: complex type");
606*700637cbSDimitry Andric   return createDummyValue(getLoc(loc), boolTy);
607*700637cbSDimitry Andric }
608*700637cbSDimitry Andric 
emitUnaryOpLValue(const UnaryOperator * e)609*700637cbSDimitry Andric LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {
610*700637cbSDimitry Andric   UnaryOperatorKind op = e->getOpcode();
611*700637cbSDimitry Andric 
612*700637cbSDimitry Andric   // __extension__ doesn't affect lvalue-ness.
613*700637cbSDimitry Andric   if (op == UO_Extension)
614*700637cbSDimitry Andric     return emitLValue(e->getSubExpr());
615*700637cbSDimitry Andric 
616*700637cbSDimitry Andric   switch (op) {
617*700637cbSDimitry Andric   case UO_Deref: {
618*700637cbSDimitry Andric     QualType t = e->getSubExpr()->getType()->getPointeeType();
619*700637cbSDimitry Andric     assert(!t.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
620*700637cbSDimitry Andric 
621*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opTBAA());
622*700637cbSDimitry Andric     LValueBaseInfo baseInfo;
623*700637cbSDimitry Andric     Address addr = emitPointerWithAlignment(e->getSubExpr(), &baseInfo);
624*700637cbSDimitry Andric 
625*700637cbSDimitry Andric     // Tag 'load' with deref attribute.
626*700637cbSDimitry Andric     // FIXME: This misses some derefence cases and has problematic interactions
627*700637cbSDimitry Andric     // with other operators.
628*700637cbSDimitry Andric     if (auto loadOp =
629*700637cbSDimitry Andric             dyn_cast<cir::LoadOp>(addr.getPointer().getDefiningOp())) {
630*700637cbSDimitry Andric       loadOp.setIsDerefAttr(mlir::UnitAttr::get(&getMLIRContext()));
631*700637cbSDimitry Andric     }
632*700637cbSDimitry Andric 
633*700637cbSDimitry Andric     LValue lv = makeAddrLValue(addr, t, baseInfo);
634*700637cbSDimitry Andric     assert(!cir::MissingFeatures::addressSpace());
635*700637cbSDimitry Andric     assert(!cir::MissingFeatures::setNonGC());
636*700637cbSDimitry Andric     return lv;
637*700637cbSDimitry Andric   }
638*700637cbSDimitry Andric   case UO_Real:
639*700637cbSDimitry Andric   case UO_Imag: {
640*700637cbSDimitry Andric     LValue lv = emitLValue(e->getSubExpr());
641*700637cbSDimitry Andric     assert(lv.isSimple() && "real/imag on non-ordinary l-value");
642*700637cbSDimitry Andric 
643*700637cbSDimitry Andric     // __real is valid on scalars. This is a faster way of testing that.
644*700637cbSDimitry Andric     // __imag can only produce an rvalue on scalars.
645*700637cbSDimitry Andric     if (e->getOpcode() == UO_Real &&
646*700637cbSDimitry Andric         !mlir::isa<cir::ComplexType>(lv.getAddress().getElementType())) {
647*700637cbSDimitry Andric       assert(e->getSubExpr()->getType()->isArithmeticType());
648*700637cbSDimitry Andric       return lv;
649*700637cbSDimitry Andric     }
650*700637cbSDimitry Andric 
651*700637cbSDimitry Andric     QualType exprTy = getContext().getCanonicalType(e->getSubExpr()->getType());
652*700637cbSDimitry Andric     QualType elemTy = exprTy->castAs<clang::ComplexType>()->getElementType();
653*700637cbSDimitry Andric     mlir::Location loc = getLoc(e->getExprLoc());
654*700637cbSDimitry Andric     Address component =
655*700637cbSDimitry Andric         e->getOpcode() == UO_Real
656*700637cbSDimitry Andric             ? builder.createComplexRealPtr(loc, lv.getAddress())
657*700637cbSDimitry Andric             : builder.createComplexImagPtr(loc, lv.getAddress());
658*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opTBAA());
659*700637cbSDimitry Andric     LValue elemLV = makeAddrLValue(component, elemTy);
660*700637cbSDimitry Andric     elemLV.getQuals().addQualifiers(lv.getQuals());
661*700637cbSDimitry Andric     return elemLV;
662*700637cbSDimitry Andric   }
663*700637cbSDimitry Andric   case UO_PreInc:
664*700637cbSDimitry Andric   case UO_PreDec: {
665*700637cbSDimitry Andric     bool isInc = e->isIncrementOp();
666*700637cbSDimitry Andric     LValue lv = emitLValue(e->getSubExpr());
667*700637cbSDimitry Andric 
668*700637cbSDimitry Andric     assert(e->isPrefix() && "Prefix operator in unexpected state!");
669*700637cbSDimitry Andric 
670*700637cbSDimitry Andric     if (e->getType()->isAnyComplexType()) {
671*700637cbSDimitry Andric       cgm.errorNYI(e->getSourceRange(), "UnaryOp complex inc/dec");
672*700637cbSDimitry Andric       lv = LValue();
673*700637cbSDimitry Andric     } else {
674*700637cbSDimitry Andric       emitScalarPrePostIncDec(e, lv, isInc, /*isPre=*/true);
675*700637cbSDimitry Andric     }
676*700637cbSDimitry Andric 
677*700637cbSDimitry Andric     return lv;
678*700637cbSDimitry Andric   }
679*700637cbSDimitry Andric   case UO_Extension:
680*700637cbSDimitry Andric     llvm_unreachable("UnaryOperator extension should be handled above!");
681*700637cbSDimitry Andric   case UO_Plus:
682*700637cbSDimitry Andric   case UO_Minus:
683*700637cbSDimitry Andric   case UO_Not:
684*700637cbSDimitry Andric   case UO_LNot:
685*700637cbSDimitry Andric   case UO_AddrOf:
686*700637cbSDimitry Andric   case UO_PostInc:
687*700637cbSDimitry Andric   case UO_PostDec:
688*700637cbSDimitry Andric   case UO_Coawait:
689*700637cbSDimitry Andric     llvm_unreachable("UnaryOperator of non-lvalue kind!");
690*700637cbSDimitry Andric   }
691*700637cbSDimitry Andric   llvm_unreachable("Unknown unary operator kind!");
692*700637cbSDimitry Andric }
693*700637cbSDimitry Andric 
694*700637cbSDimitry Andric /// If the specified expr is a simple decay from an array to pointer,
695*700637cbSDimitry Andric /// return the array subexpression.
696*700637cbSDimitry Andric /// FIXME: this could be abstracted into a common AST helper.
getSimpleArrayDecayOperand(const Expr * e)697*700637cbSDimitry Andric static const Expr *getSimpleArrayDecayOperand(const Expr *e) {
698*700637cbSDimitry Andric   // If this isn't just an array->pointer decay, bail out.
699*700637cbSDimitry Andric   const auto *castExpr = dyn_cast<CastExpr>(e);
700*700637cbSDimitry Andric   if (!castExpr || castExpr->getCastKind() != CK_ArrayToPointerDecay)
701*700637cbSDimitry Andric     return nullptr;
702*700637cbSDimitry Andric 
703*700637cbSDimitry Andric   // If this is a decay from variable width array, bail out.
704*700637cbSDimitry Andric   const Expr *subExpr = castExpr->getSubExpr();
705*700637cbSDimitry Andric   if (subExpr->getType()->isVariableArrayType())
706*700637cbSDimitry Andric     return nullptr;
707*700637cbSDimitry Andric 
708*700637cbSDimitry Andric   return subExpr;
709*700637cbSDimitry Andric }
710*700637cbSDimitry Andric 
getConstantIndexOrNull(mlir::Value idx)711*700637cbSDimitry Andric static cir::IntAttr getConstantIndexOrNull(mlir::Value idx) {
712*700637cbSDimitry Andric   // TODO(cir): should we consider using MLIRs IndexType instead of IntegerAttr?
713*700637cbSDimitry Andric   if (auto constantOp = dyn_cast<cir::ConstantOp>(idx.getDefiningOp()))
714*700637cbSDimitry Andric     return mlir::dyn_cast<cir::IntAttr>(constantOp.getValue());
715*700637cbSDimitry Andric   return {};
716*700637cbSDimitry Andric }
717*700637cbSDimitry Andric 
getArrayElementAlign(CharUnits arrayAlign,mlir::Value idx,CharUnits eltSize)718*700637cbSDimitry Andric static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx,
719*700637cbSDimitry Andric                                       CharUnits eltSize) {
720*700637cbSDimitry Andric   // If we have a constant index, we can use the exact offset of the
721*700637cbSDimitry Andric   // element we're accessing.
722*700637cbSDimitry Andric   const cir::IntAttr constantIdx = getConstantIndexOrNull(idx);
723*700637cbSDimitry Andric   if (constantIdx) {
724*700637cbSDimitry Andric     const CharUnits offset = constantIdx.getValue().getZExtValue() * eltSize;
725*700637cbSDimitry Andric     return arrayAlign.alignmentAtOffset(offset);
726*700637cbSDimitry Andric   }
727*700637cbSDimitry Andric   // Otherwise, use the worst-case alignment for any element.
728*700637cbSDimitry Andric   return arrayAlign.alignmentOfArrayElement(eltSize);
729*700637cbSDimitry Andric }
730*700637cbSDimitry Andric 
getFixedSizeElementType(const ASTContext & astContext,const VariableArrayType * vla)731*700637cbSDimitry Andric static QualType getFixedSizeElementType(const ASTContext &astContext,
732*700637cbSDimitry Andric                                         const VariableArrayType *vla) {
733*700637cbSDimitry Andric   QualType eltType;
734*700637cbSDimitry Andric   do {
735*700637cbSDimitry Andric     eltType = vla->getElementType();
736*700637cbSDimitry Andric   } while ((vla = astContext.getAsVariableArrayType(eltType)));
737*700637cbSDimitry Andric   return eltType;
738*700637cbSDimitry Andric }
739*700637cbSDimitry Andric 
emitArraySubscriptPtr(CIRGenFunction & cgf,mlir::Location beginLoc,mlir::Location endLoc,mlir::Value ptr,mlir::Type eltTy,mlir::Value idx,bool shouldDecay)740*700637cbSDimitry Andric static mlir::Value emitArraySubscriptPtr(CIRGenFunction &cgf,
741*700637cbSDimitry Andric                                          mlir::Location beginLoc,
742*700637cbSDimitry Andric                                          mlir::Location endLoc, mlir::Value ptr,
743*700637cbSDimitry Andric                                          mlir::Type eltTy, mlir::Value idx,
744*700637cbSDimitry Andric                                          bool shouldDecay) {
745*700637cbSDimitry Andric   CIRGenModule &cgm = cgf.getCIRGenModule();
746*700637cbSDimitry Andric   // TODO(cir): LLVM codegen emits in bound gep check here, is there anything
747*700637cbSDimitry Andric   // that would enhance tracking this later in CIR?
748*700637cbSDimitry Andric   assert(!cir::MissingFeatures::emitCheckedInBoundsGEP());
749*700637cbSDimitry Andric   return cgm.getBuilder().getArrayElement(beginLoc, endLoc, ptr, eltTy, idx,
750*700637cbSDimitry Andric                                           shouldDecay);
751*700637cbSDimitry Andric }
752*700637cbSDimitry Andric 
emitArraySubscriptPtr(CIRGenFunction & cgf,mlir::Location beginLoc,mlir::Location endLoc,Address addr,QualType eltType,mlir::Value idx,mlir::Location loc,bool shouldDecay)753*700637cbSDimitry Andric static Address emitArraySubscriptPtr(CIRGenFunction &cgf,
754*700637cbSDimitry Andric                                      mlir::Location beginLoc,
755*700637cbSDimitry Andric                                      mlir::Location endLoc, Address addr,
756*700637cbSDimitry Andric                                      QualType eltType, mlir::Value idx,
757*700637cbSDimitry Andric                                      mlir::Location loc, bool shouldDecay) {
758*700637cbSDimitry Andric 
759*700637cbSDimitry Andric   // Determine the element size of the statically-sized base.  This is
760*700637cbSDimitry Andric   // the thing that the indices are expressed in terms of.
761*700637cbSDimitry Andric   if (const VariableArrayType *vla =
762*700637cbSDimitry Andric           cgf.getContext().getAsVariableArrayType(eltType)) {
763*700637cbSDimitry Andric     eltType = getFixedSizeElementType(cgf.getContext(), vla);
764*700637cbSDimitry Andric   }
765*700637cbSDimitry Andric 
766*700637cbSDimitry Andric   // We can use that to compute the best alignment of the element.
767*700637cbSDimitry Andric   const CharUnits eltSize = cgf.getContext().getTypeSizeInChars(eltType);
768*700637cbSDimitry Andric   const CharUnits eltAlign =
769*700637cbSDimitry Andric       getArrayElementAlign(addr.getAlignment(), idx, eltSize);
770*700637cbSDimitry Andric 
771*700637cbSDimitry Andric   assert(!cir::MissingFeatures::preservedAccessIndexRegion());
772*700637cbSDimitry Andric   const mlir::Value eltPtr =
773*700637cbSDimitry Andric       emitArraySubscriptPtr(cgf, beginLoc, endLoc, addr.getPointer(),
774*700637cbSDimitry Andric                             addr.getElementType(), idx, shouldDecay);
775*700637cbSDimitry Andric   const mlir::Type elementType = cgf.convertTypeForMem(eltType);
776*700637cbSDimitry Andric   return Address(eltPtr, elementType, eltAlign);
777*700637cbSDimitry Andric }
778*700637cbSDimitry Andric 
779*700637cbSDimitry Andric LValue
emitArraySubscriptExpr(const clang::ArraySubscriptExpr * e)780*700637cbSDimitry Andric CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
781*700637cbSDimitry Andric   if (isa<ExtVectorElementExpr>(e->getBase())) {
782*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(),
783*700637cbSDimitry Andric                  "emitArraySubscriptExpr: ExtVectorElementExpr");
784*700637cbSDimitry Andric     return LValue::makeAddr(Address::invalid(), e->getType(), LValueBaseInfo());
785*700637cbSDimitry Andric   }
786*700637cbSDimitry Andric 
787*700637cbSDimitry Andric   if (getContext().getAsVariableArrayType(e->getType())) {
788*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(),
789*700637cbSDimitry Andric                  "emitArraySubscriptExpr: VariableArrayType");
790*700637cbSDimitry Andric     return LValue::makeAddr(Address::invalid(), e->getType(), LValueBaseInfo());
791*700637cbSDimitry Andric   }
792*700637cbSDimitry Andric 
793*700637cbSDimitry Andric   if (e->getType()->getAs<ObjCObjectType>()) {
794*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjCObjectType");
795*700637cbSDimitry Andric     return LValue::makeAddr(Address::invalid(), e->getType(), LValueBaseInfo());
796*700637cbSDimitry Andric   }
797*700637cbSDimitry Andric 
798*700637cbSDimitry Andric   // The index must always be an integer, which is not an aggregate.  Emit it
799*700637cbSDimitry Andric   // in lexical order (this complexity is, sadly, required by C++17).
800*700637cbSDimitry Andric   assert((e->getIdx() == e->getLHS() || e->getIdx() == e->getRHS()) &&
801*700637cbSDimitry Andric          "index was neither LHS nor RHS");
802*700637cbSDimitry Andric 
803*700637cbSDimitry Andric   auto emitIdxAfterBase = [&](bool promote) -> mlir::Value {
804*700637cbSDimitry Andric     const mlir::Value idx = emitScalarExpr(e->getIdx());
805*700637cbSDimitry Andric 
806*700637cbSDimitry Andric     // Extend or truncate the index type to 32 or 64-bits.
807*700637cbSDimitry Andric     auto ptrTy = mlir::dyn_cast<cir::PointerType>(idx.getType());
808*700637cbSDimitry Andric     if (promote && ptrTy && ptrTy.isPtrTo<cir::IntType>())
809*700637cbSDimitry Andric       cgm.errorNYI(e->getSourceRange(),
810*700637cbSDimitry Andric                    "emitArraySubscriptExpr: index type cast");
811*700637cbSDimitry Andric     return idx;
812*700637cbSDimitry Andric   };
813*700637cbSDimitry Andric 
814*700637cbSDimitry Andric   // If the base is a vector type, then we are forming a vector element
815*700637cbSDimitry Andric   // with this subscript.
816*700637cbSDimitry Andric   if (e->getBase()->getType()->isVectorType() &&
817*700637cbSDimitry Andric       !isa<ExtVectorElementExpr>(e->getBase())) {
818*700637cbSDimitry Andric     const mlir::Value idx = emitIdxAfterBase(/*promote=*/false);
819*700637cbSDimitry Andric     const LValue lhs = emitLValue(e->getBase());
820*700637cbSDimitry Andric     return LValue::makeVectorElt(lhs.getAddress(), idx, e->getBase()->getType(),
821*700637cbSDimitry Andric                                  lhs.getBaseInfo());
822*700637cbSDimitry Andric   }
823*700637cbSDimitry Andric 
824*700637cbSDimitry Andric   const mlir::Value idx = emitIdxAfterBase(/*promote=*/true);
825*700637cbSDimitry Andric   if (const Expr *array = getSimpleArrayDecayOperand(e->getBase())) {
826*700637cbSDimitry Andric     LValue arrayLV;
827*700637cbSDimitry Andric     if (const auto *ase = dyn_cast<ArraySubscriptExpr>(array))
828*700637cbSDimitry Andric       arrayLV = emitArraySubscriptExpr(ase);
829*700637cbSDimitry Andric     else
830*700637cbSDimitry Andric       arrayLV = emitLValue(array);
831*700637cbSDimitry Andric 
832*700637cbSDimitry Andric     // Propagate the alignment from the array itself to the result.
833*700637cbSDimitry Andric     const Address addr = emitArraySubscriptPtr(
834*700637cbSDimitry Andric         *this, cgm.getLoc(array->getBeginLoc()), cgm.getLoc(array->getEndLoc()),
835*700637cbSDimitry Andric         arrayLV.getAddress(), e->getType(), idx, cgm.getLoc(e->getExprLoc()),
836*700637cbSDimitry Andric         /*shouldDecay=*/true);
837*700637cbSDimitry Andric 
838*700637cbSDimitry Andric     const LValue lv = LValue::makeAddr(addr, e->getType(), LValueBaseInfo());
839*700637cbSDimitry Andric 
840*700637cbSDimitry Andric     if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC) {
841*700637cbSDimitry Andric       cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjC with GC");
842*700637cbSDimitry Andric     }
843*700637cbSDimitry Andric 
844*700637cbSDimitry Andric     return lv;
845*700637cbSDimitry Andric   }
846*700637cbSDimitry Andric 
847*700637cbSDimitry Andric   // The base must be a pointer; emit it with an estimate of its alignment.
848*700637cbSDimitry Andric   assert(e->getBase()->getType()->isPointerType() &&
849*700637cbSDimitry Andric          "The base must be a pointer");
850*700637cbSDimitry Andric 
851*700637cbSDimitry Andric   LValueBaseInfo eltBaseInfo;
852*700637cbSDimitry Andric   const Address ptrAddr = emitPointerWithAlignment(e->getBase(), &eltBaseInfo);
853*700637cbSDimitry Andric   // Propagate the alignment from the array itself to the result.
854*700637cbSDimitry Andric   const Address addxr = emitArraySubscriptPtr(
855*700637cbSDimitry Andric       *this, cgm.getLoc(e->getBeginLoc()), cgm.getLoc(e->getEndLoc()), ptrAddr,
856*700637cbSDimitry Andric       e->getType(), idx, cgm.getLoc(e->getExprLoc()),
857*700637cbSDimitry Andric       /*shouldDecay=*/false);
858*700637cbSDimitry Andric 
859*700637cbSDimitry Andric   const LValue lv = LValue::makeAddr(addxr, e->getType(), eltBaseInfo);
860*700637cbSDimitry Andric 
861*700637cbSDimitry Andric   if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC) {
862*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjC with GC");
863*700637cbSDimitry Andric   }
864*700637cbSDimitry Andric 
865*700637cbSDimitry Andric   return lv;
866*700637cbSDimitry Andric }
867*700637cbSDimitry Andric 
emitStringLiteralLValue(const StringLiteral * e)868*700637cbSDimitry Andric LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral *e) {
869*700637cbSDimitry Andric   cir::GlobalOp globalOp = cgm.getGlobalForStringLiteral(e);
870*700637cbSDimitry Andric   assert(globalOp.getAlignment() && "expected alignment for string literal");
871*700637cbSDimitry Andric   unsigned align = *(globalOp.getAlignment());
872*700637cbSDimitry Andric   mlir::Value addr =
873*700637cbSDimitry Andric       builder.createGetGlobal(getLoc(e->getSourceRange()), globalOp);
874*700637cbSDimitry Andric   return makeAddrLValue(
875*700637cbSDimitry Andric       Address(addr, globalOp.getSymType(), CharUnits::fromQuantity(align)),
876*700637cbSDimitry Andric       e->getType(), AlignmentSource::Decl);
877*700637cbSDimitry Andric }
878*700637cbSDimitry Andric 
879*700637cbSDimitry Andric /// Casts are never lvalues unless that cast is to a reference type. If the cast
880*700637cbSDimitry Andric /// is to a reference, we can have the usual lvalue result, otherwise if a cast
881*700637cbSDimitry Andric /// is needed by the code generator in an lvalue context, then it must mean that
882*700637cbSDimitry Andric /// we need the address of an aggregate in order to access one of its members.
883*700637cbSDimitry Andric /// This can happen for all the reasons that casts are permitted with aggregate
884*700637cbSDimitry Andric /// result, including noop aggregate casts, and cast from scalar to union.
emitCastLValue(const CastExpr * e)885*700637cbSDimitry Andric LValue CIRGenFunction::emitCastLValue(const CastExpr *e) {
886*700637cbSDimitry Andric   switch (e->getCastKind()) {
887*700637cbSDimitry Andric   case CK_ToVoid:
888*700637cbSDimitry Andric   case CK_BitCast:
889*700637cbSDimitry Andric   case CK_LValueToRValueBitCast:
890*700637cbSDimitry Andric   case CK_ArrayToPointerDecay:
891*700637cbSDimitry Andric   case CK_FunctionToPointerDecay:
892*700637cbSDimitry Andric   case CK_NullToMemberPointer:
893*700637cbSDimitry Andric   case CK_NullToPointer:
894*700637cbSDimitry Andric   case CK_IntegralToPointer:
895*700637cbSDimitry Andric   case CK_PointerToIntegral:
896*700637cbSDimitry Andric   case CK_PointerToBoolean:
897*700637cbSDimitry Andric   case CK_IntegralCast:
898*700637cbSDimitry Andric   case CK_BooleanToSignedIntegral:
899*700637cbSDimitry Andric   case CK_IntegralToBoolean:
900*700637cbSDimitry Andric   case CK_IntegralToFloating:
901*700637cbSDimitry Andric   case CK_FloatingToIntegral:
902*700637cbSDimitry Andric   case CK_FloatingToBoolean:
903*700637cbSDimitry Andric   case CK_FloatingCast:
904*700637cbSDimitry Andric   case CK_FloatingRealToComplex:
905*700637cbSDimitry Andric   case CK_FloatingComplexToReal:
906*700637cbSDimitry Andric   case CK_FloatingComplexToBoolean:
907*700637cbSDimitry Andric   case CK_FloatingComplexCast:
908*700637cbSDimitry Andric   case CK_FloatingComplexToIntegralComplex:
909*700637cbSDimitry Andric   case CK_IntegralRealToComplex:
910*700637cbSDimitry Andric   case CK_IntegralComplexToReal:
911*700637cbSDimitry Andric   case CK_IntegralComplexToBoolean:
912*700637cbSDimitry Andric   case CK_IntegralComplexCast:
913*700637cbSDimitry Andric   case CK_IntegralComplexToFloatingComplex:
914*700637cbSDimitry Andric   case CK_DerivedToBaseMemberPointer:
915*700637cbSDimitry Andric   case CK_BaseToDerivedMemberPointer:
916*700637cbSDimitry Andric   case CK_MemberPointerToBoolean:
917*700637cbSDimitry Andric   case CK_ReinterpretMemberPointer:
918*700637cbSDimitry Andric   case CK_AnyPointerToBlockPointerCast:
919*700637cbSDimitry Andric   case CK_ARCProduceObject:
920*700637cbSDimitry Andric   case CK_ARCConsumeObject:
921*700637cbSDimitry Andric   case CK_ARCReclaimReturnedObject:
922*700637cbSDimitry Andric   case CK_ARCExtendBlockObject:
923*700637cbSDimitry Andric   case CK_CopyAndAutoreleaseBlockObject:
924*700637cbSDimitry Andric   case CK_IntToOCLSampler:
925*700637cbSDimitry Andric   case CK_FloatingToFixedPoint:
926*700637cbSDimitry Andric   case CK_FixedPointToFloating:
927*700637cbSDimitry Andric   case CK_FixedPointCast:
928*700637cbSDimitry Andric   case CK_FixedPointToBoolean:
929*700637cbSDimitry Andric   case CK_FixedPointToIntegral:
930*700637cbSDimitry Andric   case CK_IntegralToFixedPoint:
931*700637cbSDimitry Andric   case CK_MatrixCast:
932*700637cbSDimitry Andric   case CK_HLSLVectorTruncation:
933*700637cbSDimitry Andric   case CK_HLSLArrayRValue:
934*700637cbSDimitry Andric   case CK_HLSLElementwiseCast:
935*700637cbSDimitry Andric   case CK_HLSLAggregateSplatCast:
936*700637cbSDimitry Andric     llvm_unreachable("unexpected cast lvalue");
937*700637cbSDimitry Andric 
938*700637cbSDimitry Andric   case CK_Dependent:
939*700637cbSDimitry Andric     llvm_unreachable("dependent cast kind in IR gen!");
940*700637cbSDimitry Andric 
941*700637cbSDimitry Andric   case CK_BuiltinFnToFnPtr:
942*700637cbSDimitry Andric     llvm_unreachable("builtin functions are handled elsewhere");
943*700637cbSDimitry Andric 
944*700637cbSDimitry Andric   // These are never l-values; just use the aggregate emission code.
945*700637cbSDimitry Andric   case CK_NonAtomicToAtomic:
946*700637cbSDimitry Andric   case CK_AtomicToNonAtomic:
947*700637cbSDimitry Andric   case CK_Dynamic:
948*700637cbSDimitry Andric   case CK_ToUnion:
949*700637cbSDimitry Andric   case CK_BaseToDerived:
950*700637cbSDimitry Andric   case CK_LValueBitCast:
951*700637cbSDimitry Andric   case CK_AddressSpaceConversion:
952*700637cbSDimitry Andric   case CK_ObjCObjectLValueCast:
953*700637cbSDimitry Andric   case CK_VectorSplat:
954*700637cbSDimitry Andric   case CK_ConstructorConversion:
955*700637cbSDimitry Andric   case CK_UserDefinedConversion:
956*700637cbSDimitry Andric   case CK_CPointerToObjCPointerCast:
957*700637cbSDimitry Andric   case CK_BlockPointerToObjCPointerCast:
958*700637cbSDimitry Andric   case CK_LValueToRValue: {
959*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(),
960*700637cbSDimitry Andric                  std::string("emitCastLValue for unhandled cast kind: ") +
961*700637cbSDimitry Andric                      e->getCastKindName());
962*700637cbSDimitry Andric 
963*700637cbSDimitry Andric     return {};
964*700637cbSDimitry Andric   }
965*700637cbSDimitry Andric 
966*700637cbSDimitry Andric   case CK_NoOp: {
967*700637cbSDimitry Andric     // CK_NoOp can model a qualification conversion, which can remove an array
968*700637cbSDimitry Andric     // bound and change the IR type.
969*700637cbSDimitry Andric     LValue lv = emitLValue(e->getSubExpr());
970*700637cbSDimitry Andric     // Propagate the volatile qualifier to LValue, if exists in e.
971*700637cbSDimitry Andric     if (e->changesVolatileQualification())
972*700637cbSDimitry Andric       cgm.errorNYI(e->getSourceRange(),
973*700637cbSDimitry Andric                    "emitCastLValue: NoOp changes volatile qual");
974*700637cbSDimitry Andric     if (lv.isSimple()) {
975*700637cbSDimitry Andric       Address v = lv.getAddress();
976*700637cbSDimitry Andric       if (v.isValid()) {
977*700637cbSDimitry Andric         mlir::Type ty = convertTypeForMem(e->getType());
978*700637cbSDimitry Andric         if (v.getElementType() != ty)
979*700637cbSDimitry Andric           cgm.errorNYI(e->getSourceRange(),
980*700637cbSDimitry Andric                        "emitCastLValue: NoOp needs bitcast");
981*700637cbSDimitry Andric       }
982*700637cbSDimitry Andric     }
983*700637cbSDimitry Andric     return lv;
984*700637cbSDimitry Andric   }
985*700637cbSDimitry Andric 
986*700637cbSDimitry Andric   case CK_UncheckedDerivedToBase:
987*700637cbSDimitry Andric   case CK_DerivedToBase: {
988*700637cbSDimitry Andric     const auto *derivedClassTy =
989*700637cbSDimitry Andric         e->getSubExpr()->getType()->castAs<clang::RecordType>();
990*700637cbSDimitry Andric     auto *derivedClassDecl = cast<CXXRecordDecl>(derivedClassTy->getDecl());
991*700637cbSDimitry Andric 
992*700637cbSDimitry Andric     LValue lv = emitLValue(e->getSubExpr());
993*700637cbSDimitry Andric     Address thisAddr = lv.getAddress();
994*700637cbSDimitry Andric 
995*700637cbSDimitry Andric     // Perform the derived-to-base conversion
996*700637cbSDimitry Andric     Address baseAddr =
997*700637cbSDimitry Andric         getAddressOfBaseClass(thisAddr, derivedClassDecl, e->path(),
998*700637cbSDimitry Andric                               /*NullCheckValue=*/false, e->getExprLoc());
999*700637cbSDimitry Andric 
1000*700637cbSDimitry Andric     // TODO: Support accesses to members of base classes in TBAA. For now, we
1001*700637cbSDimitry Andric     // conservatively pretend that the complete object is of the base class
1002*700637cbSDimitry Andric     // type.
1003*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opTBAA());
1004*700637cbSDimitry Andric     return makeAddrLValue(baseAddr, e->getType(), lv.getBaseInfo());
1005*700637cbSDimitry Andric   }
1006*700637cbSDimitry Andric 
1007*700637cbSDimitry Andric   case CK_ZeroToOCLOpaqueType:
1008*700637cbSDimitry Andric     llvm_unreachable("NULL to OpenCL opaque type lvalue cast is not valid");
1009*700637cbSDimitry Andric   }
1010*700637cbSDimitry Andric 
1011*700637cbSDimitry Andric   llvm_unreachable("Invalid cast kind");
1012*700637cbSDimitry Andric }
1013*700637cbSDimitry Andric 
emitMemberExpr(const MemberExpr * e)1014*700637cbSDimitry Andric LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {
1015*700637cbSDimitry Andric   if (isa<VarDecl>(e->getMemberDecl())) {
1016*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: VarDecl");
1017*700637cbSDimitry Andric     return LValue();
1018*700637cbSDimitry Andric   }
1019*700637cbSDimitry Andric 
1020*700637cbSDimitry Andric   Expr *baseExpr = e->getBase();
1021*700637cbSDimitry Andric   // If this is s.x, emit s as an lvalue.  If it is s->x, emit s as a scalar.
1022*700637cbSDimitry Andric   LValue baseLV;
1023*700637cbSDimitry Andric   if (e->isArrow()) {
1024*700637cbSDimitry Andric     LValueBaseInfo baseInfo;
1025*700637cbSDimitry Andric     assert(!cir::MissingFeatures::opTBAA());
1026*700637cbSDimitry Andric     Address addr = emitPointerWithAlignment(baseExpr, &baseInfo);
1027*700637cbSDimitry Andric     QualType ptrTy = baseExpr->getType()->getPointeeType();
1028*700637cbSDimitry Andric     assert(!cir::MissingFeatures::typeChecks());
1029*700637cbSDimitry Andric     baseLV = makeAddrLValue(addr, ptrTy, baseInfo);
1030*700637cbSDimitry Andric   } else {
1031*700637cbSDimitry Andric     assert(!cir::MissingFeatures::typeChecks());
1032*700637cbSDimitry Andric     baseLV = emitLValue(baseExpr);
1033*700637cbSDimitry Andric   }
1034*700637cbSDimitry Andric 
1035*700637cbSDimitry Andric   const NamedDecl *nd = e->getMemberDecl();
1036*700637cbSDimitry Andric   if (auto *field = dyn_cast<FieldDecl>(nd)) {
1037*700637cbSDimitry Andric     LValue lv = emitLValueForField(baseLV, field);
1038*700637cbSDimitry Andric     assert(!cir::MissingFeatures::setObjCGCLValueClass());
1039*700637cbSDimitry Andric     if (getLangOpts().OpenMP) {
1040*700637cbSDimitry Andric       // If the member was explicitly marked as nontemporal, mark it as
1041*700637cbSDimitry Andric       // nontemporal. If the base lvalue is marked as nontemporal, mark access
1042*700637cbSDimitry Andric       // to children as nontemporal too.
1043*700637cbSDimitry Andric       cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: OpenMP");
1044*700637cbSDimitry Andric     }
1045*700637cbSDimitry Andric     return lv;
1046*700637cbSDimitry Andric   }
1047*700637cbSDimitry Andric 
1048*700637cbSDimitry Andric   if (isa<FunctionDecl>(nd)) {
1049*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: FunctionDecl");
1050*700637cbSDimitry Andric     return LValue();
1051*700637cbSDimitry Andric   }
1052*700637cbSDimitry Andric 
1053*700637cbSDimitry Andric   llvm_unreachable("Unhandled member declaration!");
1054*700637cbSDimitry Andric }
1055*700637cbSDimitry Andric 
emitCallExprLValue(const CallExpr * e)1056*700637cbSDimitry Andric LValue CIRGenFunction::emitCallExprLValue(const CallExpr *e) {
1057*700637cbSDimitry Andric   RValue rv = emitCallExpr(e);
1058*700637cbSDimitry Andric 
1059*700637cbSDimitry Andric   if (!rv.isScalar()) {
1060*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "emitCallExprLValue: non-scalar return");
1061*700637cbSDimitry Andric     return {};
1062*700637cbSDimitry Andric   }
1063*700637cbSDimitry Andric 
1064*700637cbSDimitry Andric   assert(e->getCallReturnType(getContext())->isReferenceType() &&
1065*700637cbSDimitry Andric          "Can't have a scalar return unless the return type is a "
1066*700637cbSDimitry Andric          "reference type!");
1067*700637cbSDimitry Andric 
1068*700637cbSDimitry Andric   return makeNaturalAlignPointeeAddrLValue(rv.getValue(), e->getType());
1069*700637cbSDimitry Andric }
1070*700637cbSDimitry Andric 
emitBinaryOperatorLValue(const BinaryOperator * e)1071*700637cbSDimitry Andric LValue CIRGenFunction::emitBinaryOperatorLValue(const BinaryOperator *e) {
1072*700637cbSDimitry Andric   // Comma expressions just emit their LHS then their RHS as an l-value.
1073*700637cbSDimitry Andric   if (e->getOpcode() == BO_Comma) {
1074*700637cbSDimitry Andric     emitIgnoredExpr(e->getLHS());
1075*700637cbSDimitry Andric     return emitLValue(e->getRHS());
1076*700637cbSDimitry Andric   }
1077*700637cbSDimitry Andric 
1078*700637cbSDimitry Andric   if (e->getOpcode() == BO_PtrMemD || e->getOpcode() == BO_PtrMemI) {
1079*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "member pointers");
1080*700637cbSDimitry Andric     return {};
1081*700637cbSDimitry Andric   }
1082*700637cbSDimitry Andric 
1083*700637cbSDimitry Andric   assert(e->getOpcode() == BO_Assign && "unexpected binary l-value");
1084*700637cbSDimitry Andric 
1085*700637cbSDimitry Andric   // Note that in all of these cases, __block variables need the RHS
1086*700637cbSDimitry Andric   // evaluated first just in case the variable gets moved by the RHS.
1087*700637cbSDimitry Andric 
1088*700637cbSDimitry Andric   switch (CIRGenFunction::getEvaluationKind(e->getType())) {
1089*700637cbSDimitry Andric   case cir::TEK_Scalar: {
1090*700637cbSDimitry Andric     assert(!cir::MissingFeatures::objCLifetime());
1091*700637cbSDimitry Andric     if (e->getLHS()->getType().getObjCLifetime() !=
1092*700637cbSDimitry Andric         clang::Qualifiers::ObjCLifetime::OCL_None) {
1093*700637cbSDimitry Andric       cgm.errorNYI(e->getSourceRange(), "objc lifetimes");
1094*700637cbSDimitry Andric       return {};
1095*700637cbSDimitry Andric     }
1096*700637cbSDimitry Andric 
1097*700637cbSDimitry Andric     RValue rv = emitAnyExpr(e->getRHS());
1098*700637cbSDimitry Andric     LValue lv = emitLValue(e->getLHS());
1099*700637cbSDimitry Andric 
1100*700637cbSDimitry Andric     SourceLocRAIIObject loc{*this, getLoc(e->getSourceRange())};
1101*700637cbSDimitry Andric     if (lv.isBitField())
1102*700637cbSDimitry Andric       emitStoreThroughBitfieldLValue(rv, lv);
1103*700637cbSDimitry Andric     else
1104*700637cbSDimitry Andric       emitStoreThroughLValue(rv, lv);
1105*700637cbSDimitry Andric 
1106*700637cbSDimitry Andric     if (getLangOpts().OpenMP) {
1107*700637cbSDimitry Andric       cgm.errorNYI(e->getSourceRange(), "openmp");
1108*700637cbSDimitry Andric       return {};
1109*700637cbSDimitry Andric     }
1110*700637cbSDimitry Andric 
1111*700637cbSDimitry Andric     return lv;
1112*700637cbSDimitry Andric   }
1113*700637cbSDimitry Andric 
1114*700637cbSDimitry Andric   case cir::TEK_Complex: {
1115*700637cbSDimitry Andric     return emitComplexAssignmentLValue(e);
1116*700637cbSDimitry Andric   }
1117*700637cbSDimitry Andric 
1118*700637cbSDimitry Andric   case cir::TEK_Aggregate:
1119*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "aggregate lvalues");
1120*700637cbSDimitry Andric     return {};
1121*700637cbSDimitry Andric   }
1122*700637cbSDimitry Andric   llvm_unreachable("bad evaluation kind");
1123*700637cbSDimitry Andric }
1124*700637cbSDimitry Andric 
1125*700637cbSDimitry Andric /// Emit code to compute the specified expression which
1126*700637cbSDimitry Andric /// can have any type.  The result is returned as an RValue struct.
emitAnyExpr(const Expr * e,AggValueSlot aggSlot)1127*700637cbSDimitry Andric RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot) {
1128*700637cbSDimitry Andric   switch (CIRGenFunction::getEvaluationKind(e->getType())) {
1129*700637cbSDimitry Andric   case cir::TEK_Scalar:
1130*700637cbSDimitry Andric     return RValue::get(emitScalarExpr(e));
1131*700637cbSDimitry Andric   case cir::TEK_Complex:
1132*700637cbSDimitry Andric     return RValue::getComplex(emitComplexExpr(e));
1133*700637cbSDimitry Andric   case cir::TEK_Aggregate: {
1134*700637cbSDimitry Andric     if (aggSlot.isIgnored())
1135*700637cbSDimitry Andric       aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),
1136*700637cbSDimitry Andric                               getCounterAggTmpAsString());
1137*700637cbSDimitry Andric     emitAggExpr(e, aggSlot);
1138*700637cbSDimitry Andric     return aggSlot.asRValue();
1139*700637cbSDimitry Andric   }
1140*700637cbSDimitry Andric   }
1141*700637cbSDimitry Andric   llvm_unreachable("bad evaluation kind");
1142*700637cbSDimitry Andric }
1143*700637cbSDimitry Andric 
emitFunctionDeclPointer(CIRGenModule & cgm,GlobalDecl gd)1144*700637cbSDimitry Andric static cir::FuncOp emitFunctionDeclPointer(CIRGenModule &cgm, GlobalDecl gd) {
1145*700637cbSDimitry Andric   assert(!cir::MissingFeatures::weakRefReference());
1146*700637cbSDimitry Andric   return cgm.getAddrOfFunction(gd);
1147*700637cbSDimitry Andric }
1148*700637cbSDimitry Andric 
1149*700637cbSDimitry Andric // Detect the unusual situation where an inline version is shadowed by a
1150*700637cbSDimitry Andric // non-inline version. In that case we should pick the external one
1151*700637cbSDimitry Andric // everywhere. That's GCC behavior too.
onlyHasInlineBuiltinDeclaration(const FunctionDecl * fd)1152*700637cbSDimitry Andric static bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *fd) {
1153*700637cbSDimitry Andric   for (const FunctionDecl *pd = fd; pd; pd = pd->getPreviousDecl())
1154*700637cbSDimitry Andric     if (!pd->isInlineBuiltinDeclaration())
1155*700637cbSDimitry Andric       return false;
1156*700637cbSDimitry Andric   return true;
1157*700637cbSDimitry Andric }
1158*700637cbSDimitry Andric 
emitDirectCallee(const GlobalDecl & gd)1159*700637cbSDimitry Andric CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) {
1160*700637cbSDimitry Andric   const auto *fd = cast<FunctionDecl>(gd.getDecl());
1161*700637cbSDimitry Andric 
1162*700637cbSDimitry Andric   if (unsigned builtinID = fd->getBuiltinID()) {
1163*700637cbSDimitry Andric     if (fd->getAttr<AsmLabelAttr>()) {
1164*700637cbSDimitry Andric       cgm.errorNYI("AsmLabelAttr");
1165*700637cbSDimitry Andric     }
1166*700637cbSDimitry Andric 
1167*700637cbSDimitry Andric     StringRef ident = fd->getName();
1168*700637cbSDimitry Andric     std::string fdInlineName = (ident + ".inline").str();
1169*700637cbSDimitry Andric 
1170*700637cbSDimitry Andric     bool isPredefinedLibFunction =
1171*700637cbSDimitry Andric         cgm.getASTContext().BuiltinInfo.isPredefinedLibFunction(builtinID);
1172*700637cbSDimitry Andric     // Assume nobuiltins everywhere until we actually read the attributes.
1173*700637cbSDimitry Andric     bool hasAttributeNoBuiltin = true;
1174*700637cbSDimitry Andric     assert(!cir::MissingFeatures::attributeNoBuiltin());
1175*700637cbSDimitry Andric 
1176*700637cbSDimitry Andric     // When directing calling an inline builtin, call it through it's mangled
1177*700637cbSDimitry Andric     // name to make it clear it's not the actual builtin.
1178*700637cbSDimitry Andric     auto fn = cast<cir::FuncOp>(curFn);
1179*700637cbSDimitry Andric     if (fn.getName() != fdInlineName && onlyHasInlineBuiltinDeclaration(fd)) {
1180*700637cbSDimitry Andric       cgm.errorNYI("Inline only builtin function calls");
1181*700637cbSDimitry Andric     }
1182*700637cbSDimitry Andric 
1183*700637cbSDimitry Andric     // Replaceable builtins provide their own implementation of a builtin. If we
1184*700637cbSDimitry Andric     // are in an inline builtin implementation, avoid trivial infinite
1185*700637cbSDimitry Andric     // recursion. Honor __attribute__((no_builtin("foo"))) or
1186*700637cbSDimitry Andric     // __attribute__((no_builtin)) on the current function unless foo is
1187*700637cbSDimitry Andric     // not a predefined library function which means we must generate the
1188*700637cbSDimitry Andric     // builtin no matter what.
1189*700637cbSDimitry Andric     else if (!isPredefinedLibFunction || !hasAttributeNoBuiltin)
1190*700637cbSDimitry Andric       return CIRGenCallee::forBuiltin(builtinID, fd);
1191*700637cbSDimitry Andric   }
1192*700637cbSDimitry Andric 
1193*700637cbSDimitry Andric   cir::FuncOp callee = emitFunctionDeclPointer(cgm, gd);
1194*700637cbSDimitry Andric 
1195*700637cbSDimitry Andric   assert(!cir::MissingFeatures::hip());
1196*700637cbSDimitry Andric 
1197*700637cbSDimitry Andric   return CIRGenCallee::forDirect(callee, gd);
1198*700637cbSDimitry Andric }
1199*700637cbSDimitry Andric 
getUndefRValue(QualType ty)1200*700637cbSDimitry Andric RValue CIRGenFunction::getUndefRValue(QualType ty) {
1201*700637cbSDimitry Andric   if (ty->isVoidType())
1202*700637cbSDimitry Andric     return RValue::get(nullptr);
1203*700637cbSDimitry Andric 
1204*700637cbSDimitry Andric   cgm.errorNYI("unsupported type for undef rvalue");
1205*700637cbSDimitry Andric   return RValue::get(nullptr);
1206*700637cbSDimitry Andric }
1207*700637cbSDimitry Andric 
emitCall(clang::QualType calleeTy,const CIRGenCallee & callee,const clang::CallExpr * e,ReturnValueSlot returnValue)1208*700637cbSDimitry Andric RValue CIRGenFunction::emitCall(clang::QualType calleeTy,
1209*700637cbSDimitry Andric                                 const CIRGenCallee &callee,
1210*700637cbSDimitry Andric                                 const clang::CallExpr *e,
1211*700637cbSDimitry Andric                                 ReturnValueSlot returnValue) {
1212*700637cbSDimitry Andric   // Get the actual function type. The callee type will always be a pointer to
1213*700637cbSDimitry Andric   // function type or a block pointer type.
1214*700637cbSDimitry Andric   assert(calleeTy->isFunctionPointerType() &&
1215*700637cbSDimitry Andric          "Callee must have function pointer type!");
1216*700637cbSDimitry Andric 
1217*700637cbSDimitry Andric   calleeTy = getContext().getCanonicalType(calleeTy);
1218*700637cbSDimitry Andric   auto pointeeTy = cast<PointerType>(calleeTy)->getPointeeType();
1219*700637cbSDimitry Andric 
1220*700637cbSDimitry Andric   if (getLangOpts().CPlusPlus)
1221*700637cbSDimitry Andric     assert(!cir::MissingFeatures::sanitizers());
1222*700637cbSDimitry Andric 
1223*700637cbSDimitry Andric   const auto *fnType = cast<FunctionType>(pointeeTy);
1224*700637cbSDimitry Andric 
1225*700637cbSDimitry Andric   assert(!cir::MissingFeatures::sanitizers());
1226*700637cbSDimitry Andric 
1227*700637cbSDimitry Andric   CallArgList args;
1228*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opCallArgEvaluationOrder());
1229*700637cbSDimitry Andric 
1230*700637cbSDimitry Andric   emitCallArgs(args, dyn_cast<FunctionProtoType>(fnType), e->arguments(),
1231*700637cbSDimitry Andric                e->getDirectCallee());
1232*700637cbSDimitry Andric 
1233*700637cbSDimitry Andric   const CIRGenFunctionInfo &funcInfo =
1234*700637cbSDimitry Andric       cgm.getTypes().arrangeFreeFunctionCall(args, fnType);
1235*700637cbSDimitry Andric 
1236*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opCallNoPrototypeFunc());
1237*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opCallFnInfoOpts());
1238*700637cbSDimitry Andric   assert(!cir::MissingFeatures::hip());
1239*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opCallMustTail());
1240*700637cbSDimitry Andric 
1241*700637cbSDimitry Andric   cir::CIRCallOpInterface callOp;
1242*700637cbSDimitry Andric   RValue callResult = emitCall(funcInfo, callee, returnValue, args, &callOp,
1243*700637cbSDimitry Andric                                getLoc(e->getExprLoc()));
1244*700637cbSDimitry Andric 
1245*700637cbSDimitry Andric   assert(!cir::MissingFeatures::generateDebugInfo());
1246*700637cbSDimitry Andric 
1247*700637cbSDimitry Andric   return callResult;
1248*700637cbSDimitry Andric }
1249*700637cbSDimitry Andric 
emitCallee(const clang::Expr * e)1250*700637cbSDimitry Andric CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {
1251*700637cbSDimitry Andric   e = e->IgnoreParens();
1252*700637cbSDimitry Andric 
1253*700637cbSDimitry Andric   // Look through function-to-pointer decay.
1254*700637cbSDimitry Andric   if (const auto *implicitCast = dyn_cast<ImplicitCastExpr>(e)) {
1255*700637cbSDimitry Andric     if (implicitCast->getCastKind() == CK_FunctionToPointerDecay ||
1256*700637cbSDimitry Andric         implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {
1257*700637cbSDimitry Andric       return emitCallee(implicitCast->getSubExpr());
1258*700637cbSDimitry Andric     }
1259*700637cbSDimitry Andric     // When performing an indirect call through a function pointer lvalue, the
1260*700637cbSDimitry Andric     // function pointer lvalue is implicitly converted to an rvalue through an
1261*700637cbSDimitry Andric     // lvalue-to-rvalue conversion.
1262*700637cbSDimitry Andric     assert(implicitCast->getCastKind() == CK_LValueToRValue &&
1263*700637cbSDimitry Andric            "unexpected implicit cast on function pointers");
1264*700637cbSDimitry Andric   } else if (const auto *declRef = dyn_cast<DeclRefExpr>(e)) {
1265*700637cbSDimitry Andric     // Resolve direct calls.
1266*700637cbSDimitry Andric     const auto *funcDecl = cast<FunctionDecl>(declRef->getDecl());
1267*700637cbSDimitry Andric     return emitDirectCallee(funcDecl);
1268*700637cbSDimitry Andric   } else if (isa<MemberExpr>(e)) {
1269*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(),
1270*700637cbSDimitry Andric                  "emitCallee: call to member function is NYI");
1271*700637cbSDimitry Andric     return {};
1272*700637cbSDimitry Andric   }
1273*700637cbSDimitry Andric 
1274*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opCallPseudoDtor());
1275*700637cbSDimitry Andric 
1276*700637cbSDimitry Andric   // Otherwise, we have an indirect reference.
1277*700637cbSDimitry Andric   mlir::Value calleePtr;
1278*700637cbSDimitry Andric   QualType functionType;
1279*700637cbSDimitry Andric   if (const auto *ptrType = e->getType()->getAs<clang::PointerType>()) {
1280*700637cbSDimitry Andric     calleePtr = emitScalarExpr(e);
1281*700637cbSDimitry Andric     functionType = ptrType->getPointeeType();
1282*700637cbSDimitry Andric   } else {
1283*700637cbSDimitry Andric     functionType = e->getType();
1284*700637cbSDimitry Andric     calleePtr = emitLValue(e).getPointer();
1285*700637cbSDimitry Andric   }
1286*700637cbSDimitry Andric   assert(functionType->isFunctionType());
1287*700637cbSDimitry Andric 
1288*700637cbSDimitry Andric   GlobalDecl gd;
1289*700637cbSDimitry Andric   if (const auto *vd =
1290*700637cbSDimitry Andric           dyn_cast_or_null<VarDecl>(e->getReferencedDeclOfCallee()))
1291*700637cbSDimitry Andric     gd = GlobalDecl(vd);
1292*700637cbSDimitry Andric 
1293*700637cbSDimitry Andric   CIRGenCalleeInfo calleeInfo(functionType->getAs<FunctionProtoType>(), gd);
1294*700637cbSDimitry Andric   CIRGenCallee callee(calleeInfo, calleePtr.getDefiningOp());
1295*700637cbSDimitry Andric   return callee;
1296*700637cbSDimitry Andric }
1297*700637cbSDimitry Andric 
emitCallExpr(const clang::CallExpr * e,ReturnValueSlot returnValue)1298*700637cbSDimitry Andric RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
1299*700637cbSDimitry Andric                                     ReturnValueSlot returnValue) {
1300*700637cbSDimitry Andric   assert(!cir::MissingFeatures::objCBlocks());
1301*700637cbSDimitry Andric 
1302*700637cbSDimitry Andric   if (const auto *ce = dyn_cast<CXXMemberCallExpr>(e))
1303*700637cbSDimitry Andric     return emitCXXMemberCallExpr(ce, returnValue);
1304*700637cbSDimitry Andric 
1305*700637cbSDimitry Andric   if (isa<CUDAKernelCallExpr>(e)) {
1306*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "call to CUDA kernel");
1307*700637cbSDimitry Andric     return RValue::get(nullptr);
1308*700637cbSDimitry Andric   }
1309*700637cbSDimitry Andric 
1310*700637cbSDimitry Andric   if (const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(e)) {
1311*700637cbSDimitry Andric     // If the callee decl is a CXXMethodDecl, we need to emit this as a C++
1312*700637cbSDimitry Andric     // operator member call.
1313*700637cbSDimitry Andric     if (const CXXMethodDecl *md =
1314*700637cbSDimitry Andric             dyn_cast_or_null<CXXMethodDecl>(operatorCall->getCalleeDecl()))
1315*700637cbSDimitry Andric       return emitCXXOperatorMemberCallExpr(operatorCall, md, returnValue);
1316*700637cbSDimitry Andric     // A CXXOperatorCallExpr is created even for explicit object methods, but
1317*700637cbSDimitry Andric     // these should be treated like static function calls. Fall through to do
1318*700637cbSDimitry Andric     // that.
1319*700637cbSDimitry Andric   }
1320*700637cbSDimitry Andric 
1321*700637cbSDimitry Andric   CIRGenCallee callee = emitCallee(e->getCallee());
1322*700637cbSDimitry Andric 
1323*700637cbSDimitry Andric   if (callee.isBuiltin())
1324*700637cbSDimitry Andric     return emitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), e,
1325*700637cbSDimitry Andric                            returnValue);
1326*700637cbSDimitry Andric 
1327*700637cbSDimitry Andric   if (isa<CXXPseudoDestructorExpr>(e->getCallee())) {
1328*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "call to pseudo destructor");
1329*700637cbSDimitry Andric   }
1330*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opCallPseudoDtor());
1331*700637cbSDimitry Andric 
1332*700637cbSDimitry Andric   return emitCall(e->getCallee()->getType(), callee, e, returnValue);
1333*700637cbSDimitry Andric }
1334*700637cbSDimitry Andric 
1335*700637cbSDimitry Andric /// Emit code to compute the specified expression, ignoring the result.
emitIgnoredExpr(const Expr * e)1336*700637cbSDimitry Andric void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
1337*700637cbSDimitry Andric   if (e->isPRValue()) {
1338*700637cbSDimitry Andric     assert(!cir::MissingFeatures::aggValueSlot());
1339*700637cbSDimitry Andric     emitAnyExpr(e);
1340*700637cbSDimitry Andric     return;
1341*700637cbSDimitry Andric   }
1342*700637cbSDimitry Andric 
1343*700637cbSDimitry Andric   // Just emit it as an l-value and drop the result.
1344*700637cbSDimitry Andric   emitLValue(e);
1345*700637cbSDimitry Andric }
1346*700637cbSDimitry Andric 
emitArrayToPointerDecay(const Expr * e)1347*700637cbSDimitry Andric Address CIRGenFunction::emitArrayToPointerDecay(const Expr *e) {
1348*700637cbSDimitry Andric   assert(e->getType()->isArrayType() &&
1349*700637cbSDimitry Andric          "Array to pointer decay must have array source type!");
1350*700637cbSDimitry Andric 
1351*700637cbSDimitry Andric   // Expressions of array type can't be bitfields or vector elements.
1352*700637cbSDimitry Andric   LValue lv = emitLValue(e);
1353*700637cbSDimitry Andric   Address addr = lv.getAddress();
1354*700637cbSDimitry Andric 
1355*700637cbSDimitry Andric   // If the array type was an incomplete type, we need to make sure
1356*700637cbSDimitry Andric   // the decay ends up being the right type.
1357*700637cbSDimitry Andric   auto lvalueAddrTy = mlir::cast<cir::PointerType>(addr.getPointer().getType());
1358*700637cbSDimitry Andric 
1359*700637cbSDimitry Andric   if (e->getType()->isVariableArrayType())
1360*700637cbSDimitry Andric     return addr;
1361*700637cbSDimitry Andric 
1362*700637cbSDimitry Andric   auto pointeeTy = mlir::cast<cir::ArrayType>(lvalueAddrTy.getPointee());
1363*700637cbSDimitry Andric 
1364*700637cbSDimitry Andric   mlir::Type arrayTy = convertType(e->getType());
1365*700637cbSDimitry Andric   assert(mlir::isa<cir::ArrayType>(arrayTy) && "expected array");
1366*700637cbSDimitry Andric   assert(pointeeTy == arrayTy);
1367*700637cbSDimitry Andric 
1368*700637cbSDimitry Andric   // The result of this decay conversion points to an array element within the
1369*700637cbSDimitry Andric   // base lvalue. However, since TBAA currently does not support representing
1370*700637cbSDimitry Andric   // accesses to elements of member arrays, we conservatively represent accesses
1371*700637cbSDimitry Andric   // to the pointee object as if it had no any base lvalue specified.
1372*700637cbSDimitry Andric   // TODO: Support TBAA for member arrays.
1373*700637cbSDimitry Andric   QualType eltType = e->getType()->castAsArrayTypeUnsafe()->getElementType();
1374*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opTBAA());
1375*700637cbSDimitry Andric 
1376*700637cbSDimitry Andric   mlir::Value ptr = builder.maybeBuildArrayDecay(
1377*700637cbSDimitry Andric       cgm.getLoc(e->getSourceRange()), addr.getPointer(),
1378*700637cbSDimitry Andric       convertTypeForMem(eltType));
1379*700637cbSDimitry Andric   return Address(ptr, addr.getAlignment());
1380*700637cbSDimitry Andric }
1381*700637cbSDimitry Andric 
1382*700637cbSDimitry Andric /// Given the address of a temporary variable, produce an r-value of its type.
convertTempToRValue(Address addr,clang::QualType type,clang::SourceLocation loc)1383*700637cbSDimitry Andric RValue CIRGenFunction::convertTempToRValue(Address addr, clang::QualType type,
1384*700637cbSDimitry Andric                                            clang::SourceLocation loc) {
1385*700637cbSDimitry Andric   LValue lvalue = makeAddrLValue(addr, type, AlignmentSource::Decl);
1386*700637cbSDimitry Andric   switch (getEvaluationKind(type)) {
1387*700637cbSDimitry Andric   case cir::TEK_Complex:
1388*700637cbSDimitry Andric     cgm.errorNYI(loc, "convertTempToRValue: complex type");
1389*700637cbSDimitry Andric     return RValue::get(nullptr);
1390*700637cbSDimitry Andric   case cir::TEK_Aggregate:
1391*700637cbSDimitry Andric     cgm.errorNYI(loc, "convertTempToRValue: aggregate type");
1392*700637cbSDimitry Andric     return RValue::get(nullptr);
1393*700637cbSDimitry Andric   case cir::TEK_Scalar:
1394*700637cbSDimitry Andric     return RValue::get(emitLoadOfScalar(lvalue, loc));
1395*700637cbSDimitry Andric   }
1396*700637cbSDimitry Andric   llvm_unreachable("bad evaluation kind");
1397*700637cbSDimitry Andric }
1398*700637cbSDimitry Andric 
1399*700637cbSDimitry Andric /// Emit an `if` on a boolean condition, filling `then` and `else` into
1400*700637cbSDimitry Andric /// appropriated regions.
emitIfOnBoolExpr(const Expr * cond,const Stmt * thenS,const Stmt * elseS)1401*700637cbSDimitry Andric mlir::LogicalResult CIRGenFunction::emitIfOnBoolExpr(const Expr *cond,
1402*700637cbSDimitry Andric                                                      const Stmt *thenS,
1403*700637cbSDimitry Andric                                                      const Stmt *elseS) {
1404*700637cbSDimitry Andric   mlir::Location thenLoc = getLoc(thenS->getSourceRange());
1405*700637cbSDimitry Andric   std::optional<mlir::Location> elseLoc;
1406*700637cbSDimitry Andric   if (elseS)
1407*700637cbSDimitry Andric     elseLoc = getLoc(elseS->getSourceRange());
1408*700637cbSDimitry Andric 
1409*700637cbSDimitry Andric   mlir::LogicalResult resThen = mlir::success(), resElse = mlir::success();
1410*700637cbSDimitry Andric   emitIfOnBoolExpr(
1411*700637cbSDimitry Andric       cond, /*thenBuilder=*/
1412*700637cbSDimitry Andric       [&](mlir::OpBuilder &, mlir::Location) {
1413*700637cbSDimitry Andric         LexicalScope lexScope{*this, thenLoc, builder.getInsertionBlock()};
1414*700637cbSDimitry Andric         resThen = emitStmt(thenS, /*useCurrentScope=*/true);
1415*700637cbSDimitry Andric       },
1416*700637cbSDimitry Andric       thenLoc,
1417*700637cbSDimitry Andric       /*elseBuilder=*/
1418*700637cbSDimitry Andric       [&](mlir::OpBuilder &, mlir::Location) {
1419*700637cbSDimitry Andric         assert(elseLoc && "Invalid location for elseS.");
1420*700637cbSDimitry Andric         LexicalScope lexScope{*this, *elseLoc, builder.getInsertionBlock()};
1421*700637cbSDimitry Andric         resElse = emitStmt(elseS, /*useCurrentScope=*/true);
1422*700637cbSDimitry Andric       },
1423*700637cbSDimitry Andric       elseLoc);
1424*700637cbSDimitry Andric 
1425*700637cbSDimitry Andric   return mlir::LogicalResult::success(resThen.succeeded() &&
1426*700637cbSDimitry Andric                                       resElse.succeeded());
1427*700637cbSDimitry Andric }
1428*700637cbSDimitry Andric 
1429*700637cbSDimitry Andric /// Emit an `if` on a boolean condition, filling `then` and `else` into
1430*700637cbSDimitry Andric /// appropriated regions.
emitIfOnBoolExpr(const clang::Expr * cond,BuilderCallbackRef thenBuilder,mlir::Location thenLoc,BuilderCallbackRef elseBuilder,std::optional<mlir::Location> elseLoc)1431*700637cbSDimitry Andric cir::IfOp CIRGenFunction::emitIfOnBoolExpr(
1432*700637cbSDimitry Andric     const clang::Expr *cond, BuilderCallbackRef thenBuilder,
1433*700637cbSDimitry Andric     mlir::Location thenLoc, BuilderCallbackRef elseBuilder,
1434*700637cbSDimitry Andric     std::optional<mlir::Location> elseLoc) {
1435*700637cbSDimitry Andric   // Attempt to be as accurate as possible with IfOp location, generate
1436*700637cbSDimitry Andric   // one fused location that has either 2 or 4 total locations, depending
1437*700637cbSDimitry Andric   // on else's availability.
1438*700637cbSDimitry Andric   SmallVector<mlir::Location, 2> ifLocs{thenLoc};
1439*700637cbSDimitry Andric   if (elseLoc)
1440*700637cbSDimitry Andric     ifLocs.push_back(*elseLoc);
1441*700637cbSDimitry Andric   mlir::Location loc = mlir::FusedLoc::get(&getMLIRContext(), ifLocs);
1442*700637cbSDimitry Andric 
1443*700637cbSDimitry Andric   // Emit the code with the fully general case.
1444*700637cbSDimitry Andric   mlir::Value condV = emitOpOnBoolExpr(loc, cond);
1445*700637cbSDimitry Andric   return builder.create<cir::IfOp>(loc, condV, elseLoc.has_value(),
1446*700637cbSDimitry Andric                                    /*thenBuilder=*/thenBuilder,
1447*700637cbSDimitry Andric                                    /*elseBuilder=*/elseBuilder);
1448*700637cbSDimitry Andric }
1449*700637cbSDimitry Andric 
1450*700637cbSDimitry Andric /// TODO(cir): see EmitBranchOnBoolExpr for extra ideas).
emitOpOnBoolExpr(mlir::Location loc,const Expr * cond)1451*700637cbSDimitry Andric mlir::Value CIRGenFunction::emitOpOnBoolExpr(mlir::Location loc,
1452*700637cbSDimitry Andric                                              const Expr *cond) {
1453*700637cbSDimitry Andric   assert(!cir::MissingFeatures::pgoUse());
1454*700637cbSDimitry Andric   assert(!cir::MissingFeatures::generateDebugInfo());
1455*700637cbSDimitry Andric   cond = cond->IgnoreParens();
1456*700637cbSDimitry Andric 
1457*700637cbSDimitry Andric   // In LLVM the condition is reversed here for efficient codegen.
1458*700637cbSDimitry Andric   // This should be done in CIR prior to LLVM lowering, if we do now
1459*700637cbSDimitry Andric   // we can make CIR based diagnostics misleading.
1460*700637cbSDimitry Andric   //  cir.ternary(!x, t, f) -> cir.ternary(x, f, t)
1461*700637cbSDimitry Andric   assert(!cir::MissingFeatures::shouldReverseUnaryCondOnBoolExpr());
1462*700637cbSDimitry Andric 
1463*700637cbSDimitry Andric   if (const ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(cond)) {
1464*700637cbSDimitry Andric     Expr *trueExpr = condOp->getTrueExpr();
1465*700637cbSDimitry Andric     Expr *falseExpr = condOp->getFalseExpr();
1466*700637cbSDimitry Andric     mlir::Value condV = emitOpOnBoolExpr(loc, condOp->getCond());
1467*700637cbSDimitry Andric 
1468*700637cbSDimitry Andric     mlir::Value ternaryOpRes =
1469*700637cbSDimitry Andric         builder
1470*700637cbSDimitry Andric             .create<cir::TernaryOp>(
1471*700637cbSDimitry Andric                 loc, condV, /*thenBuilder=*/
1472*700637cbSDimitry Andric                 [this, trueExpr](mlir::OpBuilder &b, mlir::Location loc) {
1473*700637cbSDimitry Andric                   mlir::Value lhs = emitScalarExpr(trueExpr);
1474*700637cbSDimitry Andric                   b.create<cir::YieldOp>(loc, lhs);
1475*700637cbSDimitry Andric                 },
1476*700637cbSDimitry Andric                 /*elseBuilder=*/
1477*700637cbSDimitry Andric                 [this, falseExpr](mlir::OpBuilder &b, mlir::Location loc) {
1478*700637cbSDimitry Andric                   mlir::Value rhs = emitScalarExpr(falseExpr);
1479*700637cbSDimitry Andric                   b.create<cir::YieldOp>(loc, rhs);
1480*700637cbSDimitry Andric                 })
1481*700637cbSDimitry Andric             .getResult();
1482*700637cbSDimitry Andric 
1483*700637cbSDimitry Andric     return emitScalarConversion(ternaryOpRes, condOp->getType(),
1484*700637cbSDimitry Andric                                 getContext().BoolTy, condOp->getExprLoc());
1485*700637cbSDimitry Andric   }
1486*700637cbSDimitry Andric 
1487*700637cbSDimitry Andric   if (isa<CXXThrowExpr>(cond)) {
1488*700637cbSDimitry Andric     cgm.errorNYI("NYI");
1489*700637cbSDimitry Andric     return createDummyValue(loc, cond->getType());
1490*700637cbSDimitry Andric   }
1491*700637cbSDimitry Andric 
1492*700637cbSDimitry Andric   // If the branch has a condition wrapped by __builtin_unpredictable,
1493*700637cbSDimitry Andric   // create metadata that specifies that the branch is unpredictable.
1494*700637cbSDimitry Andric   // Don't bother if not optimizing because that metadata would not be used.
1495*700637cbSDimitry Andric   assert(!cir::MissingFeatures::insertBuiltinUnpredictable());
1496*700637cbSDimitry Andric 
1497*700637cbSDimitry Andric   // Emit the code with the fully general case.
1498*700637cbSDimitry Andric   return evaluateExprAsBool(cond);
1499*700637cbSDimitry Andric }
1500*700637cbSDimitry Andric 
emitAlloca(StringRef name,mlir::Type ty,mlir::Location loc,CharUnits alignment,bool insertIntoFnEntryBlock,mlir::Value arraySize)1501*700637cbSDimitry Andric mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
1502*700637cbSDimitry Andric                                        mlir::Location loc, CharUnits alignment,
1503*700637cbSDimitry Andric                                        bool insertIntoFnEntryBlock,
1504*700637cbSDimitry Andric                                        mlir::Value arraySize) {
1505*700637cbSDimitry Andric   mlir::Block *entryBlock = insertIntoFnEntryBlock
1506*700637cbSDimitry Andric                                 ? getCurFunctionEntryBlock()
1507*700637cbSDimitry Andric                                 : curLexScope->getEntryBlock();
1508*700637cbSDimitry Andric 
1509*700637cbSDimitry Andric   // If this is an alloca in the entry basic block of a cir.try and there's
1510*700637cbSDimitry Andric   // a surrounding cir.scope, make sure the alloca ends up in the surrounding
1511*700637cbSDimitry Andric   // scope instead. This is necessary in order to guarantee all SSA values are
1512*700637cbSDimitry Andric   // reachable during cleanups.
1513*700637cbSDimitry Andric   assert(!cir::MissingFeatures::tryOp());
1514*700637cbSDimitry Andric 
1515*700637cbSDimitry Andric   return emitAlloca(name, ty, loc, alignment,
1516*700637cbSDimitry Andric                     builder.getBestAllocaInsertPoint(entryBlock), arraySize);
1517*700637cbSDimitry Andric }
1518*700637cbSDimitry Andric 
emitAlloca(StringRef name,mlir::Type ty,mlir::Location loc,CharUnits alignment,mlir::OpBuilder::InsertPoint ip,mlir::Value arraySize)1519*700637cbSDimitry Andric mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
1520*700637cbSDimitry Andric                                        mlir::Location loc, CharUnits alignment,
1521*700637cbSDimitry Andric                                        mlir::OpBuilder::InsertPoint ip,
1522*700637cbSDimitry Andric                                        mlir::Value arraySize) {
1523*700637cbSDimitry Andric   // CIR uses its own alloca address space rather than follow the target data
1524*700637cbSDimitry Andric   // layout like original CodeGen. The data layout awareness should be done in
1525*700637cbSDimitry Andric   // the lowering pass instead.
1526*700637cbSDimitry Andric   assert(!cir::MissingFeatures::addressSpace());
1527*700637cbSDimitry Andric   cir::PointerType localVarPtrTy = builder.getPointerTo(ty);
1528*700637cbSDimitry Andric   mlir::IntegerAttr alignIntAttr = cgm.getSize(alignment);
1529*700637cbSDimitry Andric 
1530*700637cbSDimitry Andric   mlir::Value addr;
1531*700637cbSDimitry Andric   {
1532*700637cbSDimitry Andric     mlir::OpBuilder::InsertionGuard guard(builder);
1533*700637cbSDimitry Andric     builder.restoreInsertionPoint(ip);
1534*700637cbSDimitry Andric     addr = builder.createAlloca(loc, /*addr type*/ localVarPtrTy,
1535*700637cbSDimitry Andric                                 /*var type*/ ty, name, alignIntAttr);
1536*700637cbSDimitry Andric     assert(!cir::MissingFeatures::astVarDeclInterface());
1537*700637cbSDimitry Andric   }
1538*700637cbSDimitry Andric   return addr;
1539*700637cbSDimitry Andric }
1540*700637cbSDimitry Andric 
1541*700637cbSDimitry Andric // Note: this function also emit constructor calls to support a MSVC extensions
1542*700637cbSDimitry Andric // allowing explicit constructor function call.
emitCXXMemberCallExpr(const CXXMemberCallExpr * ce,ReturnValueSlot returnValue)1543*700637cbSDimitry Andric RValue CIRGenFunction::emitCXXMemberCallExpr(const CXXMemberCallExpr *ce,
1544*700637cbSDimitry Andric                                              ReturnValueSlot returnValue) {
1545*700637cbSDimitry Andric   const Expr *callee = ce->getCallee()->IgnoreParens();
1546*700637cbSDimitry Andric 
1547*700637cbSDimitry Andric   if (isa<BinaryOperator>(callee)) {
1548*700637cbSDimitry Andric     cgm.errorNYI(ce->getSourceRange(),
1549*700637cbSDimitry Andric                  "emitCXXMemberCallExpr: C++ binary operator");
1550*700637cbSDimitry Andric     return RValue::get(nullptr);
1551*700637cbSDimitry Andric   }
1552*700637cbSDimitry Andric 
1553*700637cbSDimitry Andric   const auto *me = cast<MemberExpr>(callee);
1554*700637cbSDimitry Andric   const auto *md = cast<CXXMethodDecl>(me->getMemberDecl());
1555*700637cbSDimitry Andric 
1556*700637cbSDimitry Andric   if (md->isStatic()) {
1557*700637cbSDimitry Andric     cgm.errorNYI(ce->getSourceRange(), "emitCXXMemberCallExpr: static method");
1558*700637cbSDimitry Andric     return RValue::get(nullptr);
1559*700637cbSDimitry Andric   }
1560*700637cbSDimitry Andric 
1561*700637cbSDimitry Andric   bool hasQualifier = me->hasQualifier();
1562*700637cbSDimitry Andric   NestedNameSpecifier *qualifier = hasQualifier ? me->getQualifier() : nullptr;
1563*700637cbSDimitry Andric   bool isArrow = me->isArrow();
1564*700637cbSDimitry Andric   const Expr *base = me->getBase();
1565*700637cbSDimitry Andric 
1566*700637cbSDimitry Andric   return emitCXXMemberOrOperatorMemberCallExpr(
1567*700637cbSDimitry Andric       ce, md, returnValue, hasQualifier, qualifier, isArrow, base);
1568*700637cbSDimitry Andric }
1569*700637cbSDimitry Andric 
emitCXXConstructExpr(const CXXConstructExpr * e,AggValueSlot dest)1570*700637cbSDimitry Andric void CIRGenFunction::emitCXXConstructExpr(const CXXConstructExpr *e,
1571*700637cbSDimitry Andric                                           AggValueSlot dest) {
1572*700637cbSDimitry Andric   assert(!dest.isIgnored() && "Must have a destination!");
1573*700637cbSDimitry Andric   const CXXConstructorDecl *cd = e->getConstructor();
1574*700637cbSDimitry Andric 
1575*700637cbSDimitry Andric   // If we require zero initialization before (or instead of) calling the
1576*700637cbSDimitry Andric   // constructor, as can be the case with a non-user-provided default
1577*700637cbSDimitry Andric   // constructor, emit the zero initialization now, unless destination is
1578*700637cbSDimitry Andric   // already zeroed.
1579*700637cbSDimitry Andric   if (e->requiresZeroInitialization() && !dest.isZeroed()) {
1580*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(),
1581*700637cbSDimitry Andric                  "emitCXXConstructExpr: requires initialization");
1582*700637cbSDimitry Andric     return;
1583*700637cbSDimitry Andric   }
1584*700637cbSDimitry Andric 
1585*700637cbSDimitry Andric   // If this is a call to a trivial default constructor:
1586*700637cbSDimitry Andric   // In LLVM: do nothing.
1587*700637cbSDimitry Andric   // In CIR: emit as a regular call, other later passes should lower the
1588*700637cbSDimitry Andric   // ctor call into trivial initialization.
1589*700637cbSDimitry Andric 
1590*700637cbSDimitry Andric   // Elide the constructor if we're constructing from a temporary
1591*700637cbSDimitry Andric   if (getLangOpts().ElideConstructors && e->isElidable()) {
1592*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(),
1593*700637cbSDimitry Andric                  "emitCXXConstructExpr: elidable constructor");
1594*700637cbSDimitry Andric     return;
1595*700637cbSDimitry Andric   }
1596*700637cbSDimitry Andric 
1597*700637cbSDimitry Andric   if (getContext().getAsArrayType(e->getType())) {
1598*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "emitCXXConstructExpr: array type");
1599*700637cbSDimitry Andric     return;
1600*700637cbSDimitry Andric   }
1601*700637cbSDimitry Andric 
1602*700637cbSDimitry Andric   clang::CXXCtorType type = Ctor_Complete;
1603*700637cbSDimitry Andric   bool forVirtualBase = false;
1604*700637cbSDimitry Andric   bool delegating = false;
1605*700637cbSDimitry Andric 
1606*700637cbSDimitry Andric   switch (e->getConstructionKind()) {
1607*700637cbSDimitry Andric   case CXXConstructionKind::Complete:
1608*700637cbSDimitry Andric     type = Ctor_Complete;
1609*700637cbSDimitry Andric     break;
1610*700637cbSDimitry Andric   case CXXConstructionKind::Delegating:
1611*700637cbSDimitry Andric     // We should be emitting a constructor; GlobalDecl will assert this
1612*700637cbSDimitry Andric     type = curGD.getCtorType();
1613*700637cbSDimitry Andric     delegating = true;
1614*700637cbSDimitry Andric     break;
1615*700637cbSDimitry Andric   case CXXConstructionKind::VirtualBase:
1616*700637cbSDimitry Andric     // This should just set 'forVirtualBase' to true and fall through, but
1617*700637cbSDimitry Andric     // virtual base class support is otherwise missing, so this needs to wait
1618*700637cbSDimitry Andric     // until it can be tested.
1619*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(),
1620*700637cbSDimitry Andric                  "emitCXXConstructExpr: virtual base constructor");
1621*700637cbSDimitry Andric     return;
1622*700637cbSDimitry Andric   case CXXConstructionKind::NonVirtualBase:
1623*700637cbSDimitry Andric     type = Ctor_Base;
1624*700637cbSDimitry Andric     break;
1625*700637cbSDimitry Andric   }
1626*700637cbSDimitry Andric 
1627*700637cbSDimitry Andric   emitCXXConstructorCall(cd, type, forVirtualBase, delegating, dest, e);
1628*700637cbSDimitry Andric }
1629*700637cbSDimitry Andric 
emitReferenceBindingToExpr(const Expr * e)1630*700637cbSDimitry Andric RValue CIRGenFunction::emitReferenceBindingToExpr(const Expr *e) {
1631*700637cbSDimitry Andric   // Emit the expression as an lvalue.
1632*700637cbSDimitry Andric   LValue lv = emitLValue(e);
1633*700637cbSDimitry Andric   assert(lv.isSimple());
1634*700637cbSDimitry Andric   mlir::Value value = lv.getPointer();
1635*700637cbSDimitry Andric 
1636*700637cbSDimitry Andric   assert(!cir::MissingFeatures::sanitizers());
1637*700637cbSDimitry Andric 
1638*700637cbSDimitry Andric   return RValue::get(value);
1639*700637cbSDimitry Andric }
1640*700637cbSDimitry Andric 
emitLoadOfReference(LValue refLVal,mlir::Location loc,LValueBaseInfo * pointeeBaseInfo)1641*700637cbSDimitry Andric Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc,
1642*700637cbSDimitry Andric                                             LValueBaseInfo *pointeeBaseInfo) {
1643*700637cbSDimitry Andric   if (refLVal.isVolatile())
1644*700637cbSDimitry Andric     cgm.errorNYI(loc, "load of volatile reference");
1645*700637cbSDimitry Andric 
1646*700637cbSDimitry Andric   cir::LoadOp load =
1647*700637cbSDimitry Andric       builder.create<cir::LoadOp>(loc, refLVal.getAddress().getElementType(),
1648*700637cbSDimitry Andric                                   refLVal.getAddress().getPointer());
1649*700637cbSDimitry Andric 
1650*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opTBAA());
1651*700637cbSDimitry Andric 
1652*700637cbSDimitry Andric   QualType pointeeType = refLVal.getType()->getPointeeType();
1653*700637cbSDimitry Andric   CharUnits align = cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);
1654*700637cbSDimitry Andric   return Address(load, convertTypeForMem(pointeeType), align);
1655*700637cbSDimitry Andric }
1656*700637cbSDimitry Andric 
emitLoadOfReferenceLValue(Address refAddr,mlir::Location loc,QualType refTy,AlignmentSource source)1657*700637cbSDimitry Andric LValue CIRGenFunction::emitLoadOfReferenceLValue(Address refAddr,
1658*700637cbSDimitry Andric                                                  mlir::Location loc,
1659*700637cbSDimitry Andric                                                  QualType refTy,
1660*700637cbSDimitry Andric                                                  AlignmentSource source) {
1661*700637cbSDimitry Andric   LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source));
1662*700637cbSDimitry Andric   LValueBaseInfo pointeeBaseInfo;
1663*700637cbSDimitry Andric   assert(!cir::MissingFeatures::opTBAA());
1664*700637cbSDimitry Andric   Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo);
1665*700637cbSDimitry Andric   return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(),
1666*700637cbSDimitry Andric                         pointeeBaseInfo);
1667*700637cbSDimitry Andric }
1668*700637cbSDimitry Andric 
createDummyValue(mlir::Location loc,clang::QualType qt)1669*700637cbSDimitry Andric mlir::Value CIRGenFunction::createDummyValue(mlir::Location loc,
1670*700637cbSDimitry Andric                                              clang::QualType qt) {
1671*700637cbSDimitry Andric   mlir::Type t = convertType(qt);
1672*700637cbSDimitry Andric   CharUnits alignment = getContext().getTypeAlignInChars(qt);
1673*700637cbSDimitry Andric   return builder.createDummyValue(loc, t, alignment);
1674*700637cbSDimitry Andric }
1675*700637cbSDimitry Andric 
1676*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
1677*700637cbSDimitry Andric // CIR builder helpers
1678*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
1679*700637cbSDimitry Andric 
createMemTemp(QualType ty,mlir::Location loc,const Twine & name,Address * alloca,mlir::OpBuilder::InsertPoint ip)1680*700637cbSDimitry Andric Address CIRGenFunction::createMemTemp(QualType ty, mlir::Location loc,
1681*700637cbSDimitry Andric                                       const Twine &name, Address *alloca,
1682*700637cbSDimitry Andric                                       mlir::OpBuilder::InsertPoint ip) {
1683*700637cbSDimitry Andric   // FIXME: Should we prefer the preferred type alignment here?
1684*700637cbSDimitry Andric   return createMemTemp(ty, getContext().getTypeAlignInChars(ty), loc, name,
1685*700637cbSDimitry Andric                        alloca, ip);
1686*700637cbSDimitry Andric }
1687*700637cbSDimitry Andric 
createMemTemp(QualType ty,CharUnits align,mlir::Location loc,const Twine & name,Address * alloca,mlir::OpBuilder::InsertPoint ip)1688*700637cbSDimitry Andric Address CIRGenFunction::createMemTemp(QualType ty, CharUnits align,
1689*700637cbSDimitry Andric                                       mlir::Location loc, const Twine &name,
1690*700637cbSDimitry Andric                                       Address *alloca,
1691*700637cbSDimitry Andric                                       mlir::OpBuilder::InsertPoint ip) {
1692*700637cbSDimitry Andric   Address result = createTempAlloca(convertTypeForMem(ty), align, loc, name,
1693*700637cbSDimitry Andric                                     /*ArraySize=*/nullptr, alloca, ip);
1694*700637cbSDimitry Andric   if (ty->isConstantMatrixType()) {
1695*700637cbSDimitry Andric     assert(!cir::MissingFeatures::matrixType());
1696*700637cbSDimitry Andric     cgm.errorNYI(loc, "temporary matrix value");
1697*700637cbSDimitry Andric   }
1698*700637cbSDimitry Andric   return result;
1699*700637cbSDimitry Andric }
1700*700637cbSDimitry Andric 
1701*700637cbSDimitry Andric /// This creates a alloca and inserts it into the entry block of the
1702*700637cbSDimitry Andric /// current region.
createTempAllocaWithoutCast(mlir::Type ty,CharUnits align,mlir::Location loc,const Twine & name,mlir::Value arraySize,mlir::OpBuilder::InsertPoint ip)1703*700637cbSDimitry Andric Address CIRGenFunction::createTempAllocaWithoutCast(
1704*700637cbSDimitry Andric     mlir::Type ty, CharUnits align, mlir::Location loc, const Twine &name,
1705*700637cbSDimitry Andric     mlir::Value arraySize, mlir::OpBuilder::InsertPoint ip) {
1706*700637cbSDimitry Andric   cir::AllocaOp alloca = ip.isSet()
1707*700637cbSDimitry Andric                              ? createTempAlloca(ty, loc, name, ip, arraySize)
1708*700637cbSDimitry Andric                              : createTempAlloca(ty, loc, name, arraySize);
1709*700637cbSDimitry Andric   alloca.setAlignmentAttr(cgm.getSize(align));
1710*700637cbSDimitry Andric   return Address(alloca, ty, align);
1711*700637cbSDimitry Andric }
1712*700637cbSDimitry Andric 
1713*700637cbSDimitry Andric /// This creates a alloca and inserts it into the entry block. The alloca is
1714*700637cbSDimitry Andric /// casted to default address space if necessary.
createTempAlloca(mlir::Type ty,CharUnits align,mlir::Location loc,const Twine & name,mlir::Value arraySize,Address * allocaAddr,mlir::OpBuilder::InsertPoint ip)1715*700637cbSDimitry Andric Address CIRGenFunction::createTempAlloca(mlir::Type ty, CharUnits align,
1716*700637cbSDimitry Andric                                          mlir::Location loc, const Twine &name,
1717*700637cbSDimitry Andric                                          mlir::Value arraySize,
1718*700637cbSDimitry Andric                                          Address *allocaAddr,
1719*700637cbSDimitry Andric                                          mlir::OpBuilder::InsertPoint ip) {
1720*700637cbSDimitry Andric   Address alloca =
1721*700637cbSDimitry Andric       createTempAllocaWithoutCast(ty, align, loc, name, arraySize, ip);
1722*700637cbSDimitry Andric   if (allocaAddr)
1723*700637cbSDimitry Andric     *allocaAddr = alloca;
1724*700637cbSDimitry Andric   mlir::Value v = alloca.getPointer();
1725*700637cbSDimitry Andric   // Alloca always returns a pointer in alloca address space, which may
1726*700637cbSDimitry Andric   // be different from the type defined by the language. For example,
1727*700637cbSDimitry Andric   // in C++ the auto variables are in the default address space. Therefore
1728*700637cbSDimitry Andric   // cast alloca to the default address space when necessary.
1729*700637cbSDimitry Andric   assert(!cir::MissingFeatures::addressSpace());
1730*700637cbSDimitry Andric   return Address(v, ty, align);
1731*700637cbSDimitry Andric }
1732*700637cbSDimitry Andric 
1733*700637cbSDimitry Andric /// This creates an alloca and inserts it into the entry block if \p ArraySize
1734*700637cbSDimitry Andric /// is nullptr, otherwise inserts it at the current insertion point of the
1735*700637cbSDimitry Andric /// builder.
createTempAlloca(mlir::Type ty,mlir::Location loc,const Twine & name,mlir::Value arraySize,bool insertIntoFnEntryBlock)1736*700637cbSDimitry Andric cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty,
1737*700637cbSDimitry Andric                                                mlir::Location loc,
1738*700637cbSDimitry Andric                                                const Twine &name,
1739*700637cbSDimitry Andric                                                mlir::Value arraySize,
1740*700637cbSDimitry Andric                                                bool insertIntoFnEntryBlock) {
1741*700637cbSDimitry Andric   return cast<cir::AllocaOp>(emitAlloca(name.str(), ty, loc, CharUnits(),
1742*700637cbSDimitry Andric                                         insertIntoFnEntryBlock, arraySize)
1743*700637cbSDimitry Andric                                  .getDefiningOp());
1744*700637cbSDimitry Andric }
1745*700637cbSDimitry Andric 
1746*700637cbSDimitry Andric /// This creates an alloca and inserts it into the provided insertion point
createTempAlloca(mlir::Type ty,mlir::Location loc,const Twine & name,mlir::OpBuilder::InsertPoint ip,mlir::Value arraySize)1747*700637cbSDimitry Andric cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty,
1748*700637cbSDimitry Andric                                                mlir::Location loc,
1749*700637cbSDimitry Andric                                                const Twine &name,
1750*700637cbSDimitry Andric                                                mlir::OpBuilder::InsertPoint ip,
1751*700637cbSDimitry Andric                                                mlir::Value arraySize) {
1752*700637cbSDimitry Andric   assert(ip.isSet() && "Insertion point is not set");
1753*700637cbSDimitry Andric   return cast<cir::AllocaOp>(
1754*700637cbSDimitry Andric       emitAlloca(name.str(), ty, loc, CharUnits(), ip, arraySize)
1755*700637cbSDimitry Andric           .getDefiningOp());
1756*700637cbSDimitry Andric }
1757*700637cbSDimitry Andric 
1758*700637cbSDimitry Andric /// Try to emit a reference to the given value without producing it as
1759*700637cbSDimitry Andric /// an l-value.  For many cases, this is just an optimization, but it avoids
1760*700637cbSDimitry Andric /// us needing to emit global copies of variables if they're named without
1761*700637cbSDimitry Andric /// triggering a formal use in a context where we can't emit a direct
1762*700637cbSDimitry Andric /// reference to them, for instance if a block or lambda or a member of a
1763*700637cbSDimitry Andric /// local class uses a const int variable or constexpr variable from an
1764*700637cbSDimitry Andric /// enclosing function.
1765*700637cbSDimitry Andric ///
1766*700637cbSDimitry Andric /// For named members of enums, this is the only way they are emitted.
1767*700637cbSDimitry Andric CIRGenFunction::ConstantEmission
tryEmitAsConstant(DeclRefExpr * refExpr)1768*700637cbSDimitry Andric CIRGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
1769*700637cbSDimitry Andric   ValueDecl *value = refExpr->getDecl();
1770*700637cbSDimitry Andric 
1771*700637cbSDimitry Andric   // There is a lot more to do here, but for now only EnumConstantDecl is
1772*700637cbSDimitry Andric   // supported.
1773*700637cbSDimitry Andric   assert(!cir::MissingFeatures::tryEmitAsConstant());
1774*700637cbSDimitry Andric 
1775*700637cbSDimitry Andric   // The value needs to be an enum constant or a constant variable.
1776*700637cbSDimitry Andric   if (!isa<EnumConstantDecl>(value))
1777*700637cbSDimitry Andric     return ConstantEmission();
1778*700637cbSDimitry Andric 
1779*700637cbSDimitry Andric   Expr::EvalResult result;
1780*700637cbSDimitry Andric   if (!refExpr->EvaluateAsRValue(result, getContext()))
1781*700637cbSDimitry Andric     return ConstantEmission();
1782*700637cbSDimitry Andric 
1783*700637cbSDimitry Andric   QualType resultType = refExpr->getType();
1784*700637cbSDimitry Andric 
1785*700637cbSDimitry Andric   // As long as we're only handling EnumConstantDecl, there should be no
1786*700637cbSDimitry Andric   // side-effects.
1787*700637cbSDimitry Andric   assert(!result.HasSideEffects);
1788*700637cbSDimitry Andric 
1789*700637cbSDimitry Andric   // Emit as a constant.
1790*700637cbSDimitry Andric   // FIXME(cir): have emitAbstract build a TypedAttr instead (this requires
1791*700637cbSDimitry Andric   // somewhat heavy refactoring...)
1792*700637cbSDimitry Andric   mlir::Attribute c = ConstantEmitter(*this).emitAbstract(
1793*700637cbSDimitry Andric       refExpr->getLocation(), result.Val, resultType);
1794*700637cbSDimitry Andric   mlir::TypedAttr cstToEmit = mlir::dyn_cast_if_present<mlir::TypedAttr>(c);
1795*700637cbSDimitry Andric   assert(cstToEmit && "expected a typed attribute");
1796*700637cbSDimitry Andric 
1797*700637cbSDimitry Andric   assert(!cir::MissingFeatures::generateDebugInfo());
1798*700637cbSDimitry Andric 
1799*700637cbSDimitry Andric   return ConstantEmission::forValue(cstToEmit);
1800*700637cbSDimitry Andric }
1801*700637cbSDimitry Andric 
emitScalarConstant(const CIRGenFunction::ConstantEmission & constant,Expr * e)1802*700637cbSDimitry Andric mlir::Value CIRGenFunction::emitScalarConstant(
1803*700637cbSDimitry Andric     const CIRGenFunction::ConstantEmission &constant, Expr *e) {
1804*700637cbSDimitry Andric   assert(constant && "not a constant");
1805*700637cbSDimitry Andric   if (constant.isReference()) {
1806*700637cbSDimitry Andric     cgm.errorNYI(e->getSourceRange(), "emitScalarConstant: reference");
1807*700637cbSDimitry Andric     return {};
1808*700637cbSDimitry Andric   }
1809*700637cbSDimitry Andric   return builder.getConstant(getLoc(e->getSourceRange()), constant.getValue());
1810*700637cbSDimitry Andric }
1811*700637cbSDimitry Andric 
1812*700637cbSDimitry Andric /// An LValue is a candidate for having its loads and stores be made atomic if
1813*700637cbSDimitry Andric /// we are operating under /volatile:ms *and* the LValue itself is volatile and
1814*700637cbSDimitry Andric /// performing such an operation can be performed without a libcall.
isLValueSuitableForInlineAtomic(LValue lv)1815*700637cbSDimitry Andric bool CIRGenFunction::isLValueSuitableForInlineAtomic(LValue lv) {
1816*700637cbSDimitry Andric   if (!cgm.getLangOpts().MSVolatile)
1817*700637cbSDimitry Andric     return false;
1818*700637cbSDimitry Andric 
1819*700637cbSDimitry Andric   cgm.errorNYI("LValueSuitableForInlineAtomic LangOpts MSVolatile");
1820*700637cbSDimitry Andric   return false;
1821*700637cbSDimitry Andric }
1822