@@ -329,6 +329,222 @@ emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType,
329
329
return {};
330
330
}
331
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
+
332
548
// ===----------------------------------------------------------------------===//
333
549
// ConstantEmitter
334
550
// ===----------------------------------------------------------------------===//
@@ -556,23 +772,8 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
556
772
cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate member pointer" );
557
773
return {};
558
774
}
559
- case APValue::LValue: {
560
-
561
- if (value.getLValueBase ()) {
562
- cgm.errorNYI (" non-null pointer initialization" );
563
- } else {
564
-
565
- mlir::Type desiredType = cgm.convertType (destType);
566
- if (const cir::PointerType ptrType =
567
- mlir::dyn_cast<cir::PointerType>(desiredType)) {
568
- return builder.getConstPtrAttr (ptrType,
569
- value.getLValueOffset ().getQuantity ());
570
- } else {
571
- llvm_unreachable (" non-pointer variable initialized with a pointer" );
572
- }
573
- }
574
- return {};
575
- }
775
+ case APValue::LValue:
776
+ return ConstantLValueEmitter (*this , value, destType).tryEmit ();
576
777
case APValue::Struct:
577
778
case APValue::Union:
578
779
cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate struct or union" );
0 commit comments