Skip to content

Commit df71972

Browse files
m0hamedrafi-kamal
authored andcommitted
Simplify template exporting macros
1 parent 394f5c8 commit df71972

File tree

4 files changed

+30
-209
lines changed

4 files changed

+30
-209
lines changed

src/google/protobuf/port_def.inc

Lines changed: 14 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -343,20 +343,28 @@
343343
#if defined(PROTOBUF_USE_DLLS)
344344
#if defined(_MSC_VER)
345345
#ifdef LIBPROTOBUF_EXPORTS
346-
#define PROTOBUF_EXPORT __declspec(dllexport)
346+
#define PROTOBUF_EXPORT __declspec(dllexport)
347+
#define PROTOBUF_EXPORT_TEMPLATE_DECLARE
348+
#define PROTOBUF_EXPORT_TEMPLATE_DEFINE __declspec(dllexport)
347349
#else
348-
#define PROTOBUF_EXPORT __declspec(dllimport)
350+
#define PROTOBUF_EXPORT __declspec(dllimport)
351+
#define PROTOBUF_EXPORT_TEMPLATE_DECLARE
352+
#define PROTOBUF_EXPORT_TEMPLATE_DEFINE __declspec(dllimport)
349353
#endif
350354
#ifdef LIBPROTOC_EXPORTS
351-
#define PROTOC_EXPORT __declspec(dllexport)
355+
#define PROTOC_EXPORT __declspec(dllexport)
352356
#else
353-
#define PROTOC_EXPORT __declspec(dllimport)
357+
#define PROTOC_EXPORT __declspec(dllimport)
354358
#endif
355359
#else // defined(_MSC_VER)
356360
#ifdef LIBPROTOBUF_EXPORTS
357361
#define PROTOBUF_EXPORT __attribute__((visibility("default")))
362+
#define PROTOBUF_EXPORT_TEMPLATE_DECLARE __attribute__((visibility("default")))
363+
#define PROTOBUF_EXPORT_TEMPLATE_DEFINE
358364
#else
359365
#define PROTOBUF_EXPORT
366+
#define PROTOBUF_EXPORT_TEMPLATE_DECLARE
367+
#define PROTOBUF_EXPORT_TEMPLATE_DEFINE
360368
#endif
361369
#ifdef LIBPROTOC_EXPORTS
362370
#define PROTOC_EXPORT __attribute__((visibility("default")))
@@ -367,168 +375,10 @@
367375
#else // defined(PROTOBUF_USE_DLLS)
368376
#define PROTOBUF_EXPORT
369377
#define PROTOC_EXPORT
378+
#define PROTOBUF_EXPORT_TEMPLATE_DECLARE
379+
#define PROTOBUF_EXPORT_TEMPLATE_DEFINE
370380
#endif
371381

