@@ -329,6 +329,222 @@ emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType,
329329 return {};
330330}
331331
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+
332548// ===----------------------------------------------------------------------===//
333549// ConstantEmitter
334550// ===----------------------------------------------------------------------===//
@@ -556,23 +772,8 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
556772 cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate member pointer" );
557773 return {};
558774 }
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 ();
576777 case APValue::Struct:
577778 case APValue::Union:
578779 cgm.errorNYI (" ConstExprEmitter::tryEmitPrivate struct or union" );
0 commit comments