forked from mirrors/gecko-dev
		
	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:
		
							parent
							
								
									2357f45d41
								
							
						
					
					
						commit
						c1becb4a54
					
				
					 7 changed files with 27 additions and 60 deletions
				
			
		|  | @ -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 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Mike Hommey
						Mike Hommey