summaryrefslogtreecommitdiff
path: root/src/expr/attribute.h
diff options
context:
space:
mode:
authorAndres Noetzli <andres.noetzli@gmail.com>2020-01-13 12:26:52 -0800
committerGitHub <noreply@github.com>2020-01-13 12:26:52 -0800
commit4e50d35447b5ee07304d2b857af388ea569db98b (patch)
tree7eb2497463ad1807dd0153b7e60c909f70cabb8d /src/expr/attribute.h
parent81a2e226251bea677f6a920004e846a08072c851 (diff)
Support arbitrary unsigned integer attributes (#3591)
Fixes #3586. On macOS, `size_t` resolves to `unsigned long` whereas `uint64_t` resolves to `unsigned long long`. Even though the types have the same bit-width and signedness, they are not considered the same type. This caused issues with `Attribute`s that store `size_t` values because we only specialized the `getTable()` struct for `uint64_t`. This commit changes the specialization to work for arbitrary unsigned integer types of at most 64-bit. It does that by generalizing the specialization of `getTable()` and by implementing a `KindValueToTableValueMapping` for unsigned integer attributes of up to 64-bit that casts integers between the attributes bit-width and `uint64_t`.
Diffstat (limited to 'src/expr/attribute.h')
-rw-r--r--src/expr/attribute.h17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/expr/attribute.h b/src/expr/attribute.h
index 46302fc9f..44bf7aae5 100644
--- a/src/expr/attribute.h
+++ b/src/expr/attribute.h
@@ -61,7 +61,7 @@ class AttributeManager {
* getTable<> is a helper template that gets the right table from an
* AttributeManager given its type.
*/
- template <class T, bool context_dep>
+ template <class T, bool context_dep, class Enable>
friend struct getTable;
bool d_inGarbageCollection;
@@ -190,8 +190,13 @@ namespace attr {
/**
* The getTable<> template provides (static) access to the
* AttributeManager field holding the table.
+ *
+ * The `Enable` template parameter is used to instantiate the template
+ * conditionally: If the template substitution of Enable fails (e.g. when using
+ * `std::enable_if` in the template parameter and the condition is false), the
+ * instantiation is ignored due to the SFINAE rule.
*/
-template <class T, bool context_dep>
+template <class T, bool context_dep, class Enable = void>
struct getTable;
/** Access the "d_bools" member of AttributeManager. */
@@ -208,8 +213,12 @@ struct getTable<bool, false> {
};
/** Access the "d_ints" member of AttributeManager. */
-template <>
-struct getTable<uint64_t, false> {
+template <class T>
+struct getTable<T,
+ false,
+ // Use this specialization only for unsigned integers
+ typename std::enable_if<std::is_unsigned<T>::value>::type>
+{
static const AttrTableId id = AttrTableUInt64;
typedef AttrHash<uint64_t> table_type;
static inline table_type& get(AttributeManager& am) {
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback