зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
2357f45d41
Коммит
c1becb4a54
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче