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 "CIRGenConstantEmitter.h"
15#include "CIRGenFunction.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"
22#include "clang/AST/ASTContext.h"
23#include "clang/AST/Attr.h"
24#include "clang/AST/OperationKinds.h"
25#include "clang/AST/RecordLayout.h"
26#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Builtins.h"
28#include "clang/Basic/Specifiers.h"
29#include "clang/CIR/Dialect/IR/CIRAttrs.h"
30#include "clang/CIR/Dialect/IR/CIRTypes.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/Sequence.h"
33#include "llvm/Support/ErrorHandling.h"
34
35using namespace clang;
36using namespace clang::CIRGen;
37
38//===----------------------------------------------------------------------===//
39// ConstExprEmitter
40//===----------------------------------------------------------------------===//
41
42// This class only needs to handle arrays, structs and unions.
43//
44// In LLVM codegen, when outside C++11 mode, those types are not constant
45// folded, while all other types are handled by constant folding.
46//
47// In CIR codegen, instead of folding things here, we should defer that work
48// to MLIR: do not attempt to do much here.
49class ConstExprEmitter
50 : public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {
51 CIRGenModule &cgm;
52 LLVM_ATTRIBUTE_UNUSED ConstantEmitter &emitter;
53
54public:
55 ConstExprEmitter(ConstantEmitter &emitter)
56 : cgm(emitter.cgm), emitter(emitter) {}
57
58 //===--------------------------------------------------------------------===//
59 // Visitor Methods
60 //===--------------------------------------------------------------------===//
61
62 mlir::Attribute VisitStmt(Stmt *S, QualType T) { return {}; }
63
64 mlir::Attribute VisitConstantExpr(ConstantExpr *ce, QualType t) {
65 if (mlir::Attribute result = emitter.tryEmitConstantExpr(ce))
66 return result;
67 return Visit(ce->getSubExpr(), t);
68 }
69
70 mlir::Attribute VisitParenExpr(ParenExpr *pe, QualType t) {
71 return Visit(pe->getSubExpr(), t);
72 }
73
74 mlir::Attribute
75 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe,
76 QualType t) {
77 return Visit(pe->getReplacement(), t);
78 }
79
80 mlir::Attribute VisitGenericSelectionExpr(GenericSelectionExpr *ge,
81 QualType t) {
82 return Visit(ge->getResultExpr(), t);
83 }
84
85 mlir::Attribute VisitChooseExpr(ChooseExpr *ce, QualType t) {
86 return Visit(ce->getChosenSubExpr(), t);
87 }
88
89 mlir::Attribute VisitCompoundLiteralExpr(CompoundLiteralExpr *e, QualType t) {
90 return Visit(e->getInitializer(), t);
91 }
92
93 mlir::Attribute VisitCastExpr(CastExpr *e, QualType destType) {
94 if (isa<ExplicitCastExpr>(Val: e))
95 cgm.errorNYI(e->getBeginLoc(),
96 "ConstExprEmitter::VisitCastExpr explicit cast");
97
98 Expr *subExpr = e->getSubExpr();
99
100 switch (e->getCastKind()) {
101 case CK_ToUnion:
102 case CK_AddressSpaceConversion:
103 case CK_ReinterpretMemberPointer:
104 case CK_DerivedToBaseMemberPointer:
105 case CK_BaseToDerivedMemberPointer:
106 cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitCastExpr");
107 return {};
108
109 case CK_LValueToRValue:
110 case CK_AtomicToNonAtomic:
111 case CK_NonAtomicToAtomic:
112 case CK_NoOp:
113 case CK_ConstructorConversion:
114 return Visit(subExpr, destType);
115
116 case CK_IntToOCLSampler:
117 llvm_unreachable("global sampler variables are not generated");
118
119 case CK_Dependent:
120 llvm_unreachable("saw dependent cast!");
121
122 case CK_BuiltinFnToFnPtr:
123 llvm_unreachable("builtin functions are handled elsewhere");
124
125 // These will never be supported.
126 case CK_ObjCObjectLValueCast:
127 case CK_ARCProduceObject:
128 case CK_ARCConsumeObject:
129 case CK_ARCReclaimReturnedObject:
130 case CK_ARCExtendBlockObject:
131 case CK_CopyAndAutoreleaseBlockObject:
132 return {};
133
134 // These don't need to be handled here because Evaluate knows how to
135 // evaluate them in the cases where they can be folded.
136 case CK_BitCast:
137 case CK_ToVoid:
138 case CK_Dynamic:
139 case CK_LValueBitCast:
140 case CK_LValueToRValueBitCast:
141 case CK_NullToMemberPointer:
142 case CK_UserDefinedConversion:
143 case CK_CPointerToObjCPointerCast:
144 case CK_BlockPointerToObjCPointerCast:
145 case CK_AnyPointerToBlockPointerCast:
146 case CK_ArrayToPointerDecay:
147 case CK_FunctionToPointerDecay:
148 case CK_BaseToDerived:
149 case CK_DerivedToBase:
150 case CK_UncheckedDerivedToBase:
151 case CK_MemberPointerToBoolean:
152 case CK_VectorSplat:
153 case CK_FloatingRealToComplex:
154 case CK_FloatingComplexToReal:
155 case CK_FloatingComplexToBoolean:
156 case CK_FloatingComplexCast:
157 case CK_FloatingComplexToIntegralComplex:
158 case CK_IntegralRealToComplex:
159 case CK_IntegralComplexToReal:
160 case CK_IntegralComplexToBoolean:
161 case CK_IntegralComplexCast:
162 case CK_IntegralComplexToFloatingComplex:
163 case CK_PointerToIntegral:
164 case CK_PointerToBoolean:
165 case CK_NullToPointer:
166 case CK_IntegralCast:
167 case CK_BooleanToSignedIntegral:
168 case CK_IntegralToPointer:
169 case CK_IntegralToBoolean:
170 case CK_IntegralToFloating:
171 case CK_FloatingToIntegral:
172 case CK_FloatingToBoolean:
173 case CK_FloatingCast:
174 case CK_FloatingToFixedPoint:
175 case CK_FixedPointToFloating:
176 case CK_FixedPointCast:
177 case CK_FixedPointToBoolean:
178 case CK_FixedPointToIntegral:
179 case CK_IntegralToFixedPoint:
180 case CK_ZeroToOCLOpaqueType:
181 case CK_MatrixCast:
182 case CK_HLSLArrayRValue:
183 case CK_HLSLVectorTruncation:
184 case CK_HLSLElementwiseCast:
185 case CK_HLSLAggregateSplatCast:
186 return {};
187 }
188 llvm_unreachable("Invalid CastKind");
189 }
190
191 mlir::Attribute VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die, QualType t) {
192 cgm.errorNYI(die->getBeginLoc(),
193 "ConstExprEmitter::VisitCXXDefaultInitExpr");
194 return {};
195 }
196
197 mlir::Attribute VisitExprWithCleanups(ExprWithCleanups *e, QualType t) {
198 // Since this about constant emission no need to wrap this under a scope.
199 return Visit(e->getSubExpr(), t);
200 }
201
202 mlir::Attribute VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e,
203 QualType t) {
204 return Visit(e->getSubExpr(), t);
205 }
206
207 mlir::Attribute VisitImplicitValueInitExpr(ImplicitValueInitExpr *E,
208 QualType T) {
209 cgm.errorNYI(E->getBeginLoc(),
210 "ConstExprEmitter::VisitImplicitValueInitExpr");
211 return {};
212 }
213
214 mlir::Attribute VisitInitListExpr(InitListExpr *ile, QualType t) {
215 if (ile->isTransparent())
216 return Visit(ile->getInit(Init: 0), t);
217
218 if (ile->getType()->isArrayType()) {
219 // If we return null here, the non-constant initializer will take care of
220 // it, but we would prefer to handle it here.
221 assert(!cir::MissingFeatures::constEmitterArrayILE());
222 return {};
223 }
224
225 if (ile->getType()->isRecordType()) {
226 cgm.errorNYI(ile->getBeginLoc(), "ConstExprEmitter: record ILE");
227 return {};
228 }
229
230 if (ile->getType()->isVectorType()) {
231 // If we return null here, the non-constant initializer will take care of
232 // it, but we would prefer to handle it here.
233 assert(!cir::MissingFeatures::constEmitterVectorILE());
234 return {};
235 }
236
237 return {};
238 }
239
240 mlir::Attribute VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e,
241 QualType destType) {
242 mlir::Attribute c = Visit(e->getBase(), destType);
243 if (!c)
244 return {};
245
246 cgm.errorNYI(e->getBeginLoc(),
247 "ConstExprEmitter::VisitDesignatedInitUpdateExpr");
248 return {};
249 }
250
251 mlir::Attribute VisitCXXConstructExpr(CXXConstructExpr *e, QualType ty) {
252 cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitCXXConstructExpr");
253 return {};
254 }
255
256 mlir::Attribute VisitStringLiteral(StringLiteral *e, QualType t) {
257 // This is a string literal initializing an array in an initializer.
258 return cgm.getConstantArrayFromStringLiteral(e);
259 }
260
261 mlir::Attribute VisitObjCEncodeExpr(ObjCEncodeExpr *e, QualType t) {
262 cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitObjCEncodeExpr");
263 return {};
264 }
265
266 mlir::Attribute VisitUnaryExtension(const UnaryOperator *e, QualType t) {
267 return Visit(e->getSubExpr(), t);
268 }
269
270 // Utility methods
271 mlir::Type convertType(QualType t) { return cgm.convertType(t); }
272};
273
274// TODO(cir): this can be shared with LLVM's codegen
275static QualType getNonMemoryType(CIRGenModule &cgm, QualType type) {
276 if (const auto *at = type->getAs<AtomicType>()) {
277 return cgm.getASTContext().getQualifiedType(T: at->getValueType(),
278 Qs: type.getQualifiers());
279 }
280 return type;
281}
282
283static mlir::Attribute
284emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType,
285 mlir::Type commonElementType, unsigned arrayBound,
286 SmallVectorImpl<mlir::TypedAttr> &elements,
287 mlir::TypedAttr filler) {
288 const CIRGenBuilderTy &builder = cgm.getBuilder();
289
290 unsigned nonzeroLength = arrayBound;
291 if (elements.size() < nonzeroLength && builder.isNullValue(filler))
292 nonzeroLength = elements.size();
293
294 if (nonzeroLength == elements.size()) {
295 while (nonzeroLength > 0 &&
296 builder.isNullValue(elements[nonzeroLength - 1]))
297 --nonzeroLength;
298 }
299
300 if (nonzeroLength == 0)
301 return cir::ZeroAttr::get(desiredType);
302
303 const unsigned trailingZeroes = arrayBound - nonzeroLength;
304
305 // Add a zeroinitializer array filler if we have lots of trailing zeroes.
306 if (trailingZeroes >= 8) {
307 assert(elements.size() >= nonzeroLength &&
308 "missing initializer for non-zero element");
309 } else if (elements.size() != arrayBound) {
310 elements.resize(arrayBound, filler);
311
312 if (filler.getType() != commonElementType)
313 commonElementType = {};
314 }
315
316 if (commonElementType) {
317 SmallVector<mlir::Attribute, 4> eles;
318 eles.reserve(elements.size());
319
320 for (const auto &element : elements)
321 eles.push_back(element);
322
323 return cir::ConstArrayAttr::get(
324 cir::ArrayType::get(commonElementType, arrayBound),
325 mlir::ArrayAttr::get(builder.getContext(), eles));
326 }
327
328 cgm.errorNYI(feature: "array with different type elements");
329 return {};
330}
331
332//===----------------------------------------------------------------------===//
333// ConstantLValueEmitter
334//===----------------------------------------------------------------------===//
335
336namespace {
337/// A struct which can be used to peephole certain kinds of finalization
338/// that normally happen during l-value emission.
339struct ConstantLValue {
340 llvm::PointerUnion<mlir::Value, mlir::Attribute> value;
341 bool hasOffsetApplied;
342
343 ConstantLValue(std::nullptr_t) : value(nullptr), hasOffsetApplied(false) {}
344 ConstantLValue() : value(nullptr), hasOffsetApplied(false) {}
345};
346
347/// A helper class for emitting constant l-values.
348class ConstantLValueEmitter
349 : public ConstStmtVisitor<ConstantLValueEmitter, ConstantLValue> {
350 CIRGenModule &cgm;
351 ConstantEmitter &emitter;
352 const APValue &value;
353 QualType destType;
354
355 // Befriend StmtVisitorBase so that we don't have to expose Visit*.
356 friend StmtVisitorBase;
357
358public:
359 ConstantLValueEmitter(ConstantEmitter &emitter, const APValue &value,
360 QualType destType)
361 : cgm(emitter.cgm), emitter(emitter), value(value), destType(destType) {}
362
363 mlir::Attribute tryEmit();
364
365private:
366 mlir::Attribute tryEmitAbsolute(mlir::Type destTy);
367 ConstantLValue tryEmitBase(const APValue::LValueBase &base);
368
369 ConstantLValue VisitStmt(const Stmt *s) { return nullptr; }
370 ConstantLValue VisitConstantExpr(const ConstantExpr *e);
371 ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *e);
372 ConstantLValue VisitStringLiteral(const StringLiteral *e);
373 ConstantLValue VisitObjCBoxedExpr(const ObjCBoxedExpr *e);
374 ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *e);
375 ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *e);
376 ConstantLValue VisitPredefinedExpr(const PredefinedExpr *e);
377 ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *e);
378 ConstantLValue VisitCallExpr(const CallExpr *e);
379 ConstantLValue VisitBlockExpr(const BlockExpr *e);
380 ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *e);
381 ConstantLValue
382 VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e);
383};
384
385} // namespace
386
387mlir::Attribute ConstantLValueEmitter::tryEmit() {
388 const APValue::LValueBase &base = value.getLValueBase();
389
390 // The destination type should be a pointer or reference
391 // type, but it might also be a cast thereof.
392 //
393 // FIXME: the chain of casts required should be reflected in the APValue.
394 // We need this in order to correctly handle things like a ptrtoint of a
395 // non-zero null pointer and addrspace casts that aren't trivially
396 // represented in LLVM IR.
397 mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);
398 assert(mlir::isa<cir::PointerType>(destTy));
399
400 // If there's no base at all, this is a null or absolute pointer,
401 // possibly cast back to an integer type.
402 if (!base)
403 return tryEmitAbsolute(destTy);
404
405 // Otherwise, try to emit the base.
406 ConstantLValue result = tryEmitBase(base);
407
408 // If that failed, we're done.
409 llvm::PointerUnion<mlir::Value, mlir::Attribute> &value = result.value;
410 if (!value)
411 return {};
412
413 // Apply the offset if necessary and not already done.
414 if (!result.hasOffsetApplied) {
415 cgm.errorNYI(feature: "ConstantLValueEmitter: apply offset");
416 return {};
417 }
418
419 // Convert to the appropriate type; this could be an lvalue for
420 // an integer. FIXME: performAddrSpaceCast
421 if (mlir::isa<cir::PointerType>(destTy)) {
422 if (auto attr = mlir::dyn_cast<mlir::Attribute>(value))
423 return attr;
424 cgm.errorNYI(feature: "ConstantLValueEmitter: non-attribute pointer");
425 return {};
426 }
427
428 cgm.errorNYI(feature: "ConstantLValueEmitter: other?");
429 return {};
430}
431
432/// Try to emit an absolute l-value, such as a null pointer or an integer
433/// bitcast to pointer type.
434mlir::Attribute ConstantLValueEmitter::tryEmitAbsolute(mlir::Type destTy) {
435 // If we're producing a pointer, this is easy.
436 auto destPtrTy = mlir::cast<cir::PointerType>(destTy);
437 return cgm.getBuilder().getConstPtrAttr(
438 destPtrTy, value.getLValueOffset().getQuantity());
439}
440
441ConstantLValue
442ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
443 // Handle values.
444 if (const ValueDecl *d = base.dyn_cast<const ValueDecl *>()) {
445 // The constant always points to the canonical declaration. We want to look
446 // at properties of the most recent declaration at the point of emission.
447 d = cast<ValueDecl>(Val: d->getMostRecentDecl());
448
449 if (d->hasAttr<WeakRefAttr>()) {
450 cgm.errorNYI(d->getSourceRange(),
451 "ConstantLValueEmitter: emit pointer base for weakref");
452 return {};
453 }
454
455 if (auto *fd = dyn_cast<FunctionDecl>(Val: d)) {
456 cgm.errorNYI(fd->getSourceRange(),
457 "ConstantLValueEmitter: function decl");
458 return {};
459 }
460
461 if (auto *vd = dyn_cast<VarDecl>(Val: d)) {
462 cgm.errorNYI(vd->getSourceRange(), "ConstantLValueEmitter: var decl");
463 return {};
464 }
465 }
466
467 // Handle typeid(T).
468 if (base.dyn_cast<TypeInfoLValue>()) {
469 cgm.errorNYI(feature: "ConstantLValueEmitter: typeid");
470 return {};
471 }
472
473 // Otherwise, it must be an expression.
474 return Visit(S: base.get<const Expr *>());
475}
476
477ConstantLValue ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *e) {
478 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: constant expr");
479 return {};
480}
481
482ConstantLValue
483ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *e) {
484 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: compound literal");
485 return {};
486}
487
488ConstantLValue
489ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *e) {
490 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: string literal");
491 return {};
492}
493
494ConstantLValue
495ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *e) {
496 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc encode expr");
497 return {};
498}
499
500ConstantLValue
501ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *e) {
502 cgm.errorNYI(e->getSourceRange(),
503 "ConstantLValueEmitter: objc string literal");
504 return {};
505}
506
507ConstantLValue
508ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *e) {
509 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc boxed expr");
510 return {};
511}
512
513ConstantLValue
514ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *e) {
515 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: predefined expr");
516 return {};
517}
518
519ConstantLValue
520ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *e) {
521 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: addr label expr");
522 return {};
523}
524
525ConstantLValue ConstantLValueEmitter::VisitCallExpr(const CallExpr *e) {
526 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: call expr");
527 return {};
528}
529
530ConstantLValue ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *e) {
531 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: block expr");
532 return {};
533}
534
535ConstantLValue
536ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *e) {
537 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: cxx typeid expr");
538 return {};
539}
540
541ConstantLValue ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
542 const MaterializeTemporaryExpr *e) {
543 cgm.errorNYI(e->getSourceRange(),
544 "ConstantLValueEmitter: materialize temporary expr");
545 return {};
546}
547
548//===----------------------------------------------------------------------===//
549// ConstantEmitter
550//===----------------------------------------------------------------------===//
551
552mlir::Attribute ConstantEmitter::tryEmitForInitializer(const VarDecl &d) {
553 initializeNonAbstract();
554 return markIfFailed(tryEmitPrivateForVarInit(d));
555}
556
557void ConstantEmitter::finalize(cir::GlobalOp gv) {
558 assert(initializedNonAbstract &&
559 "finalizing emitter that was used for abstract emission?");
560 assert(!finalized && "finalizing emitter multiple times");
561 assert(!gv.isDeclaration());
562#ifndef NDEBUG
563 // Note that we might also be Failed.
564 finalized = true;
565#endif // NDEBUG
566}
567
568mlir::Attribute
569ConstantEmitter::tryEmitAbstractForInitializer(const VarDecl &d) {
570 AbstractStateRAII state(*this, true);
571 return tryEmitPrivateForVarInit(d);
572}
573
574ConstantEmitter::~ConstantEmitter() {
575 assert((!initializedNonAbstract || finalized || failed) &&
576 "not finalized after being initialized for non-abstract emission");
577}
578
579mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &d) {
580 // Make a quick check if variable can be default NULL initialized
581 // and avoid going through rest of code which may do, for c++11,
582 // initialization of memory to all NULLs.
583 if (!d.hasLocalStorage()) {
584 QualType ty = cgm.getASTContext().getBaseElementType(QT: d.getType());
585 if (ty->isRecordType()) {
586 if (const auto *e = dyn_cast_or_null<CXXConstructExpr>(Val: d.getInit())) {
587 const CXXConstructorDecl *cd = e->getConstructor();
588 // FIXME: we should probably model this more closely to C++ than
589 // just emitting a global with zero init (mimic what we do for trivial
590 // assignments and whatnots). Since this is for globals shouldn't
591 // be a problem for the near future.
592 if (cd->isTrivial() && cd->isDefaultConstructor()) {
593 const auto *cxxrd =
594 cast<CXXRecordDecl>(Val: ty->getAs<RecordType>()->getDecl());
595 if (cxxrd->getNumBases() != 0) {
596 // There may not be anything additional to do here, but this will
597 // force us to pause and test this path when it is supported.
598 cgm.errorNYI(feature: "tryEmitPrivateForVarInit: cxx record with bases");
599 return {};
600 }
601 if (!cgm.getTypes().isZeroInitializable(rd: cxxrd)) {
602 // To handle this case, we really need to go through
603 // emitNullConstant, but we need an attribute, not a value
604 cgm.errorNYI(
605 feature: "tryEmitPrivateForVarInit: non-zero-initializable cxx record");
606 return {};
607 }
608 return cir::ZeroAttr::get(cgm.convertType(d.getType()));
609 }
610 }
611 }
612 }
613 inConstantContext = d.hasConstantInitialization();
614
615 const Expr *e = d.getInit();
616 assert(e && "No initializer to emit");
617
618 QualType destType = d.getType();
619
620 if (!destType->isReferenceType()) {
621 QualType nonMemoryDestType = getNonMemoryType(cgm, type: destType);
622 if (mlir::Attribute c = ConstExprEmitter(*this).Visit(const_cast<Expr *>(e),
623 nonMemoryDestType))
624 return emitForMemory(c, destType);
625 }
626
627 // Try to emit the initializer. Note that this can allow some things that
628 // are not allowed by tryEmitPrivateForMemory alone.
629 if (APValue *value = d.evaluateValue())
630 return tryEmitPrivateForMemory(*value, destType);
631
632 return {};
633}
634
635mlir::Attribute ConstantEmitter::tryEmitConstantExpr(const ConstantExpr *ce) {
636 if (!ce->hasAPValueResult())
637 return {};
638
639 QualType retType = ce->getType();
640 if (ce->isGLValue())
641 retType = cgm.getASTContext().getLValueReferenceType(T: retType);
642
643 return emitAbstract(ce->getBeginLoc(), ce->getAPValueResult(), retType);
644}
645
646mlir::Attribute ConstantEmitter::tryEmitPrivateForMemory(const APValue &value,
647 QualType destType) {
648 QualType nonMemoryDestType = getNonMemoryType(cgm, type: destType);
649 mlir::Attribute c = tryEmitPrivate(value, nonMemoryDestType);
650 return (c ? emitForMemory(c, destType) : nullptr);
651}
652
653mlir::Attribute ConstantEmitter::emitAbstract(SourceLocation loc,
654 const APValue &value,
655 QualType destType) {
656 AbstractStateRAII state(*this, true);
657 mlir::Attribute c = tryEmitPrivate(value, destType);
658 if (!c)
659 cgm.errorNYI(loc, "emitAbstract failed, emit null constaant");
660 return c;
661}
662
663mlir::Attribute ConstantEmitter::emitForMemory(mlir::Attribute c,
664 QualType destType) {
665 // For an _Atomic-qualified constant, we may need to add tail padding.
666 if (destType->getAs<AtomicType>()) {
667 cgm.errorNYI(feature: "emitForMemory: atomic type");
668 return {};
669 }
670
671 return c;
672}
673
674mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
675 QualType destType) {
676 auto &builder = cgm.getBuilder();
677 switch (value.getKind()) {
678 case APValue::None:
679 case APValue::Indeterminate:
680 cgm.errorNYI(feature: "ConstExprEmitter::tryEmitPrivate none or indeterminate");
681 return {};
682 case APValue::Int: {
683 mlir::Type ty = cgm.convertType(destType);
684 if (mlir::isa<cir::BoolType>(ty))
685 return builder.getCIRBoolAttr(value.getInt().getZExtValue());
686 assert(mlir::isa<cir::IntType>(ty) && "expected integral type");
687 return cir::IntAttr::get(ty, value.getInt());
688 }
689 case APValue::Float: {
690 const llvm::APFloat &init = value.getFloat();
691 if (&init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
692 !cgm.getASTContext().getLangOpts().NativeHalfType &&
693 cgm.getASTContext().getTargetInfo().useFP16ConversionIntrinsics()) {
694 cgm.errorNYI(feature: "ConstExprEmitter::tryEmitPrivate half");
695 return {};
696 }
697
698 mlir::Type ty = cgm.convertType(destType);
699 assert(mlir::isa<cir::FPTypeInterface>(ty) &&
700 "expected floating-point type");
701 return cir::FPAttr::get(ty, init);
702 }
703 case APValue::Array: {
704 const ArrayType *arrayTy = cgm.getASTContext().getAsArrayType(T: destType);
705 const QualType arrayElementTy = arrayTy->getElementType();
706 const unsigned numElements = value.getArraySize();
707 const unsigned numInitElts = value.getArrayInitializedElts();
708
709 mlir::Attribute filler;
710 if (value.hasArrayFiller()) {
711 filler = tryEmitPrivate(value.getArrayFiller(), arrayElementTy);
712 if (!filler)
713 return {};
714 }
715
716 SmallVector<mlir::TypedAttr, 16> elements;
717 if (filler && builder.isNullValue(filler))
718 elements.reserve(numInitElts + 1);
719 else
720 elements.reserve(numInitElts);
721
722 mlir::Type commonElementType;
723 for (unsigned i = 0; i < numInitElts; ++i) {
724 const APValue &arrayElement = value.getArrayInitializedElt(I: i);
725 const mlir::Attribute element =
726 tryEmitPrivateForMemory(arrayElement, arrayElementTy);
727 if (!element)
728 return {};
729
730 const mlir::TypedAttr elementTyped = mlir::cast<mlir::TypedAttr>(element);
731 if (i == 0)
732 commonElementType = elementTyped.getType();
733 else if (elementTyped.getType() != commonElementType) {
734 commonElementType = {};
735 }
736
737 elements.push_back(elementTyped);
738 }
739
740 mlir::TypedAttr typedFiller = llvm::cast_or_null<mlir::TypedAttr>(filler);
741 if (filler && !typedFiller)
742 cgm.errorNYI(feature: "array filler should always be typed");
743
744 mlir::Type desiredType = cgm.convertType(destType);
745 return emitArrayConstant(cgm, desiredType, commonElementType, numElements,
746 elements, typedFiller);
747 }
748 case APValue::Vector: {
749 const QualType elementType =
750 destType->castAs<VectorType>()->getElementType();
751 const unsigned numElements = value.getVectorLength();
752
753 SmallVector<mlir::Attribute, 16> elements;
754 elements.reserve(numElements);
755
756 for (unsigned i = 0; i < numElements; ++i) {
757 const mlir::Attribute element =
758 tryEmitPrivateForMemory(value.getVectorElt(i), elementType);
759 if (!element)
760 return {};
761 elements.push_back(element);
762 }
763
764 const auto desiredVecTy =
765 mlir::cast<cir::VectorType>(cgm.convertType(destType));
766
767 return cir::ConstVectorAttr::get(
768 desiredVecTy,
769 mlir::ArrayAttr::get(cgm.getBuilder().getContext(), elements));
770 }
771 case APValue::MemberPointer: {
772 cgm.errorNYI(feature: "ConstExprEmitter::tryEmitPrivate member pointer");
773 return {};
774 }
775 case APValue::LValue:
776 return ConstantLValueEmitter(*this, value, destType).tryEmit();
777 case APValue::Struct:
778 case APValue::Union:
779 cgm.errorNYI(feature: "ConstExprEmitter::tryEmitPrivate struct or union");
780 return {};
781 case APValue::ComplexInt:
782 case APValue::ComplexFloat: {
783 mlir::Type desiredType = cgm.convertType(destType);
784 cir::ComplexType complexType =
785 mlir::dyn_cast<cir::ComplexType>(desiredType);
786
787 mlir::Type complexElemTy = complexType.getElementType();
788 if (isa<cir::IntType>(complexElemTy)) {
789 llvm::APSInt real = value.getComplexIntReal();
790 llvm::APSInt imag = value.getComplexIntImag();
791 return builder.getAttr<cir::ConstComplexAttr>(
792 complexType, cir::IntAttr::get(complexElemTy, real),
793 cir::IntAttr::get(complexElemTy, imag));
794 }
795
796 assert(isa<cir::FPTypeInterface>(complexElemTy) &&
797 "expected floating-point type");
798 llvm::APFloat real = value.getComplexFloatReal();
799 llvm::APFloat imag = value.getComplexFloatImag();
800 return builder.getAttr<cir::ConstComplexAttr>(
801 complexType, cir::FPAttr::get(complexElemTy, real),
802 cir::FPAttr::get(complexElemTy, imag));
803 }
804 case APValue::FixedPoint:
805 case APValue::AddrLabelDiff:
806 cgm.errorNYI(
807 feature: "ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");
808 return {};
809 }
810 llvm_unreachable("Unknown APValue kind");
811}
812
813mlir::Value CIRGenModule::emitNullConstant(QualType t, mlir::Location loc) {
814 if (t->getAs<PointerType>()) {
815 return builder.getNullPtr(getTypes().convertTypeForMem(t), loc);
816 }
817
818 if (getTypes().isZeroInitializable(ty: t))
819 return builder.getNullValue(getTypes().convertTypeForMem(t), loc);
820
821 if (getASTContext().getAsConstantArrayType(T: t)) {
822 errorNYI(feature: "CIRGenModule::emitNullConstant ConstantArrayType");
823 }
824
825 if (t->getAs<RecordType>())
826 errorNYI(feature: "CIRGenModule::emitNullConstant RecordType");
827
828 assert(t->isMemberDataPointerType() &&
829 "Should only see pointers to data members here!");
830
831 errorNYI(feature: "CIRGenModule::emitNullConstant unsupported type");
832 return {};
833}
834

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