From 167c3271778cd1a8c4433b9d2230901ce17c099e Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Mon, 9 Nov 2015 17:17:56 +0800 Subject: [PATCH] Fix build on MSVC >= 2012 Use the DEFINE_ENUM_FLAG_OPERATORS macro in winnt.h on Visual Studio, which defines the bitwise operators for the enumerations that we want to mark as hb_mark_as_flags_t, which will take care of the situation on newer Visual Studio (>= 2012), where the build breaks with C2057 errors as the underlying types of the enumerations is not clear to the compiler when we do a bitwise op within the declaration of the enumerations themselves. Also disable the C4200 (nonstandard extension used : zero-sized array in struct/union) and C4800 ('type' : forcing value to bool 'true' or 'false' (performance warning)) warnings as the C4200 is the intended scenario and C4800 is harmless but is so far an unavoidable side effect of using DEFINE_ENUM_FLAG_OPERATORS. --- src/hb-buffer-private.hh | 6 +++--- src/hb-ot-layout-common-private.hh | 2 +- src/hb-ot-layout-private.hh | 4 ++-- src/hb-ot-map-private.hh | 2 +- src/hb-private.hh | 11 +++++++++++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index 67c431d3..ceccecdc 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -48,8 +48,8 @@ ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20); ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)); -template <> class hb_mark_as_flags_t {}; -template <> class hb_mark_as_flags_t {}; +HB_MARK_AS_FLAG_T (hb_buffer_flags_t); +HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t); enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, @@ -64,7 +64,7 @@ enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_COMPLEX2 = 0x04000000u, HB_BUFFER_SCRATCH_FLAG_COMPLEX3 = 0x08000000u, }; -template <> class hb_mark_as_flags_t {}; +HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t); /* diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index 04958a81..5b21f142 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -581,7 +581,7 @@ struct LookupFlag : USHORT } /* namespace OT */ /* This has to be outside the namespace. */ -template <> class hb_mark_as_flags_t {}; +HB_MARK_AS_FLAG_T (OT::LookupFlag::Flags); namespace OT { struct Lookup diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 049b232d..45897ed5 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -65,7 +65,7 @@ enum hb_ot_layout_glyph_props_flags_t HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED }; -template <> class hb_mark_as_flags_t {}; +HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t); /* @@ -237,7 +237,7 @@ enum hb_unicode_props_flags_t { UPROPS_MASK_IGNORABLE = 0x80u, UPROPS_MASK_GEN_CAT = 0x1Fu }; -template <> class hb_mark_as_flags_t {}; +HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); static inline void _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index 1e3ff67e..6f62c77d 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -159,7 +159,7 @@ enum hb_ot_map_feature_flags_t { F_MANUAL_ZWJ = 0x0004u, /* Don't skip over ZWJ when matching. */ F_GLOBAL_SEARCH = 0x0008u /* If feature not found in LangSys, look for it in global feature list and pick one. */ }; -template <> class hb_mark_as_flags_t {}; +HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t); /* Macro version for where const is desired. */ #define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r))) diff --git a/src/hb-private.hh b/src/hb-private.hh index 5ed7ff3b..32f8d5e3 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -119,6 +119,15 @@ extern "C" void hb_free_impl(void *ptr); #define HB_FUNC __func__ #endif +/* Use templates for bitwise ops on enums or MSVC's DEFINE_ENUM_FLAG_OPERATORS */ +#ifdef _MSC_VER +# pragma warning(disable:4200) +# pragma warning(disable:4800) +# define HB_MARK_AS_FLAG_T(flags_t) DEFINE_ENUM_FLAG_OPERATORS (##flags_t##); +#else +# define HB_MARK_AS_FLAG_T(flags_t) template <> class hb_mark_as_flags_t {}; +#endif + /* * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411 * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch @@ -895,6 +904,7 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) /* To my surprise, looks like the function resolver is happy to silently cast * one enum to another... So this doesn't provide the type-checking that I * originally had in mind... :( */ +#ifndef _MSC_VER template class hb_mark_as_flags_t; template static inline T operator | (T l, T r) { hb_mark_as_flags_t unused HB_UNUSED; return T ((unsigned int) l | (unsigned int) r); } @@ -906,6 +916,7 @@ template static inline T& operator |= (T &l, T r) { hb_mark_as_flags_t unused HB_UNUSED; l = l | r; return l; } template static inline T& operator &= (T& l, T r) { hb_mark_as_flags_t unused HB_UNUSED; l = l & r; return l; } +#endif /* Useful for set-operations on small enums. -- GitLab