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
29using namespace clang;
30using namespace clang::CIRGen;
31using 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.
35Address CIRGenFunction::emitAddrOfFieldStorage(Address base,
36 const FieldDecl *field,
37 llvm::StringRef fieldName,
38 unsigned fieldIndex) {
39 if (field->isZeroSize(Ctx: 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(rd: rec);
59 unsigned idx = layout.getCIRFieldNo(fd: 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.
67Address 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>(Val: expr)) {
76 if (isa<ExplicitCastExpr>(Val: 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(expr: ce->getSubExpr(), baseInfo);
104 const CXXRecordDecl *derived =
105 ce->getSubExpr()->getType()->getPointeeCXXRecordDecl();
106 return getAddressOfBaseClass(value: addr, derived, path: ce->path(),
107 nullCheckValue: shouldNullCheckClassCastValue(ce),
108 loc: 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>(Val: 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>(Val: 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
213void 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
242static 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(D: 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, ty: t, source: AlignmentSource::Decl);
275 assert(!cir::MissingFeatures::setObjCGCLValueClass());
276 return lv;
277}
278
279void 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
326mlir::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
345RValue 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
361Address 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
372LValue CIRGenFunction::emitLValueForBitField(LValue base,
373 const FieldDecl *field) {
374 LValueBaseInfo baseInfo = base.getBaseInfo();
375 const CIRGenRecordLayout &layout =
376 cgm.getTypes().getCIRGenRecordLayout(rd: field->getParent());
377 const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(fd: field);
378 assert(!cir::MissingFeatures::armComputeVolatileBitfields());
379 assert(!cir::MissingFeatures::preservedAccessIndexRegion());
380 unsigned idx = layout.getCIRFieldNo(fd: field);
381
382 Address addr = getAddrOfBitFieldStorage(base, field, fieldType: info.storageType, index: 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(CVR: 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, type: fieldType, baseInfo: fieldBaseInfo);
394}
395
396LValue 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(source: baseAlignSource));
406 assert(!cir::MissingFeatures::opTBAA());
407
408 Address addr = base.getAddress();
409 if (auto *classDecl = dyn_cast<CXXRecordDecl>(Val: 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(rd: field->getParent());
428 fieldIndex = layout.getCIRFieldNo(fd: field);
429 }
430
431 addr = emitAddrOfFieldStorage(base: 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, ty: fieldType, baseInfo: fieldBaseInfo);
446 lv.getQuals().addCVRQualifiers(mask: 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
458LValue 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(rd: field->getParent());
467 unsigned fieldIndex = layout.getCIRFieldNo(fd: field);
468
469 Address v =
470 emitAddrOfFieldStorage(base: 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(source: fieldAlignSource));
482 assert(!cir::MissingFeatures::opTBAA());
483 return makeAddrLValue(addr: v, ty: fieldType, baseInfo: fieldBaseInfo);
484}
485
486mlir::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
493void 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
504mlir::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.
524RValue 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
545LValue 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>(Val: 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(cgf&: *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(Val: 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
590mlir::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
609LValue 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: 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(expr: e->getSubExpr(), baseInfo: &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, ty: 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: 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(T: 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(addr: component, ty: elemTy);
660 elemLV.getQuals().addQualifiers(Q: lv.getQuals());
661 return elemLV;
662 }
663 case UO_PreInc:
664 case UO_PreDec: {
665 bool isInc = e->isIncrementOp();
666 LValue lv = emitLValue(e: 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.
697static 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>(Val: 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
711static 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
718static 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(elementSize: eltSize);
729}
730
731static QualType getFixedSizeElementType(const ASTContext &astContext,
732 const VariableArrayType *vla) {
733 QualType eltType;
734 do {
735 eltType = vla->getElementType();
736 } while ((vla = astContext.getAsVariableArrayType(T: eltType)));
737 return eltType;
738}
739
740static 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
753static 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(T: eltType)) {
763 eltType = getFixedSizeElementType(astContext: 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(T: 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
779LValue
780CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
781 if (isa<ExtVectorElementExpr>(Val: e->getBase())) {
782 cgm.errorNYI(e->getSourceRange(),
783 "emitArraySubscriptExpr: ExtVectorElementExpr");
784 return LValue::makeAddr(address: Address::invalid(), t: e->getType(), baseInfo: LValueBaseInfo());
785 }
786
787 if (getContext().getAsVariableArrayType(T: e->getType())) {
788 cgm.errorNYI(e->getSourceRange(),
789 "emitArraySubscriptExpr: VariableArrayType");
790 return LValue::makeAddr(address: Address::invalid(), t: e->getType(), baseInfo: LValueBaseInfo());
791 }
792
793 if (e->getType()->getAs<ObjCObjectType>()) {
794 cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjCObjectType");
795 return LValue::makeAddr(address: Address::invalid(), t: e->getType(), baseInfo: 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>(Val: e->getBase())) {
818 const mlir::Value idx = emitIdxAfterBase(/*promote=*/false);
819 const LValue lhs = emitLValue(e: 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: e->getBase())) {
826 LValue arrayLV;
827 if (const auto *ase = dyn_cast<ArraySubscriptExpr>(Val: array))
828 arrayLV = emitArraySubscriptExpr(e: ase);
829 else
830 arrayLV = emitLValue(e: 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(address: addr, t: e->getType(), baseInfo: 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(expr: e->getBase(), baseInfo: &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(address: addxr, t: e->getType(), baseInfo: 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
868LValue 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 addr: Address(addr, globalOp.getSymType(), CharUnits::fromQuantity(Quantity: align)),
876 ty: e->getType(), source: 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.
885LValue 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: 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>(Val: derivedClassTy->getDecl());
991
992 LValue lv = emitLValue(e: e->getSubExpr());
993 Address thisAddr = lv.getAddress();
994
995 // Perform the derived-to-base conversion
996 Address baseAddr =
997 getAddressOfBaseClass(value: thisAddr, derived: derivedClassDecl, path: e->path(),
998 /*NullCheckValue=*/nullCheckValue: false, loc: 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(addr: baseAddr, ty: e->getType(), baseInfo: 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
1014LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {
1015 if (isa<VarDecl>(Val: 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(expr: baseExpr, baseInfo: &baseInfo);
1027 QualType ptrTy = baseExpr->getType()->getPointeeType();
1028 assert(!cir::MissingFeatures::typeChecks());
1029 baseLV = makeAddrLValue(addr, ty: ptrTy, baseInfo);
1030 } else {
1031 assert(!cir::MissingFeatures::typeChecks());
1032 baseLV = emitLValue(e: baseExpr);
1033 }
1034
1035 const NamedDecl *nd = e->getMemberDecl();
1036 if (auto *field = dyn_cast<FieldDecl>(Val: nd)) {
1037 LValue lv = emitLValueForField(base: 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>(Val: nd)) {
1049 cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: FunctionDecl");
1050 return LValue();
1051 }
1052
1053 llvm_unreachable("Unhandled member declaration!");
1054}
1055
1056LValue 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
1071LValue 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: e->getLHS());
1075 return emitLValue(e: 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(type: 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: e->getRHS());
1098 LValue lv = emitLValue(e: e->getLHS());
1099
1100 SourceLocRAIIObject loc{*this, getLoc(e->getSourceRange())};
1101 if (lv.isBitField())
1102 emitStoreThroughBitfieldLValue(rv, lv);
1103 else
1104 emitStoreThroughLValue(src: rv, dst: 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.
1127RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot) {
1128 switch (CIRGenFunction::getEvaluationKind(type: 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, slot: aggSlot);
1138 return aggSlot.asRValue();
1139 }
1140 }
1141 llvm_unreachable("bad evaluation kind");
1142}
1143
1144static 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.
1152static 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
1159CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) {
1160 const auto *fd = cast<FunctionDecl>(Val: gd.getDecl());
1161
1162 if (unsigned builtinID = fd->getBuiltinID()) {
1163 if (fd->getAttr<AsmLabelAttr>()) {
1164 cgm.errorNYI(feature: "AsmLabelAttr");
1165 }
1166
1167 StringRef ident = fd->getName();
1168 std::string fdInlineName = (ident + ".inline").str();
1169
1170 bool isPredefinedLibFunction =
1171 cgm.getASTContext().BuiltinInfo.isPredefinedLibFunction(ID: 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(feature: "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, builtinDecl: 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
1200RValue CIRGenFunction::getUndefRValue(QualType ty) {
1201 if (ty->isVoidType())
1202 return RValue::get(nullptr);
1203
1204 cgm.errorNYI(feature: "unsupported type for undef rvalue");
1205 return RValue::get(nullptr);
1206}
1207
1208RValue 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(T: calleeTy);
1218 auto pointeeTy = cast<PointerType>(Val&: calleeTy)->getPointeeType();
1219
1220 if (getLangOpts().CPlusPlus)
1221 assert(!cir::MissingFeatures::sanitizers());
1222
1223 const auto *fnType = cast<FunctionType>(Val&: pointeeTy);
1224
1225 assert(!cir::MissingFeatures::sanitizers());
1226
1227 CallArgList args;
1228 assert(!cir::MissingFeatures::opCallArgEvaluationOrder());
1229
1230 emitCallArgs(args, prototype: dyn_cast<FunctionProtoType>(Val: fnType), argRange: e->arguments(),
1231 callee: 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
1250CIRGenCallee 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>(Val: e)) {
1255 if (implicitCast->getCastKind() == CK_FunctionToPointerDecay ||
1256 implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {
1257 return emitCallee(e: 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>(Val: e)) {
1265 // Resolve direct calls.
1266 const auto *funcDecl = cast<FunctionDecl>(Val: declRef->getDecl());
1267 return emitDirectCallee(gd: funcDecl);
1268 } else if (isa<MemberExpr>(Val: 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>(Val: 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
1298RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
1299 ReturnValueSlot returnValue) {
1300 assert(!cir::MissingFeatures::objCBlocks());
1301
1302 if (const auto *ce = dyn_cast<CXXMemberCallExpr>(Val: e))
1303 return emitCXXMemberCallExpr(e: ce, returnValue);
1304
1305 if (isa<CUDAKernelCallExpr>(Val: 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>(Val: 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>(Val: operatorCall->getCalleeDecl()))
1315 return emitCXXOperatorMemberCallExpr(e: 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: e->getCallee());
1322
1323 if (callee.isBuiltin())
1324 return emitBuiltinExpr(gd: callee.getBuiltinDecl(), builtinID: callee.getBuiltinID(), e,
1325 returnValue);
1326
1327 if (isa<CXXPseudoDestructorExpr>(Val: e->getCallee())) {
1328 cgm.errorNYI(e->getSourceRange(), "call to pseudo destructor");
1329 }
1330 assert(!cir::MissingFeatures::opCallPseudoDtor());
1331
1332 return emitCall(calleeTy: e->getCallee()->getType(), callee, e, returnValue);
1333}
1334
1335/// Emit code to compute the specified expression, ignoring the result.
1336void 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
1347Address 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.
1383RValue CIRGenFunction::convertTempToRValue(Address addr, clang::QualType type,
1384 clang::SourceLocation loc) {
1385 LValue lvalue = makeAddrLValue(addr, ty: type, source: 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.
1401mlir::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.
1431cir::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).
1451mlir::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>(Val: 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>(Val: cond)) {
1488 cgm.errorNYI(feature: "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
1501mlir::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
1519mlir::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.
1543RValue CIRGenFunction::emitCXXMemberCallExpr(const CXXMemberCallExpr *ce,
1544 ReturnValueSlot returnValue) {
1545 const Expr *callee = ce->getCallee()->IgnoreParens();
1546
1547 if (isa<BinaryOperator>(Val: callee)) {
1548 cgm.errorNYI(ce->getSourceRange(),
1549 "emitCXXMemberCallExpr: C++ binary operator");
1550 return RValue::get(nullptr);
1551 }
1552
1553 const auto *me = cast<MemberExpr>(Val: callee);
1554 const auto *md = cast<CXXMethodDecl>(Val: 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
1570void 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(T: 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(d: cd, type, forVirtualBase, delegating, thisAVS: dest, e);
1628}
1629
1630RValue 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
1641Address 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(t: pointeeType, baseInfo: pointeeBaseInfo);
1654 return Address(load, convertTypeForMem(pointeeType), align);
1655}
1656
1657LValue CIRGenFunction::emitLoadOfReferenceLValue(Address refAddr,
1658 mlir::Location loc,
1659 QualType refTy,
1660 AlignmentSource source) {
1661 LValue refLVal = makeAddrLValue(addr: refAddr, ty: refTy, baseInfo: LValueBaseInfo(source));
1662 LValueBaseInfo pointeeBaseInfo;
1663 assert(!cir::MissingFeatures::opTBAA());
1664 Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo);
1665 return makeAddrLValue(addr: pointeeAddr, ty: refLVal.getType()->getPointeeType(),
1666 baseInfo: pointeeBaseInfo);
1667}
1668
1669mlir::Value CIRGenFunction::createDummyValue(mlir::Location loc,
1670 clang::QualType qt) {
1671 mlir::Type t = convertType(qt);
1672 CharUnits alignment = getContext().getTypeAlignInChars(T: qt);
1673 return builder.createDummyValue(loc, t, alignment);
1674}
1675
1676//===----------------------------------------------------------------------===//
1677// CIR builder helpers
1678//===----------------------------------------------------------------------===//
1679
1680Address 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
1688Address 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.
1703Address 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.
1715Address 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.
1736cir::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
1747cir::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.
1767CIRGenFunction::ConstantEmission
1768CIRGenFunction::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>(Val: value))
1777 return ConstantEmission();
1778
1779 Expr::EvalResult result;
1780 if (!refExpr->EvaluateAsRValue(Result&: result, Ctx: 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
1802mlir::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.
1815bool CIRGenFunction::isLValueSuitableForInlineAtomic(LValue lv) {
1816 if (!cgm.getLangOpts().MSVolatile)
1817 return false;
1818
1819 cgm.errorNYI(feature: "LValueSuitableForInlineAtomic LangOpts MSVolatile");
1820 return false;
1821}
1822

source code of clang/lib/CIR/CodeGen/CIRGenExpr.cpp