mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 15:41:46 +00:00
[IntegerAttr] Add helpers for working with LLVM's APSInt type.
The FIRRTL dialect in CIRCT uses inherently signful types, and APSInt is the best way to model that. Add a couple of helpers that make it easier to work with an IntegerAttr that carries a sign. This follows the example of getZExt() and getSExt() which assert when the underlying type of the attribute is unexpected. In this case we assert fail when the underlying type of the attribute is signless. This is strictly additive, so it is NFC. It is tested in the CIRCT repo. Differential Revision: https://reviews.llvm.org/D102701
This commit is contained in:
parent
5781f9a743
commit
855b42ddd0
@ -466,6 +466,12 @@ def Builtin_IntegerAttr : Builtin_Attr<"Integer"> {
|
||||
return BoolAttr::get(type.getContext(), value.getBoolValue());
|
||||
return $_get(type.getContext(), type, value);
|
||||
}]>,
|
||||
AttrBuilder<(ins "const APSInt &":$value), [{
|
||||
auto signedness = value.isSigned() ?
|
||||
IntegerType::Signed : IntegerType::Unsigned;
|
||||
auto type = IntegerType::get($_ctxt, value.getBitWidth(), signedness);
|
||||
return $_get(type.getContext(), type, value);
|
||||
}]>,
|
||||
AttrBuilderWithInferredContext<(ins "Type":$type, "int64_t":$value), [{
|
||||
// `index` has a defined internal storage width.
|
||||
if (type.isIndex()) {
|
||||
@ -492,6 +498,10 @@ def Builtin_IntegerAttr : Builtin_Attr<"Integer"> {
|
||||
/// an unsigned integer.
|
||||
uint64_t getUInt() const;
|
||||
|
||||
/// Return the value as an APSInt which carries the signed from the type of
|
||||
/// the attribute. This traps on signless integers types!
|
||||
APSInt getAPSInt() const;
|
||||
|
||||
private:
|
||||
/// Return a boolean attribute. This is a special variant of the `get`
|
||||
/// method that is used by the MLIRContext to cache the boolean IntegerAttr
|
||||
|
@ -64,6 +64,7 @@ template <typename T, typename ResultT> class TypeSwitch;
|
||||
|
||||
// Other common classes.
|
||||
class APInt;
|
||||
class APSInt;
|
||||
class APFloat;
|
||||
template <typename Fn> class function_ref;
|
||||
template <typename IteratorT> class iterator_range;
|
||||
@ -118,6 +119,7 @@ using TypeSwitch = llvm::TypeSwitch<T, ResultT>;
|
||||
// Other common classes.
|
||||
using llvm::APFloat;
|
||||
using llvm::APInt;
|
||||
using llvm::APSInt;
|
||||
template <typename Fn> using function_ref = llvm::function_ref<Fn>;
|
||||
using llvm::iterator_range;
|
||||
using llvm::raw_ostream;
|
||||
|
@ -259,6 +259,14 @@ uint64_t IntegerAttr::getUInt() const {
|
||||
return getValue().getZExtValue();
|
||||
}
|
||||
|
||||
/// Return the value as an APSInt which carries the signed from the type of
|
||||
/// the attribute. This traps on signless integers types!
|
||||
APSInt IntegerAttr::getAPSInt() const {
|
||||
assert(!getType().isSignlessInteger() &&
|
||||
"Signless integers don't carry a sign for APSInt");
|
||||
return APSInt(getValue(), getType().isUnsignedInteger());
|
||||
}
|
||||
|
||||
LogicalResult IntegerAttr::verify(function_ref<InFlightDiagnostic()> emitError,
|
||||
Type type, APInt value) {
|
||||
if (IntegerType integerType = type.dyn_cast<IntegerType>()) {
|
||||
|
Loading…
Reference in New Issue
Block a user