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