clang 22.0.0git
CIRGenExpr.cpp
Go to the documentation of this file.
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"
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"
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.
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);
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.
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 (const auto *ece = dyn_cast<ExplicitCastExpr>(ce))
77 cgm.emitExplicitCastExprType(ece);
78
79 switch (ce->getCastKind()) {
80 // Non-converting casts (but not C's implicit conversion from void*).
81 case CK_BitCast:
82 case CK_NoOp:
83 case CK_AddressSpaceConversion: {
84 if (const auto *ptrTy =
85 ce->getSubExpr()->getType()->getAs<PointerType>()) {
86 if (ptrTy->getPointeeType()->isVoidType())
87 break;
88
89 LValueBaseInfo innerBaseInfo;
91 Address addr =
92 emitPointerWithAlignment(ce->getSubExpr(), &innerBaseInfo);
93 if (baseInfo)
94 *baseInfo = innerBaseInfo;
95
96 if (isa<ExplicitCastExpr>(ce)) {
97 LValueBaseInfo targetTypeBaseInfo;
98
99 const QualType pointeeType = expr->getType()->getPointeeType();
100 const CharUnits align =
101 cgm.getNaturalTypeAlignment(pointeeType, &targetTypeBaseInfo);
102
103 // If the source l-value is opaque, honor the alignment of the
104 // casted-to type.
105 if (innerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) {
106 if (baseInfo)
107 baseInfo->mergeForCast(targetTypeBaseInfo);
108 addr = Address(addr.getPointer(), addr.getElementType(), align);
109 }
110 }
111
113
114 const mlir::Type eltTy =
115 convertTypeForMem(expr->getType()->getPointeeType());
116 addr = getBuilder().createElementBitCast(getLoc(expr->getSourceRange()),
117 addr, eltTy);
119
120 return addr;
121 }
122 break;
123 }
124
125 // Array-to-pointer decay. TODO(cir): BaseInfo and TBAAInfo.
126 case CK_ArrayToPointerDecay:
127 return emitArrayToPointerDecay(ce->getSubExpr(), baseInfo);
128
129 case CK_UncheckedDerivedToBase:
130 case CK_DerivedToBase: {
133 Address addr = emitPointerWithAlignment(ce->getSubExpr(), baseInfo);
134 const CXXRecordDecl *derived =
135 ce->getSubExpr()->getType()->getPointeeCXXRecordDecl();
136 return getAddressOfBaseClass(addr, derived, ce->path(),
138 ce->getExprLoc());
139 }
140
141 case CK_AnyPointerToBlockPointerCast:
142 case CK_BaseToDerived:
143 case CK_BaseToDerivedMemberPointer:
144 case CK_BlockPointerToObjCPointerCast:
145 case CK_BuiltinFnToFnPtr:
146 case CK_CPointerToObjCPointerCast:
147 case CK_DerivedToBaseMemberPointer:
148 case CK_Dynamic:
149 case CK_FunctionToPointerDecay:
150 case CK_IntegralToPointer:
151 case CK_LValueToRValue:
152 case CK_LValueToRValueBitCast:
153 case CK_NullToMemberPointer:
154 case CK_NullToPointer:
155 case CK_ReinterpretMemberPointer:
156 // Common pointer conversions, nothing to do here.
157 // TODO: Is there any reason to treat base-to-derived conversions
158 // specially?
159 break;
160
161 case CK_ARCConsumeObject:
162 case CK_ARCExtendBlockObject:
163 case CK_ARCProduceObject:
164 case CK_ARCReclaimReturnedObject:
165 case CK_AtomicToNonAtomic:
166 case CK_BooleanToSignedIntegral:
167 case CK_ConstructorConversion:
168 case CK_CopyAndAutoreleaseBlockObject:
169 case CK_Dependent:
170 case CK_FixedPointCast:
171 case CK_FixedPointToBoolean:
172 case CK_FixedPointToFloating:
173 case CK_FixedPointToIntegral:
174 case CK_FloatingCast:
175 case CK_FloatingComplexCast:
176 case CK_FloatingComplexToBoolean:
177 case CK_FloatingComplexToIntegralComplex:
178 case CK_FloatingComplexToReal:
179 case CK_FloatingRealToComplex:
180 case CK_FloatingToBoolean:
181 case CK_FloatingToFixedPoint:
182 case CK_FloatingToIntegral:
183 case CK_HLSLAggregateSplatCast:
184 case CK_HLSLArrayRValue:
185 case CK_HLSLElementwiseCast:
186 case CK_HLSLVectorTruncation:
187 case CK_IntToOCLSampler:
188 case CK_IntegralCast:
189 case CK_IntegralComplexCast:
190 case CK_IntegralComplexToBoolean:
191 case CK_IntegralComplexToFloatingComplex:
192 case CK_IntegralComplexToReal:
193 case CK_IntegralRealToComplex:
194 case CK_IntegralToBoolean:
195 case CK_IntegralToFixedPoint:
196 case CK_IntegralToFloating:
197 case CK_LValueBitCast:
198 case CK_MatrixCast:
199 case CK_MemberPointerToBoolean:
200 case CK_NonAtomicToAtomic:
201 case CK_ObjCObjectLValueCast:
202 case CK_PointerToBoolean:
203 case CK_PointerToIntegral:
204 case CK_ToUnion:
205 case CK_ToVoid:
206 case CK_UserDefinedConversion:
207 case CK_VectorSplat:
208 case CK_ZeroToOCLOpaqueType:
209 llvm_unreachable("unexpected cast for emitPointerWithAlignment");
210 }
211 }
212
213 // Unary &
214 if (const UnaryOperator *uo = dyn_cast<UnaryOperator>(expr)) {
215 // TODO(cir): maybe we should use cir.unary for pointers here instead.
216 if (uo->getOpcode() == UO_AddrOf) {
217 LValue lv = emitLValue(uo->getSubExpr());
218 if (baseInfo)
219 *baseInfo = lv.getBaseInfo();
221 return lv.getAddress();
222 }
223 }
224
225 // std::addressof and variants.
226 if (auto const *call = dyn_cast<CallExpr>(expr)) {
227 switch (call->getBuiltinCallee()) {
228 default:
229 break;
230 case Builtin::BIaddressof:
231 case Builtin::BI__addressof:
232 case Builtin::BI__builtin_addressof: {
233 cgm.errorNYI(expr->getSourceRange(),
234 "emitPointerWithAlignment: builtin addressof");
235 return Address::invalid();
236 }
237 }
238 }
239
240 // Otherwise, use the alignment of the type.
242 emitScalarExpr(expr), expr->getType()->getPointeeType(), CharUnits(),
243 /*forPointeeType=*/true, baseInfo);
244}
245
247 bool isInit) {
248 if (!dst.isSimple()) {
249 if (dst.isVectorElt()) {
250 // Read/modify/write the vector, inserting the new element
251 const mlir::Location loc = dst.getVectorPointer().getLoc();
252 const mlir::Value vector =
253 builder.createLoad(loc, dst.getVectorAddress());
254 const mlir::Value newVector = builder.create<cir::VecInsertOp>(
255 loc, vector, src.getValue(), dst.getVectorIdx());
256 builder.createStore(loc, newVector, dst.getVectorAddress());
257 return;
258 }
259
260 assert(dst.isBitField() && "Unknown LValue type");
262 return;
263
264 cgm.errorNYI(dst.getPointer().getLoc(),
265 "emitStoreThroughLValue: non-simple lvalue");
266 return;
267 }
268
270
271 assert(src.isScalar() && "Can't emit an aggregate store with this method");
272 emitStoreOfScalar(src.getValue(), dst, isInit);
273}
274
275static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e,
276 const VarDecl *vd) {
277 QualType t = e->getType();
278
279 // If it's thread_local, emit a call to its wrapper function instead.
281 if (vd->getTLSKind() == VarDecl::TLS_Dynamic)
282 cgf.cgm.errorNYI(e->getSourceRange(),
283 "emitGlobalVarDeclLValue: thread_local variable");
284
285 // Check if the variable is marked as declare target with link clause in
286 // device codegen.
287 if (cgf.getLangOpts().OpenMP)
288 cgf.cgm.errorNYI(e->getSourceRange(), "emitGlobalVarDeclLValue: OpenMP");
289
290 // Traditional LLVM codegen handles thread local separately, CIR handles
291 // as part of getAddrOfGlobalVar.
292 mlir::Value v = cgf.cgm.getAddrOfGlobalVar(vd);
293
295 mlir::Type realVarTy = cgf.convertTypeForMem(vd->getType());
296 cir::PointerType realPtrTy = cgf.getBuilder().getPointerTo(realVarTy);
297 if (realPtrTy != v.getType())
298 v = cgf.getBuilder().createBitcast(v.getLoc(), v, realPtrTy);
299
300 CharUnits alignment = cgf.getContext().getDeclAlign(vd);
301 Address addr(v, realVarTy, alignment);
302 LValue lv;
303 if (vd->getType()->isReferenceType())
304 cgf.cgm.errorNYI(e->getSourceRange(),
305 "emitGlobalVarDeclLValue: reference type");
306 else
307 lv = cgf.makeAddrLValue(addr, t, AlignmentSource::Decl);
309 return lv;
310}
311
312void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
313 bool isVolatile, QualType ty,
314 bool isInit, bool isNontemporal) {
316
317 if (const auto *clangVecTy = ty->getAs<clang::VectorType>()) {
318 // Boolean vectors use `iN` as storage type.
319 if (clangVecTy->isExtVectorBoolType())
320 cgm.errorNYI(addr.getPointer().getLoc(),
321 "emitStoreOfScalar ExtVectorBoolType");
322
323 // Handle vectors of size 3 like size 4 for better performance.
324 const mlir::Type elementType = addr.getElementType();
325 const auto vecTy = cast<cir::VectorType>(elementType);
326
327 // TODO(CIR): Use `ABIInfo::getOptimalVectorMemoryType` once it upstreamed
329 if (vecTy.getSize() == 3 && !getLangOpts().PreserveVec3Type)
330 cgm.errorNYI(addr.getPointer().getLoc(),
331 "emitStoreOfScalar Vec3 & PreserveVec3Type disabled");
332 }
333
334 value = emitToMemory(value, ty);
335
337
338 // Update the alloca with more info on initialization.
339 assert(addr.getPointer() && "expected pointer to exist");
340 auto srcAlloca = addr.getDefiningOp<cir::AllocaOp>();
341 if (currVarDecl && srcAlloca) {
342 const VarDecl *vd = currVarDecl;
343 assert(vd && "VarDecl expected");
344 if (vd->hasInit())
345 srcAlloca.setInitAttr(mlir::UnitAttr::get(&getMLIRContext()));
346 }
347
348 assert(currSrcLoc && "must pass in source location");
349 builder.createStore(*currSrcLoc, value, addr, isVolatile);
350
351 if (isNontemporal) {
352 cgm.errorNYI(addr.getPointer().getLoc(), "emitStoreOfScalar nontemporal");
353 return;
354 }
355
357}
358
359// TODO: Replace this with a proper TargetInfo function call.
360/// Helper method to check if the underlying ABI is AAPCS
361static bool isAAPCS(const TargetInfo &targetInfo) {
362 return targetInfo.getABI().starts_with("aapcs");
363}
364
366 LValue dst) {
367
368 const CIRGenBitFieldInfo &info = dst.getBitFieldInfo();
369 mlir::Type resLTy = convertTypeForMem(dst.getType());
370 Address ptr = dst.getBitFieldAddress();
371
372 bool useVoaltile = cgm.getCodeGenOpts().AAPCSBitfieldWidth &&
373 dst.isVolatileQualified() &&
374 info.volatileStorageSize != 0 && isAAPCS(cgm.getTarget());
375
376 mlir::Value dstAddr = dst.getAddress().getPointer();
377
378 return builder.createSetBitfield(dstAddr.getLoc(), resLTy, ptr,
379 ptr.getElementType(), src.getValue(), info,
380 dst.isVolatileQualified(), useVoaltile);
381}
382
384 const CIRGenBitFieldInfo &info = lv.getBitFieldInfo();
385
386 // Get the output type.
387 mlir::Type resLTy = convertType(lv.getType());
388 Address ptr = lv.getBitFieldAddress();
389
390 bool useVoaltile = lv.isVolatileQualified() && info.volatileOffset != 0 &&
391 isAAPCS(cgm.getTarget());
392
393 mlir::Value field =
394 builder.createGetBitfield(getLoc(loc), resLTy, ptr, ptr.getElementType(),
395 info, lv.isVolatile(), useVoaltile);
397 return RValue::get(field);
398}
399
401 const FieldDecl *field,
402 mlir::Type fieldType,
403 unsigned index) {
404 mlir::Location loc = getLoc(field->getLocation());
405 cir::PointerType fieldPtr = cir::PointerType::get(fieldType);
407 cir::GetMemberOp sea = getBuilder().createGetMember(
408 loc, fieldPtr, base.getPointer(), field->getName(),
409 rec.isUnion() ? field->getFieldIndex() : index);
411 rec.getElementOffset(cgm.getDataLayout().layout, index));
412 return Address(sea, base.getAlignment().alignmentAtOffset(offset));
413}
414
416 const FieldDecl *field) {
417 LValueBaseInfo baseInfo = base.getBaseInfo();
418 const CIRGenRecordLayout &layout =
419 cgm.getTypes().getCIRGenRecordLayout(field->getParent());
420 const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);
421
423
424 unsigned idx = layout.getCIRFieldNo(field);
425 Address addr = getAddrOfBitFieldStorage(base, field, info.storageType, idx);
426
427 mlir::Location loc = getLoc(field->getLocation());
428 if (addr.getElementType() != info.storageType)
429 addr = builder.createElementBitCast(loc, addr, info.storageType);
430
431 QualType fieldType =
433 // TODO(cir): Support TBAA for bit fields.
435 LValueBaseInfo fieldBaseInfo(baseInfo.getAlignmentSource());
436 return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo);
437}
438
440 LValueBaseInfo baseInfo = base.getBaseInfo();
441
442 if (field->isBitField())
443 return emitLValueForBitField(base, field);
444
445 QualType fieldType = field->getType();
446 const RecordDecl *rec = field->getParent();
447 AlignmentSource baseAlignSource = baseInfo.getAlignmentSource();
448 LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(baseAlignSource));
450
451 Address addr = base.getAddress();
452 if (auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {
453 if (cgm.getCodeGenOpts().StrictVTablePointers &&
454 classDecl->isDynamicClass()) {
455 cgm.errorNYI(field->getSourceRange(),
456 "emitLValueForField: strict vtable for dynamic class");
457 }
458 }
459
460 unsigned recordCVR = base.getVRQualifiers();
461
462 llvm::StringRef fieldName = field->getName();
463 unsigned fieldIndex;
465
466 if (rec->isUnion())
467 fieldIndex = field->getFieldIndex();
468 else {
469 const CIRGenRecordLayout &layout =
470 cgm.getTypes().getCIRGenRecordLayout(field->getParent());
471 fieldIndex = layout.getCIRFieldNo(field);
472 }
473
474 addr = emitAddrOfFieldStorage(addr, field, fieldName, fieldIndex);
476
477 // If this is a reference field, load the reference right now.
478 if (fieldType->isReferenceType()) {
479 cgm.errorNYI(field->getSourceRange(), "emitLValueForField: reference type");
480 return LValue();
481 }
482
483 if (field->hasAttr<AnnotateAttr>()) {
484 cgm.errorNYI(field->getSourceRange(), "emitLValueForField: AnnotateAttr");
485 return LValue();
486 }
487
488 LValue lv = makeAddrLValue(addr, fieldType, fieldBaseInfo);
489 lv.getQuals().addCVRQualifiers(recordCVR);
490
491 // __weak attribute on a field is ignored.
493 cgm.errorNYI(field->getSourceRange(),
494 "emitLValueForField: __weak attribute");
495 return LValue();
496 }
497
498 return lv;
499}
500
502 LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName) {
503 QualType fieldType = field->getType();
504
505 if (!fieldType->isReferenceType())
506 return emitLValueForField(base, field);
507
508 const CIRGenRecordLayout &layout =
509 cgm.getTypes().getCIRGenRecordLayout(field->getParent());
510 unsigned fieldIndex = layout.getCIRFieldNo(field);
511
512 Address v =
513 emitAddrOfFieldStorage(base.getAddress(), field, fieldName, fieldIndex);
514
515 // Make sure that the address is pointing to the right type.
516 mlir::Type memTy = convertTypeForMem(fieldType);
517 v = builder.createElementBitCast(getLoc(field->getSourceRange()), v, memTy);
518
519 // TODO: Generate TBAA information that describes this access as a structure
520 // member access and not just an access to an object of the field's type. This
521 // should be similar to what we do in EmitLValueForField().
522 LValueBaseInfo baseInfo = base.getBaseInfo();
523 AlignmentSource fieldAlignSource = baseInfo.getAlignmentSource();
524 LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(fieldAlignSource));
526 return makeAddrLValue(v, fieldType, fieldBaseInfo);
527}
528
529mlir::Value CIRGenFunction::emitToMemory(mlir::Value value, QualType ty) {
530 // Bool has a different representation in memory than in registers,
531 // but in ClangIR, it is simply represented as a cir.bool value.
532 // This function is here as a placeholder for possible future changes.
533 return value;
534}
535
536void CIRGenFunction::emitStoreOfScalar(mlir::Value value, LValue lvalue,
537 bool isInit) {
538 if (lvalue.getType()->isConstantMatrixType()) {
539 assert(0 && "NYI: emitStoreOfScalar constant matrix type");
540 return;
541 }
542
543 emitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
544 lvalue.getType(), isInit, /*isNontemporal=*/false);
545}
546
547mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
548 QualType ty, SourceLocation loc,
549 LValueBaseInfo baseInfo) {
551 mlir::Type eltTy = addr.getElementType();
552
553 if (const auto *clangVecTy = ty->getAs<clang::VectorType>()) {
554 if (clangVecTy->isExtVectorBoolType()) {
555 cgm.errorNYI(loc, "emitLoadOfScalar: ExtVectorBoolType");
556 return nullptr;
557 }
558
559 const auto vecTy = cast<cir::VectorType>(eltTy);
560
561 // Handle vectors of size 3 like size 4 for better performance.
563 if (vecTy.getSize() == 3 && !getLangOpts().PreserveVec3Type)
564 cgm.errorNYI(addr.getPointer().getLoc(),
565 "emitLoadOfScalar Vec3 & PreserveVec3Type disabled");
566 }
567
569 LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
570 if (ty->isAtomicType() || isLValueSuitableForInlineAtomic(atomicLValue))
571 cgm.errorNYI("emitLoadOfScalar: load atomic");
572
573 if (mlir::isa<cir::VoidType>(eltTy))
574 cgm.errorNYI(loc, "emitLoadOfScalar: void type");
575
577
578 mlir::Value loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);
579 if (!ty->isBooleanType() && ty->hasBooleanRepresentation())
580 cgm.errorNYI("emitLoadOfScalar: boolean type with boolean representation");
581
582 return loadOp;
583}
584
586 SourceLocation loc) {
589 return emitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
590 lvalue.getType(), loc, lvalue.getBaseInfo());
591}
592
593/// Given an expression that represents a value lvalue, this
594/// method emits the address of the lvalue, then loads the result as an rvalue,
595/// returning the rvalue.
597 assert(!lv.getType()->isFunctionType());
598 assert(!(lv.getType()->isConstantMatrixType()) && "not implemented");
599
600 if (lv.isBitField())
601 return emitLoadOfBitfieldLValue(lv, loc);
602
603 if (lv.isSimple())
604 return RValue::get(emitLoadOfScalar(lv, loc));
605
606 if (lv.isVectorElt()) {
607 const mlir::Value load =
608 builder.createLoad(getLoc(loc), lv.getVectorAddress());
609 return RValue::get(builder.create<cir::VecExtractOp>(getLoc(loc), load,
610 lv.getVectorIdx()));
611 }
612
613 cgm.errorNYI(loc, "emitLoadOfLValue");
614 return RValue::get(nullptr);
615}
616
617static cir::FuncOp emitFunctionDeclPointer(CIRGenModule &cgm, GlobalDecl gd) {
619 return cgm.getAddrOfFunction(gd);
620}
621
622static LValue emitFunctionDeclLValue(CIRGenFunction &cgf, const Expr *e,
623 GlobalDecl gd) {
624 const FunctionDecl *fd = cast<FunctionDecl>(gd.getDecl());
625 cir::FuncOp funcOp = emitFunctionDeclPointer(cgf.cgm, gd);
626 mlir::Location loc = cgf.getLoc(e->getSourceRange());
627 CharUnits align = cgf.getContext().getDeclAlign(fd);
628
630
631 mlir::Type fnTy = funcOp.getFunctionType();
632 mlir::Type ptrTy = cir::PointerType::get(fnTy);
633 mlir::Value addr = cgf.getBuilder().create<cir::GetGlobalOp>(
634 loc, ptrTy, funcOp.getSymName());
635
636 if (funcOp.getFunctionType() != cgf.convertType(fd->getType())) {
637 fnTy = cgf.convertType(fd->getType());
638 ptrTy = cir::PointerType::get(fnTy);
639
640 addr = cir::CastOp::create(cgf.getBuilder(), addr.getLoc(), ptrTy,
641 cir::CastKind::bitcast, addr);
642 }
643
644 return cgf.makeAddrLValue(Address(addr, fnTy, align), e->getType(),
646}
647
649 const NamedDecl *nd = e->getDecl();
650 QualType ty = e->getType();
651
652 assert(e->isNonOdrUse() != NOUR_Unevaluated &&
653 "should not emit an unevaluated operand");
654
655 if (const auto *vd = dyn_cast<VarDecl>(nd)) {
656 // Checks for omitted feature handling
663
664 // Check if this is a global variable
665 if (vd->hasLinkage() || vd->isStaticDataMember())
666 return emitGlobalVarDeclLValue(*this, e, vd);
667
668 Address addr = Address::invalid();
669
670 // The variable should generally be present in the local decl map.
671 auto iter = localDeclMap.find(vd);
672 if (iter != localDeclMap.end()) {
673 addr = iter->second;
674 } else {
675 // Otherwise, it might be static local we haven't emitted yet for some
676 // reason; most likely, because it's in an outer function.
677 cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: static local");
678 }
679
680 // Drill into reference types.
681 LValue lv =
682 vd->getType()->isReferenceType()
686
687 // Statics are defined as globals, so they are not include in the function's
688 // symbol table.
689 assert((vd->isStaticLocal() || symbolTable.count(vd)) &&
690 "non-static locals should be already mapped");
691
692 return lv;
693 }
694
695 if (const auto *bd = dyn_cast<BindingDecl>(nd)) {
698 cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: lambda captures");
699 return LValue();
700 }
701 return emitLValue(bd->getBinding());
702 }
703
704 if (const auto *fd = dyn_cast<FunctionDecl>(nd)) {
705 LValue lv = emitFunctionDeclLValue(*this, e, fd);
706
707 // Emit debuginfo for the function declaration if the target wants to.
708 if (getContext().getTargetInfo().allowDebugInfoForExternalRef())
710
711 return lv;
712 }
713
714 cgm.errorNYI(e->getSourceRange(), "emitDeclRefLValue: unhandled decl type");
715 return LValue();
716}
717
719 QualType boolTy = getContext().BoolTy;
720 SourceLocation loc = e->getExprLoc();
721
723 if (e->getType()->getAs<MemberPointerType>()) {
724 cgm.errorNYI(e->getSourceRange(),
725 "evaluateExprAsBool: member pointer type");
726 return createDummyValue(getLoc(loc), boolTy);
727 }
728
730 if (!e->getType()->isAnyComplexType())
731 return emitScalarConversion(emitScalarExpr(e), e->getType(), boolTy, loc);
732
733 cgm.errorNYI(e->getSourceRange(), "evaluateExprAsBool: complex type");
734 return createDummyValue(getLoc(loc), boolTy);
735}
736
739
740 // __extension__ doesn't affect lvalue-ness.
741 if (op == UO_Extension)
742 return emitLValue(e->getSubExpr());
743
744 switch (op) {
745 case UO_Deref: {
747 assert(!t.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
748
750 LValueBaseInfo baseInfo;
751 Address addr = emitPointerWithAlignment(e->getSubExpr(), &baseInfo);
752
753 // Tag 'load' with deref attribute.
754 // FIXME: This misses some derefence cases and has problematic interactions
755 // with other operators.
756 if (auto loadOp = addr.getDefiningOp<cir::LoadOp>())
757 loadOp.setIsDerefAttr(mlir::UnitAttr::get(&getMLIRContext()));
758
759 LValue lv = makeAddrLValue(addr, t, baseInfo);
762 return lv;
763 }
764 case UO_Real:
765 case UO_Imag: {
766 LValue lv = emitLValue(e->getSubExpr());
767 assert(lv.isSimple() && "real/imag on non-ordinary l-value");
768
769 // __real is valid on scalars. This is a faster way of testing that.
770 // __imag can only produce an rvalue on scalars.
771 if (e->getOpcode() == UO_Real &&
772 !mlir::isa<cir::ComplexType>(lv.getAddress().getElementType())) {
773 assert(e->getSubExpr()->getType()->isArithmeticType());
774 return lv;
775 }
776
778 QualType elemTy = exprTy->castAs<clang::ComplexType>()->getElementType();
779 mlir::Location loc = getLoc(e->getExprLoc());
780 Address component =
781 e->getOpcode() == UO_Real
782 ? builder.createComplexRealPtr(loc, lv.getAddress())
783 : builder.createComplexImagPtr(loc, lv.getAddress());
785 LValue elemLV = makeAddrLValue(component, elemTy);
786 elemLV.getQuals().addQualifiers(lv.getQuals());
787 return elemLV;
788 }
789 case UO_PreInc:
790 case UO_PreDec: {
791 cir::UnaryOpKind kind =
792 e->isIncrementOp() ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec;
793 LValue lv = emitLValue(e->getSubExpr());
794
795 assert(e->isPrefix() && "Prefix operator in unexpected state!");
796
797 if (e->getType()->isAnyComplexType()) {
798 cgm.errorNYI(e->getSourceRange(), "UnaryOp complex inc/dec");
799 lv = LValue();
800 } else {
801 emitScalarPrePostIncDec(e, lv, kind, /*isPre=*/true);
802 }
803
804 return lv;
805 }
806 case UO_Extension:
807 llvm_unreachable("UnaryOperator extension should be handled above!");
808 case UO_Plus:
809 case UO_Minus:
810 case UO_Not:
811 case UO_LNot:
812 case UO_AddrOf:
813 case UO_PostInc:
814 case UO_PostDec:
815 case UO_Coawait:
816 llvm_unreachable("UnaryOperator of non-lvalue kind!");
817 }
818 llvm_unreachable("Unknown unary operator kind!");
819}
820
821/// If the specified expr is a simple decay from an array to pointer,
822/// return the array subexpression.
823/// FIXME: this could be abstracted into a common AST helper.
824static const Expr *getSimpleArrayDecayOperand(const Expr *e) {
825 // If this isn't just an array->pointer decay, bail out.
826 const auto *castExpr = dyn_cast<CastExpr>(e);
827 if (!castExpr || castExpr->getCastKind() != CK_ArrayToPointerDecay)
828 return nullptr;
829
830 // If this is a decay from variable width array, bail out.
831 const Expr *subExpr = castExpr->getSubExpr();
832 if (subExpr->getType()->isVariableArrayType())
833 return nullptr;
834
835 return subExpr;
836}
837
838static cir::IntAttr getConstantIndexOrNull(mlir::Value idx) {
839 // TODO(cir): should we consider using MLIRs IndexType instead of IntegerAttr?
840 if (auto constantOp = idx.getDefiningOp<cir::ConstantOp>())
841 return constantOp.getValueAttr<cir::IntAttr>();
842 return {};
843}
844
845static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx,
846 CharUnits eltSize) {
847 // If we have a constant index, we can use the exact offset of the
848 // element we're accessing.
849 if (const cir::IntAttr constantIdx = getConstantIndexOrNull(idx)) {
850 const CharUnits offset = constantIdx.getValue().getZExtValue() * eltSize;
851 return arrayAlign.alignmentAtOffset(offset);
852 }
853 // Otherwise, use the worst-case alignment for any element.
854 return arrayAlign.alignmentOfArrayElement(eltSize);
855}
856
858 const VariableArrayType *vla) {
859 QualType eltType;
860 do {
861 eltType = vla->getElementType();
862 } while ((vla = astContext.getAsVariableArrayType(eltType)));
863 return eltType;
864}
865
866static mlir::Value emitArraySubscriptPtr(CIRGenFunction &cgf,
867 mlir::Location beginLoc,
868 mlir::Location endLoc, mlir::Value ptr,
869 mlir::Type eltTy, mlir::Value idx,
870 bool shouldDecay) {
871 CIRGenModule &cgm = cgf.getCIRGenModule();
872 // TODO(cir): LLVM codegen emits in bound gep check here, is there anything
873 // that would enhance tracking this later in CIR?
875 return cgm.getBuilder().getArrayElement(beginLoc, endLoc, ptr, eltTy, idx,
876 shouldDecay);
877}
878
880 mlir::Location beginLoc,
881 mlir::Location endLoc, Address addr,
882 QualType eltType, mlir::Value idx,
883 mlir::Location loc, bool shouldDecay) {
884
885 // Determine the element size of the statically-sized base. This is
886 // the thing that the indices are expressed in terms of.
887 if (const VariableArrayType *vla =
888 cgf.getContext().getAsVariableArrayType(eltType)) {
889 eltType = getFixedSizeElementType(cgf.getContext(), vla);
890 }
891
892 // We can use that to compute the best alignment of the element.
893 const CharUnits eltSize = cgf.getContext().getTypeSizeInChars(eltType);
894 const CharUnits eltAlign =
895 getArrayElementAlign(addr.getAlignment(), idx, eltSize);
896
898 const mlir::Value eltPtr =
899 emitArraySubscriptPtr(cgf, beginLoc, endLoc, addr.getPointer(),
900 addr.getElementType(), idx, shouldDecay);
901 const mlir::Type elementType = cgf.convertTypeForMem(eltType);
902 return Address(eltPtr, elementType, eltAlign);
903}
904
905LValue
908 cgm.errorNYI(e->getSourceRange(),
909 "emitArraySubscriptExpr: ExtVectorElementExpr");
911 }
912
913 if (getContext().getAsVariableArrayType(e->getType())) {
914 cgm.errorNYI(e->getSourceRange(),
915 "emitArraySubscriptExpr: VariableArrayType");
917 }
918
919 if (e->getType()->getAs<ObjCObjectType>()) {
920 cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjCObjectType");
922 }
923
924 // The index must always be an integer, which is not an aggregate. Emit it
925 // in lexical order (this complexity is, sadly, required by C++17).
926 assert((e->getIdx() == e->getLHS() || e->getIdx() == e->getRHS()) &&
927 "index was neither LHS nor RHS");
928
929 auto emitIdxAfterBase = [&](bool promote) -> mlir::Value {
930 const mlir::Value idx = emitScalarExpr(e->getIdx());
931
932 // Extend or truncate the index type to 32 or 64-bits.
933 auto ptrTy = mlir::dyn_cast<cir::PointerType>(idx.getType());
934 if (promote && ptrTy && ptrTy.isPtrTo<cir::IntType>())
935 cgm.errorNYI(e->getSourceRange(),
936 "emitArraySubscriptExpr: index type cast");
937 return idx;
938 };
939
940 // If the base is a vector type, then we are forming a vector element
941 // with this subscript.
942 if (e->getBase()->getType()->isVectorType() &&
944 const mlir::Value idx = emitIdxAfterBase(/*promote=*/false);
945 const LValue lhs = emitLValue(e->getBase());
946 return LValue::makeVectorElt(lhs.getAddress(), idx, e->getBase()->getType(),
947 lhs.getBaseInfo());
948 }
949
950 const mlir::Value idx = emitIdxAfterBase(/*promote=*/true);
951 if (const Expr *array = getSimpleArrayDecayOperand(e->getBase())) {
952 LValue arrayLV;
953 if (const auto *ase = dyn_cast<ArraySubscriptExpr>(array))
954 arrayLV = emitArraySubscriptExpr(ase);
955 else
956 arrayLV = emitLValue(array);
957
958 // Propagate the alignment from the array itself to the result.
959 const Address addr = emitArraySubscriptPtr(
960 *this, cgm.getLoc(array->getBeginLoc()), cgm.getLoc(array->getEndLoc()),
961 arrayLV.getAddress(), e->getType(), idx, cgm.getLoc(e->getExprLoc()),
962 /*shouldDecay=*/true);
963
964 const LValue lv = LValue::makeAddr(addr, e->getType(), LValueBaseInfo());
965
966 if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC) {
967 cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjC with GC");
968 }
969
970 return lv;
971 }
972
973 // The base must be a pointer; emit it with an estimate of its alignment.
974 assert(e->getBase()->getType()->isPointerType() &&
975 "The base must be a pointer");
976
977 LValueBaseInfo eltBaseInfo;
978 const Address ptrAddr = emitPointerWithAlignment(e->getBase(), &eltBaseInfo);
979 // Propagate the alignment from the array itself to the result.
980 const Address addxr = emitArraySubscriptPtr(
981 *this, cgm.getLoc(e->getBeginLoc()), cgm.getLoc(e->getEndLoc()), ptrAddr,
982 e->getType(), idx, cgm.getLoc(e->getExprLoc()),
983 /*shouldDecay=*/false);
984
985 const LValue lv = LValue::makeAddr(addxr, e->getType(), eltBaseInfo);
986
987 if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC) {
988 cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: ObjC with GC");
989 }
990
991 return lv;
992}
993
995 cir::GlobalOp globalOp = cgm.getGlobalForStringLiteral(e);
996 assert(globalOp.getAlignment() && "expected alignment for string literal");
997 unsigned align = *(globalOp.getAlignment());
998 mlir::Value addr =
999 builder.createGetGlobal(getLoc(e->getSourceRange()), globalOp);
1000 return makeAddrLValue(
1001 Address(addr, globalOp.getSymType(), CharUnits::fromQuantity(align)),
1003}
1004
1005/// Casts are never lvalues unless that cast is to a reference type. If the cast
1006/// is to a reference, we can have the usual lvalue result, otherwise if a cast
1007/// is needed by the code generator in an lvalue context, then it must mean that
1008/// we need the address of an aggregate in order to access one of its members.
1009/// This can happen for all the reasons that casts are permitted with aggregate
1010/// result, including noop aggregate casts, and cast from scalar to union.
1012 switch (e->getCastKind()) {
1013 case CK_ToVoid:
1014 case CK_BitCast:
1015 case CK_LValueToRValueBitCast:
1016 case CK_ArrayToPointerDecay:
1017 case CK_FunctionToPointerDecay:
1018 case CK_NullToMemberPointer:
1019 case CK_NullToPointer:
1020 case CK_IntegralToPointer:
1021 case CK_PointerToIntegral:
1022 case CK_PointerToBoolean:
1023 case CK_IntegralCast:
1024 case CK_BooleanToSignedIntegral:
1025 case CK_IntegralToBoolean:
1026 case CK_IntegralToFloating:
1027 case CK_FloatingToIntegral:
1028 case CK_FloatingToBoolean:
1029 case CK_FloatingCast:
1030 case CK_FloatingRealToComplex:
1031 case CK_FloatingComplexToReal:
1032 case CK_FloatingComplexToBoolean:
1033 case CK_FloatingComplexCast:
1034 case CK_FloatingComplexToIntegralComplex:
1035 case CK_IntegralRealToComplex:
1036 case CK_IntegralComplexToReal:
1037 case CK_IntegralComplexToBoolean:
1038 case CK_IntegralComplexCast:
1039 case CK_IntegralComplexToFloatingComplex:
1040 case CK_DerivedToBaseMemberPointer:
1041 case CK_BaseToDerivedMemberPointer:
1042 case CK_MemberPointerToBoolean:
1043 case CK_ReinterpretMemberPointer:
1044 case CK_AnyPointerToBlockPointerCast:
1045 case CK_ARCProduceObject:
1046 case CK_ARCConsumeObject:
1047 case CK_ARCReclaimReturnedObject:
1048 case CK_ARCExtendBlockObject:
1049 case CK_CopyAndAutoreleaseBlockObject:
1050 case CK_IntToOCLSampler:
1051 case CK_FloatingToFixedPoint:
1052 case CK_FixedPointToFloating:
1053 case CK_FixedPointCast:
1054 case CK_FixedPointToBoolean:
1055 case CK_FixedPointToIntegral:
1056 case CK_IntegralToFixedPoint:
1057 case CK_MatrixCast:
1058 case CK_HLSLVectorTruncation:
1059 case CK_HLSLArrayRValue:
1060 case CK_HLSLElementwiseCast:
1061 case CK_HLSLAggregateSplatCast:
1062 llvm_unreachable("unexpected cast lvalue");
1063
1064 case CK_Dependent:
1065 llvm_unreachable("dependent cast kind in IR gen!");
1066
1067 case CK_BuiltinFnToFnPtr:
1068 llvm_unreachable("builtin functions are handled elsewhere");
1069
1070 // These are never l-values; just use the aggregate emission code.
1071 case CK_NonAtomicToAtomic:
1072 case CK_AtomicToNonAtomic:
1073 case CK_Dynamic:
1074 case CK_ToUnion:
1075 case CK_BaseToDerived:
1076 case CK_AddressSpaceConversion:
1077 case CK_ObjCObjectLValueCast:
1078 case CK_VectorSplat:
1079 case CK_ConstructorConversion:
1080 case CK_UserDefinedConversion:
1081 case CK_CPointerToObjCPointerCast:
1082 case CK_BlockPointerToObjCPointerCast:
1083 case CK_LValueToRValue: {
1084 cgm.errorNYI(e->getSourceRange(),
1085 std::string("emitCastLValue for unhandled cast kind: ") +
1086 e->getCastKindName());
1087
1088 return {};
1089 }
1090
1091 case CK_LValueBitCast: {
1092 // This must be a reinterpret_cast (or c-style equivalent).
1093 const auto *ce = cast<ExplicitCastExpr>(e);
1094
1095 cgm.emitExplicitCastExprType(ce, this);
1096 LValue LV = emitLValue(e->getSubExpr());
1098 builder, convertTypeForMem(ce->getTypeAsWritten()->getPointeeType()));
1099
1100 return makeAddrLValue(V, e->getType(), LV.getBaseInfo());
1101 }
1102
1103 case CK_NoOp: {
1104 // CK_NoOp can model a qualification conversion, which can remove an array
1105 // bound and change the IR type.
1106 LValue lv = emitLValue(e->getSubExpr());
1107 // Propagate the volatile qualifier to LValue, if exists in e.
1109 cgm.errorNYI(e->getSourceRange(),
1110 "emitCastLValue: NoOp changes volatile qual");
1111 if (lv.isSimple()) {
1112 Address v = lv.getAddress();
1113 if (v.isValid()) {
1114 mlir::Type ty = convertTypeForMem(e->getType());
1115 if (v.getElementType() != ty)
1116 cgm.errorNYI(e->getSourceRange(),
1117 "emitCastLValue: NoOp needs bitcast");
1118 }
1119 }
1120 return lv;
1121 }
1122
1123 case CK_UncheckedDerivedToBase:
1124 case CK_DerivedToBase: {
1125 auto *derivedClassDecl = e->getSubExpr()->getType()->castAsCXXRecordDecl();
1126
1127 LValue lv = emitLValue(e->getSubExpr());
1128 Address thisAddr = lv.getAddress();
1129
1130 // Perform the derived-to-base conversion
1131 Address baseAddr =
1132 getAddressOfBaseClass(thisAddr, derivedClassDecl, e->path(),
1133 /*NullCheckValue=*/false, e->getExprLoc());
1134
1135 // TODO: Support accesses to members of base classes in TBAA. For now, we
1136 // conservatively pretend that the complete object is of the base class
1137 // type.
1139 return makeAddrLValue(baseAddr, e->getType(), lv.getBaseInfo());
1140 }
1141
1142 case CK_ZeroToOCLOpaqueType:
1143 llvm_unreachable("NULL to OpenCL opaque type lvalue cast is not valid");
1144 }
1145
1146 llvm_unreachable("Invalid cast kind");
1147}
1148
1150 const MemberExpr *me) {
1151 if (auto *vd = dyn_cast<VarDecl>(me->getMemberDecl())) {
1152 // Try to emit static variable member expressions as DREs.
1153 return DeclRefExpr::Create(
1155 /*RefersToEnclosingVariableOrCapture=*/false, me->getExprLoc(),
1156 me->getType(), me->getValueKind(), nullptr, nullptr, me->isNonOdrUse());
1157 }
1158 return nullptr;
1159}
1160
1162 if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, e)) {
1164 return emitDeclRefLValue(dre);
1165 }
1166
1167 Expr *baseExpr = e->getBase();
1168 // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
1169 LValue baseLV;
1170 if (e->isArrow()) {
1171 LValueBaseInfo baseInfo;
1173 Address addr = emitPointerWithAlignment(baseExpr, &baseInfo);
1174 QualType ptrTy = baseExpr->getType()->getPointeeType();
1176 baseLV = makeAddrLValue(addr, ptrTy, baseInfo);
1177 } else {
1179 baseLV = emitLValue(baseExpr);
1180 }
1181
1182 const NamedDecl *nd = e->getMemberDecl();
1183 if (auto *field = dyn_cast<FieldDecl>(nd)) {
1184 LValue lv = emitLValueForField(baseLV, field);
1186 if (getLangOpts().OpenMP) {
1187 // If the member was explicitly marked as nontemporal, mark it as
1188 // nontemporal. If the base lvalue is marked as nontemporal, mark access
1189 // to children as nontemporal too.
1190 cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: OpenMP");
1191 }
1192 return lv;
1193 }
1194
1195 if (isa<FunctionDecl>(nd)) {
1196 cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: FunctionDecl");
1197 return LValue();
1198 }
1199
1200 llvm_unreachable("Unhandled member declaration!");
1201}
1202
1203/// Evaluate an expression into a given memory location.
1205 Qualifiers quals, bool isInit) {
1206 // FIXME: This function should take an LValue as an argument.
1207 switch (getEvaluationKind(e->getType())) {
1208 case cir::TEK_Complex: {
1209 LValue lv = makeAddrLValue(location, e->getType());
1210 emitComplexExprIntoLValue(e, lv, isInit);
1211 return;
1212 }
1213
1214 case cir::TEK_Aggregate: {
1215 emitAggExpr(e, AggValueSlot::forAddr(location, quals,
1219 return;
1220 }
1221
1222 case cir::TEK_Scalar: {
1224 LValue lv = makeAddrLValue(location, e->getType());
1225 emitStoreThroughLValue(rv, lv);
1226 return;
1227 }
1228 }
1229
1230 llvm_unreachable("bad evaluation kind");
1231}
1232
1234 const MaterializeTemporaryExpr *m,
1235 const Expr *inner) {
1236 // TODO(cir): cgf.getTargetHooks();
1237 switch (m->getStorageDuration()) {
1238 case SD_FullExpression:
1239 case SD_Automatic: {
1240 QualType ty = inner->getType();
1241
1243
1244 // The temporary memory should be created in the same scope as the extending
1245 // declaration of the temporary materialization expression.
1246 cir::AllocaOp extDeclAlloca;
1247 if (const ValueDecl *extDecl = m->getExtendingDecl()) {
1248 auto extDeclAddrIter = cgf.localDeclMap.find(extDecl);
1249 if (extDeclAddrIter != cgf.localDeclMap.end())
1250 extDeclAlloca = extDeclAddrIter->second.getDefiningOp<cir::AllocaOp>();
1251 }
1252 mlir::OpBuilder::InsertPoint ip;
1253 if (extDeclAlloca)
1254 ip = {extDeclAlloca->getBlock(), extDeclAlloca->getIterator()};
1255 return cgf.createMemTemp(ty, cgf.getLoc(m->getSourceRange()),
1256 cgf.getCounterRefTmpAsString(), /*alloca=*/nullptr,
1257 ip);
1258 }
1259 case SD_Thread:
1260 case SD_Static: {
1261 cgf.cgm.errorNYI(
1262 m->getSourceRange(),
1263 "createReferenceTemporary: static/thread storage duration");
1264 return Address::invalid();
1265 }
1266
1267 case SD_Dynamic:
1268 llvm_unreachable("temporary can't have dynamic storage duration");
1269 }
1270 llvm_unreachable("unknown storage duration");
1271}
1272
1274 const MaterializeTemporaryExpr *m,
1275 const Expr *e, Address referenceTemporary) {
1276 // Objective-C++ ARC:
1277 // If we are binding a reference to a temporary that has ownership, we
1278 // need to perform retain/release operations on the temporary.
1279 //
1280 // FIXME(ogcg): This should be looking at e, not m.
1281 if (m->getType().getObjCLifetime()) {
1282 cgf.cgm.errorNYI(e->getSourceRange(), "pushTemporaryCleanup: ObjCLifetime");
1283 return;
1284 }
1285
1287 if (dk == QualType::DK_none)
1288 return;
1289
1290 switch (m->getStorageDuration()) {
1291 case SD_Static:
1292 case SD_Thread: {
1293 CXXDestructorDecl *referenceTemporaryDtor = nullptr;
1294 if (const auto *classDecl =
1296 classDecl && !classDecl->hasTrivialDestructor())
1297 // Get the destructor for the reference temporary.
1298 referenceTemporaryDtor = classDecl->getDestructor();
1299
1300 if (!referenceTemporaryDtor)
1301 return;
1302
1303 cgf.cgm.errorNYI(e->getSourceRange(), "pushTemporaryCleanup: static/thread "
1304 "storage duration with destructors");
1305 break;
1306 }
1307
1308 case SD_FullExpression:
1309 cgf.pushDestroy(NormalAndEHCleanup, referenceTemporary, e->getType(),
1311 break;
1312
1313 case SD_Automatic:
1314 cgf.cgm.errorNYI(e->getSourceRange(),
1315 "pushTemporaryCleanup: automatic storage duration");
1316 break;
1317
1318 case SD_Dynamic:
1319 llvm_unreachable("temporary cannot have dynamic storage duration");
1320 }
1321}
1322
1324 const MaterializeTemporaryExpr *m) {
1325 const Expr *e = m->getSubExpr();
1326
1327 assert((!m->getExtendingDecl() || !isa<VarDecl>(m->getExtendingDecl()) ||
1328 !cast<VarDecl>(m->getExtendingDecl())->isARCPseudoStrong()) &&
1329 "Reference should never be pseudo-strong!");
1330
1331 // FIXME: ideally this would use emitAnyExprToMem, however, we cannot do so
1332 // as that will cause the lifetime adjustment to be lost for ARC
1333 auto ownership = m->getType().getObjCLifetime();
1334 if (ownership != Qualifiers::OCL_None &&
1335 ownership != Qualifiers::OCL_ExplicitNone) {
1336 cgm.errorNYI(e->getSourceRange(),
1337 "emitMaterializeTemporaryExpr: ObjCLifetime");
1338 return {};
1339 }
1340
1343 e = e->skipRValueSubobjectAdjustments(commaLHSs, adjustments);
1344
1345 for (const Expr *ignored : commaLHSs)
1346 emitIgnoredExpr(ignored);
1347
1348 if (isa<OpaqueValueExpr>(e)) {
1349 cgm.errorNYI(e->getSourceRange(),
1350 "emitMaterializeTemporaryExpr: OpaqueValueExpr");
1351 return {};
1352 }
1353
1354 // Create and initialize the reference temporary.
1355 Address object = createReferenceTemporary(*this, m, e);
1356
1357 if (auto var = object.getPointer().getDefiningOp<cir::GlobalOp>()) {
1358 // TODO(cir): add something akin to stripPointerCasts() to ptr above
1359 cgm.errorNYI(e->getSourceRange(), "emitMaterializeTemporaryExpr: GlobalOp");
1360 return {};
1361 } else {
1363 emitAnyExprToMem(e, object, Qualifiers(), /*isInitializer=*/true);
1364 }
1365 pushTemporaryCleanup(*this, m, e, object);
1366
1367 // Perform derived-to-base casts and/or field accesses, to get from the
1368 // temporary object we created (and, potentially, for which we extended
1369 // the lifetime) to the subobject we're binding the reference to.
1370 if (!adjustments.empty()) {
1371 cgm.errorNYI(e->getSourceRange(),
1372 "emitMaterializeTemporaryExpr: Adjustments");
1373 return {};
1374 }
1375
1376 return makeAddrLValue(object, m->getType(), AlignmentSource::Decl);
1377}
1378
1379LValue
1382
1383 auto it = opaqueLValues.find(e);
1384 if (it != opaqueLValues.end())
1385 return it->second;
1386
1387 assert(e->isUnique() && "LValue for a nonunique OVE hasn't been emitted");
1388 return emitLValue(e->getSourceExpr());
1389}
1390
1391RValue
1394
1395 auto it = opaqueRValues.find(e);
1396 if (it != opaqueRValues.end())
1397 return it->second;
1398
1399 assert(e->isUnique() && "RValue for a nonunique OVE hasn't been emitted");
1400 return emitAnyExpr(e->getSourceExpr());
1401}
1402
1404 if (e->isFileScope()) {
1405 cgm.errorNYI(e->getSourceRange(), "emitCompoundLiteralLValue: FileScope");
1406 return {};
1407 }
1408
1409 if (e->getType()->isVariablyModifiedType()) {
1410 cgm.errorNYI(e->getSourceRange(),
1411 "emitCompoundLiteralLValue: VariablyModifiedType");
1412 return {};
1413 }
1414
1415 Address declPtr = createMemTemp(e->getType(), getLoc(e->getSourceRange()),
1416 ".compoundliteral");
1417 const Expr *initExpr = e->getInitializer();
1418 LValue result = makeAddrLValue(declPtr, e->getType(), AlignmentSource::Decl);
1419
1420 emitAnyExprToMem(initExpr, declPtr, e->getType().getQualifiers(),
1421 /*Init*/ true);
1422
1423 // Block-scope compound literals are destroyed at the end of the enclosing
1424 // scope in C.
1425 if (!getLangOpts().CPlusPlus && e->getType().isDestructedType()) {
1426 cgm.errorNYI(e->getSourceRange(),
1427 "emitCompoundLiteralLValue: non C++ DestructedType");
1428 return {};
1429 }
1430
1431 return result;
1432}
1433
1435 RValue rv = emitCallExpr(e);
1436
1437 if (!rv.isScalar()) {
1438 cgm.errorNYI(e->getSourceRange(), "emitCallExprLValue: non-scalar return");
1439 return {};
1440 }
1441
1442 assert(e->getCallReturnType(getContext())->isReferenceType() &&
1443 "Can't have a scalar return unless the return type is a "
1444 "reference type!");
1445
1447}
1448
1450 // Comma expressions just emit their LHS then their RHS as an l-value.
1451 if (e->getOpcode() == BO_Comma) {
1452 emitIgnoredExpr(e->getLHS());
1453 return emitLValue(e->getRHS());
1454 }
1455
1456 if (e->getOpcode() == BO_PtrMemD || e->getOpcode() == BO_PtrMemI) {
1457 cgm.errorNYI(e->getSourceRange(), "member pointers");
1458 return {};
1459 }
1460
1461 assert(e->getOpcode() == BO_Assign && "unexpected binary l-value");
1462
1463 // Note that in all of these cases, __block variables need the RHS
1464 // evaluated first just in case the variable gets moved by the RHS.
1465
1467 case cir::TEK_Scalar: {
1469 if (e->getLHS()->getType().getObjCLifetime() !=
1471 cgm.errorNYI(e->getSourceRange(), "objc lifetimes");
1472 return {};
1473 }
1474
1475 RValue rv = emitAnyExpr(e->getRHS());
1476 LValue lv = emitLValue(e->getLHS());
1477
1478 SourceLocRAIIObject loc{*this, getLoc(e->getSourceRange())};
1479 if (lv.isBitField())
1481 else
1482 emitStoreThroughLValue(rv, lv);
1483
1484 if (getLangOpts().OpenMP) {
1485 cgm.errorNYI(e->getSourceRange(), "openmp");
1486 return {};
1487 }
1488
1489 return lv;
1490 }
1491
1492 case cir::TEK_Complex: {
1494 }
1495
1496 case cir::TEK_Aggregate:
1497 cgm.errorNYI(e->getSourceRange(), "aggregate lvalues");
1498 return {};
1499 }
1500 llvm_unreachable("bad evaluation kind");
1501}
1502
1503/// Emit code to compute the specified expression which
1504/// can have any type. The result is returned as an RValue struct.
1507 case cir::TEK_Scalar:
1508 return RValue::get(emitScalarExpr(e));
1509 case cir::TEK_Complex:
1511 case cir::TEK_Aggregate: {
1512 if (aggSlot.isIgnored())
1513 aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),
1515 emitAggExpr(e, aggSlot);
1516 return aggSlot.asRValue();
1517 }
1518 }
1519 llvm_unreachable("bad evaluation kind");
1520}
1521
1522// Detect the unusual situation where an inline version is shadowed by a
1523// non-inline version. In that case we should pick the external one
1524// everywhere. That's GCC behavior too.
1526 for (const FunctionDecl *pd = fd; pd; pd = pd->getPreviousDecl())
1527 if (!pd->isInlineBuiltinDeclaration())
1528 return false;
1529 return true;
1530}
1531
1532CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) {
1533 const auto *fd = cast<FunctionDecl>(gd.getDecl());
1534
1535 if (unsigned builtinID = fd->getBuiltinID()) {
1536 if (fd->getAttr<AsmLabelAttr>()) {
1537 cgm.errorNYI("AsmLabelAttr");
1538 }
1539
1540 StringRef ident = fd->getName();
1541 std::string fdInlineName = (ident + ".inline").str();
1542
1543 bool isPredefinedLibFunction =
1544 cgm.getASTContext().BuiltinInfo.isPredefinedLibFunction(builtinID);
1545 // Assume nobuiltins everywhere until we actually read the attributes.
1546 bool hasAttributeNoBuiltin = true;
1548
1549 // When directing calling an inline builtin, call it through it's mangled
1550 // name to make it clear it's not the actual builtin.
1551 auto fn = cast<cir::FuncOp>(curFn);
1552 if (fn.getName() != fdInlineName && onlyHasInlineBuiltinDeclaration(fd)) {
1553 cgm.errorNYI("Inline only builtin function calls");
1554 }
1555
1556 // Replaceable builtins provide their own implementation of a builtin. If we
1557 // are in an inline builtin implementation, avoid trivial infinite
1558 // recursion. Honor __attribute__((no_builtin("foo"))) or
1559 // __attribute__((no_builtin)) on the current function unless foo is
1560 // not a predefined library function which means we must generate the
1561 // builtin no matter what.
1562 else if (!isPredefinedLibFunction || !hasAttributeNoBuiltin)
1563 return CIRGenCallee::forBuiltin(builtinID, fd);
1564 }
1565
1566 cir::FuncOp callee = emitFunctionDeclPointer(cgm, gd);
1567
1568 assert(!cir::MissingFeatures::hip());
1569
1570 return CIRGenCallee::forDirect(callee, gd);
1571}
1572
1574 if (ty->isVoidType())
1575 return RValue::get(nullptr);
1576
1577 cgm.errorNYI("unsupported type for undef rvalue");
1578 return RValue::get(nullptr);
1579}
1580
1582 const CIRGenCallee &origCallee,
1583 const clang::CallExpr *e,
1585 // Get the actual function type. The callee type will always be a pointer to
1586 // function type or a block pointer type.
1587 assert(calleeTy->isFunctionPointerType() &&
1588 "Callee must have function pointer type!");
1589
1590 calleeTy = getContext().getCanonicalType(calleeTy);
1591 auto pointeeTy = cast<PointerType>(calleeTy)->getPointeeType();
1592
1593 CIRGenCallee callee = origCallee;
1594
1595 if (getLangOpts().CPlusPlus)
1597
1598 const auto *fnType = cast<FunctionType>(pointeeTy);
1599
1601
1602 CallArgList args;
1604
1605 emitCallArgs(args, dyn_cast<FunctionProtoType>(fnType), e->arguments(),
1606 e->getDirectCallee());
1607
1608 const CIRGenFunctionInfo &funcInfo =
1609 cgm.getTypes().arrangeFreeFunctionCall(args, fnType);
1610
1611 // C99 6.5.2.2p6:
1612 // If the expression that denotes the called function has a type that does
1613 // not include a prototype, [the default argument promotions are performed].
1614 // If the number of arguments does not equal the number of parameters, the
1615 // behavior is undefined. If the function is defined with a type that
1616 // includes a prototype, and either the prototype ends with an ellipsis (,
1617 // ...) or the types of the arguments after promotion are not compatible
1618 // with the types of the parameters, the behavior is undefined. If the
1619 // function is defined with a type that does not include a prototype, and
1620 // the types of the arguments after promotion are not compatible with those
1621 // of the parameters after promotion, the behavior is undefined [except in
1622 // some trivial cases].
1623 // That is, in the general case, we should assume that a call through an
1624 // unprototyped function type works like a *non-variadic* call. The way we
1625 // make this work is to cast to the exxact type fo the promoted arguments.
1626 if (isa<FunctionNoProtoType>(fnType)) {
1629 cir::FuncType calleeTy = getTypes().getFunctionType(funcInfo);
1630 // get non-variadic function type
1631 calleeTy = cir::FuncType::get(calleeTy.getInputs(),
1632 calleeTy.getReturnType(), false);
1633 auto calleePtrTy = cir::PointerType::get(calleeTy);
1634
1635 mlir::Operation *fn = callee.getFunctionPointer();
1636 mlir::Value addr;
1637 if (auto funcOp = mlir::dyn_cast<cir::FuncOp>(fn)) {
1638 addr = builder.create<cir::GetGlobalOp>(
1639 getLoc(e->getSourceRange()),
1640 cir::PointerType::get(funcOp.getFunctionType()), funcOp.getSymName());
1641 } else {
1642 addr = fn->getResult(0);
1643 }
1644
1645 fn = builder.createBitcast(addr, calleePtrTy).getDefiningOp();
1646 callee.setFunctionPointer(fn);
1647 }
1648
1650 assert(!cir::MissingFeatures::hip());
1652
1653 cir::CIRCallOpInterface callOp;
1654 RValue callResult = emitCall(funcInfo, callee, returnValue, args, &callOp,
1655 getLoc(e->getExprLoc()));
1656
1658
1659 return callResult;
1660}
1661
1663 e = e->IgnoreParens();
1664
1665 // Look through function-to-pointer decay.
1666 if (const auto *implicitCast = dyn_cast<ImplicitCastExpr>(e)) {
1667 if (implicitCast->getCastKind() == CK_FunctionToPointerDecay ||
1668 implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {
1669 return emitCallee(implicitCast->getSubExpr());
1670 }
1671 // When performing an indirect call through a function pointer lvalue, the
1672 // function pointer lvalue is implicitly converted to an rvalue through an
1673 // lvalue-to-rvalue conversion.
1674 assert(implicitCast->getCastKind() == CK_LValueToRValue &&
1675 "unexpected implicit cast on function pointers");
1676 } else if (const auto *declRef = dyn_cast<DeclRefExpr>(e)) {
1677 // Resolve direct calls.
1678 const auto *funcDecl = cast<FunctionDecl>(declRef->getDecl());
1679 return emitDirectCallee(funcDecl);
1680 } else if (isa<MemberExpr>(e)) {
1681 cgm.errorNYI(e->getSourceRange(),
1682 "emitCallee: call to member function is NYI");
1683 return {};
1684 } else if (auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
1686 }
1687
1688 // Otherwise, we have an indirect reference.
1689 mlir::Value calleePtr;
1691 if (const auto *ptrType = e->getType()->getAs<clang::PointerType>()) {
1692 calleePtr = emitScalarExpr(e);
1693 functionType = ptrType->getPointeeType();
1694 } else {
1695 functionType = e->getType();
1696 calleePtr = emitLValue(e).getPointer();
1697 }
1698 assert(functionType->isFunctionType());
1699
1700 GlobalDecl gd;
1701 if (const auto *vd =
1702 dyn_cast_or_null<VarDecl>(e->getReferencedDeclOfCallee()))
1703 gd = GlobalDecl(vd);
1704
1705 CIRGenCalleeInfo calleeInfo(functionType->getAs<FunctionProtoType>(), gd);
1706 CIRGenCallee callee(calleeInfo, calleePtr.getDefiningOp());
1707 return callee;
1708}
1709
1713
1714 if (const auto *ce = dyn_cast<CXXMemberCallExpr>(e))
1716
1717 if (isa<CUDAKernelCallExpr>(e)) {
1718 cgm.errorNYI(e->getSourceRange(), "call to CUDA kernel");
1719 return RValue::get(nullptr);
1720 }
1721
1722 if (const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(e)) {
1723 // If the callee decl is a CXXMethodDecl, we need to emit this as a C++
1724 // operator member call.
1725 if (const CXXMethodDecl *md =
1726 dyn_cast_or_null<CXXMethodDecl>(operatorCall->getCalleeDecl()))
1727 return emitCXXOperatorMemberCallExpr(operatorCall, md, returnValue);
1728 // A CXXOperatorCallExpr is created even for explicit object methods, but
1729 // these should be treated like static function calls. Fall through to do
1730 // that.
1731 }
1732
1733 CIRGenCallee callee = emitCallee(e->getCallee());
1734
1735 if (callee.isBuiltin())
1736 return emitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), e,
1737 returnValue);
1738
1739 if (callee.isPseudoDestructor())
1741
1742 return emitCall(e->getCallee()->getType(), callee, e, returnValue);
1743}
1744
1745/// Emit code to compute the specified expression, ignoring the result.
1747 if (e->isPRValue()) {
1749 emitAnyExpr(e);
1750 return;
1751 }
1752
1753 // Just emit it as an l-value and drop the result.
1754 emitLValue(e);
1755}
1756
1758 LValueBaseInfo *baseInfo) {
1760 assert(e->getType()->isArrayType() &&
1761 "Array to pointer decay must have array source type!");
1762
1763 // Expressions of array type can't be bitfields or vector elements.
1764 LValue lv = emitLValue(e);
1765 Address addr = lv.getAddress();
1766
1767 // If the array type was an incomplete type, we need to make sure
1768 // the decay ends up being the right type.
1769 auto lvalueAddrTy = mlir::cast<cir::PointerType>(addr.getPointer().getType());
1770
1771 if (e->getType()->isVariableArrayType())
1772 return addr;
1773
1774 [[maybe_unused]] auto pointeeTy =
1775 mlir::cast<cir::ArrayType>(lvalueAddrTy.getPointee());
1776
1777 [[maybe_unused]] mlir::Type arrayTy = convertType(e->getType());
1778 assert(mlir::isa<cir::ArrayType>(arrayTy) && "expected array");
1779 assert(pointeeTy == arrayTy);
1780
1781 // The result of this decay conversion points to an array element within the
1782 // base lvalue. However, since TBAA currently does not support representing
1783 // accesses to elements of member arrays, we conservatively represent accesses
1784 // to the pointee object as if it had no any base lvalue specified.
1785 // TODO: Support TBAA for member arrays.
1788
1789 mlir::Value ptr = builder.maybeBuildArrayDecay(
1790 cgm.getLoc(e->getSourceRange()), addr.getPointer(),
1791 convertTypeForMem(eltType));
1792 return Address(ptr, addr.getAlignment());
1793}
1794
1795/// Given the address of a temporary variable, produce an r-value of its type.
1799 switch (getEvaluationKind(type)) {
1800 case cir::TEK_Complex:
1801 cgm.errorNYI(loc, "convertTempToRValue: complex type");
1802 return RValue::get(nullptr);
1803 case cir::TEK_Aggregate:
1804 cgm.errorNYI(loc, "convertTempToRValue: aggregate type");
1805 return RValue::get(nullptr);
1806 case cir::TEK_Scalar:
1807 return RValue::get(emitLoadOfScalar(lvalue, loc));
1808 }
1809 llvm_unreachable("bad evaluation kind");
1810}
1811
1812/// Emit an `if` on a boolean condition, filling `then` and `else` into
1813/// appropriated regions.
1814mlir::LogicalResult CIRGenFunction::emitIfOnBoolExpr(const Expr *cond,
1815 const Stmt *thenS,
1816 const Stmt *elseS) {
1817 mlir::Location thenLoc = getLoc(thenS->getSourceRange());
1818 std::optional<mlir::Location> elseLoc;
1819 if (elseS)
1820 elseLoc = getLoc(elseS->getSourceRange());
1821
1822 mlir::LogicalResult resThen = mlir::success(), resElse = mlir::success();
1824 cond, /*thenBuilder=*/
1825 [&](mlir::OpBuilder &, mlir::Location) {
1826 LexicalScope lexScope{*this, thenLoc, builder.getInsertionBlock()};
1827 resThen = emitStmt(thenS, /*useCurrentScope=*/true);
1828 },
1829 thenLoc,
1830 /*elseBuilder=*/
1831 [&](mlir::OpBuilder &, mlir::Location) {
1832 assert(elseLoc && "Invalid location for elseS.");
1833 LexicalScope lexScope{*this, *elseLoc, builder.getInsertionBlock()};
1834 resElse = emitStmt(elseS, /*useCurrentScope=*/true);
1835 },
1836 elseLoc);
1837
1838 return mlir::LogicalResult::success(resThen.succeeded() &&
1839 resElse.succeeded());
1840}
1841
1842/// Emit an `if` on a boolean condition, filling `then` and `else` into
1843/// appropriated regions.
1845 const clang::Expr *cond, BuilderCallbackRef thenBuilder,
1846 mlir::Location thenLoc, BuilderCallbackRef elseBuilder,
1847 std::optional<mlir::Location> elseLoc) {
1848 // Attempt to be as accurate as possible with IfOp location, generate
1849 // one fused location that has either 2 or 4 total locations, depending
1850 // on else's availability.
1851 SmallVector<mlir::Location, 2> ifLocs{thenLoc};
1852 if (elseLoc)
1853 ifLocs.push_back(*elseLoc);
1854 mlir::Location loc = mlir::FusedLoc::get(&getMLIRContext(), ifLocs);
1855
1856 // Emit the code with the fully general case.
1857 mlir::Value condV = emitOpOnBoolExpr(loc, cond);
1858 return builder.create<cir::IfOp>(loc, condV, elseLoc.has_value(),
1859 /*thenBuilder=*/thenBuilder,
1860 /*elseBuilder=*/elseBuilder);
1861}
1862
1863/// TODO(cir): see EmitBranchOnBoolExpr for extra ideas).
1864mlir::Value CIRGenFunction::emitOpOnBoolExpr(mlir::Location loc,
1865 const Expr *cond) {
1868 cond = cond->IgnoreParens();
1869
1870 // In LLVM the condition is reversed here for efficient codegen.
1871 // This should be done in CIR prior to LLVM lowering, if we do now
1872 // we can make CIR based diagnostics misleading.
1873 // cir.ternary(!x, t, f) -> cir.ternary(x, f, t)
1875
1876 if (const ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(cond)) {
1877 Expr *trueExpr = condOp->getTrueExpr();
1878 Expr *falseExpr = condOp->getFalseExpr();
1879 mlir::Value condV = emitOpOnBoolExpr(loc, condOp->getCond());
1880
1881 mlir::Value ternaryOpRes =
1882 builder
1883 .create<cir::TernaryOp>(
1884 loc, condV, /*thenBuilder=*/
1885 [this, trueExpr](mlir::OpBuilder &b, mlir::Location loc) {
1886 mlir::Value lhs = emitScalarExpr(trueExpr);
1887 b.create<cir::YieldOp>(loc, lhs);
1888 },
1889 /*elseBuilder=*/
1890 [this, falseExpr](mlir::OpBuilder &b, mlir::Location loc) {
1891 mlir::Value rhs = emitScalarExpr(falseExpr);
1892 b.create<cir::YieldOp>(loc, rhs);
1893 })
1894 .getResult();
1895
1896 return emitScalarConversion(ternaryOpRes, condOp->getType(),
1897 getContext().BoolTy, condOp->getExprLoc());
1898 }
1899
1900 if (isa<CXXThrowExpr>(cond)) {
1901 cgm.errorNYI("NYI");
1902 return createDummyValue(loc, cond->getType());
1903 }
1904
1905 // If the branch has a condition wrapped by __builtin_unpredictable,
1906 // create metadata that specifies that the branch is unpredictable.
1907 // Don't bother if not optimizing because that metadata would not be used.
1909
1910 // Emit the code with the fully general case.
1911 return evaluateExprAsBool(cond);
1912}
1913
1914mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
1915 mlir::Location loc, CharUnits alignment,
1916 bool insertIntoFnEntryBlock,
1917 mlir::Value arraySize) {
1918 mlir::Block *entryBlock = insertIntoFnEntryBlock
1920 : curLexScope->getEntryBlock();
1921
1922 // If this is an alloca in the entry basic block of a cir.try and there's
1923 // a surrounding cir.scope, make sure the alloca ends up in the surrounding
1924 // scope instead. This is necessary in order to guarantee all SSA values are
1925 // reachable during cleanups.
1926 assert(!cir::MissingFeatures::tryOp());
1927
1928 return emitAlloca(name, ty, loc, alignment,
1929 builder.getBestAllocaInsertPoint(entryBlock), arraySize);
1930}
1931
1932mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
1933 mlir::Location loc, CharUnits alignment,
1934 mlir::OpBuilder::InsertPoint ip,
1935 mlir::Value arraySize) {
1936 // CIR uses its own alloca address space rather than follow the target data
1937 // layout like original CodeGen. The data layout awareness should be done in
1938 // the lowering pass instead.
1940 cir::PointerType localVarPtrTy = builder.getPointerTo(ty);
1941 mlir::IntegerAttr alignIntAttr = cgm.getSize(alignment);
1942
1943 mlir::Value addr;
1944 {
1945 mlir::OpBuilder::InsertionGuard guard(builder);
1946 builder.restoreInsertionPoint(ip);
1947 addr = builder.createAlloca(loc, /*addr type*/ localVarPtrTy,
1948 /*var type*/ ty, name, alignIntAttr);
1950 }
1951 return addr;
1952}
1953
1954// Note: this function also emit constructor calls to support a MSVC extensions
1955// allowing explicit constructor function call.
1958 const Expr *callee = ce->getCallee()->IgnoreParens();
1959
1960 if (isa<BinaryOperator>(callee)) {
1961 cgm.errorNYI(ce->getSourceRange(),
1962 "emitCXXMemberCallExpr: C++ binary operator");
1963 return RValue::get(nullptr);
1964 }
1965
1966 const auto *me = cast<MemberExpr>(callee);
1967 const auto *md = cast<CXXMethodDecl>(me->getMemberDecl());
1968
1969 if (md->isStatic()) {
1970 cgm.errorNYI(ce->getSourceRange(), "emitCXXMemberCallExpr: static method");
1971 return RValue::get(nullptr);
1972 }
1973
1974 bool hasQualifier = me->hasQualifier();
1975 NestedNameSpecifier qualifier = me->getQualifier();
1976 bool isArrow = me->isArrow();
1977 const Expr *base = me->getBase();
1978
1980 ce, md, returnValue, hasQualifier, qualifier, isArrow, base);
1981}
1982
1984 AggValueSlot dest) {
1985 assert(!dest.isIgnored() && "Must have a destination!");
1986 const CXXConstructorDecl *cd = e->getConstructor();
1987
1988 // If we require zero initialization before (or instead of) calling the
1989 // constructor, as can be the case with a non-user-provided default
1990 // constructor, emit the zero initialization now, unless destination is
1991 // already zeroed.
1992 if (e->requiresZeroInitialization() && !dest.isZeroed()) {
1993 switch (e->getConstructionKind()) {
1997 e->getType());
1998 break;
2001 cgm.errorNYI(e->getSourceRange(),
2002 "emitCXXConstructExpr: base requires initialization");
2003 break;
2004 }
2005 }
2006
2007 // If this is a call to a trivial default constructor, do nothing.
2008 if (cd->isTrivial() && cd->isDefaultConstructor())
2009 return;
2010
2011 // Elide the constructor if we're constructing from a temporary
2012 if (getLangOpts().ElideConstructors && e->isElidable()) {
2013 // FIXME: This only handles the simplest case, where the source object is
2014 // passed directly as the first argument to the constructor. This
2015 // should also handle stepping through implicit casts and conversion
2016 // sequences which involve two steps, with a conversion operator
2017 // follwed by a converting constructor.
2018 const Expr *srcObj = e->getArg(0);
2019 assert(srcObj->isTemporaryObject(getContext(), cd->getParent()));
2020 assert(
2021 getContext().hasSameUnqualifiedType(e->getType(), srcObj->getType()));
2022 emitAggExpr(srcObj, dest);
2023 return;
2024 }
2025
2026 if (const ArrayType *arrayType = getContext().getAsArrayType(e->getType())) {
2028 emitCXXAggrConstructorCall(cd, arrayType, dest.getAddress(), e, false);
2029 } else {
2030
2032 bool forVirtualBase = false;
2033 bool delegating = false;
2034
2035 switch (e->getConstructionKind()) {
2038 break;
2040 // We should be emitting a constructor; GlobalDecl will assert this
2041 type = curGD.getCtorType();
2042 delegating = true;
2043 break;
2045 forVirtualBase = true;
2046 [[fallthrough]];
2048 type = Ctor_Base;
2049 break;
2050 }
2051
2052 emitCXXConstructorCall(cd, type, forVirtualBase, delegating, dest, e);
2053 }
2054}
2055
2057 // Emit the expression as an lvalue.
2058 LValue lv = emitLValue(e);
2059 assert(lv.isSimple());
2060 mlir::Value value = lv.getPointer();
2061
2063
2064 return RValue::get(value);
2065}
2066
2068 LValueBaseInfo *pointeeBaseInfo) {
2069 if (refLVal.isVolatile())
2070 cgm.errorNYI(loc, "load of volatile reference");
2071
2072 cir::LoadOp load =
2073 builder.create<cir::LoadOp>(loc, refLVal.getAddress().getElementType(),
2074 refLVal.getAddress().getPointer());
2075
2077
2078 QualType pointeeType = refLVal.getType()->getPointeeType();
2079 CharUnits align = cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);
2080 return Address(load, convertTypeForMem(pointeeType), align);
2081}
2082
2084 mlir::Location loc,
2085 QualType refTy,
2086 AlignmentSource source) {
2087 LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source));
2088 LValueBaseInfo pointeeBaseInfo;
2090 Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo);
2091 return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(),
2092 pointeeBaseInfo);
2093}
2094
2095void CIRGenFunction::emitTrap(mlir::Location loc, bool createNewBlock) {
2096 cir::TrapOp::create(builder, loc);
2097 if (createNewBlock)
2098 builder.createBlock(builder.getBlock()->getParent());
2099}
2100
2102 bool createNewBlock) {
2104 cir::UnreachableOp::create(builder, getLoc(loc));
2105 if (createNewBlock)
2106 builder.createBlock(builder.getBlock()->getParent());
2107}
2108
2109mlir::Value CIRGenFunction::createDummyValue(mlir::Location loc,
2110 clang::QualType qt) {
2111 mlir::Type t = convertType(qt);
2112 CharUnits alignment = getContext().getTypeAlignInChars(qt);
2113 return builder.createDummyValue(loc, t, alignment);
2114}
2115
2116//===----------------------------------------------------------------------===//
2117// CIR builder helpers
2118//===----------------------------------------------------------------------===//
2119
2121 const Twine &name, Address *alloca,
2122 mlir::OpBuilder::InsertPoint ip) {
2123 // FIXME: Should we prefer the preferred type alignment here?
2124 return createMemTemp(ty, getContext().getTypeAlignInChars(ty), loc, name,
2125 alloca, ip);
2126}
2127
2129 mlir::Location loc, const Twine &name,
2130 Address *alloca,
2131 mlir::OpBuilder::InsertPoint ip) {
2132 Address result = createTempAlloca(convertTypeForMem(ty), align, loc, name,
2133 /*ArraySize=*/nullptr, alloca, ip);
2134 if (ty->isConstantMatrixType()) {
2136 cgm.errorNYI(loc, "temporary matrix value");
2137 }
2138 return result;
2139}
2140
2141/// This creates a alloca and inserts it into the entry block of the
2142/// current region.
2144 mlir::Type ty, CharUnits align, mlir::Location loc, const Twine &name,
2145 mlir::Value arraySize, mlir::OpBuilder::InsertPoint ip) {
2146 cir::AllocaOp alloca = ip.isSet()
2147 ? createTempAlloca(ty, loc, name, ip, arraySize)
2148 : createTempAlloca(ty, loc, name, arraySize);
2149 alloca.setAlignmentAttr(cgm.getSize(align));
2150 return Address(alloca, ty, align);
2151}
2152
2153/// This creates a alloca and inserts it into the entry block. The alloca is
2154/// casted to default address space if necessary.
2156 mlir::Location loc, const Twine &name,
2157 mlir::Value arraySize,
2158 Address *allocaAddr,
2159 mlir::OpBuilder::InsertPoint ip) {
2160 Address alloca =
2161 createTempAllocaWithoutCast(ty, align, loc, name, arraySize, ip);
2162 if (allocaAddr)
2163 *allocaAddr = alloca;
2164 mlir::Value v = alloca.getPointer();
2165 // Alloca always returns a pointer in alloca address space, which may
2166 // be different from the type defined by the language. For example,
2167 // in C++ the auto variables are in the default address space. Therefore
2168 // cast alloca to the default address space when necessary.
2170 return Address(v, ty, align);
2171}
2172
2173/// This creates an alloca and inserts it into the entry block if \p ArraySize
2174/// is nullptr, otherwise inserts it at the current insertion point of the
2175/// builder.
2176cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty,
2177 mlir::Location loc,
2178 const Twine &name,
2179 mlir::Value arraySize,
2180 bool insertIntoFnEntryBlock) {
2181 return mlir::cast<cir::AllocaOp>(emitAlloca(name.str(), ty, loc, CharUnits(),
2182 insertIntoFnEntryBlock, arraySize)
2183 .getDefiningOp());
2184}
2185
2186/// This creates an alloca and inserts it into the provided insertion point
2187cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty,
2188 mlir::Location loc,
2189 const Twine &name,
2190 mlir::OpBuilder::InsertPoint ip,
2191 mlir::Value arraySize) {
2192 assert(ip.isSet() && "Insertion point is not set");
2193 return mlir::cast<cir::AllocaOp>(
2194 emitAlloca(name.str(), ty, loc, CharUnits(), ip, arraySize)
2195 .getDefiningOp());
2196}
2197
2198/// Try to emit a reference to the given value without producing it as
2199/// an l-value. For many cases, this is just an optimization, but it avoids
2200/// us needing to emit global copies of variables if they're named without
2201/// triggering a formal use in a context where we can't emit a direct
2202/// reference to them, for instance if a block or lambda or a member of a
2203/// local class uses a const int variable or constexpr variable from an
2204/// enclosing function.
2205///
2206/// For named members of enums, this is the only way they are emitted.
2209 const ValueDecl *value = refExpr->getDecl();
2210
2211 // There is a lot more to do here, but for now only EnumConstantDecl is
2212 // supported.
2214
2215 // The value needs to be an enum constant or a constant variable.
2216 if (!isa<EnumConstantDecl>(value))
2217 return ConstantEmission();
2218
2219 Expr::EvalResult result;
2220 if (!refExpr->EvaluateAsRValue(result, getContext()))
2221 return ConstantEmission();
2222
2223 QualType resultType = refExpr->getType();
2224
2225 // As long as we're only handling EnumConstantDecl, there should be no
2226 // side-effects.
2227 assert(!result.HasSideEffects);
2228
2229 // Emit as a constant.
2230 // FIXME(cir): have emitAbstract build a TypedAttr instead (this requires
2231 // somewhat heavy refactoring...)
2232 mlir::Attribute c = ConstantEmitter(*this).emitAbstract(
2233 refExpr->getLocation(), result.Val, resultType);
2234 mlir::TypedAttr cstToEmit = mlir::dyn_cast_if_present<mlir::TypedAttr>(c);
2235 assert(cstToEmit && "expected a typed attribute");
2236
2238
2239 return ConstantEmission::forValue(cstToEmit);
2240}
2241
2245 return tryEmitAsConstant(dre);
2246 return ConstantEmission();
2247}
2248
2250 const CIRGenFunction::ConstantEmission &constant, Expr *e) {
2251 assert(constant && "not a constant");
2252 if (constant.isReference()) {
2253 cgm.errorNYI(e->getSourceRange(), "emitScalarConstant: reference");
2254 return {};
2255 }
2256 return builder.getConstant(getLoc(e->getSourceRange()), constant.getValue());
2257}
2258
2259/// An LValue is a candidate for having its loads and stores be made atomic if
2260/// we are operating under /volatile:ms *and* the LValue itself is volatile and
2261/// performing such an operation can be performed without a libcall.
2263 if (!cgm.getLangOpts().MSVolatile)
2264 return false;
2265
2266 cgm.errorNYI("LValueSuitableForInlineAtomic LangOpts MSVolatile");
2267 return false;
2268}
#define V(N, I)
llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> BuilderCallbackRef
Definition CIRDialect.h:37
static Address createReferenceTemporary(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *inner)
static bool isAAPCS(const TargetInfo &targetInfo)
Helper method to check if the underlying ABI is AAPCS.
static LValue emitFunctionDeclLValue(CIRGenFunction &cgf, const Expr *e, GlobalDecl gd)
static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx, CharUnits eltSize)
static void pushTemporaryCleanup(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *e, Address referenceTemporary)
static cir::IntAttr getConstantIndexOrNull(mlir::Value idx)
static const Expr * getSimpleArrayDecayOperand(const Expr *e)
If the specified expr is a simple decay from an array to pointer, return the array subexpression.
static QualType getFixedSizeElementType(const ASTContext &astContext, const VariableArrayType *vla)
static DeclRefExpr * tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf, const MemberExpr *me)
static cir::FuncOp emitFunctionDeclPointer(CIRGenModule &cgm, GlobalDecl gd)
static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e, const VarDecl *vd)
static mlir::Value emitArraySubscriptPtr(CIRGenFunction &cgf, mlir::Location beginLoc, mlir::Location endLoc, mlir::Value ptr, mlir::Type eltTy, mlir::Value idx, bool shouldDecay)
static bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *fd)
Defines the clang::Expr interface and subclasses for C++ expressions.
__device__ __2f16 b
__device__ __2f16 float c
static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block)
cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy, mlir::Value base, llvm::StringRef name, unsigned index)
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, mlir::Type type, llvm::StringRef name, mlir::IntegerAttr alignment, mlir::Value dynAllocSize)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CanQualType BoolTy
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2723
SourceLocation getExprLoc() const LLVM_READONLY
Definition Expr.h:2778
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Definition Expr.h:2752
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Expr.h:2766
SourceLocation getEndLoc() const
Definition Expr.h:2769
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3720
QualType getElementType() const
Definition TypeBase.h:3732
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:3974
Expr * getLHS() const
Definition Expr.h:4024
Expr * getRHS() const
Definition Expr.h:4026
Opcode getOpcode() const
Definition Expr.h:4019
mlir::Value getPointer() const
Definition Address.h:81
mlir::Type getElementType() const
Definition Address.h:101
static Address invalid()
Definition Address.h:66
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
clang::CharUnits getAlignment() const
Definition Address.h:109
mlir::Type getType() const
Definition Address.h:93
bool isValid() const
Definition Address.h:67
mlir::Operation * getDefiningOp() const
Get the operation which defines this address.
Definition Address.h:112
An aggregate value slot.
IsZeroed_t isZeroed() const
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Address createElementBitCast(mlir::Location loc, Address addr, mlir::Type destType)
Cast the element type of the given address to a different type, preserving information like the align...
mlir::Value getArrayElement(mlir::Location arrayLocBegin, mlir::Location arrayLocEnd, mlir::Value arrayPtr, mlir::Type eltTy, mlir::Value idx, bool shouldDecay)
Create a cir.ptr_stride operation to get access to an array element.
Abstract information about a function or function prototype.
Definition CIRGenCall.h:27
bool isPseudoDestructor() const
Definition CIRGenCall.h:121
void setFunctionPointer(mlir::Operation *functionPtr)
Definition CIRGenCall.h:183
const clang::FunctionDecl * getBuiltinDecl() const
Definition CIRGenCall.h:97
const CXXPseudoDestructorExpr * getPseudoDestructorExpr() const
Definition CIRGenCall.h:125
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
Definition CIRGenCall.h:90
unsigned getBuiltinID() const
Definition CIRGenCall.h:101
static CIRGenCallee forBuiltin(unsigned builtinID, const clang::FunctionDecl *builtinDecl)
Definition CIRGenCall.h:106
mlir::Operation * getFunctionPointer() const
Definition CIRGenCall.h:145
static CIRGenCallee forPseudoDestructor(const clang::CXXPseudoDestructorExpr *expr)
Definition CIRGenCall.h:115
static ConstantEmission forValue(mlir::TypedAttr c)
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0)
mlir::Type convertType(clang::QualType t)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
RValue convertTempToRValue(Address addr, clang::QualType type, clang::SourceLocation loc)
Given the address of a temporary variable, produce an r-value of its type.
CIRGenTypes & getTypes() const
Address emitPointerWithAlignment(const clang::Expr *expr, LValueBaseInfo *baseInfo=nullptr)
Given an expression with a pointer type, emit the value and compute our best estimate of the alignmen...
RValue emitLoadOfLValue(LValue lv, SourceLocation loc)
Given an expression that represents a value lvalue, this method emits the address of the lvalue,...
const clang::LangOptions & getLangOpts() const
cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, bool insertIntoFnEntryBlock=false)
This creates an alloca and inserts it into the entry block if ArraySize is nullptr,...
void emitTrap(mlir::Location loc, bool createNewBlock)
Emit a trap instruction, which is used to abort the program in an abnormal way, usually for debugging...
mlir::Block * getCurFunctionEntryBlock()
RValue emitCXXMemberCallExpr(const clang::CXXMemberCallExpr *e, ReturnValueSlot returnValue)
LValue emitLValueForBitField(LValue base, const FieldDecl *field)
mlir::LogicalResult emitIfOnBoolExpr(const clang::Expr *cond, const clang::Stmt *thenS, const clang::Stmt *elseS)
Emit an if on a boolean condition to the specified blocks.
mlir::Value emitComplexExpr(const Expr *e)
Emit the computation of the specified expression of complex type, returning the result.
LValue makeNaturalAlignPointeeAddrLValue(mlir::Value v, clang::QualType t)
Given a value of type T* that may not be to a complete object, construct an l-vlaue withi the natural...
RValue emitCallExpr(const clang::CallExpr *e, ReturnValueSlot returnValue=ReturnValueSlot())
LValue emitMemberExpr(const MemberExpr *e)
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
Address makeNaturalAddressForPointer(mlir::Value ptr, QualType t, CharUnits alignment, bool forPointeeType=false, LValueBaseInfo *baseInfo=nullptr)
Construct an address with the natural alignment of T.
mlir::Value evaluateExprAsBool(const clang::Expr *e)
Perform the usual unary conversions on the specified expression and compare the result against zero,...
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, bool isInit=false, bool isNontemporal=false)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
mlir::Value emitOpOnBoolExpr(mlir::Location loc, const clang::Expr *cond)
TODO(cir): see EmitBranchOnBoolExpr for extra ideas).
Address getAddressOfBaseClass(Address value, const CXXRecordDecl *derived, llvm::iterator_range< CastExpr::path_const_iterator > path, bool nullCheckValue, SourceLocation loc)
LValue emitStringLiteralLValue(const StringLiteral *e)
LValue emitLoadOfReferenceLValue(Address refAddr, mlir::Location loc, QualType refTy, AlignmentSource source)
mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv, cir::UnaryOpKind kind, bool isPre)
void emitAnyExprToMem(const Expr *e, Address location, Qualifiers quals, bool isInitializer)
Emits the code necessary to evaluate an arbitrary expression into the given memory location.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty)
RValue emitReferenceBindingToExpr(const Expr *e)
Emits a reference binding to the passed in expression.
RValue emitAnyExpr(const clang::Expr *e, AggValueSlot aggSlot=AggValueSlot::ignored())
Emit code to compute the specified expression which can have any type.
LValue emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e)
mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType, clang::QualType dstType, clang::SourceLocation loc)
Emit a conversion from the specified type to the specified destination type, both of which are CIR sc...
AggValueSlot createAggTemp(QualType ty, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr)
Create a temporary memory object for the given aggregate type.
mlir::Type convertTypeForMem(QualType t)
mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, mlir::Location loc, clang::CharUnits alignment, bool insertIntoFnEntryBlock, mlir::Value arraySize=nullptr)
void emitUnreachable(clang::SourceLocation loc, bool createNewBlock)
Emit a reached-unreachable diagnostic if loc is valid and runtime checking is enabled.
mlir::Value createDummyValue(mlir::Location loc, clang::QualType qt)
void emitCXXConstructExpr(const clang::CXXConstructExpr *e, AggValueSlot dest)
RValue getUndefRValue(clang::QualType ty)
Get an appropriate 'undef' rvalue for the given type.
Address returnValue
The temporary alloca to hold the return value.
void emitCXXConstructorCall(const clang::CXXConstructorDecl *d, clang::CXXCtorType type, bool forVirtualBase, bool delegating, AggValueSlot thisAVS, const clang::CXXConstructExpr *e)
LValue emitUnaryOpLValue(const clang::UnaryOperator *e)
RValue emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc)
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
LValue emitComplexAssignmentLValue(const BinaryOperator *e)
LValue emitLValueForFieldInitialization(LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName)
Like emitLValueForField, excpet that if the Field is a reference, this will return the address of the...
LValue emitCallExprLValue(const clang::CallExpr *e)
mlir::Value emitScalarExpr(const clang::Expr *e)
Emit the computation of the specified expression of scalar type.
mlir::Value emitToMemory(mlir::Value value, clang::QualType ty)
Given a value and its clang type, returns the value casted to its memory representation.
LValue emitLValueForField(LValue base, const clang::FieldDecl *field)
cir::FuncOp curFn
The function for which code is currently being generated.
void pushDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer)
Address emitLoadOfReference(LValue refLVal, mlir::Location loc, LValueBaseInfo *pointeeBaseInfo)
bool shouldNullCheckClassCastValue(const CastExpr *ce)
CIRGenBuilderTy & getBuilder()
LValue emitBinaryOperatorLValue(const BinaryOperator *e)
Address getAddrOfBitFieldStorage(LValue base, const clang::FieldDecl *field, mlir::Type fieldType, unsigned index)
mlir::MLIRContext & getMLIRContext()
LValue emitCastLValue(const CastExpr *e)
Casts are never lvalues unless that cast is to a reference type.
mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
DeclMapTy localDeclMap
This keeps track of the CIR allocas or globals for local C declarations.
LValue emitDeclRefLValue(const clang::DeclRefExpr *e)
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
ConstantEmission tryEmitAsConstant(const DeclRefExpr *refExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
llvm::DenseMap< const OpaqueValueExpr *, RValue > opaqueRValues
Address emitArrayToPointerDecay(const Expr *e, LValueBaseInfo *baseInfo=nullptr)
void emitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, const clang::ArrayType *arrayType, Address arrayBegin, const CXXConstructExpr *e, bool newPointerIsChecked, bool zeroInitialize=false)
Emit a loop to call a particular constructor for each of several members of an array.
mlir::Value emitStoreThroughBitfieldLValue(RValue src, LValue dstresult)
llvm::DenseMap< const OpaqueValueExpr *, LValue > opaqueLValues
Keeps track of the current set of opaque value expressions.
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
LValue emitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e)
clang::ASTContext & getContext() const
RValue emitCXXMemberOrOperatorMemberCallExpr(const clang::CallExpr *ce, const clang::CXXMethodDecl *md, ReturnValueSlot returnValue, bool hasQualifier, clang::NestedNameSpecifier qualifier, bool isArrow, const clang::Expr *base)
mlir::Value emitScalarConstant(const ConstantEmission &constant, Expr *e)
RValue emitBuiltinExpr(const clang::GlobalDecl &gd, unsigned builtinID, const clang::CallExpr *e, ReturnValueSlot returnValue)
RValue emitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *e, const CXXMethodDecl *md, ReturnValueSlot returnValue)
void emitStoreThroughLValue(RValue src, LValue dst, bool isInit=false)
Store the specified rvalue into the specified lvalue, where both are guaranteed to the have the same ...
bool isLValueSuitableForInlineAtomic(LValue lv)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
Address createTempAllocaWithoutCast(mlir::Type ty, CharUnits align, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, mlir::OpBuilder::InsertPoint ip={})
This creates a alloca and inserts it into the entry block of the current region.
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr)
LValue emitCompoundLiteralLValue(const CompoundLiteralExpr *e)
CIRGenCallee emitCallee(const clang::Expr *e)
Address emitAddrOfFieldStorage(Address base, const FieldDecl *field, llvm::StringRef fieldName, unsigned fieldIndex)
Get the address of a zero-sized field within a record.
This class organizes the cross-function state that is used while generating CIR code.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
mlir::Value getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty={}, ForDefinition_t isForDefinition=NotForDefinition)
Return the mlir::Value for the address of the given global variable.
This class handles record and union layout info while lowering AST types to CIR types.
cir::RecordType getCIRType() const
Return the "complete object" LLVM type associated with this record.
const CIRGenBitFieldInfo & getBitFieldInfo(const clang::FieldDecl *fd) const
Return the BitFieldInfo that corresponds to the field FD.
unsigned getCIRFieldNo(const clang::FieldDecl *fd) const
Return cir::RecordType element number that corresponds to the field FD.
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
mlir::Attribute emitAbstract(const Expr *e, QualType destType)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
AlignmentSource getAlignmentSource() const
void mergeForCast(const LValueBaseInfo &info)
const clang::Qualifiers & getQuals() const
mlir::Value getVectorIdx() const
bool isVectorElt() const
Address getAddress() const
static LValue makeAddr(Address address, clang::QualType t, LValueBaseInfo baseInfo)
static LValue makeVectorElt(Address vecAddress, mlir::Value index, clang::QualType t, LValueBaseInfo baseInfo)
unsigned getVRQualifiers() const
clang::QualType getType() const
static LValue makeBitfield(Address addr, const CIRGenBitFieldInfo &info, clang::QualType type, LValueBaseInfo baseInfo)
Create a new object to represent a bit-field access.
mlir::Value getPointer() const
bool isVolatileQualified() const
bool isBitField() const
Address getVectorAddress() const
clang::CharUnits getAlignment() const
LValueBaseInfo getBaseInfo() const
bool isVolatile() const
const CIRGenBitFieldInfo & getBitFieldInfo() const
Address getBitFieldAddress() const
bool isSimple() const
This trivial value class is used to represent the result of an expression that is evaluated.
Definition CIRGenValue.h:33
static RValue get(mlir::Value v)
Definition CIRGenValue.h:82
static RValue getComplex(mlir::Value v)
Definition CIRGenValue.h:90
mlir::Value getValue() const
Return the value of this scalar value.
Definition CIRGenValue.h:56
bool isScalar() const
Definition CIRGenValue.h:49
Contains the address where the return value of a function can be stored, and whether the address is v...
Definition CIRGenCall.h:252
Represents a call to a C++ constructor.
Definition ExprCXX.h:1549
bool isElidable() const
Whether this construction is elidable.
Definition ExprCXX.h:1618
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1692
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
Definition ExprCXX.h:1651
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1612
CXXConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
Definition ExprCXX.h:1660
Represents a C++ constructor within a class.
Definition DeclCXX.h:2604
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Definition DeclCXX.cpp:2999
Represents a C++ destructor within a class.
Definition DeclCXX.h:2869
Represents a call to a member function that may be written either with member call syntax (e....
Definition ExprCXX.h:179
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2255
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition DeclCXX.h:1366
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2879
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3062
Expr * getCallee()
Definition Expr.h:3026
arg_range arguments()
Definition Expr.h:3131
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition Expr.cpp:1599
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition Expr.h:3612
CastKind getCastKind() const
Definition Expr.h:3656
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
Definition Expr.h:3699
bool changesVolatileQualification() const
Return.
Definition Expr.h:3746
static const char * getCastKindName(CastKind CK)
Definition Expr.cpp:1946
Expr * getSubExpr()
Definition Expr.h:3662
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
Definition CharUnits.h:207
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
Definition CharUnits.h:214
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3275
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3541
bool isFileScope() const
Definition Expr.h:3573
const Expr * getInitializer() const
Definition Expr.h:3569
ConditionalOperator - The ?
Definition Expr.h:4327
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1272
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
Definition Expr.h:1476
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
Definition Expr.cpp:484
ValueDecl * getDecl()
Definition Expr.h:1340
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
Definition Expr.h:1470
SourceLocation getLocation() const
Definition Expr.h:1348
SourceLocation getLocation() const
Definition DeclBase.h:439
bool hasAttr() const
Definition DeclBase.h:577
This represents one expression.
Definition Expr.h:112
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Definition Expr.cpp:80
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Definition Expr.h:444
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3069
bool isPRValue() const
Definition Expr.h:285
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Decl * getReferencedDeclOfCallee()
Definition Expr.cpp:1542
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
Definition Expr.cpp:3207
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:273
QualType getType() const
Definition Expr.h:144
Represents a member of a struct/union/class.
Definition Decl.h:3157
bool isBitField() const
Determines whether this field is a bitfield.
Definition Decl.h:3260
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4767
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
Definition Decl.h:3242
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Definition Decl.h:3393
bool isZeroSize(const ASTContext &Ctx) const
Determine if this field is a subobject of zero size, that is, either a zero-length bit-field or a fie...
Definition Decl.cpp:4707
Represents a function declaration or definition.
Definition Decl.h:1999
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2376
FunctionDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5264
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
const Decl * getDecl() const
Definition GlobalDecl.h:106
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4914
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition ExprCXX.h:4939
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4931
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
Definition ExprCXX.h:4964
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3300
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3383
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
Definition Expr.h:3524
Expr * getBase() const
Definition Expr.h:3377
bool isArrow() const
Definition Expr.h:3484
SourceLocation getExprLoc() const LLVM_READONLY
Definition Expr.h:3495
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3651
This represents a decl that may have a name.
Definition Decl.h:273
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:300
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1180
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition Expr.h:1230
bool isUnique() const
Definition Expr.h:1238
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3328
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8325
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition TypeBase.h:1438
QualType withCVRQualifiers(unsigned CVR) const
Definition TypeBase.h:1179
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
Definition TypeBase.h:1545
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
GC getObjCGCAttr() const
Definition TypeBase.h:519
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition TypeBase.h:354
@ OCL_None
There is no lifetime qualification on this type.
Definition TypeBase.h:350
void addCVRQualifiers(unsigned mask)
Definition TypeBase.h:502
void addQualifiers(Qualifiers Q)
Add the qualifiers from the given set to this set.
Definition TypeBase.h:650
Represents a struct/union/class.
Definition Decl.h:4309
Encodes a location in the source.
Stmt - This represents one statement.
Definition Stmt.h:85
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:334
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1801
bool isUnion() const
Definition Decl.h:3919
Exposes information about the current target.
Definition TargetInfo.h:226
virtual StringRef getABI() const
Get the ABI currently in use.
bool isVoidType() const
Definition TypeBase.h:8878
bool isBooleanType() const
Definition TypeBase.h:9008
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9177
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
bool isArrayType() const
Definition TypeBase.h:8621
bool isFunctionPointerType() const
Definition TypeBase.h:8589
CXXRecordDecl * castAsCXXRecordDecl() const
Definition Type.h:36
bool isArithmeticType() const
Definition Type.cpp:2337
bool isConstantMatrixType() const
Definition TypeBase.h:8683
bool isPointerType() const
Definition TypeBase.h:8522
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9168
bool isReferenceType() const
Definition TypeBase.h:8546
bool isVariableArrayType() const
Definition TypeBase.h:8633
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:752
bool isAnyComplexType() const
Definition TypeBase.h:8657
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition TypeBase.h:9051
bool isAtomicType() const
Definition TypeBase.h:8704
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition TypeBase.h:2800
bool isFunctionType() const
Definition TypeBase.h:8518
bool isVectorType() const
Definition TypeBase.h:8661
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9101
bool hasBooleanRepresentation() const
Determine whether this type has a boolean representation – i.e., it is a boolean type,...
Definition Type.cpp:2354
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2246
SourceLocation getExprLoc() const
Definition Expr.h:2370
Expr * getSubExpr() const
Definition Expr.h:2287
Opcode getOpcode() const
Definition Expr.h:2282
static bool isIncrementOp(Opcode Op)
Definition Expr.h:2328
static bool isPrefix(Opcode Op)
isPrefix - Return true if this is a prefix operation, like –x.
Definition Expr.h:2321
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:711
QualType getType() const
Definition Decl.h:722
Represents a variable declaration or definition.
Definition Decl.h:925
TLSKind getTLSKind() const
Definition Decl.cpp:2168
bool hasInit() const
Definition Decl.cpp:2398
@ TLS_Dynamic
TLS with a dynamic initializer.
Definition Decl.h:951
Represents a C array with a specified size that is not an integer-constant-expression.
Definition TypeBase.h:3964
Represents a GCC generic vector type.
Definition TypeBase.h:4173
AlignmentSource
The source of the alignment of an l-value; an expression of confidence in the alignment actually matc...
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
static AlignmentSource getFieldAlignmentSource(AlignmentSource source)
Given that the base address has the given alignment source, what's our confidence in the alignment of...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
const AstTypeMatcher< FunctionType > functionType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
The JSON file list parser is used to communicate input to InstallAPI.
CXXCtorType
C++ constructor types.
Definition ABI.h:24
@ Ctor_Base
Base object ctor.
Definition ABI.h:26
@ Ctor_Complete
Complete object ctor.
Definition ABI.h:25
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus
@ SD_Thread
Thread storage duration.
Definition Specifiers.h:342
@ SD_Static
Static storage duration.
Definition Specifiers.h:343
@ SD_FullExpression
Full-expression storage duration (for temporaries).
Definition Specifiers.h:340
@ SD_Automatic
Automatic storage duration (most local variables).
Definition Specifiers.h:341
@ SD_Dynamic
Dynamic storage duration.
Definition Specifiers.h:344
U cast(CodeGen::Address addr)
Definition Address.h:327
@ NOUR_Unevaluated
This name appears in an unevaluated operand.
Definition Specifiers.h:177
static bool weakRefReference()
static bool objCLifetime()
static bool emitLifetimeMarkers()
static bool opLoadEmitScalarRangeCheck()
static bool addressSpace()
static bool opLoadStoreThreadLocal()
static bool opAllocaNonGC()
static bool opGlobalThreadLocal()
static bool opAllocaOpenMPThreadPrivate()
static bool preservedAccessIndexRegion()
static bool mergeAllConstants()
static bool opLoadStoreAtomic()
static bool opLoadStoreTbaa()
static bool cgFPOptionsRAII()
static bool opCallChain()
static bool opAllocaImpreciseLifetime()
static bool opAllocaStaticLocal()
static bool aggValueSlot()
static bool opAllocaTLS()
static bool emitCheckedInBoundsGEP()
static bool attributeNoBuiltin()
static bool lambdaFieldToName()
static bool setObjCGCLValueClass()
static bool cirgenABIInfo()
static bool opLoadStoreObjC()
static bool opCallArgEvaluationOrder()
static bool lambdaCaptures()
static bool insertBuiltinUnpredictable()
static bool opCallMustTail()
static bool shouldReverseUnaryCondOnBoolExpr()
static bool tryEmitAsConstant()
static bool addressIsKnownNonNull()
static bool astVarDeclInterface()
static bool opAllocaEscapeByReference()
static bool opLoadStoreNontemporal()
static bool opCallFnInfoOpts()
static bool generateDebugInfo()
Record with information about how a bitfield should be accessed.
unsigned volatileStorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned volatileOffset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:645
APValue Val
Val - This is the value the expression can be folded to.
Definition Expr.h:647
bool HasSideEffects
Whether the evaluated expression has side effects.
Definition Expr.h:612