Bug 1368932 - Allow MOZ_PASTE_PREFIX_AND_ARG_COUNT to work with 0 arguments. r=froydnj

At the same time, remove the MOZ_STATIC_ASSERT_VALID_ARG_COUNT, which
doesn't actually work for more than 50 arguments(*), and which is now not
useful to detect 0 arguments.

(*) the build fails, but not directly thanks to the static_assert it
expands to.

--HG--
extra : rebase_source : 8f0fe7b352c89b5a3ec87f42ef5464c370c362ef
This commit is contained in:
Mike Hommey 2017-05-25 15:47:21 +09:00
Родитель 2357f45d41
Коммит c1becb4a54
7 изменённых файлов: 27 добавлений и 60 удалений

Просмотреть файл

@ -314,7 +314,6 @@ MOZ_CrashPrintf(const char* aFilename, int aLine, const char* aFormat, ...);
*/
#define MOZ_CRASH_UNSAFE_PRINTF(format, ...) \
do { \
MOZ_STATIC_ASSERT_VALID_ARG_COUNT(__VA_ARGS__); \
static_assert( \
MOZ_PASTE_PREFIX_AND_ARG_COUNT(, __VA_ARGS__) <= sPrintfMaxArgs, \
"Only up to 4 additional arguments are allowed!"); \

Просмотреть файл

@ -21,27 +21,29 @@
*
* MOZ_PASTE_PREFIX_AND_ARG_COUNT(, foo, 42) expands to 2
* MOZ_PASTE_PREFIX_AND_ARG_COUNT(A, foo, 42, bar) expands to A3
* MOZ_PASTE_PREFIX_AND_ARG_COUNT(A) expands to A0
* MOZ_PASTE_PREFIX_AND_ARG_COUNT() expands to 0, but MSVC warns there
* aren't enough arguments given.
*
* You must pass in between 1 and 50 (inclusive) variadic arguments, past
* |aPrefix|. It is not legal to do
* You must pass in between 0 and 50 (inclusive) variadic arguments, past
* |aPrefix|.
*
* MOZ_PASTE_PREFIX_AND_ARG_COUNT(prefix)
* The `##__VA_ARGS__` form is a GCC extension that removes the comma if
* __VA_ARGS__ is empty. It is supported by Clang too. MSVC ignores ##,
* and its default behavior is already to strip the comma when __VA_ARGS__
* is empty.
*
* (that is, pass in 0 variadic arguments). To ensure that a compile-time
* error occurs when these constraints are violated, use the
* MOZ_STATIC_ASSERT_VALID_ARG_COUNT macro with the same variaidc arguments
* wherever this macro is used.
*
* Passing (__VA_ARGS__, <rest of arguments>) rather than simply calling
* MOZ_MACROARGS_ARG_COUNT_HELPER2(__VA_ARGS__, <rest of arguments>) very
* carefully tiptoes around a MSVC bug where it improperly expands __VA_ARGS__
* as a single token in argument lists. For details, see:
*
* http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement
* http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/#comment-644
* So MOZ_MACROARGS_ARG_COUNT_HELPER(prefix) expands to
* (_, prefix50, prefix49, ...)
* MOZ_MACROARGS_ARG_COUNT_HELPER(prefix, a) expands to
* (_, a, prefix50, prefix49, ...)
* etc.
*/
#define MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) \
MOZ_MACROARGS_ARG_COUNT_HELPER((__VA_ARGS__, \
MOZ_MACROARGS_ARG_COUNT_HELPER2( \
MOZ_MACROARGS_ARG_COUNT_HELPER(aPrefix, ##__VA_ARGS__))
#define MOZ_MACROARGS_ARG_COUNT_HELPER(aPrefix, ...) (_, ##__VA_ARGS__, \
aPrefix##50, aPrefix##49, aPrefix##48, aPrefix##47, aPrefix##46, \
aPrefix##45, aPrefix##44, aPrefix##43, aPrefix##42, aPrefix##41, \
aPrefix##40, aPrefix##39, aPrefix##38, aPrefix##37, aPrefix##36, \
@ -51,12 +53,12 @@
aPrefix##20, aPrefix##19, aPrefix##18, aPrefix##17, aPrefix##16, \
aPrefix##15, aPrefix##14, aPrefix##13, aPrefix##12, aPrefix##11, \
aPrefix##10, aPrefix##9, aPrefix##8, aPrefix##7, aPrefix##6, \
aPrefix##5, aPrefix##4, aPrefix##3, aPrefix##2, aPrefix##1, aPrefix##0))
aPrefix##5, aPrefix##4, aPrefix##3, aPrefix##2, aPrefix##1, aPrefix##0)
#define MOZ_MACROARGS_ARG_COUNT_HELPER(aArgs) \
MOZ_MACROARGS_ARG_COUNT_HELPER2 aArgs
#define MOZ_MACROARGS_ARG_COUNT_HELPER2(aArgs) \
MOZ_MACROARGS_ARG_COUNT_HELPER3 aArgs
#define MOZ_MACROARGS_ARG_COUNT_HELPER2( \
#define MOZ_MACROARGS_ARG_COUNT_HELPER3(a0, \
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, \
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, \
a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, \
@ -64,33 +66,6 @@
a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, \
a51, ...) a51
/*
* MOZ_STATIC_ASSERT_VALID_ARG_COUNT ensures that a compile-time error occurs
* when the argument count constraints of MOZ_PASTE_PREFIX_AND_ARG_COUNT are
* violated. Use this macro wherever MOZ_PASTE_PREFIX_AND_ARG_COUNT is used
* and pass it the same variadic arguments.
*
* This macro employs a few dirty tricks to function. To detect the zero
* argument case, |(__VA_ARGS__)| is stringified, sizeof-ed, and compared to
* what it should be in the absence of arguments.
*
* Detecting too many arguments is a little trickier. With a valid argument
* count and a prefix of 1, MOZ_PASTE_PREFIX_AND_ARG_COUNT expands to e.g. 14.
* With a prefix of 0.0, it expands to e.g. 0.04. If there are too many
* arguments, it expands to the first argument over the limit. If this
* exceeding argument is a number, the assertion will fail as there is no
* number than can simultaneously be both > 10 and == 0. If the exceeding
* argument is not a number, a compile-time error should still occur due to
* the operations performed on it.
*/
#define MOZ_MACROARGS_STRINGIFY_HELPER(x) #x
#define MOZ_STATIC_ASSERT_VALID_ARG_COUNT(...) \
static_assert( \
sizeof(MOZ_MACROARGS_STRINGIFY_HELPER((__VA_ARGS__))) != sizeof("()") && \
(MOZ_PASTE_PREFIX_AND_ARG_COUNT(1, __VA_ARGS__)) > 10 && \
(int)(MOZ_PASTE_PREFIX_AND_ARG_COUNT(0.0, __VA_ARGS__)) == 0, \
"MOZ_STATIC_ASSERT_VALID_ARG_COUNT requires 1 to 50 arguments") /* ; */
/*
* MOZ_ARGS_AFTER_N expands to its arguments excluding the first |N|
* arguments. For example:

Просмотреть файл

@ -50,9 +50,7 @@
*
* If the |aFixedArgs| list is not empty, a trailing comma must be included.
*
* The |aArgs| list must be not be empty and may be up to 50 items long. Use
* MOZ_STATIC_ASSERT_VALID_ARG_COUNT to ensure that violating this constraint
* results in a compile-time error.
* The |aArgs| list may be up to 50 items long.
*/
#define MOZ_FOR_EACH_EXPAND_HELPER(...) __VA_ARGS__
#define MOZ_FOR_EACH_GLUE(a, b) a b
@ -70,6 +68,7 @@
aMacro, \
(MOZ_FOR_EACH_EXPAND_HELPER aFixedArgs MOZ_ARG_1 aArgs))
#define MOZ_FOR_EACH_0(m, s, fa, a)
#define MOZ_FOR_EACH_1(m, s, fa, a) \
MOZ_FOR_EACH_HELPER(m, fa, a)
#define MOZ_FOR_EACH_2(m, s, fa, a) \

Просмотреть файл

@ -6,9 +6,9 @@
#include "mozilla/MacroArgs.h"
MOZ_STATIC_ASSERT_VALID_ARG_COUNT(1);
MOZ_STATIC_ASSERT_VALID_ARG_COUNT(1, 2);
static_assert(MOZ_PASTE_PREFIX_AND_ARG_COUNT(100) == 1000, "");
static_assert(MOZ_PASTE_PREFIX_AND_ARG_COUNT(100, a) == 1001, "");
static_assert(MOZ_PASTE_PREFIX_AND_ARG_COUNT(100, a, b) == 1002, "");
static_assert(MOZ_PASTE_PREFIX_AND_ARG_COUNT(100, a, b, c) == 1003, "");
static_assert(MOZ_PASTE_PREFIX_AND_ARG_COUNT(, a, b, c) == 3, "");

Просмотреть файл

@ -442,7 +442,6 @@ DowncastCCParticipant(void* aPtr)
ImplCycleCollectionUnlink(tmp->_field);
#define NS_IMPL_CYCLE_COLLECTION_UNLINK(...) \
MOZ_STATIC_ASSERT_VALID_ARG_COUNT(__VA_ARGS__); \
MOZ_FOR_EACH(NS_IMPL_CYCLE_COLLECTION_UNLINK_HELPER, (), (__VA_ARGS__))
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
@ -494,7 +493,6 @@ DowncastCCParticipant(void* aPtr)
ImplCycleCollectionTraverse(cb, tmp->_field, #_field, 0);
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE(...) \
MOZ_STATIC_ASSERT_VALID_ARG_COUNT(__VA_ARGS__); \
MOZ_FOR_EACH(NS_IMPL_CYCLE_COLLECTION_TRAVERSE_HELPER, (), (__VA_ARGS__))
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(_field) \

Просмотреть файл

@ -156,7 +156,6 @@ NS_CI_INTERFACE_GETTER_NAME(_class)(uint32_t *count, nsIID ***array) \
}
#define NS_IMPL_CI_INTERFACE_GETTER(aClass, ...) \
MOZ_STATIC_ASSERT_VALID_ARG_COUNT(__VA_ARGS__); \
NS_CLASSINFO_HELPER_BEGIN(aClass, \
MOZ_PASTE_PREFIX_AND_ARG_COUNT(/* No prefix */, \
__VA_ARGS__)) \
@ -164,7 +163,6 @@ NS_CI_INTERFACE_GETTER_NAME(_class)(uint32_t *count, nsIID ***array) \
NS_CLASSINFO_HELPER_END
#define NS_IMPL_QUERY_INTERFACE_CI(aClass, ...) \
MOZ_STATIC_ASSERT_VALID_ARG_COUNT(__VA_ARGS__); \
NS_INTERFACE_MAP_BEGIN(aClass) \
MOZ_FOR_EACH(NS_INTERFACE_MAP_ENTRY, (), (__VA_ARGS__)) \
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, MOZ_ARG_1(__VA_ARGS__)) \

Просмотреть файл

@ -960,7 +960,6 @@ NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
NS_INTERFACE_TABLE_END
#define NS_INTERFACE_TABLE(aClass, ...) \
MOZ_STATIC_ASSERT_VALID_ARG_COUNT(__VA_ARGS__); \
NS_INTERFACE_TABLE_BEGIN \
MOZ_FOR_EACH(NS_INTERFACE_TABLE_ENTRY, (aClass,), (__VA_ARGS__)) \
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(aClass, nsISupports, \
@ -1041,7 +1040,6 @@ NS_IMETHODIMP_(MozExternalRefCountType) Class::Release(void) \
#define NS_INTERFACE_TABLE_INHERITED0(Class) /* Nothing to do here */
#define NS_INTERFACE_TABLE_INHERITED(aClass, ...) \
MOZ_STATIC_ASSERT_VALID_ARG_COUNT(__VA_ARGS__); \
NS_INTERFACE_TABLE_BEGIN \
MOZ_FOR_EACH(NS_INTERFACE_TABLE_ENTRY, (aClass,), (__VA_ARGS__)) \
NS_INTERFACE_TABLE_END