class FIROpsDialect;
namespace detail {
-struct OpaqueAttributeStorage;
struct RealAttributeStorage;
struct TypeAttributeStorage;
} // namespace detail
llvm::APFloat getValue() const;
};
-/// An opaque attribute is used to provide dictionary lookups of pointers. The
-/// underlying type of the pointee object is left up to the client. Opaque
-/// attributes are always constructed as null pointers when parsing. Clearly,
-/// opaque attributes come with restrictions and must be used with care.
-/// 1. An opaque attribute should not refer to information of semantic
-/// significance, since the pointed-to object will not be a part of
-/// round-tripping the IR.
-/// 2. The lifetime of the pointed-to object must outlive any possible uses
-/// via the opaque attribute.
-class OpaqueAttr
- : public mlir::Attribute::AttrBase<OpaqueAttr, mlir::Attribute,
- detail::OpaqueAttributeStorage> {
-public:
- using Base::Base;
-
- static constexpr llvm::StringRef getAttrName() { return "opaque"; }
- static OpaqueAttr get(mlir::MLIRContext *ctxt, void *pointer);
-
- void *getPointer() const;
-};
-
mlir::Attribute parseFirAttribute(FIROpsDialect *dialect,
mlir::DialectAsmParser &parser,
mlir::Type type);
private:
mlir::Type value;
};
-
-/// An attribute representing a raw pointer.
-struct OpaqueAttributeStorage : public mlir::AttributeStorage {
- using KeyTy = void *;
-
- OpaqueAttributeStorage(void *value) : value(value) {}
-
- /// Key equality function.
- bool operator==(const KeyTy &key) const { return key == value; }
-
- /// Construct a new storage instance.
- static OpaqueAttributeStorage *
- construct(mlir::AttributeStorageAllocator &allocator, KeyTy key) {
- return new (allocator.allocate<OpaqueAttributeStorage>())
- OpaqueAttributeStorage(key);
- }
-
- void *getPointer() const { return value; }
-
-private:
- void *value;
-};
} // namespace fir::detail
//===----------------------------------------------------------------------===//
llvm::APFloat fir::RealAttr::getValue() const { return getImpl()->getValue(); }
//===----------------------------------------------------------------------===//
-// OpaqueAttr
-//===----------------------------------------------------------------------===//
-
-OpaqueAttr fir::OpaqueAttr::get(mlir::MLIRContext *ctxt, void *key) {
- return Base::get(ctxt, key);
-}
-
-void *fir::OpaqueAttr::getPointer() const { return getImpl()->getPointer(); }
-
-//===----------------------------------------------------------------------===//
// FIR attribute parsing
//===----------------------------------------------------------------------===//
}
return SubclassAttr::get(type);
}
- if (attrName == OpaqueAttr::getAttrName()) {
- if (parser.parseLess() || parser.parseGreater()) {
- parser.emitError(loc, "expected <>");
- return {};
- }
- // NB: opaque pointers are always parsed in as nullptrs. The tool must
- // rebuild the context.
- return OpaqueAttr::get(dialect->getContext(), nullptr);
- }
if (attrName == PointIntervalAttr::getAttrName())
return PointIntervalAttr::get(dialect->getContext());
if (attrName == LowerBoundAttr::getAttrName())
llvm::SmallString<40> ss;
a.getValue().bitcastToAPInt().toStringUnsigned(ss, 16);
os << ss << '>';
- } else if (attr.isa<fir::OpaqueAttr>()) {
- os << fir::OpaqueAttr::getAttrName() << "<>";
} else {
// don't know how to print the attribute, so use a default
os << "<(unknown attribute)>";
PointerType, RealType, RecordType, ReferenceType, SequenceType,
ShapeType, ShapeShiftType, SliceType, TypeDescType,
fir::VectorType>();
- addAttributes<ClosedIntervalAttr, ExactTypeAttr, LowerBoundAttr, OpaqueAttr,
+ addAttributes<ClosedIntervalAttr, ExactTypeAttr, LowerBoundAttr,
PointIntervalAttr, RealAttr, SubclassAttr, UpperBoundAttr>();
addOperations<
#define GET_OP_LIST