Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
213799 views
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
35
using namespace clang;
36
using 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.
49
class ConstExprEmitter
50
: public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {
51
CIRGenModule &cgm;
52
LLVM_ATTRIBUTE_UNUSED ConstantEmitter &emitter;
53
54
public:
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>(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(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
275
static QualType getNonMemoryType(CIRGenModule &cgm, QualType type) {
276
if (const auto *at = type->getAs<AtomicType>()) {
277
return cgm.getASTContext().getQualifiedType(at->getValueType(),
278
type.getQualifiers());
279
}
280
return type;
281
}
282
283
static mlir::Attribute
284
emitArrayConstant(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("array with different type elements");
329
return {};
330
}
331
332
//===----------------------------------------------------------------------===//
333
// ConstantLValueEmitter
334
//===----------------------------------------------------------------------===//
335
336
namespace {
337
/// A struct which can be used to peephole certain kinds of finalization
338
/// that normally happen during l-value emission.
339
struct 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.
348
class 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
358
public:
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
365
private:
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
387
mlir::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("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("ConstantLValueEmitter: non-attribute pointer");
425
return {};
426
}
427
428
cgm.errorNYI("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.
434
mlir::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
441
ConstantLValue
442
ConstantLValueEmitter::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>(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>(d)) {
456
cgm.errorNYI(fd->getSourceRange(),
457
"ConstantLValueEmitter: function decl");
458
return {};
459
}
460
461
if (auto *vd = dyn_cast<VarDecl>(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("ConstantLValueEmitter: typeid");
470
return {};
471
}
472
473
// Otherwise, it must be an expression.
474
return Visit(base.get<const Expr *>());
475
}
476
477
ConstantLValue ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *e) {
478
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: constant expr");
479
return {};
480
}
481
482
ConstantLValue
483
ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *e) {
484
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: compound literal");
485
return {};
486
}
487
488
ConstantLValue
489
ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *e) {
490
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: string literal");
491
return {};
492
}
493
494
ConstantLValue
495
ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *e) {
496
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc encode expr");
497
return {};
498
}
499
500
ConstantLValue
501
ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *e) {
502
cgm.errorNYI(e->getSourceRange(),
503
"ConstantLValueEmitter: objc string literal");
504
return {};
505
}
506
507
ConstantLValue
508
ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *e) {
509
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc boxed expr");
510
return {};
511
}
512
513
ConstantLValue
514
ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *e) {
515
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: predefined expr");
516
return {};
517
}
518
519
ConstantLValue
520
ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *e) {
521
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: addr label expr");
522
return {};
523
}
524
525
ConstantLValue ConstantLValueEmitter::VisitCallExpr(const CallExpr *e) {
526
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: call expr");
527
return {};
528
}
529
530
ConstantLValue ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *e) {
531
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: block expr");
532
return {};
533
}
534
535
ConstantLValue
536
ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *e) {
537
cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: cxx typeid expr");
538
return {};
539
}
540
541
ConstantLValue 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
552
mlir::Attribute ConstantEmitter::tryEmitForInitializer(const VarDecl &d) {
553
initializeNonAbstract();
554
return markIfFailed(tryEmitPrivateForVarInit(d));
555
}
556
557
void 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
568
mlir::Attribute
569
ConstantEmitter::tryEmitAbstractForInitializer(const VarDecl &d) {
570
AbstractStateRAII state(*this, true);
571
return tryEmitPrivateForVarInit(d);
572
}
573
574
ConstantEmitter::~ConstantEmitter() {
575
assert((!initializedNonAbstract || finalized || failed) &&
576
"not finalized after being initialized for non-abstract emission");
577
}
578
579
mlir::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(d.getType());
585
if (ty->isRecordType()) {
586
if (const auto *e = dyn_cast_or_null<CXXConstructExpr>(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>(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("tryEmitPrivateForVarInit: cxx record with bases");
599
return {};
600
}
601
if (!cgm.getTypes().isZeroInitializable(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
"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, 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
635
mlir::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(retType);
642
643
return emitAbstract(ce->getBeginLoc(), ce->getAPValueResult(), retType);
644
}
645
646
mlir::Attribute ConstantEmitter::tryEmitPrivateForMemory(const APValue &value,
647
QualType destType) {
648
QualType nonMemoryDestType = getNonMemoryType(cgm, destType);
649
mlir::Attribute c = tryEmitPrivate(value, nonMemoryDestType);
650
return (c ? emitForMemory(c, destType) : nullptr);
651
}
652
653
mlir::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
663
mlir::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("emitForMemory: atomic type");
668
return {};
669
}
670
671
return c;
672
}
673
674
mlir::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("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("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(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);
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("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("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("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
"ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");
808
return {};
809
}
810
llvm_unreachable("Unknown APValue kind");
811
}
812
813
mlir::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(t))
819
return builder.getNullValue(getTypes().convertTypeForMem(t), loc);
820
821
if (getASTContext().getAsConstantArrayType(t)) {
822
errorNYI("CIRGenModule::emitNullConstant ConstantArrayType");
823
}
824
825
if (t->getAs<RecordType>())
826
errorNYI("CIRGenModule::emitNullConstant RecordType");
827
828
assert(t->isMemberDataPointerType() &&
829
"Should only see pointers to data members here!");
830
831
errorNYI("CIRGenModule::emitNullConstant unsupported type");
832
return {};
833
}
834
835