372-
373-
// This portion provides macros for using FOO_EXPORT macros with explicit
374-
// template instantiation declarations and definitions.
375-
// Generally, the FOO_EXPORT macros are used at declarations,
376-
// and GCC requires them to be used at explicit instantiation declarations,
377-
// but MSVC requires __declspec(dllexport) to be used at the explicit
378-
// instantiation definitions instead.
379-
380-
// Usage
381-
//
382-
// In a header file, write:
383-
//
384-
// extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE(FOO_EXPORT) foo<bar>;
385-
//
386-
// In a source file, write:
387-
//
388-
// template class PROTOBUF_EXPORT_TEMPLATE_DEFINE(FOO_EXPORT) foo<bar>;
389-
//
390-
// Where FOO_EXPORT is either PROTOBUF_EXPORT or PROTOC_EXPORT
391-
392-
// Implementation notes
393-
//
394-
// The implementation of these macros uses some subtle macro semantics to
395-
// detect what the provided FOO_EXPORT value was defined as and then
396-
// to dispatch to appropriate macro definitions. Unfortunately,
397-
// MSVC's C preprocessor is rather non-compliant and requires special
398-
// care to make it work.
399-
//
400-
// Issue 1.
401-
//
402-
// #define F(x)
403-
// F()
404-
//
405-
// MSVC emits warning C4003 ("not enough actual parameters for macro
406-
// 'F'), even though it's a valid macro invocation. This affects the
407-
// macros below that take just an "export" parameter, because export
408-
// may be empty.
409-
//
410-
// As a workaround, we can add a dummy parameter and arguments:
411-
//
412-
// #define F(x,_)
413-
// F(,)
414-
//
415-
// Issue 2.
416-
//
417-
// #define F(x) G##x
418-
// #define Gj() ok
419-
// F(j())
420-
//
421-
// The correct replacement for "F(j())" is "ok", but MSVC replaces it
422-
// with "Gj()". As a workaround, we can pass the result to an
423-
// identity macro to force MSVC to look for replacements again. (This
424-
// is why PROTOBUF_EXPORT_TEMPLATE_STYLE_3 exists.)
425-
426-
#define PROTOBUF_EXPORT_TEMPLATE_DECLARE(export) \
427-
PROTOBUF_EXPORT_TEMPLATE_INVOKE( \
428-
DECLARE, PROTOBUF_EXPORT_TEMPLATE_STYLE(export, ), export)
429-
#define PROTOBUF_EXPORT_TEMPLATE_DEFINE(export) \
430-
PROTOBUF_EXPORT_TEMPLATE_INVOKE( \
431-
DEFINE, PROTOBUF_EXPORT_TEMPLATE_STYLE(export, ), export)
432-
433-
// INVOKE is an internal helper macro to perform parameter replacements
434-
// and token pasting to chain invoke another macro. E.g.,
435-
// PROTOBUF_EXPORT_TEMPLATE_INVOKE(DECLARE, DEFAULT, FOO_EXPORT)
436-
// will export to call
437-
// PROTOBUF_EXPORT_TEMPLATE_DECLARE_DEFAULT(FOO_EXPORT, )
438-
// (but with FOO_EXPORT expanded too).
439-
#define PROTOBUF_EXPORT_TEMPLATE_INVOKE(which, style, export) \
440-
PROTOBUF_EXPORT_TEMPLATE_INVOKE_2(which, style, export)
441-
#define PROTOBUF_EXPORT_TEMPLATE_INVOKE_2(which, style, export) \
442-
PROTOBUF_EXPORT_TEMPLATE_##which##_##style(export, )
443-
444-
// Default style is to apply the FOO_EXPORT macro at declaration sites.
445-
#define PROTOBUF_EXPORT_TEMPLATE_DECLARE_DEFAULT(export, _) export
446-
#define PROTOBUF_EXPORT_TEMPLATE_DEFINE_DEFAULT(export, _)
447-
448-
// The "MSVC hack" style is used when FOO_EXPORT is defined
449-
// as __declspec(dllexport), which MSVC requires to be used at
450-
// definition sites instead.
451-
#define PROTOBUF_EXPORT_TEMPLATE_DECLARE_MSVC_HACK(export, _)
452-
#define PROTOBUF_EXPORT_TEMPLATE_DEFINE_MSVC_HACK(export, _) export
453-
454-
// PROTOBUF_EXPORT_TEMPLATE_STYLE is an internal helper macro that identifies
455-
// which export style needs to be used for the provided FOO_EXPORT macro
456-
// definition. "", "__attribute__(...)", and "__declspec(dllimport)" are
457-
// mapped to "DEFAULT"; while "__declspec(dllexport)" is mapped to "MSVC_HACK".
458-
//
459-
// It's implemented with token pasting to transform the __attribute__ and
460-
// __declspec annotations into macro invocations. E.g., if FOO_EXPORT is
461-
// defined as "__declspec(dllimport)", it undergoes the following sequence of
462-
// macro substitutions:
463-
// PROTOBUF_EXPORT_TEMPLATE_STYLE(FOO_EXPORT, )
464-
// PROTOBUF_EXPORT_TEMPLATE_STYLE_2(__declspec(dllimport), )
465-
// PROTOBUF_EXPORT_TEMPLATE_STYLE_3(
466-
// PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH__declspec(dllimport))
467-
// PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH__declspec(dllimport)
468-
// PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllimport
469-
// DEFAULT
470-
#define PROTOBUF_EXPORT_TEMPLATE_STYLE(export, _) \
471-
PROTOBUF_EXPORT_TEMPLATE_STYLE_2(export, )
472-
#define PROTOBUF_EXPORT_TEMPLATE_STYLE_2(export, _) \
473-
PROTOBUF_EXPORT_TEMPLATE_STYLE_3( \
474-
PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA##export)
475-
#define PROTOBUF_EXPORT_TEMPLATE_STYLE_3(style) style
476-
477-
// Internal helper macros for PROTOBUF_EXPORT_TEMPLATE_STYLE.
478-
//
479-
// XXX: C++ reserves all identifiers containing "__" for the implementation,
480-
// but "__attribute__" and "__declspec" already contain "__" and the token-paste
481-
// operator can only add characters; not remove them. To minimize the risk of
482-
// conflict with implementations, we include "foj3FJo5StF0OvIzl7oMxA" (a random
483-
// 128-bit string, encoded in Base64) in the macro name.
484-
#define PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA DEFAULT
485-
#define PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__attribute__(...) \
486-
DEFAULT
487-
#define PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__declspec(arg) \
488-
PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_##arg
489-
490-
// Internal helper macros for PROTOBUF_EXPORT_TEMPLATE_STYLE.
491-
#define PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllexport MSVC_HACK
492-
#define PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllimport DEFAULT
493-
494-
// Sanity checks.
495-
//
496-
// PROTOBUF_EXPORT_TEMPLATE_TEST uses the same macro invocation pattern as
497-
// PROTOBUF_EXPORT_TEMPLATE_DECLARE and PROTOBUF_EXPORT_TEMPLATE_DEFINE do to
498-
// check that they're working correctly. When they're working correctly, the
499-
// sequence of macro replacements should go something like:
500-
//
501-
// PROTOBUF_EXPORT_TEMPLATE_TEST(DEFAULT, __declspec(dllimport));
502-
//
503-
// static_assert(PROTOBUF_EXPORT_TEMPLATE_INVOKE(TEST_DEFAULT,
504-
// PROTOBUF_EXPORT_TEMPLATE_STYLE(__declspec(dllimport), ),
505-
// __declspec(dllimport)), "__declspec(dllimport)");
506-
//
507-
// static_assert(PROTOBUF_EXPORT_TEMPLATE_INVOKE(TEST_DEFAULT,
508-
// DEFAULT, __declspec(dllimport)), "__declspec(dllimport)");
509-
//
510-
// static_assert(PROTOBUF_EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT(
511-
// __declspec(dllimport)), "__declspec(dllimport)");
512-
//
513-
// static_assert(true, "__declspec(dllimport)");
514-
//
515-
// When they're not working correctly, a syntax error should occur instead.
516-
#define PROTOBUF_EXPORT_TEMPLATE_TEST(want, export) \
517-
static_assert(PROTOBUF_EXPORT_TEMPLATE_INVOKE( \
518-
TEST_##want, PROTOBUF_EXPORT_TEMPLATE_STYLE(export, ), \
519-
export), #export)
520-
#define PROTOBUF_EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT(...) true
521-
#define PROTOBUF_EXPORT_TEMPLATE_TEST_MSVC_HACK_MSVC_HACK(...) true
522-
523-
PROTOBUF_EXPORT_TEMPLATE_TEST(DEFAULT, );
524-
PROTOBUF_EXPORT_TEMPLATE_TEST(DEFAULT, __attribute__((visibility("default"))));
525-
PROTOBUF_EXPORT_TEMPLATE_TEST(MSVC_HACK, __declspec(dllexport));
526-
PROTOBUF_EXPORT_TEMPLATE_TEST(DEFAULT, __declspec(dllimport));
527-
528-
#undef PROTOBUF_EXPORT_TEMPLATE_TEST
529-
#undef PROTOBUF_EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT
530-
#undef PROTOBUF_EXPORT_TEMPLATE_TEST_MSVC_HACK_MSVC_HACK
531-
532382
// Windows declares several inconvenient macro names. We #undef them and then
533383
// restore them in port_undef.inc.
534384
#ifdef _MSC_VER

src/google/protobuf/port_undef.inc

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,6 @@
6868
#undef PROTOBUF_ASSUME
6969
#undef PROTOBUF_EXPORT_TEMPLATE_DECLARE
7070
#undef PROTOBUF_EXPORT_TEMPLATE_DEFINE
71-
#undef PROTOBUF_EXPORT_TEMPLATE_INVOKE
72-
#undef PROTOBUF_EXPORT_TEMPLATE_INVOKE_2
73-
#undef PROTOBUF_EXPORT_TEMPLATE_DECLARE_DEFAULT
74-
#undef PROTOBUF_EXPORT_TEMPLATE_DEFINE_DEFAULT
75-
#undef PROTOBUF_EXPORT_TEMPLATE_DECLARE_MSVC_HACK
76-
#undef PROTOBUF_EXPORT_TEMPLATE_DEFINE_MSVC_HACK
77-
#undef PROTOBUF_EXPORT_TEMPLATE_STYLE
78-
#undef PROTOBUF_EXPORT_TEMPLATE_STYLE_2
79-
#undef PROTOBUF_EXPORT_TEMPLATE_STYLE_3
80-
#undef PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA
81-
#undef PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__attribute__
82-
#undef PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__declspec
83-
#undef PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllexport
84-
#undef PROTOBUF_EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllimport
8571

8672
// Restore macro that may have been #undef'd in port_def.inc.
8773
#ifdef _MSC_VER

src/google/protobuf/repeated_field.cc

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -123,22 +123,14 @@ MessageLite* RepeatedPtrFieldBase::AddWeak(const MessageLite* prototype) {
123123
} // namespace internal
124124

125125

126-
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE(PROTOBUF_EXPORT)
127-
RepeatedField<bool>;
128-
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE(PROTOBUF_EXPORT)
129-
RepeatedField<int32>;
130-
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE(PROTOBUF_EXPORT)
131-
RepeatedField<uint32>;
132-
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE(PROTOBUF_EXPORT)
133-
RepeatedField<int64>;
134-
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE(PROTOBUF_EXPORT)
135-
RepeatedField<uint64>;
136-
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE(PROTOBUF_EXPORT)
137-
RepeatedField<float>;
138-
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE(PROTOBUF_EXPORT)
139-
RepeatedField<double>;
140-
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE(PROTOBUF_EXPORT)
141-
RepeatedPtrField<std::string>;
126+
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<bool>;
127+
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<int32>;
128+
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<uint32>;
129+
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<int64>;
130+
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<uint64>;
131+
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<float>;
132+
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedField<double>;
133+
template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedPtrField<std::string>;
142134

143135
} // namespace protobuf
144136
} // namespace google

src/google/protobuf/repeated_field.h

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,21 +2653,14 @@ UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
26532653
}
26542654

26552655
// Extern declarations of common instantiations to reduce libray bloat.
2656-
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE(PROTOBUF_EXPORT)
2657-
RepeatedField<bool>;
2658-
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE(PROTOBUF_EXPORT)
2659-
RepeatedField<int32>;
2660-
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE(PROTOBUF_EXPORT)
2661-
RepeatedField<uint32>;
2662-
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE(PROTOBUF_EXPORT)
2663-
RepeatedField<int64>;
2664-
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE(PROTOBUF_EXPORT)
2665-
RepeatedField<uint64>;
2666-
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE(PROTOBUF_EXPORT)
2667-
RepeatedField<float>;
2668-
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE(PROTOBUF_EXPORT)
2669-
RepeatedField<double>;
2670-
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE(PROTOBUF_EXPORT)
2656+
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<bool>;
2657+
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<int32>;
2658+
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<uint32>;
2659+
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<int64>;
2660+
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<uint64>;
2661+
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<float>;
2662+
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE RepeatedField<double>;
2663+
extern template class PROTOBUF_EXPORT_TEMPLATE_DECLARE
26712664
RepeatedPtrField<std::string>;
26722665

26732666
} // namespace protobuf

0 commit comments

Comments
 (0)