================ @@ -329,6 +329,222 @@ emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType, return {}; } +//===----------------------------------------------------------------------===// +// ConstantLValueEmitter +//===----------------------------------------------------------------------===// + +namespace { +/// A struct which can be used to peephole certain kinds of finalization +/// that normally happen during l-value emission. +struct ConstantLValue { + llvm::PointerUnion<mlir::Value, mlir::Attribute> value; + bool hasOffsetApplied; + + ConstantLValue(std::nullptr_t) : value(nullptr), hasOffsetApplied(false) {} + ConstantLValue() : value(nullptr), hasOffsetApplied(false) {} +}; + +/// A helper class for emitting constant l-values. +class ConstantLValueEmitter + : public ConstStmtVisitor<ConstantLValueEmitter, ConstantLValue> { + CIRGenModule &cgm; + ConstantEmitter &emitter; + const APValue &value; + QualType destType; + + // Befriend StmtVisitorBase so that we don't have to expose Visit*. + friend StmtVisitorBase; + +public: + ConstantLValueEmitter(ConstantEmitter &emitter, const APValue &value, + QualType destType) + : cgm(emitter.cgm), emitter(emitter), value(value), destType(destType) {} + + mlir::Attribute tryEmit(); + +private: + mlir::Attribute tryEmitAbsolute(mlir::Type destTy); + ConstantLValue tryEmitBase(const APValue::LValueBase &base); + + ConstantLValue VisitStmt(const Stmt *s) { return nullptr; } + ConstantLValue VisitConstantExpr(const ConstantExpr *e); + ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *e); + ConstantLValue VisitStringLiteral(const StringLiteral *e); + ConstantLValue VisitObjCBoxedExpr(const ObjCBoxedExpr *e); + ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *e); + ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *e); + ConstantLValue VisitPredefinedExpr(const PredefinedExpr *e); + ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *e); + ConstantLValue VisitCallExpr(const CallExpr *e); + ConstantLValue VisitBlockExpr(const BlockExpr *e); + ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *e); + ConstantLValue + VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e); +}; + +} // namespace + +mlir::Attribute ConstantLValueEmitter::tryEmit() { + const APValue::LValueBase &base = value.getLValueBase(); + + // The destination type should be a pointer or reference + // type, but it might also be a cast thereof. + // + // FIXME: the chain of casts required should be reflected in the APValue. + // We need this in order to correctly handle things like a ptrtoint of a + // non-zero null pointer and addrspace casts that aren't trivially + // represented in LLVM IR. + mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType); + assert(mlir::isa<cir::PointerType>(destTy)); + + // If there's no base at all, this is a null or absolute pointer, + // possibly cast back to an integer type. + if (!base) + return tryEmitAbsolute(destTy); ---------------- andykaylor wrote:
This is the only path that doesn't hit an `errorNYI` call, and along with the `convertTypeForMem` call above, it should correspond exactly to the previous implementation. https://github.com/llvm/llvm-project/pull/144165 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits