clang 23.0.0git
CIRGenExprConstant.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 Constant Expr nodes as LLVM code.
10//
11//===----------------------------------------------------------------------===//
12
13#include "Address.h"
14#include "CIRGenCXXABI.h"
16#include "CIRGenModule.h"
17#include "CIRGenRecordLayout.h"
18#include "mlir/IR/Attributes.h"
19#include "mlir/IR/BuiltinAttributeInterfaces.h"
20#include "mlir/IR/BuiltinAttributes.h"
21#include "clang/AST/APValue.h"
23#include "clang/AST/Attr.h"
24#include "clang/AST/CharUnits.h"
32#include "llvm/ADT/ArrayRef.h"
33#include "llvm/ADT/STLExtras.h"
34#include "llvm/Support/ErrorHandling.h"
35#include <functional>
36#include <iterator>
37
38using namespace clang;
39using namespace clang::CIRGen;
40
41//===----------------------------------------------------------------------===//
42// ConstantAggregateBuilder
43//===----------------------------------------------------------------------===//
44
45namespace {
47// A class to manage the list of 'initializers' for building the record
48// initialization. This abstracts out the APValue and the InitListExpr.
49class RecordBuilderInitList {
50 unsigned initIdx = 0;
51 bool isUnion = false;
52 std::variant<APValue, const InitListExpr *> value;
53
54 bool holdsExpr() const {
55 return std::holds_alternative<const InitListExpr *>(value);
56 }
57
58 bool holdsAPValue() const { return std::holds_alternative<APValue>(value); }
59
60 const Expr *getExpr() {
61 assert(holdsExpr());
62 return std::get<const InitListExpr *>(value)->getInit(initIdx);
63 }
64
65 mlir::Location getExprLoc(CIRGenModule &cgm) {
66 assert(holdsExpr());
67 return cgm.getLoc(std::get<const InitListExpr *>(value)->getBeginLoc());
68 }
69
70 const APValue getAPVal() {
71 assert(holdsAPValue());
72 if (isUnion)
73 return std::get<APValue>(value).getUnionValue();
74 return std::get<APValue>(value).getStructField(initIdx);
75 }
76
77public:
78 RecordBuilderInitList(const RecordDecl *rd, APValue val)
79 : isUnion(rd->isUnion()), value(val) {}
80 RecordBuilderInitList(const RecordDecl *rd, const InitListExpr *ile)
81 : isUnion(rd->isUnion()), value(ile) {
82 assert(ile);
83 }
84
85 bool empty() const {
86 if (auto *const *ile = std::get_if<const InitListExpr *>(&value))
87 return initIdx >= (*ile)->getNumInits();
88
89 // This branch is likely always true, but we guard against it being 'none'
90 // anyway.
91 if (isUnion)
92 return !std::get<APValue>(value).isUnion();
93
94 return initIdx >= std::get<APValue>(value).getStructNumFields();
95 }
96
97 const FieldDecl *getActiveUnionField() const {
98 if (holdsExpr())
99 return std::get<const InitListExpr *>(value)
100 ->getInitializedFieldInUnion();
101 return std::get<APValue>(value).getUnionField();
102 }
103
104 // Return whether this is a field that should be skipped for one reason or
105 // another.
106 bool shouldSkip(const FieldDecl *fd) {
107 if (fd->isUnnamedBitField())
108 return true;
109
110 if (holdsExpr() && isa_and_nonnull<NoInitExpr>(getExpr()))
111 return true;
112
113 return false;
114 }
115
116 // Advance the iterator on a 'skipped' field. Note in the case of an
117 // init-list this doesn't advance if its an unnamed bitfield, as those aren't
118 // represented in the AST.
119 void advanceSkip(const FieldDecl *fd) {
120 assert(!isUnion);
121 if (holdsExpr() && fd->isUnnamedBitField())
122 return;
123 ++initIdx;
124 }
125 // Advance the iterator on a 'normal' field, which always just increments the
126 // index.
127 void advance() {
128 assert(!isUnion);
129 ++initIdx;
130 }
131
132 APValue getBase(unsigned idx) {
133 // We could potentially handle this with init-list, but we just skip it
134 // because classic codegen does. If we decide to, we'll probably have to do
135 // something where we get through the init-list elements to make this work
136 // right (sub-init-list?).
137 assert(holdsAPValue());
138
139 return std::get<APValue>(value).getStructBase(idx);
140 }
141
142 bool hasSideEffects(const ASTContext &ctx) {
143 if (holdsExpr() && getExpr()->HasSideEffects(ctx))
144 return true;
145 // APValue never has side effects.
146 return false;
147 }
148
149 mlir::Attribute emit(ConstantEmitter &emitter, QualType fieldTy) {
150 if (holdsExpr()) {
151 const Expr *e = getExpr();
152 return e ? emitter.tryEmitPrivateForMemory(e, fieldTy)
153 : emitter.emitNullForMemory(getExprLoc(emitter.cgm), fieldTy);
154 }
155 return emitter.tryEmitPrivateForMemory(getAPVal(), fieldTy);
156 }
157};
158
159mlir::Attribute updateBitfieldInit(CIRGenModule &cgm, cir::IntAttr existingVal,
160 cir::IntAttr newVal, bool isSigned,
161 const CIRGenBitFieldInfo &bfInfo) {
162 llvm::APInt result(bfInfo.storageSize, 0);
163 if (existingVal)
164 result = existingVal.getValue();
165
166 llvm::APInt curValue = newVal.getValue();
167 // Make sure we truncate (or properly extend) the existing value for the
168 // number of bits in the bitfield. The AST/Sema doesn't do a good job of
169 // making sure this is done.
170 if (isSigned)
171 curValue = curValue.sextOrTrunc(bfInfo.size);
172 else
173 curValue = curValue.zextOrTrunc(bfInfo.size);
174
175 // Extend to the full storage size so we can shift/mask.
176 curValue = curValue.zext(bfInfo.storageSize);
177
178 unsigned offset = bfInfo.offset;
179 if (cgm.getDataLayout().isBigEndian())
180 offset = bfInfo.storageSize - bfInfo.size - offset;
181
182 curValue = curValue.shl(offset);
183 llvm::APInt mask(bfInfo.storageSize, 0);
184 mask.setBits(offset, offset + bfInfo.size);
185
186 result &= ~mask;
187 result |= curValue;
188
189 return cir::IntAttr::get(bfInfo.storageType, result);
190}
191
192mlir::Attribute
193setBitfieldInit(CIRGenModule &cgm, const CIRGenRecordLayout &cirLayout,
194 CIRGenBuilderTy &builder, const FieldDecl *field,
195 mlir::Attribute existingVal, mlir::Attribute newVal) {
196 const CIRGenBitFieldInfo &info = cirLayout.getBitFieldInfo(field);
197 auto intAttr = mlir::dyn_cast<cir::IntAttr>(newVal);
198 // This could alternatively be a 'bool' attr here, so do a quick fixup to
199 // get the value correctly initialized.
200 if (!intAttr) {
201 auto boolAttr = mlir::cast<cir::BoolAttr>(newVal);
202 intAttr = cir::IntAttr::get(
203 builder.getUIntNTy(1), llvm::APInt(/*numBits=*/1, boolAttr.getValue()));
204 }
205
206 return updateBitfieldInit(
207 cgm, dyn_cast_if_present<cir::IntAttr>(existingVal), intAttr,
208 field->getType()->isSignedIntegerOrEnumerationType(), info);
209}
210
211mlir::Attribute buildRecordHelper(ConstantEmitter &emitter,
212 const RecordDecl *rd,
213 const RecordDecl *vtableBaseTy,
214 RecordBuilderInitList inits, bool handleBases,
215 CharUnits offsetInDerived,
216 bool asBaseSubObj) {
217 CIRGenModule &cgm = emitter.cgm;
218 CIRGenBuilderTy &builder = cgm.getBuilder();
219 const CIRGenRecordLayout &cirLayout =
221 cir::RecordType recordTy = asBaseSubObj ? cirLayout.getBaseSubobjectCIRType()
222 : cirLayout.getCIRType();
223 // Unions in CIR are represented by all of their types, so we should be able
224 // to just initialize it with whatever the active field is.
225 if (rd->isUnion()) {
226 if (inits.empty())
227 return builder.getZeroInitAttr(recordTy);
228
229 const FieldDecl *activeField = inits.getActiveUnionField();
230 if (!activeField || activeField->isZeroSize(cgm.getASTContext()))
231 return builder.getZeroInitAttr(recordTy);
232
233 mlir::Attribute eltAttr = inits.emit(emitter, activeField->getType());
234 if (!eltAttr)
235 return {};
236
237 if (activeField->isBitField())
238 eltAttr = setBitfieldInit(cgm, cirLayout, builder, activeField,
239 /*existingVal=*/{}, eltAttr);
240
241 return cir::ConstRecordAttr::get(recordTy, builder.getArrayAttr({eltAttr}));
242 }
243
245
246 if (auto *cxxrd = dyn_cast<CXXRecordDecl>(rd)) {
247 const ASTRecordLayout &astLayout =
248 emitter.cgm.getASTContext().getASTRecordLayout(cxxrd);
249 if (astLayout.hasOwnVFPtr()) {
250 mlir::Value addrPtr = emitter.cgm.getCXXABI().getVTableAddressPoint(
251 BaseSubobject(cxxrd, offsetInDerived),
252 cast<CXXRecordDecl>(vtableBaseTy));
254 auto apOp = addrPtr.getDefiningOp<cir::VTableAddrPointOp>();
255 mlir::ArrayAttr indices = builder.getArrayAttr(
256 {builder.getI32IntegerAttr(apOp.getAddressPoint().getIndex()),
257 builder.getI32IntegerAttr(apOp.getAddressPoint().getOffset())});
258 elements[0] =
259 cir::GlobalViewAttr::get(cir::VPtrType::get(builder.getContext()),
260 apOp.getNameAttr(), indices);
261 }
262
263 for (auto [idx, base] : llvm::enumerate(cxxrd->bases())) {
264 // Our init-list implementation here just skips bases because classic
265 // compiler does (see the comment in buildRecord). We perhaps COULD do
266 // this, but for now we'll skip them.
267 if (!handleBases)
268 return {};
269
270 if (base.isVirtual())
271 continue;
272
273 const auto *baseDecl = base.getType()->castAsCXXRecordDecl();
274
275 if (!cirLayout.hasNonVirtualBaseCIRField(baseDecl))
276 continue;
277
278 APValue baseValue = inits.getBase(idx);
279
280 const ASTRecordLayout &derivedLayout =
282 CharUnits baseOff =
283 offsetInDerived + derivedLayout.getBaseClassOffset(baseDecl);
284
285 unsigned baseFieldIdx = cirLayout.getNonVirtualBaseCIRFieldNo(baseDecl);
286 elements[baseFieldIdx] = buildRecordHelper(
287 emitter, baseDecl, vtableBaseTy, RecordBuilderInitList(rd, baseValue),
288 handleBases, baseOff, /*asBaseSubObj=*/true);
289 }
290
291 if (cxxrd->getNumVBases()) {
292 cgm.errorNYI(cxxrd->getSourceRange(),
293 "buildRecordHelper: virtual base classes");
294 return {};
295 }
296 }
297
298 for (const FieldDecl *field : rd->fields()) {
299 // If we don't have any initializers left, we'll just zero-init below. This
300 // isn't perfectly accurate to classic compiler, since we are potentially
301 // zero-initing padding (instead of leaving it undef), but that is a
302 // complexity we can deal with later if we find it necessary.
303 if (inits.empty())
304 break;
305
306 if (inits.shouldSkip(field)) {
307 inits.advanceSkip(field);
308 continue;
309 }
310
311 // If we didn't lay it out, there is nothing to initialize. This is
312 // either zero size or nothing at all. IF our init has side effects, we
313 // cannot const init this.
314 if (!cirLayout.hasCIRField(field)) {
315 if (inits.hasSideEffects(cgm.getASTContext()))
316 return {};
317 inits.advance();
318 continue;
319 }
320
321 unsigned fieldIdx = cirLayout.getCIRFieldNo(field);
322
323 mlir::Attribute eltAttr = inits.emit(emitter, field->getType());
324 inits.advance();
325
326 if (!eltAttr)
327 return {};
328
329 if (field->isBitField())
330 elements[fieldIdx] = setBitfieldInit(cgm, cirLayout, builder, field,
331 elements[fieldIdx], eltAttr);
332 else
333 elements[fieldIdx] = eltAttr;
334 }
335
336 // Anything we haven't initialized, we try to zero init. We could/should
337 // probably leave the padding as undef if !CGM.ZeroInitPadding, but that ends
338 // up being quite an additional bit of complexity (but could be implemented in
339 // the field searching above).
340 for (unsigned i = 0; i < elements.size(); ++i) {
341 if (!elements[i]) {
342 elements[i] = builder.getZeroInitAttr(recordTy.getElementType(i));
343 if (!elements[i])
344 return {};
345 }
346 }
347
348 return builder.getConstRecordOrZeroAttr(builder.getArrayAttr(elements),
349 /*packed=*/recordTy.getPacked(),
350 /*padded=*/recordTy.getPadded(),
351 recordTy);
352}
353
354mlir::Attribute buildRecord(ConstantEmitter &emitter, InitListExpr *ile,
355 QualType valTy) {
356 // Bail out if we have base classes. We could support these, but they only
357 // arise in C++1z where we will have already constant folded most
358 // interesting cases. FIXME: There are still a few more cases we can handle
359 // this way.
360 const bool handleBases = false;
361 const RecordDecl *rd = ile->getType()->castAsRecordDecl();
362 return buildRecordHelper(emitter, rd, rd, RecordBuilderInitList(rd, ile),
363 handleBases, CharUnits::Zero(),
364 /*asBaseSubObj=*/false);
365}
366
367mlir::Attribute buildRecord(ConstantEmitter &emitter, const APValue &val,
368 QualType valTy) {
369 const RecordDecl *rd =
370 valTy->castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf();
371 return buildRecordHelper(emitter, rd, rd, RecordBuilderInitList(rd, val),
372 /*handleBases=*/true, CharUnits::Zero(),
373 /*asBaseSubObj=*/false);
374}
375} // namespace ConstRecordBuilder
376
377//===----------------------------------------------------------------------===//
378// ConstExprEmitter
379//===----------------------------------------------------------------------===//
380
381// This class only needs to handle arrays, structs and unions.
382//
383// In LLVM codegen, when outside C++11 mode, those types are not constant
384// folded, while all other types are handled by constant folding.
385//
386// In CIR codegen, instead of folding things here, we should defer that work
387// to MLIR: do not attempt to do much here.
388class ConstExprEmitter
389 : public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {
390 CIRGenModule &cgm;
391 [[maybe_unused]] ConstantEmitter &emitter;
392
393public:
394 ConstExprEmitter(ConstantEmitter &emitter)
395 : cgm(emitter.cgm), emitter(emitter) {}
396
397 //===--------------------------------------------------------------------===//
398 // Visitor Methods
399 //===--------------------------------------------------------------------===//
400
401 mlir::Attribute VisitStmt(Stmt *s, QualType t) { return {}; }
402
403 mlir::Attribute VisitConstantExpr(ConstantExpr *ce, QualType t) {
404 if (mlir::Attribute result = emitter.tryEmitConstantExpr(ce))
405 return result;
406 return Visit(ce->getSubExpr(), t);
407 }
408
409 mlir::Attribute VisitParenExpr(ParenExpr *pe, QualType t) {
410 return Visit(pe->getSubExpr(), t);
411 }
412
413 mlir::Attribute
414 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe,
415 QualType t) {
416 return Visit(pe->getReplacement(), t);
417 }
418
419 mlir::Attribute VisitGenericSelectionExpr(GenericSelectionExpr *ge,
420 QualType t) {
421 return Visit(ge->getResultExpr(), t);
422 }
423
424 mlir::Attribute VisitChooseExpr(ChooseExpr *ce, QualType t) {
425 return Visit(ce->getChosenSubExpr(), t);
426 }
427
428 mlir::Attribute VisitCompoundLiteralExpr(CompoundLiteralExpr *e, QualType t) {
429 return Visit(e->getInitializer(), t);
430 }
431
432 mlir::Attribute VisitCastExpr(CastExpr *e, QualType destType) {
433 if (const auto *ece = dyn_cast<ExplicitCastExpr>(e))
434 cgm.emitExplicitCastExprType(ece,
435 const_cast<CIRGenFunction *>(emitter.cgf));
436
437 Expr *subExpr = e->getSubExpr();
438
439 switch (e->getCastKind()) {
440 case CK_ToUnion:
441 case CK_AddressSpaceConversion:
442 case CK_ReinterpretMemberPointer:
443 cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitCastExpr");
444 return {};
445
446 case CK_DerivedToBaseMemberPointer:
447 case CK_BaseToDerivedMemberPointer:
448 // Return {} to let the APValue evaluator handle member pointer type
449 // conversions. The APValue::MemberPointer case in tryEmitPrivate
450 // already builds the correct GEP path for cross-class member pointers.
451 return {};
452
453 case CK_LValueToRValue:
454 case CK_AtomicToNonAtomic:
455 case CK_NonAtomicToAtomic:
456 case CK_NoOp:
457 case CK_ConstructorConversion:
458 return Visit(subExpr, destType);
459
460 case CK_IntToOCLSampler:
461 llvm_unreachable("global sampler variables are not generated");
462
463 case CK_Dependent:
464 llvm_unreachable("saw dependent cast!");
465
466 case CK_BuiltinFnToFnPtr:
467 llvm_unreachable("builtin functions are handled elsewhere");
468
469 // These will never be supported.
470 case CK_ObjCObjectLValueCast:
471 case CK_ARCProduceObject:
472 case CK_ARCConsumeObject:
473 case CK_ARCReclaimReturnedObject:
474 case CK_ARCExtendBlockObject:
475 case CK_CopyAndAutoreleaseBlockObject:
476 return {};
477
478 // These don't need to be handled here because Evaluate knows how to
479 // evaluate them in the cases where they can be folded.
480 case CK_BitCast:
481 case CK_ToVoid:
482 case CK_Dynamic:
483 case CK_LValueBitCast:
484 case CK_LValueToRValueBitCast:
485 case CK_NullToMemberPointer:
486 case CK_UserDefinedConversion:
487 case CK_CPointerToObjCPointerCast:
488 case CK_BlockPointerToObjCPointerCast:
489 case CK_AnyPointerToBlockPointerCast:
490 case CK_ArrayToPointerDecay:
491 case CK_FunctionToPointerDecay:
492 case CK_BaseToDerived:
493 case CK_DerivedToBase:
494 case CK_UncheckedDerivedToBase:
495 case CK_MemberPointerToBoolean:
496 case CK_VectorSplat:
497 case CK_FloatingRealToComplex:
498 case CK_FloatingComplexToReal:
499 case CK_FloatingComplexToBoolean:
500 case CK_FloatingComplexCast:
501 case CK_FloatingComplexToIntegralComplex:
502 case CK_IntegralRealToComplex:
503 case CK_IntegralComplexToReal:
504 case CK_IntegralComplexToBoolean:
505 case CK_IntegralComplexCast:
506 case CK_IntegralComplexToFloatingComplex:
507 case CK_PointerToIntegral:
508 case CK_PointerToBoolean:
509 case CK_NullToPointer:
510 case CK_IntegralCast:
511 case CK_BooleanToSignedIntegral:
512 case CK_IntegralToPointer:
513 case CK_IntegralToBoolean:
514 case CK_IntegralToFloating:
515 case CK_FloatingToIntegral:
516 case CK_FloatingToBoolean:
517 case CK_FloatingCast:
518 case CK_FloatingToFixedPoint:
519 case CK_FixedPointToFloating:
520 case CK_FixedPointCast:
521 case CK_FixedPointToBoolean:
522 case CK_FixedPointToIntegral:
523 case CK_IntegralToFixedPoint:
524 case CK_ZeroToOCLOpaqueType:
525 case CK_MatrixCast:
526 case CK_HLSLArrayRValue:
527 case CK_HLSLVectorTruncation:
528 case CK_HLSLMatrixTruncation:
529 case CK_HLSLElementwiseCast:
530 case CK_HLSLAggregateSplatCast:
531 return {};
532 }
533 llvm_unreachable("Invalid CastKind");
534 }
535
536 mlir::Attribute VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die, QualType t) {
537 // No need for a DefaultInitExprScope: we don't handle 'this' in a
538 // constant expression.
539 return Visit(die->getExpr(), t);
540 }
541
542 mlir::Attribute VisitExprWithCleanups(ExprWithCleanups *e, QualType t) {
543 // Since this about constant emission no need to wrap this under a scope.
544 return Visit(e->getSubExpr(), t);
545 }
546
547 mlir::Attribute VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e,
548 QualType t) {
549 return Visit(e->getSubExpr(), t);
550 }
551
552 mlir::Attribute VisitImplicitValueInitExpr(ImplicitValueInitExpr *e,
553 QualType t) {
554 return cgm.getBuilder().getZeroInitAttr(cgm.convertType(t));
555 }
556
557 mlir::Attribute VisitInitListExpr(InitListExpr *ile, QualType t) {
558 if (ile->isTransparent())
559 return Visit(ile->getInit(0), t);
560
561 if (ile->getType()->isArrayType()) {
562 // If we return null here, the non-constant initializer will take care of
563 // it, but we would prefer to handle it here.
565 return {};
566 }
567
568 if (ile->getType()->isRecordType()) {
569 return ConstRecordBuilder::buildRecord(emitter, ile, t);
570 }
571
572 if (ile->getType()->isVectorType()) {
573 // If we return null here, the non-constant initializer will take care of
574 // it, but we would prefer to handle it here.
576 return {};
577 }
578
579 return {};
580 }
581
582 mlir::Attribute VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e,
583 QualType destType) {
584 mlir::Attribute c = Visit(e->getBase(), destType);
585 if (!c)
586 return {};
587
588 cgm.errorNYI(e->getBeginLoc(),
589 "ConstExprEmitter::VisitDesignatedInitUpdateExpr");
590 return {};
591 }
592
593 mlir::Attribute VisitCXXConstructExpr(CXXConstructExpr *e, QualType ty) {
594 if (!e->getConstructor()->isTrivial())
595 return {};
596
597 // Only default and copy/move constructors can be trivial.
598 if (e->getNumArgs()) {
599 assert(e->getNumArgs() == 1 && "trivial ctor with > 1 argument");
601 "trivial ctor has argument but isn't a copy/move ctor");
602
603 Expr *arg = e->getArg(0);
604 assert(cgm.getASTContext().hasSameUnqualifiedType(ty, arg->getType()) &&
605 "argument to copy ctor is of wrong type");
606
607 // Look through the temporary; it's just converting the value to an lvalue
608 // to pass it to the constructor.
609 if (auto const *mte = dyn_cast<MaterializeTemporaryExpr>(arg))
610 return Visit(mte->getSubExpr(), ty);
611
612 // TODO: Investigate whether there are cases that can fall through to here
613 // that need to be handled. This is missing in classic codegen also.
615
616 // Don't try to support arbitrary lvalue-to-rvalue conversions for now.
617 return {};
618 }
619
620 return cgm.getBuilder().getZeroInitAttr(cgm.convertType(ty));
621 }
622
623 mlir::Attribute VisitStringLiteral(StringLiteral *e, QualType t) {
624 // This is a string literal initializing an array in an initializer.
625 return cgm.getConstantArrayFromStringLiteral(e);
626 }
627
628 mlir::Attribute VisitObjCEncodeExpr(ObjCEncodeExpr *e, QualType t) {
629 cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitObjCEncodeExpr");
630 return {};
631 }
632
633 mlir::Attribute VisitUnaryExtension(const UnaryOperator *e, QualType t) {
634 return Visit(e->getSubExpr(), t);
635 }
636
637 // Utility methods
638 mlir::Type convertType(QualType t) { return cgm.convertType(t); }
639};
640
641// TODO(cir): this can be shared with LLVM's codegen
643 if (const auto *at = type->getAs<AtomicType>()) {
644 return cgm.getASTContext().getQualifiedType(at->getValueType(),
645 type.getQualifiers());
646 }
647 return type;
648}
649} // namespace
650
651//===----------------------------------------------------------------------===//
652// ConstantLValueEmitter
653//===----------------------------------------------------------------------===//
654
655namespace {
656/// A struct which can be used to peephole certain kinds of finalization
657/// that normally happen during l-value emission.
658struct ConstantLValue {
659 llvm::PointerUnion<mlir::Value, mlir::Attribute> value;
660 bool hasOffsetApplied;
661
662 /*implicit*/ ConstantLValue(std::nullptr_t)
663 : value(nullptr), hasOffsetApplied(false) {}
664 /*implicit*/ ConstantLValue(cir::GlobalViewAttr address)
665 : value(address), hasOffsetApplied(false) {}
666 /*implicit*/ ConstantLValue(cir::BlockAddrInfoAttr address)
667 : value(address), hasOffsetApplied(true) {}
668
669 ConstantLValue() : value(nullptr), hasOffsetApplied(false) {}
670};
671
672/// A helper class for emitting constant l-values.
673class ConstantLValueEmitter
674 : public ConstStmtVisitor<ConstantLValueEmitter, ConstantLValue> {
675 CIRGenModule &cgm;
676 ConstantEmitter &emitter;
677 const APValue &value;
678 QualType destType;
679
680 // Befriend StmtVisitorBase so that we don't have to expose Visit*.
681 friend StmtVisitorBase;
682
683public:
684 ConstantLValueEmitter(ConstantEmitter &emitter, const APValue &value,
685 QualType destType)
686 : cgm(emitter.cgm), emitter(emitter), value(value), destType(destType) {}
687
688 mlir::Attribute tryEmit();
689
690private:
691 mlir::Attribute tryEmitAbsolute(mlir::Type destTy);
692 ConstantLValue tryEmitBase(const APValue::LValueBase &base);
693
694 ConstantLValue VisitStmt(const Stmt *s) { return nullptr; }
695 ConstantLValue VisitConstantExpr(const ConstantExpr *e);
696 ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *e);
697 ConstantLValue VisitStringLiteral(const StringLiteral *e);
698 ConstantLValue VisitObjCBoxedExpr(const ObjCBoxedExpr *e);
699 ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *e);
700 ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *e);
701 ConstantLValue VisitPredefinedExpr(const PredefinedExpr *e);
702 ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *e);
703 ConstantLValue VisitCallExpr(const CallExpr *e);
704 ConstantLValue VisitBlockExpr(const BlockExpr *e);
705 ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *e);
706 ConstantLValue
707 VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e);
708
709 /// Return GEP-like value offset
710 mlir::ArrayAttr getOffset(mlir::Type ty) {
711 int64_t offset = value.getLValueOffset().getQuantity();
712 cir::CIRDataLayout layout(cgm.getModule());
713 SmallVector<int64_t, 3> idxVec;
714 cgm.getBuilder().computeGlobalViewIndicesFromFlatOffset(offset, ty, layout,
715 idxVec);
716
717 llvm::SmallVector<mlir::Attribute, 3> indices;
718 for (int64_t i : idxVec) {
719 mlir::IntegerAttr intAttr = cgm.getBuilder().getI32IntegerAttr(i);
720 indices.push_back(intAttr);
721 }
722
723 if (indices.empty())
724 return {};
725 return cgm.getBuilder().getArrayAttr(indices);
726 }
727
728 /// Apply the value offset to the given constant.
729 ConstantLValue applyOffset(ConstantLValue &c) {
730 // Handle attribute constant LValues.
731 if (auto attr = mlir::dyn_cast<mlir::Attribute>(c.value)) {
732 if (auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(attr)) {
733 auto baseTy = mlir::cast<cir::PointerType>(gv.getType()).getPointee();
734 mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);
735 assert(!gv.getIndices() && "Global view is already indexed");
736 return cir::GlobalViewAttr::get(destTy, gv.getSymbol(),
737 getOffset(baseTy));
738 }
739 llvm_unreachable("Unsupported attribute type to offset");
740 }
741
742 cgm.errorNYI("ConstantLValue: non-attribute offset");
743 return {};
744 }
745};
746
747} // namespace
748
749mlir::Attribute ConstantLValueEmitter::tryEmit() {
750 const APValue::LValueBase &base = value.getLValueBase();
751
752 // The destination type should be a pointer or reference
753 // type, but it might also be a cast thereof.
754 //
755 // FIXME: the chain of casts required should be reflected in the APValue.
756 // We need this in order to correctly handle things like a ptrtoint of a
757 // non-zero null pointer and addrspace casts that aren't trivially
758 // represented in LLVM IR.
759 mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);
760 assert(mlir::isa<cir::PointerType>(destTy));
761
762 // If there's no base at all, this is a null or absolute pointer,
763 // possibly cast back to an integer type.
764 if (!base)
765 return tryEmitAbsolute(destTy);
766
767 // Otherwise, try to emit the base.
768 ConstantLValue result = tryEmitBase(base);
769
770 // If that failed, we're done.
771 llvm::PointerUnion<mlir::Value, mlir::Attribute> &value = result.value;
772 if (!value)
773 return {};
774
775 // Apply the offset if necessary and not already done.
776 if (!result.hasOffsetApplied)
777 value = applyOffset(result).value;
778
779 // Convert to the appropriate type; this could be an lvalue for
780 // an integer. FIXME: performAddrSpaceCast
781 if (mlir::isa<cir::PointerType>(destTy)) {
782 if (auto attr = mlir::dyn_cast<mlir::Attribute>(value))
783 return attr;
784 cgm.errorNYI("ConstantLValueEmitter: non-attribute pointer");
785 return {};
786 }
787
788 cgm.errorNYI("ConstantLValueEmitter: other?");
789 return {};
790}
791
792/// Try to emit an absolute l-value, such as a null pointer or an integer
793/// bitcast to pointer type.
794mlir::Attribute ConstantLValueEmitter::tryEmitAbsolute(mlir::Type destTy) {
795 // If we're producing a pointer, this is easy.
796 auto destPtrTy = mlir::cast<cir::PointerType>(destTy);
797 return cgm.getBuilder().getConstPtrAttr(
798 destPtrTy, value.getLValueOffset().getQuantity());
799}
800
801ConstantLValue
802ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
803 // Handle values.
804 if (const ValueDecl *d = base.dyn_cast<const ValueDecl *>()) {
805 // The constant always points to the canonical declaration. We want to look
806 // at properties of the most recent declaration at the point of emission.
807 d = cast<ValueDecl>(d->getMostRecentDecl());
808
809 if (d->hasAttr<WeakRefAttr>()) {
810 cgm.errorNYI(d->getSourceRange(),
811 "ConstantLValueEmitter: emit pointer base for weakref");
812 return {};
813 }
814
815 if (auto *fd = dyn_cast<FunctionDecl>(d)) {
816 cir::FuncOp fop = cgm.getAddrOfFunction(fd);
817 CIRGenBuilderTy &builder = cgm.getBuilder();
818 mlir::MLIRContext *mlirContext = builder.getContext();
819 // Use the destination pointer type (e.g. struct field type), not
820 // fop.getFunctionType(), so initializers stay valid when a no-prototype
821 // FuncOp is later replaced by a prototyped definition with the same
822 // symbol. CIR allows the view type to differ from the symbol's type.
823 mlir::Type ptrTy = cgm.getTypes().convertTypeForMem(destType);
824 assert(mlir::isa<cir::PointerType>(ptrTy) &&
825 "function address in constant must be a pointer");
826 return cir::GlobalViewAttr::get(
827 ptrTy,
828 mlir::FlatSymbolRefAttr::get(mlirContext, fop.getSymNameAttr()));
829 }
830
831 if (auto *vd = dyn_cast<VarDecl>(d)) {
832 // We can never refer to a variable with local storage.
833 if (!vd->hasLocalStorage()) {
834 if (vd->isFileVarDecl() || vd->hasExternalStorage())
835 return cgm.getAddrOfGlobalVarAttr(vd);
836
837 if (vd->isLocalVarDecl()) {
838 cir::GlobalLinkageKind linkage = cgm.getCIRLinkageVarDefinition(vd);
839 return cgm.getBuilder().getGlobalViewAttr(
840 cgm.getOrCreateStaticVarDecl(*vd, linkage));
841 }
842 }
843 }
844
845 if (isa<MSGuidDecl>(d))
846 cgm.errorNYI(d->getSourceRange(), "ConstantLValueEmitter: MSGuidDecl");
847
848 if (const auto *gcd = dyn_cast<UnnamedGlobalConstantDecl>(d))
849 return cgm.getBuilder().getGlobalViewAttr(
851
852 if (const auto *tpo = dyn_cast<TemplateParamObjectDecl>(d))
853 return cgm.getBuilder().getGlobalViewAttr(
855
856 return {};
857 }
858
859 // Handle typeid(T).
860 if (TypeInfoLValue typeInfo = base.dyn_cast<TypeInfoLValue>())
862 cgm.getBuilder().getUnknownLoc(), QualType(typeInfo.getType(), 0)));
863
864 // Otherwise, it must be an expression.
865 return Visit(base.get<const Expr *>());
866}
867
868ConstantLValue ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *e) {
869 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: constant expr");
870 return {};
871}
872
873static cir::GlobalViewAttr
875 const CompoundLiteralExpr *e) {
876 CIRGenModule &cgm = emitter.cgm;
877 CIRGenBuilderTy &builder = cgm.getBuilder();
879
880 if (cir::GlobalOp addr = cgm.getAddrOfConstantCompoundLiteralIfEmitted(e))
881 return builder.getGlobalViewAttr(addr);
882
884 mlir::Attribute c =
885 emitter.tryEmitForInitializer(e->getInitializer(), e->getType());
886 if (!c) {
887 assert(!e->isFileScope() &&
888 "file-scope compound literal did not have constant initializer!");
889 return {};
890 }
891
892 auto typedInit = mlir::cast<mlir::TypedAttr>(c);
893 bool isConstant = e->getType().isConstantStorage(cgm.getASTContext(),
894 /*ExcludeCtor=*/true,
895 /*ExcludeDtor=*/false);
896
897 std::string name = cgm.getUniqueGlobalName(".compoundliteral");
898 mlir::Location loc = cgm.getLoc(e->getSourceRange());
899 cir::GlobalOp gv =
900 cgm.createGlobalOp(loc, name, typedInit.getType(), isConstant);
901 gv.setLinkage(cir::GlobalLinkageKind::InternalLinkage);
902 gv.setAlignment(align.getAsAlign().value());
904
905 emitter.finalize(gv);
907 return builder.getGlobalViewAttr(gv);
908}
909
910ConstantLValue
911ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *e) {
912 ConstantEmitter compoundLiteralEmitter(cgm, emitter.cgf);
913 compoundLiteralEmitter.setInConstantContext(emitter.isInConstantContext());
914 return tryEmitGlobalCompoundLiteral(compoundLiteralEmitter, e);
915}
916
917ConstantLValue
918ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *e) {
920}
921
922ConstantLValue
923ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *e) {
924 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc encode expr");
925 return {};
926}
927
928ConstantLValue
929ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *e) {
930 cgm.errorNYI(e->getSourceRange(),
931 "ConstantLValueEmitter: objc string literal");
932 return {};
933}
934
935ConstantLValue
936ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *e) {
937 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc boxed expr");
938 return {};
939}
940
941ConstantLValue
942ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *e) {
944}
945
946ConstantLValue
947ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *e) {
948 // A label address taken in a constant context, e.g. a static computed-goto
949 // dispatch table `static const void *tbl[] = {&&L1, &&L2}`. Besides emitting
950 // the constant, register the label as address-taken so a following
951 // `goto *tbl[i]` lists it among the indirect branch's successors. A label is
952 // always function-local, so cgf is set here.
953 assert(emitter.cgf && "label address in a constant requires a function");
954 CIRGenFunction &cgf = *const_cast<CIRGenFunction *>(emitter.cgf);
955 auto func = cast<cir::FuncOp>(cgf.curFn);
956 cir::BlockAddrInfoAttr info = cir::BlockAddrInfoAttr::get(
957 &cgf.getMLIRContext(), func.getSymName(), e->getLabel()->getName());
958 cgf.indirectGotoTargets.push_back(info);
959 return info;
960}
961
962ConstantLValue ConstantLValueEmitter::VisitCallExpr(const CallExpr *e) {
963 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: call expr");
964 return {};
965}
966
967ConstantLValue ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *e) {
968 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: block expr");
969 return {};
970}
971
972ConstantLValue
973ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *e) {
974 if (e->isTypeOperand())
977 e->getTypeOperand(cgm.getASTContext())));
979 cgm.getLoc(e->getSourceRange()), e->getExprOperand()->getType()));
980}
981
982ConstantLValue ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
983 const MaterializeTemporaryExpr *e) {
984 assert(e->getStorageDuration() == SD_Static);
985 const Expr *inner = e->getSubExpr()->skipRValueSubobjectAdjustments();
986 mlir::Operation *global = cgm.getAddrOfGlobalTemporary(e, inner);
987 return ConstantLValue(
988 cgm.getBuilder().getGlobalViewAttr(mlir::cast<cir::GlobalOp>(global)));
989}
990
991//===----------------------------------------------------------------------===//
992// ConstantEmitter
993//===----------------------------------------------------------------------===//
994
996 initializeNonAbstract();
997 return markIfFailed(tryEmitPrivateForVarInit(d));
998}
999
1001 QualType destType) {
1002 initializeNonAbstract();
1003 return markIfFailed(tryEmitPrivateForMemory(e, destType));
1004}
1005
1007 QualType destType) {
1008 initializeNonAbstract();
1009 auto c = tryEmitPrivateForMemory(value, destType);
1010 assert(c && "couldn't emit constant value non-abstractly?");
1011 return c;
1012}
1013
1014void ConstantEmitter::finalize(cir::GlobalOp gv) {
1015 assert(initializedNonAbstract &&
1016 "finalizing emitter that was used for abstract emission?");
1017 assert(!finalized && "finalizing emitter multiple times");
1018 assert(!gv.isDeclaration());
1019#ifndef NDEBUG
1020 // Note that we might also be Failed.
1021 finalized = true;
1022#endif // NDEBUG
1023}
1024
1025mlir::Attribute
1027 AbstractStateRAII state(*this, true);
1028 return tryEmitPrivateForVarInit(d);
1029}
1030
1032 assert((!initializedNonAbstract || finalized || failed) &&
1033 "not finalized after being initialized for non-abstract emission");
1034}
1035
1036static mlir::TypedAttr emitNullConstantForBase(CIRGenModule &cgm,
1037 mlir::Type baseType,
1038 const CXXRecordDecl *baseDecl);
1039
1040static mlir::TypedAttr emitNullConstant(CIRGenModule &cgm, const RecordDecl *rd,
1041 bool asCompleteObject) {
1042 const CIRGenRecordLayout &layout = cgm.getTypes().getCIRGenRecordLayout(rd);
1043 mlir::Type ty = (asCompleteObject ? layout.getCIRType()
1044 : layout.getBaseSubobjectCIRType());
1045 auto recordTy = mlir::cast<cir::RecordType>(ty);
1046
1047 unsigned numElements = recordTy.getNumElements();
1048 SmallVector<mlir::Attribute> elements(numElements);
1049
1050 auto *cxxrd = dyn_cast<CXXRecordDecl>(rd);
1051 // Fill in all the bases.
1052 if (cxxrd) {
1053 for (const CXXBaseSpecifier &base : cxxrd->bases()) {
1054 if (base.isVirtual()) {
1055 // Ignore virtual bases; if we're laying out for a complete
1056 // object, we'll lay these out later.
1057 continue;
1058 }
1059
1060 const auto *baseDecl = base.getType()->castAsCXXRecordDecl();
1061 // Ignore empty bases.
1062 if (isEmptyRecordForLayout(cgm.getASTContext(), base.getType()) ||
1063 cgm.getASTContext()
1064 .getASTRecordLayout(baseDecl)
1066 .isZero())
1067 continue;
1068
1069 unsigned fieldIndex = layout.getNonVirtualBaseCIRFieldNo(baseDecl);
1070 mlir::Type baseType = recordTy.getElementType(fieldIndex);
1071 elements[fieldIndex] = emitNullConstantForBase(cgm, baseType, baseDecl);
1072 }
1073 }
1074
1075 // Fill in all the fields.
1076 for (const FieldDecl *field : rd->fields()) {
1077 // Fill in non-bitfields. (Bitfields always use a zero pattern, which we
1078 // will fill in later.)
1079 if (!field->isBitField() &&
1080 !isEmptyFieldForLayout(cgm.getASTContext(), field)) {
1081 unsigned fieldIndex = layout.getCIRFieldNo(field);
1082 elements[fieldIndex] = cgm.emitNullConstantAttr(field->getType());
1083 }
1084
1085 // For unions, stop after the first named field.
1086 if (rd->isUnion()) {
1087 if (field->getIdentifier())
1088 break;
1089 if (const auto *fieldRD = field->getType()->getAsRecordDecl())
1090 if (fieldRD->findFirstNamedDataMember())
1091 break;
1092 }
1093 }
1094
1095 // Fill in the virtual bases, if we're working with the complete object.
1096 if (cxxrd && asCompleteObject) {
1097 for ([[maybe_unused]] const CXXBaseSpecifier &vbase : cxxrd->vbases()) {
1098 cgm.errorNYI(vbase.getSourceRange(), "emitNullConstant: virtual base");
1099 return {};
1100 }
1101 }
1102
1103 // Now go through all other fields and zero them out.
1104 for (unsigned i = 0; i != numElements; ++i) {
1105 if (!elements[i])
1106 elements[i] =
1107 cgm.getBuilder().getZeroInitAttr(recordTy.getElementType(i));
1108 }
1109
1110 mlir::MLIRContext *mlirContext = recordTy.getContext();
1111 return cir::ConstRecordAttr::get(recordTy,
1112 mlir::ArrayAttr::get(mlirContext, elements));
1113}
1114
1115/// Emit the null constant for a base subobject.
1116static mlir::TypedAttr emitNullConstantForBase(CIRGenModule &cgm,
1117 mlir::Type baseType,
1118 const CXXRecordDecl *baseDecl) {
1119 const CIRGenRecordLayout &baseLayout =
1120 cgm.getTypes().getCIRGenRecordLayout(baseDecl);
1121
1122 // Just zero out bases that don't have any pointer to data members.
1123 if (baseLayout.isZeroInitializableAsBase())
1124 return cgm.getBuilder().getZeroInitAttr(baseType);
1125
1126 // Otherwise, we can just use its null constant.
1127 return emitNullConstant(cgm, baseDecl, /*asCompleteObject=*/false);
1128}
1129
1131 // Make a quick check if variable can be default NULL initialized
1132 // and avoid going through rest of code which may do, for c++11,
1133 // initialization of memory to all NULLs.
1134 if (!d.hasLocalStorage()) {
1135 QualType ty = cgm.getASTContext().getBaseElementType(d.getType());
1136 if (ty->isRecordType()) {
1137 if (const auto *e = dyn_cast_or_null<CXXConstructExpr>(d.getInit())) {
1138 const CXXConstructorDecl *cd = e->getConstructor();
1139 if (cd->isTrivial() && cd->isDefaultConstructor())
1140 return cgm.emitNullConstantAttr(d.getType());
1141 }
1142 }
1143 }
1144 inConstantContext = d.hasConstantInitialization();
1145
1146 const Expr *e = d.getInit();
1147 assert(e && "No initializer to emit");
1148
1149 QualType destType = d.getType();
1150
1151 if (!destType->isReferenceType()) {
1152 QualType nonMemoryDestType = getNonMemoryType(cgm, destType);
1153 if (mlir::Attribute c = ConstExprEmitter(*this).Visit(const_cast<Expr *>(e),
1154 nonMemoryDestType))
1155 return emitForMemory(c, destType);
1156 }
1157
1158 // Try to emit the initializer. Note that this can allow some things that
1159 // are not allowed by tryEmitPrivateForMemory alone.
1160 if (const APValue *value = d.evaluateValue())
1161 return tryEmitPrivateForMemory(*value, destType);
1162
1163 return {};
1164}
1165
1167 QualType destType) {
1168 AbstractStateRAII state{*this, true};
1169 return tryEmitPrivate(e, destType);
1170}
1171
1173 if (!ce->hasAPValueResult())
1174 return {};
1175
1176 QualType retType = ce->getType();
1177 if (ce->isGLValue())
1178 retType = cgm.getASTContext().getLValueReferenceType(retType);
1179
1180 return emitAbstract(ce->getBeginLoc(), ce->getAPValueResult(), retType);
1181}
1182
1184 QualType destType) {
1185 QualType nonMemoryDestType = getNonMemoryType(cgm, destType);
1186 mlir::TypedAttr c = tryEmitPrivate(e, nonMemoryDestType);
1187 if (c) {
1188 mlir::Attribute attr = emitForMemory(c, destType);
1189 return mlir::cast<mlir::TypedAttr>(attr);
1190 }
1191 return nullptr;
1192}
1193
1195 QualType destType) {
1196 QualType nonMemoryDestType = getNonMemoryType(cgm, destType);
1197 mlir::Attribute c = tryEmitPrivate(value, nonMemoryDestType);
1198 return (c ? emitForMemory(c, destType) : nullptr);
1199}
1200
1201mlir::Attribute ConstantEmitter::emitAbstract(const Expr *e,
1202 QualType destType) {
1203 AbstractStateRAII state{*this, true};
1204 mlir::Attribute c = mlir::cast<mlir::Attribute>(tryEmitPrivate(e, destType));
1205 if (!c)
1206 cgm.errorNYI(e->getSourceRange(),
1207 "emitAbstract failed, emit null constaant");
1208 return c;
1209}
1210
1212 const APValue &value,
1213 QualType destType) {
1214 AbstractStateRAII state(*this, true);
1215 mlir::Attribute c = tryEmitPrivate(value, destType);
1216 if (!c)
1217 cgm.errorNYI(loc, "emitAbstract failed, emit null constaant");
1218 return c;
1219}
1220
1221mlir::Attribute ConstantEmitter::emitNullForMemory(mlir::Location loc,
1223 QualType t) {
1224 cir::ConstantOp cstOp =
1225 cgm.emitNullConstant(t, loc).getDefiningOp<cir::ConstantOp>();
1226 assert(cstOp && "expected cir.const op");
1227 return emitForMemory(cgm, cstOp.getValue(), t);
1228}
1229
1230mlir::Attribute ConstantEmitter::emitForMemory(mlir::Attribute c,
1231 QualType destType) {
1232 return emitForMemory(cgm, c, destType);
1233}
1234
1236 mlir::Attribute c,
1237 QualType destType) {
1238 // For an _Atomic-qualified constant, we may need to add tail padding.
1239 if (const auto *at = destType->getAs<AtomicType>()) {
1240 QualType destValueType = at->getValueType();
1241 c = emitForMemory(cgm, c, destValueType);
1242
1243 uint64_t innerSize = cgm.getASTContext().getTypeSize(destValueType);
1244 uint64_t outerSize = cgm.getASTContext().getTypeSize(destType);
1245 if (innerSize == outerSize)
1246 return c;
1247
1248 assert(innerSize < outerSize && "emitted over-large constant for atomic");
1249 cgm.errorNYI("emitForMemory: tail padding in atomic initializer");
1250 }
1251
1252 // In HLSL bool vectors are stored in memory as a vector of i32
1253 if (destType->isExtVectorBoolType() &&
1254 !destType->isPackedVectorBoolType(cgm.getASTContext())) {
1255 cgm.errorNYI("emitForMemory: zero-extend HLSL bool vectors");
1256 }
1257
1258 if (destType->isBitIntType()) {
1259 cgm.errorNYI("emitForMemory: _BitInt type");
1260 }
1261
1262 return c;
1263}
1264
1265mlir::TypedAttr ConstantEmitter::tryEmitPrivate(const Expr *e,
1266 QualType destType) {
1267 assert(!destType->isVoidType() && "can't emit a void constant");
1268
1269 if (mlir::Attribute c =
1270 ConstExprEmitter(*this).Visit(const_cast<Expr *>(e), destType))
1271 return llvm::dyn_cast<mlir::TypedAttr>(c);
1272
1273 Expr::EvalResult result;
1274
1275 bool success = false;
1276
1277 if (destType->isReferenceType())
1278 success = e->EvaluateAsLValue(result, cgm.getASTContext());
1279 else
1280 success =
1281 e->EvaluateAsRValue(result, cgm.getASTContext(), inConstantContext);
1282
1283 if (success && !result.hasSideEffects()) {
1284 mlir::Attribute c = tryEmitPrivate(result.Val, destType);
1285 return llvm::dyn_cast<mlir::TypedAttr>(c);
1286 }
1287
1288 return nullptr;
1289}
1290
1291mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
1292 QualType destType) {
1293 auto &builder = cgm.getBuilder();
1294 switch (value.getKind()) {
1295 case APValue::None:
1297 cgm.errorNYI("ConstExprEmitter::tryEmitPrivate none or indeterminate");
1298 return {};
1299 case APValue::Int: {
1300 mlir::Type ty = cgm.convertType(destType);
1301 if (mlir::isa<cir::BoolType>(ty))
1302 return builder.getCIRBoolAttr(value.getInt().getZExtValue());
1303 assert(mlir::isa<cir::IntType>(ty) && "expected integral type");
1304 return cir::IntAttr::get(ty, value.getInt());
1305 }
1306 case APValue::Float: {
1307 const llvm::APFloat &init = value.getFloat();
1308 if (&init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
1309 !cgm.getASTContext().getLangOpts().NativeHalfType &&
1310 cgm.getASTContext().getTargetInfo().useFP16ConversionIntrinsics()) {
1311 cgm.errorNYI("ConstExprEmitter::tryEmitPrivate half");
1312 return {};
1313 }
1314
1315 mlir::Type ty = cgm.convertType(destType);
1316 assert(mlir::isa<cir::FPTypeInterface>(ty) &&
1317 "expected floating-point type");
1318 return cir::FPAttr::get(ty, init);
1319 }
1320 case APValue::Array: {
1321 const ArrayType *arrayTy = cgm.getASTContext().getAsArrayType(destType);
1322 const QualType arrayElementTy = arrayTy->getElementType();
1323 const unsigned numElements = value.getArraySize();
1324 const unsigned numInitElts = value.getArrayInitializedElts();
1325
1326 mlir::TypedAttr filler;
1327 if (value.hasArrayFiller()) {
1328 mlir::Attribute fillerTemp =
1329 tryEmitPrivate(value.getArrayFiller(), arrayElementTy);
1330 if (!fillerTemp)
1331 return {};
1332 filler = dyn_cast<mlir::TypedAttr>(fillerTemp);
1333 if (!filler) {
1334 cgm.errorNYI("ConstExprEmitter::tryEmitPrivate array filler should "
1335 "always be typed");
1336 return {};
1337 }
1338 }
1339
1340 CIRGenBuilderTy &builder = cgm.getBuilder();
1341 cir::ArrayType desiredType =
1342 cast<cir::ArrayType>(cgm.convertType(destType));
1343
1345 if (!filler || builder.isNullValue(filler))
1346 elts.reserve(numInitElts);
1347 else
1348 elts.reserve(numElements);
1349
1350 // Fill in the known values.
1351 for (unsigned i = 0; i < numInitElts; ++i) {
1352 const APValue &arrayElement = value.getArrayInitializedElt(i);
1353 const mlir::Attribute element =
1354 tryEmitPrivateForMemory(arrayElement, arrayElementTy);
1355 if (!element)
1356 return {};
1357
1358 elts.push_back(element);
1359 }
1360
1361 // If we have an actual value we have to insert for the filler, do so now.
1362 if (filler && !builder.isNullValue(filler))
1363 elts.insert(elts.end(), numElements - elts.size(), filler);
1364
1365 // Remove all null values at the end, so they become 'trailing zeroes'.
1366 while (!elts.empty() && builder.isNullValue(elts.back()))
1367 elts.pop_back();
1368
1369 // For flexible array members, we need to adjust the size of our result to
1370 // match this.
1371 if (desiredType.getSize() == 0 && numElements > 0) {
1372 desiredType =
1373 cir::ArrayType::get(desiredType.getElementType(), numElements);
1374 }
1375
1376 if (elts.empty())
1377 return cir::ZeroAttr::get(desiredType);
1378
1379 return cir::ConstArrayAttr::get(
1380 desiredType, mlir::ArrayAttr::get(builder.getContext(), elts));
1381 }
1382 case APValue::Vector: {
1383 const QualType elementType =
1384 destType->castAs<VectorType>()->getElementType();
1385 const unsigned numElements = value.getVectorLength();
1386
1388 elements.reserve(numElements);
1389
1390 for (unsigned i = 0; i < numElements; ++i) {
1391 const mlir::Attribute element =
1392 tryEmitPrivateForMemory(value.getVectorElt(i), elementType);
1393 if (!element)
1394 return {};
1395 elements.push_back(element);
1396 }
1397
1398 const auto desiredVecTy =
1399 mlir::cast<cir::VectorType>(cgm.convertType(destType));
1400
1401 return cir::ConstVectorAttr::get(
1402 desiredVecTy,
1403 mlir::ArrayAttr::get(cgm.getBuilder().getContext(), elements));
1404 }
1407
1408 const ValueDecl *memberDecl = value.getMemberPointerDecl();
1409 if (!memberDecl)
1410 return builder.getZeroInitAttr(cgm.convertType(destType));
1411
1412 if (auto const *cxxDecl = dyn_cast<CXXMethodDecl>(memberDecl)) {
1413 auto ty = mlir::cast<cir::MethodType>(cgm.convertType(destType));
1414 if (cxxDecl->isVirtual())
1415 return cgm.getCXXABI().buildVirtualMethodAttr(ty, cxxDecl);
1416
1417 cir::FuncOp methodFuncOp =
1418 cgm.getAddrOfFunction(cxxDecl, ty.getMemberFuncTy());
1419 return cgm.getBuilder().getMethodAttr(ty, methodFuncOp);
1420 }
1421
1422 auto cirTy = mlir::cast<cir::DataMemberType>(cgm.convertType(destType));
1423 const auto *fieldDecl = cast<FieldDecl>(memberDecl);
1424 const auto *mpt = destType->castAs<MemberPointerType>();
1425 const auto *destClass = mpt->getMostRecentCXXRecordDecl();
1426 std::optional<llvm::SmallVector<int32_t>> path =
1427 cgm.buildMemberPath(destClass, fieldDecl);
1428 if (!path)
1429 return {};
1430 return builder.getDataMemberAttr(cirTy, *path);
1431 }
1432 case APValue::LValue:
1433 return ConstantLValueEmitter(*this, value, destType).tryEmit();
1434 case APValue::Struct:
1435 case APValue::Union:
1436 return ConstRecordBuilder::buildRecord(*this, value, destType);
1438 case APValue::ComplexFloat: {
1439 mlir::Type desiredType = cgm.convertType(destType);
1440 auto complexType = mlir::dyn_cast<cir::ComplexType>(desiredType);
1441
1442 mlir::Type complexElemTy = complexType.getElementType();
1443 if (isa<cir::IntType>(complexElemTy)) {
1444 const llvm::APSInt &real = value.getComplexIntReal();
1445 const llvm::APSInt &imag = value.getComplexIntImag();
1446 return cir::ConstComplexAttr::get(builder.getContext(), complexType,
1447 cir::IntAttr::get(complexElemTy, real),
1448 cir::IntAttr::get(complexElemTy, imag));
1449 }
1450
1451 assert(isa<cir::FPTypeInterface>(complexElemTy) &&
1452 "expected floating-point type");
1453 const llvm::APFloat &real = value.getComplexFloatReal();
1454 const llvm::APFloat &imag = value.getComplexFloatImag();
1455 return cir::ConstComplexAttr::get(builder.getContext(), complexType,
1456 cir::FPAttr::get(complexElemTy, real),
1457 cir::FPAttr::get(complexElemTy, imag));
1458 }
1461 cgm.errorNYI(
1462 "ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");
1463 return {};
1464 case APValue::Matrix:
1465 cgm.errorNYI("ConstExprEmitter::tryEmitPrivate matrix");
1466 return {};
1467 }
1468 llvm_unreachable("Unknown APValue kind");
1469}
1470
1471mlir::Value CIRGenModule::emitNullConstant(QualType t, mlir::Location loc) {
1472 return builder.getConstant(loc, emitNullConstantAttr(t));
1473}
1474
1476 if (t->getAs<PointerType>())
1477 return builder.getConstNullPtrAttr(getTypes().convertTypeForMem(t));
1478
1479 if (getTypes().isZeroInitializable(t))
1480 return builder.getZeroInitAttr(getTypes().convertTypeForMem(t));
1481
1482 if (getASTContext().getAsConstantArrayType(t)) {
1483 errorNYI("CIRGenModule::emitNullConstantAttr ConstantArrayType");
1484 return {};
1485 }
1486
1487 if (const RecordType *rt = t->getAs<RecordType>())
1488 return ::emitNullConstant(*this, rt->getDecl(), /*asCompleteObject=*/true);
1489
1490 assert(t->isMemberDataPointerType() &&
1491 "Should only see pointers to data members here!");
1492
1494}
1495
1496mlir::TypedAttr
1498 return ::emitNullConstant(*this, record, false);
1499}
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static QualType getNonMemoryType(CodeGenModule &CGM, QualType type)
static mlir::TypedAttr emitNullConstant(CIRGenModule &cgm, const RecordDecl *rd, bool asCompleteObject)
static mlir::TypedAttr emitNullConstantForBase(CIRGenModule &cgm, mlir::Type baseType, const CXXRecordDecl *baseDecl)
Emit the null constant for a base subobject.
static cir::GlobalViewAttr tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter, const CompoundLiteralExpr *e)
static ParseState advance(ParseState S, size_t N)
Definition Parsing.cpp:137
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::BoolAttr getCIRBoolAttr(bool state)
mlir::TypedAttr getZeroInitAttr(mlir::Type ty)
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
bool isBigEndian() const
C++ view class that accepts both !cir.struct and !cir.union types.
Definition CIRTypes.h:93
mlir::Type getElementType(size_t idx) const
Definition CIRTypes.h:121
bool getPacked() const
Definition CIRTypes.cpp:507
bool getPadded() const
Definition CIRTypes.cpp:512
size_t getNumElements() const
Definition CIRTypes.h:120
QualType getType() const
Definition APValue.cpp:63
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
bool hasArrayFiller() const
Definition APValue.h:634
const LValueBase getLValueBase() const
Definition APValue.cpp:1001
APValue & getArrayInitializedElt(unsigned I)
Definition APValue.h:626
APSInt & getInt()
Definition APValue.h:508
APSInt & getComplexIntImag()
Definition APValue.h:546
ValueKind getKind() const
Definition APValue.h:479
unsigned getArrayInitializedElts() const
Definition APValue.h:645
const ValueDecl * getMemberPointerDecl() const
Definition APValue.cpp:1084
APValue & getVectorElt(unsigned I)
Definition APValue.h:582
APValue & getArrayFiller()
Definition APValue.h:637
unsigned getVectorLength() const
Definition APValue.h:590
unsigned getArraySize() const
Definition APValue.h:649
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
Definition APValue.h:131
@ None
There is no such object (it's outside its lifetime).
Definition APValue.h:129
APSInt & getComplexIntReal()
Definition APValue.h:538
APFloat & getComplexFloatImag()
Definition APValue.h:562
APFloat & getComplexFloatReal()
Definition APValue.h:554
APFloat & getFloat()
Definition APValue.h:522
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
LabelDecl * getLabel() const
Definition Expr.h:4579
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3786
QualType getElementType() const
Definition TypeBase.h:3798
cir::DataMemberAttr getDataMemberAttr(cir::DataMemberType ty, llvm::ArrayRef< int32_t > path)
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type type={})
bool isNullValue(mlir::Attribute attr) const
cir::IntType getUIntNTy(int n)
virtual mlir::Value getVTableAddressPoint(BaseSubobject base, const CXXRecordDecl *vtableClass)=0
Get the address point of the vtable for the given base subobject.
mlir::Operation * curFn
The current function or global initializer that is generated code for.
mlir::MLIRContext & getMLIRContext()
llvm::SmallVector< cir::BlockAddrInfoAttr > indirectGotoTargets
Labels whose address is taken in this function (via &&label, as either an operation or a constant ini...
This class organizes the cross-function state that is used while generating CIR code.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
cir::GlobalOp getOrCreateStaticVarDecl(const VarDecl &d, cir::GlobalLinkageKind linkage)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd)
clang::ASTContext & getASTContext() const
CIRGenBuilderTy & getBuilder()
std::string getUniqueGlobalName(const std::string &baseName)
cir::GlobalOp getAddrOfTemplateParamObject(const TemplateParamObjectDecl *tpo)
Get the GlobalOp of a template parameter object.
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
mlir::TypedAttr emitNullConstantForBase(const CXXRecordDecl *record)
Return a null constant appropriate for zero-initializing a base class with the given type.
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
mlir::TypedAttr emitNullConstantAttr(QualType t)
const cir::CIRDataLayout getDataLayout() const
mlir::Operation * getAddrOfGlobalTemporary(const MaterializeTemporaryExpr *mte, const Expr *init)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
cir::GlobalOp createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::TypedAttr emitNullMemberAttr(QualType t, const MemberPointerType *mpt)
Returns a null attribute to represent either a null method or null data member, depending on the type...
cir::GlobalOp getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *e)
mlir::Value emitNullConstant(QualType t, mlir::Location loc)
Return the result of value-initializing the given type, i.e.
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *e, cir::GlobalOp gv)
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.
cir::RecordType getBaseSubobjectCIRType() const
Return the "base subobject" LLVM type associated with this record.
bool hasNonVirtualBaseCIRField(const CXXRecordDecl *rd) const
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.
bool hasCIRField(const clang::FieldDecl *fd) const
bool isZeroInitializableAsBase() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer when considered as a bas...
unsigned getNonVirtualBaseCIRFieldNo(const CXXRecordDecl *rd) const
const CIRGenRecordLayout & getCIRGenRecordLayout(const clang::RecordDecl *rd)
Return record layout info for the given record decl.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
mlir::Attribute emitForMemory(mlir::Attribute c, QualType destType)
mlir::Attribute emitNullForMemory(mlir::Location loc, QualType t)
mlir::TypedAttr tryEmitPrivate(const Expr *e, QualType destType)
mlir::Attribute tryEmitPrivateForVarInit(const VarDecl &d)
mlir::Attribute tryEmitPrivateForMemory(const Expr *e, QualType destTy)
mlir::Attribute emitAbstract(const Expr *e, QualType destType)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
mlir::Attribute tryEmitAbstract(const Expr *e, QualType destType)
mlir::Attribute tryEmitForInitializer(const VarDecl &d)
Try to emit the initializer of the given declaration as an abstract constant.
mlir::Attribute tryEmitAbstractForInitializer(const VarDecl &d)
Try to emit the initializer of the given declaration as an abstract constant.
mlir::Attribute emitForInitializer(const APValue &value, QualType destType)
mlir::Attribute tryEmitConstantExpr(const ConstantExpr *ce)
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition ExprCXX.h:1695
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1615
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition ExprCXX.h:1692
Represents a C++ constructor within a class.
Definition DeclCXX.h:2633
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Definition DeclCXX.cpp:3047
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Definition DeclCXX.cpp:3067
Expr * getExpr()
Get the initialization expression that will be used.
Definition ExprCXX.cpp:1112
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isTypeOperand() const
Definition ExprCXX.h:888
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Definition ExprCXX.cpp:166
Expr * getExprOperand() const
Definition ExprCXX.h:899
SourceRange getSourceRange() const LLVM_READONLY
Definition ExprCXX.h:906
CastKind getCastKind() const
Definition Expr.h:3726
Expr * getSubExpr()
Definition Expr.h:3732
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition CharUnits.h:122
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Definition CharUnits.h:53
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition Expr.h:4890
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3611
bool isFileScope() const
Definition Expr.h:3643
const Expr * getInitializer() const
Definition Expr.h:3639
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition Expr.h:1088
APValue getAPValueResult() const
Definition Expr.cpp:419
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Expr.h:1138
bool hasAPValueResult() const
Definition Expr.h:1163
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Expr.cpp:4954
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:85
bool isGLValue() const
Definition Expr.h:287
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
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...
QualType getType() const
Definition Expr.h:144
Represents a member of a struct/union/class.
Definition Decl.h:3195
bool isBitField() const
Determines whether this field is a bitfield.
Definition Decl.h:3298
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:4763
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
Definition Decl.h:3301
const Expr * getSubExpr() const
Definition Expr.h:1068
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2404
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition Expr.h:6471
Describes an C or C++ initializer list.
Definition Expr.h:5305
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
Definition Expr.cpp:2471
const Expr * getInit(unsigned Init) const
Definition Expr.h:5360
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Definition ExprCXX.h:4945
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition ExprCXX.h:4937
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3717
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
Definition Type.cpp:5646
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
SourceRange getSourceRange() const LLVM_READONLY
Definition ExprObjC.h:190
SourceLocation getBeginLoc() const LLVM_READONLY
Definition ExprObjC.h:468
const Expr * getSubExpr() const
Definition Expr.h:2205
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3392
StringLiteral * getFunctionName()
Definition Expr.h:2055
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
Definition TypeBase.h:1036
Represents a struct/union/class.
Definition Decl.h:4360
field_range fields() const
Definition Decl.h:4563
Encodes a location in the source.
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
bool isUnion() const
Definition Decl.h:3963
bool isVoidType() const
Definition TypeBase.h:9050
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
Definition Type.cpp:2293
bool isPackedVectorBoolType(const ASTContext &ctx) const
Definition Type.cpp:455
bool isArrayType() const
Definition TypeBase.h:8783
CXXRecordDecl * castAsCXXRecordDecl() const
Definition Type.h:36
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9344
bool isReferenceType() const
Definition TypeBase.h:8708
bool isExtVectorBoolType() const
Definition TypeBase.h:8831
bool isMemberDataPointerType() const
Definition TypeBase.h:8776
bool isBitIntType() const
Definition TypeBase.h:8959
RecordDecl * castAsRecordDecl() const
Definition Type.h:48
bool isVectorType() const
Definition TypeBase.h:8823
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9277
bool isRecordType() const
Definition TypeBase.h:8811
Expr * getSubExpr() const
Definition Expr.h:2291
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:932
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
Definition Decl.cpp:2630
const Expr * getInit() const
Definition Decl.h:1389
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
Definition Decl.cpp:2554
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition Decl.h:1190
Represents a GCC generic vector type.
Definition TypeBase.h:4239
bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd)
isEmptyFieldForLayout - Return true if the field is "empty", that is, either a zero-width bit-field o...
bool isEmptyRecordForLayout(const ASTContext &context, QualType t)
isEmptyRecordForLayout - Return true if a structure contains only empty base classes (per isEmptyReco...
const internal::VariadicAllOfMatcher< Attr > attr
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ComplexType > complexType
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ SD_Static
Static storage duration.
Definition Specifiers.h:344
inits_range inits()
U cast(CodeGen::Address addr)
Definition Address.h:327
long int64_t
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
#define false
Definition stdbool.h:26
#define true
Definition stdbool.h:25
static bool ctorConstLvalueToRvalueConversion()
static bool addressSpace()
static bool addressPointerAuthInfo()
static bool constEmitterArrayILE()
static bool constEmitterVectorILE()
Record with information about how a bitfield should be accessed.
unsigned offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
unsigned storageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned size
The total size of the bit-field, in bits.
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:652
APValue Val
Val - This is the value the expression can be folded to.
Definition Expr.h:654
bool hasSideEffects() const
Return true if the evaluated expression has side effects.
Definition Expr.h:646