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())) {
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();
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))
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
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() &&
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 &&
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);
406 auto rec = cast<cir::RecordType>(base.getAddress().getElementType());
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 =
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 =
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 =
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
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()
684 vd->getType(), AlignmentSource::Decl)
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>()) {
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
907 if (isa<ExtVectorElementExpr>(e->getBase())) {
909 "emitArraySubscriptExpr: ExtVectorElementExpr");
911 }
912
913 if (getContext().getAsVariableArrayType(e->getType())) {
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>())
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() &&
943 !isa<ExtVectorElementExpr>(e->getBase())) {
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: {
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.
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)
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) {
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)) {
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()) {
1372 "emitMaterializeTemporaryExpr: Adjustments");
1373 return {};
1374 }
1375
1376 return makeAddrLValue(object, m->getType(), AlignmentSource::Decl);
1377}
1378
1380 if (e->isFileScope()) {
1381 cgm.errorNYI(e->getSourceRange(), "emitCompoundLiteralLValue: FileScope");
1382 return {};
1383 }
1384
1385 if (e->getType()->isVariablyModifiedType()) {
1387 "emitCompoundLiteralLValue: VariablyModifiedType");
1388 return {};
1389 }
1390
1391 Address declPtr = createMemTemp(e->getType(), getLoc(e->getSourceRange()),
1392 ".compoundliteral");
1393 const Expr *initExpr = e->getInitializer();
1394 LValue result = makeAddrLValue(declPtr, e->getType(), AlignmentSource::Decl);
1395
1396 emitAnyExprToMem(initExpr, declPtr, e->getType().getQualifiers(),
1397 /*Init*/ true);
1398
1399 // Block-scope compound literals are destroyed at the end of the enclosing
1400 // scope in C.
1401 if (!getLangOpts().CPlusPlus && e->getType().isDestructedType()) {
1403 "emitCompoundLiteralLValue: non C++ DestructedType");
1404 return {};
1405 }
1406
1407 return result;
1408}
1409
1411 RValue rv = emitCallExpr(e);
1412
1413 if (!rv.isScalar()) {
1414 cgm.errorNYI(e->getSourceRange(), "emitCallExprLValue: non-scalar return");
1415 return {};
1416 }
1417
1418 assert(e->getCallReturnType(getContext())->isReferenceType() &&
1419 "Can't have a scalar return unless the return type is a "
1420 "reference type!");
1421
1423}
1424
1426 // Comma expressions just emit their LHS then their RHS as an l-value.
1427 if (e->getOpcode() == BO_Comma) {
1428 emitIgnoredExpr(e->getLHS());
1429 return emitLValue(e->getRHS());
1430 }
1431
1432 if (e->getOpcode() == BO_PtrMemD || e->getOpcode() == BO_PtrMemI) {
1433 cgm.errorNYI(e->getSourceRange(), "member pointers");
1434 return {};
1435 }
1436
1437 assert(e->getOpcode() == BO_Assign && "unexpected binary l-value");
1438
1439 // Note that in all of these cases, __block variables need the RHS
1440 // evaluated first just in case the variable gets moved by the RHS.
1441
1443 case cir::TEK_Scalar: {
1445 if (e->getLHS()->getType().getObjCLifetime() !=
1447 cgm.errorNYI(e->getSourceRange(), "objc lifetimes");
1448 return {};
1449 }
1450
1451 RValue rv = emitAnyExpr(e->getRHS());
1452 LValue lv = emitLValue(e->getLHS());
1453
1454 SourceLocRAIIObject loc{*this, getLoc(e->getSourceRange())};
1455 if (lv.isBitField())
1457 else
1458 emitStoreThroughLValue(rv, lv);
1459
1460 if (getLangOpts().OpenMP) {
1461 cgm.errorNYI(e->getSourceRange(), "openmp");
1462 return {};
1463 }
1464
1465 return lv;
1466 }
1467
1468 case cir::TEK_Complex: {
1470 }
1471
1472 case cir::TEK_Aggregate:
1473 cgm.errorNYI(e->getSourceRange(), "aggregate lvalues");
1474 return {};
1475 }
1476 llvm_unreachable("bad evaluation kind");
1477}
1478
1479/// Emit code to compute the specified expression which
1480/// can have any type. The result is returned as an RValue struct.
1483 case cir::TEK_Scalar:
1484 return RValue::get(emitScalarExpr(e));
1485 case cir::TEK_Complex:
1487 case cir::TEK_Aggregate: {
1488 if (aggSlot.isIgnored())
1489 aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),
1491 emitAggExpr(e, aggSlot);
1492 return aggSlot.asRValue();
1493 }
1494 }
1495 llvm_unreachable("bad evaluation kind");
1496}
1497
1498// Detect the unusual situation where an inline version is shadowed by a
1499// non-inline version. In that case we should pick the external one
1500// everywhere. That's GCC behavior too.
1502 for (const FunctionDecl *pd = fd; pd; pd = pd->getPreviousDecl())
1503 if (!pd->isInlineBuiltinDeclaration())
1504 return false;
1505 return true;
1506}
1507
1508CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) {
1509 const auto *fd = cast<FunctionDecl>(gd.getDecl());
1510
1511 if (unsigned builtinID = fd->getBuiltinID()) {
1512 if (fd->getAttr<AsmLabelAttr>()) {
1513 cgm.errorNYI("AsmLabelAttr");
1514 }
1515
1516 StringRef ident = fd->getName();
1517 std::string fdInlineName = (ident + ".inline").str();
1518
1519 bool isPredefinedLibFunction =
1521 // Assume nobuiltins everywhere until we actually read the attributes.
1522 bool hasAttributeNoBuiltin = true;
1524
1525 // When directing calling an inline builtin, call it through it's mangled
1526 // name to make it clear it's not the actual builtin.
1527 auto fn = cast<cir::FuncOp>(curFn);
1528 if (fn.getName() != fdInlineName && onlyHasInlineBuiltinDeclaration(fd)) {
1529 cgm.errorNYI("Inline only builtin function calls");
1530 }
1531
1532 // Replaceable builtins provide their own implementation of a builtin. If we
1533 // are in an inline builtin implementation, avoid trivial infinite
1534 // recursion. Honor __attribute__((no_builtin("foo"))) or
1535 // __attribute__((no_builtin)) on the current function unless foo is
1536 // not a predefined library function which means we must generate the
1537 // builtin no matter what.
1538 else if (!isPredefinedLibFunction || !hasAttributeNoBuiltin)
1539 return CIRGenCallee::forBuiltin(builtinID, fd);
1540 }
1541
1542 cir::FuncOp callee = emitFunctionDeclPointer(cgm, gd);
1543
1544 assert(!cir::MissingFeatures::hip());
1545
1546 return CIRGenCallee::forDirect(callee, gd);
1547}
1548
1550 if (ty->isVoidType())
1551 return RValue::get(nullptr);
1552
1553 cgm.errorNYI("unsupported type for undef rvalue");
1554 return RValue::get(nullptr);
1555}
1556
1558 const CIRGenCallee &origCallee,
1559 const clang::CallExpr *e,
1560 ReturnValueSlot returnValue) {
1561 // Get the actual function type. The callee type will always be a pointer to
1562 // function type or a block pointer type.
1563 assert(calleeTy->isFunctionPointerType() &&
1564 "Callee must have function pointer type!");
1565
1566 calleeTy = getContext().getCanonicalType(calleeTy);
1567 auto pointeeTy = cast<PointerType>(calleeTy)->getPointeeType();
1568
1569 CIRGenCallee callee = origCallee;
1570
1571 if (getLangOpts().CPlusPlus)
1573
1574 const auto *fnType = cast<FunctionType>(pointeeTy);
1575
1577
1578 CallArgList args;
1580
1581 emitCallArgs(args, dyn_cast<FunctionProtoType>(fnType), e->arguments(),
1582 e->getDirectCallee());
1583
1584 const CIRGenFunctionInfo &funcInfo =
1585 cgm.getTypes().arrangeFreeFunctionCall(args, fnType);
1586
1587 // C99 6.5.2.2p6:
1588 // If the expression that denotes the called function has a type that does
1589 // not include a prototype, [the default argument promotions are performed].
1590 // If the number of arguments does not equal the number of parameters, the
1591 // behavior is undefined. If the function is defined with a type that
1592 // includes a prototype, and either the prototype ends with an ellipsis (,
1593 // ...) or the types of the arguments after promotion are not compatible
1594 // with the types of the parameters, the behavior is undefined. If the
1595 // function is defined with a type that does not include a prototype, and
1596 // the types of the arguments after promotion are not compatible with those
1597 // of the parameters after promotion, the behavior is undefined [except in
1598 // some trivial cases].
1599 // That is, in the general case, we should assume that a call through an
1600 // unprototyped function type works like a *non-variadic* call. The way we
1601 // make this work is to cast to the exxact type fo the promoted arguments.
1602 if (isa<FunctionNoProtoType>(fnType)) {
1605 cir::FuncType calleeTy = getTypes().getFunctionType(funcInfo);
1606 // get non-variadic function type
1607 calleeTy = cir::FuncType::get(calleeTy.getInputs(),
1608 calleeTy.getReturnType(), false);
1609 auto calleePtrTy = cir::PointerType::get(calleeTy);
1610
1611 mlir::Operation *fn = callee.getFunctionPointer();
1612 mlir::Value addr;
1613 if (auto funcOp = mlir::dyn_cast<cir::FuncOp>(fn)) {
1614 addr = builder.create<cir::GetGlobalOp>(
1615 getLoc(e->getSourceRange()),
1616 cir::PointerType::get(funcOp.getFunctionType()), funcOp.getSymName());
1617 } else {
1618 addr = fn->getResult(0);
1619 }
1620
1621 fn = builder.createBitcast(addr, calleePtrTy).getDefiningOp();
1622 callee.setFunctionPointer(fn);
1623 }
1624
1626 assert(!cir::MissingFeatures::hip());
1628
1629 cir::CIRCallOpInterface callOp;
1630 RValue callResult = emitCall(funcInfo, callee, returnValue, args, &callOp,
1631 getLoc(e->getExprLoc()));
1632
1634
1635 return callResult;
1636}
1637
1639 e = e->IgnoreParens();
1640
1641 // Look through function-to-pointer decay.
1642 if (const auto *implicitCast = dyn_cast<ImplicitCastExpr>(e)) {
1643 if (implicitCast->getCastKind() == CK_FunctionToPointerDecay ||
1644 implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {
1645 return emitCallee(implicitCast->getSubExpr());
1646 }
1647 // When performing an indirect call through a function pointer lvalue, the
1648 // function pointer lvalue is implicitly converted to an rvalue through an
1649 // lvalue-to-rvalue conversion.
1650 assert(implicitCast->getCastKind() == CK_LValueToRValue &&
1651 "unexpected implicit cast on function pointers");
1652 } else if (const auto *declRef = dyn_cast<DeclRefExpr>(e)) {
1653 // Resolve direct calls.
1654 const auto *funcDecl = cast<FunctionDecl>(declRef->getDecl());
1655 return emitDirectCallee(funcDecl);
1656 } else if (isa<MemberExpr>(e)) {
1658 "emitCallee: call to member function is NYI");
1659 return {};
1660 } else if (auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
1662 }
1663
1664 // Otherwise, we have an indirect reference.
1665 mlir::Value calleePtr;
1667 if (const auto *ptrType = e->getType()->getAs<clang::PointerType>()) {
1668 calleePtr = emitScalarExpr(e);
1669 functionType = ptrType->getPointeeType();
1670 } else {
1671 functionType = e->getType();
1672 calleePtr = emitLValue(e).getPointer();
1673 }
1674 assert(functionType->isFunctionType());
1675
1676 GlobalDecl gd;
1677 if (const auto *vd =
1678 dyn_cast_or_null<VarDecl>(e->getReferencedDeclOfCallee()))
1679 gd = GlobalDecl(vd);
1680
1681 CIRGenCalleeInfo calleeInfo(functionType->getAs<FunctionProtoType>(), gd);
1682 CIRGenCallee callee(calleeInfo, calleePtr.getDefiningOp());
1683 return callee;
1684}
1685
1687 ReturnValueSlot returnValue) {
1689
1690 if (const auto *ce = dyn_cast<CXXMemberCallExpr>(e))
1691 return emitCXXMemberCallExpr(ce, returnValue);
1692
1693 if (isa<CUDAKernelCallExpr>(e)) {
1694 cgm.errorNYI(e->getSourceRange(), "call to CUDA kernel");
1695 return RValue::get(nullptr);
1696 }
1697
1698 if (const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(e)) {
1699 // If the callee decl is a CXXMethodDecl, we need to emit this as a C++
1700 // operator member call.
1701 if (const CXXMethodDecl *md =
1702 dyn_cast_or_null<CXXMethodDecl>(operatorCall->getCalleeDecl()))
1703 return emitCXXOperatorMemberCallExpr(operatorCall, md, returnValue);
1704 // A CXXOperatorCallExpr is created even for explicit object methods, but
1705 // these should be treated like static function calls. Fall through to do
1706 // that.
1707 }
1708
1709 CIRGenCallee callee = emitCallee(e->getCallee());
1710
1711 if (callee.isBuiltin())
1712 return emitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), e,
1713 returnValue);
1714
1715 if (callee.isPseudoDestructor())
1717
1718 return emitCall(e->getCallee()->getType(), callee, e, returnValue);
1719}
1720
1721/// Emit code to compute the specified expression, ignoring the result.
1723 if (e->isPRValue()) {
1725 emitAnyExpr(e);
1726 return;
1727 }
1728
1729 // Just emit it as an l-value and drop the result.
1730 emitLValue(e);
1731}
1732
1734 LValueBaseInfo *baseInfo) {
1736 assert(e->getType()->isArrayType() &&
1737 "Array to pointer decay must have array source type!");
1738
1739 // Expressions of array type can't be bitfields or vector elements.
1740 LValue lv = emitLValue(e);
1741 Address addr = lv.getAddress();
1742
1743 // If the array type was an incomplete type, we need to make sure
1744 // the decay ends up being the right type.
1745 auto lvalueAddrTy = mlir::cast<cir::PointerType>(addr.getPointer().getType());
1746
1747 if (e->getType()->isVariableArrayType())
1748 return addr;
1749
1750 [[maybe_unused]] auto pointeeTy =
1751 mlir::cast<cir::ArrayType>(lvalueAddrTy.getPointee());
1752
1753 [[maybe_unused]] mlir::Type arrayTy = convertType(e->getType());
1754 assert(mlir::isa<cir::ArrayType>(arrayTy) && "expected array");
1755 assert(pointeeTy == arrayTy);
1756
1757 // The result of this decay conversion points to an array element within the
1758 // base lvalue. However, since TBAA currently does not support representing
1759 // accesses to elements of member arrays, we conservatively represent accesses
1760 // to the pointee object as if it had no any base lvalue specified.
1761 // TODO: Support TBAA for member arrays.
1764
1765 mlir::Value ptr = builder.maybeBuildArrayDecay(
1766 cgm.getLoc(e->getSourceRange()), addr.getPointer(),
1767 convertTypeForMem(eltType));
1768 return Address(ptr, addr.getAlignment());
1769}
1770
1771/// Given the address of a temporary variable, produce an r-value of its type.
1775 switch (getEvaluationKind(type)) {
1776 case cir::TEK_Complex:
1777 cgm.errorNYI(loc, "convertTempToRValue: complex type");
1778 return RValue::get(nullptr);
1779 case cir::TEK_Aggregate:
1780 cgm.errorNYI(loc, "convertTempToRValue: aggregate type");
1781 return RValue::get(nullptr);
1782 case cir::TEK_Scalar:
1783 return RValue::get(emitLoadOfScalar(lvalue, loc));
1784 }
1785 llvm_unreachable("bad evaluation kind");
1786}
1787
1788/// Emit an `if` on a boolean condition, filling `then` and `else` into
1789/// appropriated regions.
1790mlir::LogicalResult CIRGenFunction::emitIfOnBoolExpr(const Expr *cond,
1791 const Stmt *thenS,
1792 const Stmt *elseS) {
1793 mlir::Location thenLoc = getLoc(thenS->getSourceRange());
1794 std::optional<mlir::Location> elseLoc;
1795 if (elseS)
1796 elseLoc = getLoc(elseS->getSourceRange());
1797
1798 mlir::LogicalResult resThen = mlir::success(), resElse = mlir::success();
1800 cond, /*thenBuilder=*/
1801 [&](mlir::OpBuilder &, mlir::Location) {
1802 LexicalScope lexScope{*this, thenLoc, builder.getInsertionBlock()};
1803 resThen = emitStmt(thenS, /*useCurrentScope=*/true);
1804 },
1805 thenLoc,
1806 /*elseBuilder=*/
1807 [&](mlir::OpBuilder &, mlir::Location) {
1808 assert(elseLoc && "Invalid location for elseS.");
1809 LexicalScope lexScope{*this, *elseLoc, builder.getInsertionBlock()};
1810 resElse = emitStmt(elseS, /*useCurrentScope=*/true);
1811 },
1812 elseLoc);
1813
1814 return mlir::LogicalResult::success(resThen.succeeded() &&
1815 resElse.succeeded());
1816}
1817
1818/// Emit an `if` on a boolean condition, filling `then` and `else` into
1819/// appropriated regions.
1821 const clang::Expr *cond, BuilderCallbackRef thenBuilder,
1822 mlir::Location thenLoc, BuilderCallbackRef elseBuilder,
1823 std::optional<mlir::Location> elseLoc) {
1824 // Attempt to be as accurate as possible with IfOp location, generate
1825 // one fused location that has either 2 or 4 total locations, depending
1826 // on else's availability.
1827 SmallVector<mlir::Location, 2> ifLocs{thenLoc};
1828 if (elseLoc)
1829 ifLocs.push_back(*elseLoc);
1830 mlir::Location loc = mlir::FusedLoc::get(&getMLIRContext(), ifLocs);
1831
1832 // Emit the code with the fully general case.
1833 mlir::Value condV = emitOpOnBoolExpr(loc, cond);
1834 return builder.create<cir::IfOp>(loc, condV, elseLoc.has_value(),
1835 /*thenBuilder=*/thenBuilder,
1836 /*elseBuilder=*/elseBuilder);
1837}
1838
1839/// TODO(cir): see EmitBranchOnBoolExpr for extra ideas).
1840mlir::Value CIRGenFunction::emitOpOnBoolExpr(mlir::Location loc,
1841 const Expr *cond) {
1844 cond = cond->IgnoreParens();
1845
1846 // In LLVM the condition is reversed here for efficient codegen.
1847 // This should be done in CIR prior to LLVM lowering, if we do now
1848 // we can make CIR based diagnostics misleading.
1849 // cir.ternary(!x, t, f) -> cir.ternary(x, f, t)
1851
1852 if (const ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(cond)) {
1853 Expr *trueExpr = condOp->getTrueExpr();
1854 Expr *falseExpr = condOp->getFalseExpr();
1855 mlir::Value condV = emitOpOnBoolExpr(loc, condOp->getCond());
1856
1857 mlir::Value ternaryOpRes =
1858 builder
1859 .create<cir::TernaryOp>(
1860 loc, condV, /*thenBuilder=*/
1861 [this, trueExpr](mlir::OpBuilder &b, mlir::Location loc) {
1862 mlir::Value lhs = emitScalarExpr(trueExpr);
1863 b.create<cir::YieldOp>(loc, lhs);
1864 },
1865 /*elseBuilder=*/
1866 [this, falseExpr](mlir::OpBuilder &b, mlir::Location loc) {
1867 mlir::Value rhs = emitScalarExpr(falseExpr);
1868 b.create<cir::YieldOp>(loc, rhs);
1869 })
1870 .getResult();
1871
1872 return emitScalarConversion(ternaryOpRes, condOp->getType(),
1873 getContext().BoolTy, condOp->getExprLoc());
1874 }
1875
1876 if (isa<CXXThrowExpr>(cond)) {
1877 cgm.errorNYI("NYI");
1878 return createDummyValue(loc, cond->getType());
1879 }
1880
1881 // If the branch has a condition wrapped by __builtin_unpredictable,
1882 // create metadata that specifies that the branch is unpredictable.
1883 // Don't bother if not optimizing because that metadata would not be used.
1885
1886 // Emit the code with the fully general case.
1887 return evaluateExprAsBool(cond);
1888}
1889
1890mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
1891 mlir::Location loc, CharUnits alignment,
1892 bool insertIntoFnEntryBlock,
1893 mlir::Value arraySize) {
1894 mlir::Block *entryBlock = insertIntoFnEntryBlock
1896 : curLexScope->getEntryBlock();
1897
1898 // If this is an alloca in the entry basic block of a cir.try and there's
1899 // a surrounding cir.scope, make sure the alloca ends up in the surrounding
1900 // scope instead. This is necessary in order to guarantee all SSA values are
1901 // reachable during cleanups.
1902 assert(!cir::MissingFeatures::tryOp());
1903
1904 return emitAlloca(name, ty, loc, alignment,
1905 builder.getBestAllocaInsertPoint(entryBlock), arraySize);
1906}
1907
1908mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
1909 mlir::Location loc, CharUnits alignment,
1910 mlir::OpBuilder::InsertPoint ip,
1911 mlir::Value arraySize) {
1912 // CIR uses its own alloca address space rather than follow the target data
1913 // layout like original CodeGen. The data layout awareness should be done in
1914 // the lowering pass instead.
1916 cir::PointerType localVarPtrTy = builder.getPointerTo(ty);
1917 mlir::IntegerAttr alignIntAttr = cgm.getSize(alignment);
1918
1919 mlir::Value addr;
1920 {
1921 mlir::OpBuilder::InsertionGuard guard(builder);
1922 builder.restoreInsertionPoint(ip);
1923 addr = builder.createAlloca(loc, /*addr type*/ localVarPtrTy,
1924 /*var type*/ ty, name, alignIntAttr);
1926 }
1927 return addr;
1928}
1929
1930// Note: this function also emit constructor calls to support a MSVC extensions
1931// allowing explicit constructor function call.
1933 ReturnValueSlot returnValue) {
1934 const Expr *callee = ce->getCallee()->IgnoreParens();
1935
1936 if (isa<BinaryOperator>(callee)) {
1938 "emitCXXMemberCallExpr: C++ binary operator");
1939 return RValue::get(nullptr);
1940 }
1941
1942 const auto *me = cast<MemberExpr>(callee);
1943 const auto *md = cast<CXXMethodDecl>(me->getMemberDecl());
1944
1945 if (md->isStatic()) {
1946 cgm.errorNYI(ce->getSourceRange(), "emitCXXMemberCallExpr: static method");
1947 return RValue::get(nullptr);
1948 }
1949
1950 bool hasQualifier = me->hasQualifier();
1951 NestedNameSpecifier qualifier = me->getQualifier();
1952 bool isArrow = me->isArrow();
1953 const Expr *base = me->getBase();
1954
1956 ce, md, returnValue, hasQualifier, qualifier, isArrow, base);
1957}
1958
1960 AggValueSlot dest) {
1961 assert(!dest.isIgnored() && "Must have a destination!");
1962 const CXXConstructorDecl *cd = e->getConstructor();
1963
1964 // If we require zero initialization before (or instead of) calling the
1965 // constructor, as can be the case with a non-user-provided default
1966 // constructor, emit the zero initialization now, unless destination is
1967 // already zeroed.
1968 if (e->requiresZeroInitialization() && !dest.isZeroed()) {
1970 "emitCXXConstructExpr: requires initialization");
1971 return;
1972 }
1973
1974 // If this is a call to a trivial default constructor:
1975 // In LLVM: do nothing.
1976 // In CIR: emit as a regular call, other later passes should lower the
1977 // ctor call into trivial initialization.
1978
1979 // Elide the constructor if we're constructing from a temporary
1980 if (getLangOpts().ElideConstructors && e->isElidable()) {
1982 "emitCXXConstructExpr: elidable constructor");
1983 return;
1984 }
1985
1986 if (const ArrayType *arrayType = getContext().getAsArrayType(e->getType())) {
1988 emitCXXAggrConstructorCall(cd, arrayType, dest.getAddress(), e, false);
1989 } else {
1990
1992 bool forVirtualBase = false;
1993 bool delegating = false;
1994
1995 switch (e->getConstructionKind()) {
1998 break;
2000 // We should be emitting a constructor; GlobalDecl will assert this
2002 delegating = true;
2003 break;
2005 forVirtualBase = true;
2006 [[fallthrough]];
2008 type = Ctor_Base;
2009 break;
2010 }
2011
2012 emitCXXConstructorCall(cd, type, forVirtualBase, delegating, dest, e);
2013 }
2014}
2015
2017 // Emit the expression as an lvalue.
2018 LValue lv = emitLValue(e);
2019 assert(lv.isSimple());
2020 mlir::Value value = lv.getPointer();
2021
2023
2024 return RValue::get(value);
2025}
2026
2028 LValueBaseInfo *pointeeBaseInfo) {
2029 if (refLVal.isVolatile())
2030 cgm.errorNYI(loc, "load of volatile reference");
2031
2032 cir::LoadOp load =
2033 builder.create<cir::LoadOp>(loc, refLVal.getAddress().getElementType(),
2034 refLVal.getAddress().getPointer());
2035
2037
2038 QualType pointeeType = refLVal.getType()->getPointeeType();
2039 CharUnits align = cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);
2040 return Address(load, convertTypeForMem(pointeeType), align);
2041}
2042
2044 mlir::Location loc,
2045 QualType refTy,
2046 AlignmentSource source) {
2047 LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source));
2048 LValueBaseInfo pointeeBaseInfo;
2050 Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo);
2051 return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(),
2052 pointeeBaseInfo);
2053}
2054
2055void CIRGenFunction::emitTrap(mlir::Location loc, bool createNewBlock) {
2056 cir::TrapOp::create(builder, loc);
2057 if (createNewBlock)
2058 builder.createBlock(builder.getBlock()->getParent());
2059}
2060
2062 bool createNewBlock) {
2064 cir::UnreachableOp::create(builder, getLoc(loc));
2065 if (createNewBlock)
2066 builder.createBlock(builder.getBlock()->getParent());
2067}
2068
2069mlir::Value CIRGenFunction::createDummyValue(mlir::Location loc,
2070 clang::QualType qt) {
2071 mlir::Type t = convertType(qt);
2072 CharUnits alignment = getContext().getTypeAlignInChars(qt);
2073 return builder.createDummyValue(loc, t, alignment);
2074}
2075
2076//===----------------------------------------------------------------------===//
2077// CIR builder helpers
2078//===----------------------------------------------------------------------===//
2079
2081 const Twine &name, Address *alloca,
2082 mlir::OpBuilder::InsertPoint ip) {
2083 // FIXME: Should we prefer the preferred type alignment here?
2084 return createMemTemp(ty, getContext().getTypeAlignInChars(ty), loc, name,
2085 alloca, ip);
2086}
2087
2089 mlir::Location loc, const Twine &name,
2090 Address *alloca,
2091 mlir::OpBuilder::InsertPoint ip) {
2092 Address result = createTempAlloca(convertTypeForMem(ty), align, loc, name,
2093 /*ArraySize=*/nullptr, alloca, ip);
2094 if (ty->isConstantMatrixType()) {
2096 cgm.errorNYI(loc, "temporary matrix value");
2097 }
2098 return result;
2099}
2100
2101/// This creates a alloca and inserts it into the entry block of the
2102/// current region.
2104 mlir::Type ty, CharUnits align, mlir::Location loc, const Twine &name,
2105 mlir::Value arraySize, mlir::OpBuilder::InsertPoint ip) {
2106 cir::AllocaOp alloca = ip.isSet()
2107 ? createTempAlloca(ty, loc, name, ip, arraySize)
2108 : createTempAlloca(ty, loc, name, arraySize);
2109 alloca.setAlignmentAttr(cgm.getSize(align));
2110 return Address(alloca, ty, align);
2111}
2112
2113/// This creates a alloca and inserts it into the entry block. The alloca is
2114/// casted to default address space if necessary.
2116 mlir::Location loc, const Twine &name,
2117 mlir::Value arraySize,
2118 Address *allocaAddr,
2119 mlir::OpBuilder::InsertPoint ip) {
2120 Address alloca =
2121 createTempAllocaWithoutCast(ty, align, loc, name, arraySize, ip);
2122 if (allocaAddr)
2123 *allocaAddr = alloca;
2124 mlir::Value v = alloca.getPointer();
2125 // Alloca always returns a pointer in alloca address space, which may
2126 // be different from the type defined by the language. For example,
2127 // in C++ the auto variables are in the default address space. Therefore
2128 // cast alloca to the default address space when necessary.
2130 return Address(v, ty, align);
2131}
2132
2133/// This creates an alloca and inserts it into the entry block if \p ArraySize
2134/// is nullptr, otherwise inserts it at the current insertion point of the
2135/// builder.
2136cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty,
2137 mlir::Location loc,
2138 const Twine &name,
2139 mlir::Value arraySize,
2140 bool insertIntoFnEntryBlock) {
2141 return mlir::cast<cir::AllocaOp>(emitAlloca(name.str(), ty, loc, CharUnits(),
2142 insertIntoFnEntryBlock, arraySize)
2143 .getDefiningOp());
2144}
2145
2146/// This creates an alloca and inserts it into the provided insertion point
2147cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty,
2148 mlir::Location loc,
2149 const Twine &name,
2150 mlir::OpBuilder::InsertPoint ip,
2151 mlir::Value arraySize) {
2152 assert(ip.isSet() && "Insertion point is not set");
2153 return mlir::cast<cir::AllocaOp>(
2154 emitAlloca(name.str(), ty, loc, CharUnits(), ip, arraySize)
2155 .getDefiningOp());
2156}
2157
2158/// Try to emit a reference to the given value without producing it as
2159/// an l-value. For many cases, this is just an optimization, but it avoids
2160/// us needing to emit global copies of variables if they're named without
2161/// triggering a formal use in a context where we can't emit a direct
2162/// reference to them, for instance if a block or lambda or a member of a
2163/// local class uses a const int variable or constexpr variable from an
2164/// enclosing function.
2165///
2166/// For named members of enums, this is the only way they are emitted.
2169 const ValueDecl *value = refExpr->getDecl();
2170
2171 // There is a lot more to do here, but for now only EnumConstantDecl is
2172 // supported.
2174
2175 // The value needs to be an enum constant or a constant variable.
2176 if (!isa<EnumConstantDecl>(value))
2177 return ConstantEmission();
2178
2179 Expr::EvalResult result;
2180 if (!refExpr->EvaluateAsRValue(result, getContext()))
2181 return ConstantEmission();
2182
2183 QualType resultType = refExpr->getType();
2184
2185 // As long as we're only handling EnumConstantDecl, there should be no
2186 // side-effects.
2187 assert(!result.HasSideEffects);
2188
2189 // Emit as a constant.
2190 // FIXME(cir): have emitAbstract build a TypedAttr instead (this requires
2191 // somewhat heavy refactoring...)
2192 mlir::Attribute c = ConstantEmitter(*this).emitAbstract(
2193 refExpr->getLocation(), result.Val, resultType);
2194 mlir::TypedAttr cstToEmit = mlir::dyn_cast_if_present<mlir::TypedAttr>(c);
2195 assert(cstToEmit && "expected a typed attribute");
2196
2198
2199 return ConstantEmission::forValue(cstToEmit);
2200}
2201
2205 return tryEmitAsConstant(dre);
2206 return ConstantEmission();
2207}
2208
2210 const CIRGenFunction::ConstantEmission &constant, Expr *e) {
2211 assert(constant && "not a constant");
2212 if (constant.isReference()) {
2213 cgm.errorNYI(e->getSourceRange(), "emitScalarConstant: reference");
2214 return {};
2215 }
2216 return builder.getConstant(getLoc(e->getSourceRange()), constant.getValue());
2217}
2218
2219/// An LValue is a candidate for having its loads and stores be made atomic if
2220/// we are operating under /volatile:ms *and* the LValue itself is volatile and
2221/// performing such an operation can be performed without a libcall.
2223 if (!cgm.getLangOpts().MSVolatile)
2224 return false;
2225
2226 cgm.errorNYI("LValueSuitableForInlineAtomic LangOpts MSVolatile");
2227 return false;
2228}
#define V(N, I)
Definition: ASTContext.h:3597
llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> BuilderCallbackRef
Definition: CIRDialect.h:38
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.
Definition: CIRGenExpr.cpp:361
static LValue emitFunctionDeclLValue(CIRGenFunction &cgf, const Expr *e, GlobalDecl gd)
Definition: CIRGenExpr.cpp:622
static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx, CharUnits eltSize)
Definition: CIRGenExpr.cpp:845
static void pushTemporaryCleanup(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *e, Address referenceTemporary)
static cir::IntAttr getConstantIndexOrNull(mlir::Value idx)
Definition: CIRGenExpr.cpp:838
static const Expr * getSimpleArrayDecayOperand(const Expr *e)
If the specified expr is a simple decay from an array to pointer, return the array subexpression.
Definition: CIRGenExpr.cpp:824
static QualType getFixedSizeElementType(const ASTContext &astContext, const VariableArrayType *vla)
Definition: CIRGenExpr.cpp:857
static DeclRefExpr * tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf, const MemberExpr *me)
static cir::FuncOp emitFunctionDeclPointer(CIRGenModule &cgm, GlobalDecl gd)
Definition: CIRGenExpr.cpp:617
static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e, const VarDecl *vd)
Definition: CIRGenExpr.cpp:275
static mlir::Value emitArraySubscriptPtr(CIRGenFunction &cgf, mlir::Location beginLoc, mlir::Location endLoc, mlir::Value ptr, mlir::Type eltTy, mlir::Value idx, bool shouldDecay)
Definition: CIRGenExpr.cpp:866
static bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *fd)
Defines the clang::Expr interface and subclasses for C++ expressions.
__device__ __2f16 b
__device__ __2f16 float c
mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global)
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr)
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 createDummyValue(mlir::Location loc, mlir::Type type, clang::CharUnits alignment)
mlir::DataLayout layout
Definition: CIRDataLayout.h:28
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 ...
Definition: ASTContext.h:2851
Builtin::Context & BuiltinInfo
Definition: ASTContext.h:742
CanQualType BoolTy
Definition: ASTContext.h:1223
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
Definition: ASTContext.h:3059
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:3738
QualType getElementType() const
Definition: TypeBase.h:3750
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
bool isPredefinedLibFunction(unsigned ID) const
Determines whether this builtin is a predefined libc/libm function, such as "malloc",...
Definition: Builtins.h:313
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
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.
Definition: CIRGenValue.h:302
IsZeroed_t isZeroed() const
Definition: CIRGenValue.h:382
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Definition: CIRGenValue.h:359
Address getAddress() const
Definition: CIRGenValue.h:376
mlir::Value createComplexRealPtr(mlir::Location loc, mlir::Value value)
Create a cir.complex.real_ptr operation that derives a pointer to the real part of the complex value ...
mlir::Value createComplexImagPtr(mlir::Location loc, mlir::Value value)
Create a cir.complex.imag_ptr operation that derives a pointer to the imaginary part of the complex v...
mlir::Value maybeBuildArrayDecay(mlir::Location loc, mlir::Value arrayPtr, mlir::Type eltTy)
Returns a decayed pointer to the first element of the array pointed to by arrayPtr.
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 createGetBitfield(mlir::Location loc, mlir::Type resultType, Address addr, mlir::Type storageType, const CIRGenBitFieldInfo &info, bool isLvalueVolatile, bool useVolatile)
mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType, Address dstAddr, mlir::Type storageType, mlir::Value src, const CIRGenBitFieldInfo &info, bool isLvalueVolatile, bool useVolatile)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
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.
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::MemOrderAttr order={})
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)
Definition: CIRGenCall.cpp:731
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...
Definition: CIRGenExpr.cpp:67
RValue emitLoadOfLValue(LValue lv, SourceLocation loc)
Given an expression that represents a value lvalue, this method emits the address of the lvalue,...
Definition: CIRGenExpr.cpp:596
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)
Definition: CIRGenExpr.cpp:415
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,...
Definition: CIRGenExpr.cpp:718
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, bool isInit=false, bool isNontemporal=false)
Definition: CIRGenExpr.cpp:312
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)
Definition: CIRGenExpr.cpp:994
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.
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)
Definition: CIRGenExpr.cpp:906
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)
static Destroyer destroyCXXObject
RValue getUndefRValue(clang::QualType ty)
Get an appropriate 'undef' rvalue for the given type.
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)
Definition: CIRGenExpr.cpp:737
RValue emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc)
Definition: CIRGenExpr.cpp:383
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
Definition: CIRGenCall.cpp:500
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...
Definition: CIRGenExpr.cpp:501
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.
Definition: CIRGenExpr.cpp:529
LValue emitLValueForField(LValue base, const clang::FieldDecl *field)
Definition: CIRGenExpr.cpp:439
cir::FuncOp curFn
The function for which code is currently being generated.
void pushDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer)
Definition: CIRGenDecl.cpp:683
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)
Definition: CIRGenExpr.cpp:400
CIRGenModule & getCIRGenModule()
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...
Definition: CIRGenExpr.cpp:585
DeclMapTy localDeclMap
This keeps track of the CIR allocas or globals for local C declarations.
LValue emitDeclRefLValue(const clang::DeclRefExpr *e)
Definition: CIRGenExpr.cpp:648
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)
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)
Definition: CIRGenExpr.cpp:365
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 ...
Definition: CIRGenExpr.cpp:246
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={})
Definition: CIRGenStmt.cpp:110
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.
Definition: CIRGenExpr.cpp:35
This class organizes the cross-function state that is used while generating CIR code.
Definition: CIRGenModule.h:56
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
Definition: CIRGenModule.h:102
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
mlir::IntegerAttr getSize(CharUnits size)
Definition: CIRGenModule.h:389
CIRGenBuilderTy & getBuilder()
Definition: CIRGenModule.h:101
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo)
FIXME: this could likely be a common helper and not necessarily related with codegen.
const clang::TargetInfo & getTarget() const
Definition: CIRGenModule.h:103
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.
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
const cir::CIRDataLayout getDataLayout() const
Definition: CIRGenModule.h:112
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.
const clang::CodeGenOptions & getCodeGenOpts() const
Definition: CIRGenModule.h:104
const clang::LangOptions & getLangOpts() const
Definition: CIRGenModule.h:107
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
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.
const CIRGenFunctionInfo & arrangeFreeFunctionCall(const CallArgList &args, const FunctionType *fnType)
Definition: CIRGenCall.cpp:387
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
Definition: CIRGenCall.cpp:50
const CIRGenRecordLayout & getCIRGenRecordLayout(const clang::RecordDecl *rd)
Return record layout info for the given record decl.
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
Definition: CIRGenValue.h:145
void mergeForCast(const LValueBaseInfo &info)
Definition: CIRGenValue.h:148
const clang::Qualifiers & getQuals() const
Definition: CIRGenValue.h:223
mlir::Value getVectorIdx() const
Definition: CIRGenValue.h:252
bool isVectorElt() const
Definition: CIRGenValue.h:191
Address getAddress() const
Definition: CIRGenValue.h:211
static LValue makeAddr(Address address, clang::QualType t, LValueBaseInfo baseInfo)
Definition: CIRGenValue.h:229
static LValue makeVectorElt(Address vecAddress, mlir::Value index, clang::QualType t, LValueBaseInfo baseInfo)
Definition: CIRGenValue.h:257
unsigned getVRQualifiers() const
Definition: CIRGenValue.h:198
clang::QualType getType() const
Definition: CIRGenValue.h:202
static LValue makeBitfield(Address addr, const CIRGenBitFieldInfo &info, clang::QualType type, LValueBaseInfo baseInfo)
Create a new object to represent a bit-field access.
Definition: CIRGenValue.h:289
mlir::Value getPointer() const
Definition: CIRGenValue.h:204
bool isVolatileQualified() const
Definition: CIRGenValue.h:196
bool isBitField() const
Definition: CIRGenValue.h:192
Address getVectorAddress() const
Definition: CIRGenValue.h:243
clang::CharUnits getAlignment() const
Definition: CIRGenValue.h:206
LValueBaseInfo getBaseInfo() const
Definition: CIRGenValue.h:226
bool isVolatile() const
Definition: CIRGenValue.h:194
const CIRGenBitFieldInfo & getBitFieldInfo() const
Definition: CIRGenValue.h:278
Address getBitFieldAddress() const
Definition: CIRGenValue.h:269
bool isSimple() const
Definition: CIRGenValue.h:190
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
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
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
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:3293
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 ?: ternary operator.
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
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
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:57
CXXCtorType getCtorType() const
Definition: GlobalDecl.h:108
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? This is only meaningful if the named memb...
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:3669
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>::".
Represents a class type in Objective C.
Definition: TypeBase.h:7707
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: TypeBase.h:3346
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:8383
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
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:201
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.
Definition: TargetInfo.h:1357
bool isVoidType() const
Definition: TypeBase.h:8936
bool isBooleanType() const
Definition: TypeBase.h:9066
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
Definition: TypeBase.h:9235
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:8679
bool isFunctionPointerType() const
Definition: TypeBase.h:8647
CXXRecordDecl * castAsCXXRecordDecl() const
Definition: Type.h:36
bool isArithmeticType() const
Definition: Type.cpp:2341
bool isConstantMatrixType() const
Definition: TypeBase.h:8741
bool isPointerType() const
Definition: TypeBase.h:8580
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isReferenceType() const
Definition: TypeBase.h:8604
bool isVariableArrayType() const
Definition: TypeBase.h:8691
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:8715
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition: TypeBase.h:9109
bool isAtomicType() const
Definition: TypeBase.h:8762
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition: TypeBase.h:2818
bool isFunctionType() const
Definition: TypeBase.h:8576
bool isVectorType() const
Definition: TypeBase.h:8719
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
bool hasBooleanRepresentation() const
Determine whether this type has a boolean representation – i.e., it is a boolean type,...
Definition: Type.cpp:2358
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:3982
Represents a GCC generic vector type.
Definition: TypeBase.h:4191
Definition: ABIArgInfo.h:22
AlignmentSource
The source of the alignment of an l-value; an expression of confidence in the alignment actually matc...
Definition: CIRGenValue.h:115
@ 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...
Definition: CIRGenValue.h:133
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const AstTypeMatcher< FunctionType > functionType
Matches FunctionType nodes.
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
@ CPlusPlus
Definition: LangStandard.h:55
@ 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
UnaryOperatorKind
@ 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 sanitizers()
static bool opAllocaImpreciseLifetime()
static bool typeChecks()
static bool opAllocaStaticLocal()
static bool matrixType()
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 objCBlocks()
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()
static bool setNonGC()
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