[clang] [CIR][NFC] Refactor constant pointer l-value handling (PR #144165)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 13 15:20:06 PDT 2025
================
@@ -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
More information about the cfe-commits
mailing list