Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
8bab7883
Commit
8bab7883
authored
Oct 23, 2019
by
vslashg
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2514 from thejcannon:msvc_macro_issue
PiperOrigin-RevId: 276134684
parents
aa1146da
e1b67b07
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
41 additions
and
77 deletions
+41
-77
gmock-pp.h
googlemock/include/gmock/internal/gmock-pp.h
+31
-77
gmock-pp_test.cc
googlemock/test/gmock-pp_test.cc
+10
-0
No files found.
googlemock/include/gmock/internal/gmock-pp.h
View file @
8bab7883
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
#undef GMOCK_PP_INTERNAL_USE_MSVC
#if defined(__clang__)
#define GMOCK_PP_INTERNAL_USE_MSVC 0
#elif defined(_MSC_VER)
// TODO(iserna): Also verify tradional versus comformant preprocessor.
static_assert
(
_MSC_VER
>=
1900
,
"MSVC version not supported. There is support for MSVC 14.0 and above."
);
#define GMOCK_PP_INTERNAL_USE_MSVC 1
#else
#define GMOCK_PP_INTERNAL_USE_MSVC 0
#endif
// Expands and concatenates the arguments. Constructed macros reevaluate.
// Expands and concatenates the arguments. Constructed macros reevaluate.
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
...
@@ -29,10 +16,6 @@ static_assert(
...
@@ -29,10 +16,6 @@ static_assert(
// Returns the only argument.
// Returns the only argument.
#define GMOCK_PP_IDENTITY(_1) _1
#define GMOCK_PP_IDENTITY(_1) _1
// MSVC preprocessor collapses __VA_ARGS__ in a single argument, we use a
// CAT-like directive to force correct evaluation. Each macro has its own.
#if GMOCK_PP_INTERNAL_USE_MSVC
// Evaluates to the number of arguments after expansion.
// Evaluates to the number of arguments after expansion.
//
//
// #define PAIR x, y
// #define PAIR x, y
...
@@ -43,45 +26,27 @@ static_assert(
...
@@ -43,45 +26,27 @@ static_assert(
// GMOCK_PP_NARG(PAIR) => 2
// GMOCK_PP_NARG(PAIR) => 2
//
//
// Requires: the number of arguments after expansion is at most 15.
// Requires: the number of arguments after expansion is at most 15.
#define GMOCK_PP_NARG(...) \
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_NARG_CAT( \
GMOCK_PP_INTERNAL_16TH( \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, \
(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
8, 7, 6, 5, 4, 3, 2, 1), )
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
// returns 0. Requires no more than 15 unprotected commas.
// returns 0. Requires no more than 15 unprotected commas.
#define GMOCK_PP_HAS_COMMA(...)
\
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_
HAS_COMMA_CAT(
\
GMOCK_PP_INTERNAL_
16TH(
\
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0))
1, 1, 1, 1, 1, 0), )
// Returns the first argument.
// Returns the first argument.
#define GMOCK_PP_HEAD(...) \
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__))
GMOCK_PP_INTERNAL_HEAD_CAT(GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__), )
// Returns the tail. A variadic list of all arguments minus the first. Requires
// Returns the tail. A variadic list of all arguments minus the first. Requires
// at least one argument.
// at least one argument.
#define GMOCK_PP_TAIL(...) \
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))
GMOCK_PP_INTERNAL_TAIL_CAT(GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__), )
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT( \
GMOCK_PP_IDENTITY( \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__), )
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))
#else // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_NARG(...) \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, \
7, 6, 5, 4, 3, 2, 1)
#define GMOCK_PP_HAS_COMMA(...) \
GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 0)
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__)
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__)
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)
#endif // GMOCK_PP_INTERNAL_USE_MSVC
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
// evaluates to `0`.
// evaluates to `0`.
...
@@ -139,10 +104,9 @@ static_assert(
...
@@ -139,10 +104,9 @@ static_assert(
// Expands to 1 if the first argument starts with something in parentheses,
// Expands to 1 if the first argument starts with something in parentheses,
// otherwise to 0.
// otherwise to 0.
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD( \
GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
// Expands to 1 is there is only one argument and it is enclosed in parentheses.
// Expands to 1 is there is only one argument and it is enclosed in parentheses.
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
...
@@ -179,10 +143,6 @@ static_assert(
...
@@ -179,10 +143,6 @@ static_assert(
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, \
...) \
_16
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \
#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
...
@@ -190,30 +150,24 @@ static_assert(
...
@@ -190,30 +150,24 @@ static_assert(
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
#define GMOCK_PP_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_TAIL(_1, ...) __VA_ARGS__
#if GMOCK_PP_INTERNAL_USE_MSVC
// Because of MSVC treating a token with a comma in it as a single token when
#define GMOCK_PP_INTERNAL_NARG_CAT(_1, _2) GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2)
// passed to another macro, we need to force it to evaluate it as multiple
#define GMOCK_PP_INTERNAL_HEAD_CAT(_1, _2) GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2)
// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT(_1, _2) \
// define one per possible macro that relies on this behavior. Note "_Args" must
GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2)
// be parenthesized.
#define GMOCK_PP_INTERNAL_TAIL_CAT(_1, _2) GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2)
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT(_1, _2) \
_10, _11, _12, _13, _14, _15, _16, \
GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2)
...) \
#define GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2) _1##_2
_16
#define GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_16TH(_Args) \
#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2) _1##_2
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)
#define GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2) _1##_2
#define GMOCK_PP_INTERNAL_HEAD(_Args) \
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) \
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(GMOCK_PP_HEAD(__VA_ARGS__), )
#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(_1, _2) \
#define GMOCK_PP_INTERNAL_TAIL(_Args) \
GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2)
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2) _1##_2
#else // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) GMOCK_PP_HEAD(__VA_ARGS__)
#endif // GMOCK_PP_INTERNAL_USE_MSVC
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
...
...
googlemock/test/gmock-pp_test.cc
View file @
8bab7883
#include "gmock/internal/gmock-pp.h"
#include "gmock/internal/gmock-pp.h"
// Used to test MSVC treating __VA_ARGS__ with a comma in it as one value
#define GMOCK_TEST_REPLACE_comma_WITH_COMMA_I_comma ,
#define GMOCK_TEST_REPLACE_comma_WITH_COMMA(x) \
GMOCK_PP_CAT(GMOCK_TEST_REPLACE_comma_WITH_COMMA_I_, x)
// Static assertions.
// Static assertions.
namespace
testing
{
namespace
testing
{
namespace
internal
{
namespace
internal
{
...
@@ -17,6 +22,11 @@ static_assert(GMOCK_PP_NARG(x, y, z, w) == 4, "");
...
@@ -17,6 +22,11 @@ static_assert(GMOCK_PP_NARG(x, y, z, w) == 4, "");
static_assert
(
!
GMOCK_PP_HAS_COMMA
(),
""
);
static_assert
(
!
GMOCK_PP_HAS_COMMA
(),
""
);
static_assert
(
GMOCK_PP_HAS_COMMA
(
b
,
),
""
);
static_assert
(
GMOCK_PP_HAS_COMMA
(
b
,
),
""
);
static_assert
(
!
GMOCK_PP_HAS_COMMA
((,
)),
""
);
static_assert
(
!
GMOCK_PP_HAS_COMMA
((,
)),
""
);
static_assert
(
GMOCK_PP_HAS_COMMA
(
GMOCK_TEST_REPLACE_comma_WITH_COMMA
(
comma
)),
""
);
static_assert
(
GMOCK_PP_HAS_COMMA
(
GMOCK_TEST_REPLACE_comma_WITH_COMMA
(
comma
(
unrelated
))),
""
);
static_assert
(
!
GMOCK_PP_IS_EMPTY
(,
),
""
);
static_assert
(
!
GMOCK_PP_IS_EMPTY
(,
),
""
);
static_assert
(
!
GMOCK_PP_IS_EMPTY
(
a
),
""
);
static_assert
(
!
GMOCK_PP_IS_EMPTY
(
a
),
""
);
static_assert
(
!
GMOCK_PP_IS_EMPTY
(()),
""
);
static_assert
(
!
GMOCK_PP_IS_EMPTY
(()),
""
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment