summaryrefslogtreecommitdiff
path: root/absl/flags/flag.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2020-05-20 00:23:37 -0700
committerGravatar Mark Barolak <mbar@google.com>2020-05-21 10:16:55 -0400
commitcf1a02e2dc5a1bc9d095f4c996306de448ca200f (patch)
tree74cd530ed421fb27a8774a5a11243bd81682ee18 /absl/flags/flag.h
parent768eb2ca2857342673fcd462792ce04b8bac3fa3 (diff)
Export of internal Abseil changes
-- 30e5e00a54cabc50118a3e1055826ea02a0d32e4 by Gennadiy Rozental <rogeeff@google.com>: Move flag help into flag_cold section. To facilitate this we set flag help not in a constructor, but during flag registration. This allows us to place flag name as static variable inside non constexpr lambda and invoke it immediately in FlagRegistrar argument location. PiperOrigin-RevId: 312432625 -- efd91b05152b68df648cff5ba38e9669a817c12f by Gennadiy Rozental <rogeeff@google.com>: Make CommandLineFlag public. PiperOrigin-RevId: 312404666 -- dc7f5fb73487766fa8a76d6b97d28116e5334445 by Mark Barolak <mbar@google.com>: Internal change. PiperOrigin-RevId: 312297164 GitOrigin-RevId: 30e5e00a54cabc50118a3e1055826ea02a0d32e4 Change-Id: Ic46ab011bb804645264572caddff0becba5f9170
Diffstat (limited to 'absl/flags/flag.h')
-rw-r--r--absl/flags/flag.h91
1 files changed, 42 insertions, 49 deletions
diff --git a/absl/flags/flag.h b/absl/flags/flag.h
index ca7d581f..f84853ea 100644
--- a/absl/flags/flag.h
+++ b/absl/flags/flag.h
@@ -37,7 +37,6 @@
#include "absl/base/config.h"
#include "absl/flags/config.h"
#include "absl/flags/declare.h"
-#include "absl/flags/internal/commandlineflag.h"
#include "absl/flags/internal/flag.h"
#include "absl/flags/internal/registry.h"
#include "absl/flags/marshalling.h"
@@ -265,27 +264,29 @@ ABSL_NAMESPACE_END
// -----------------------------------------------------------------------------
// ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_NAMES
+#if !defined(_MSC_VER) || defined(__clang__)
+#define ABSL_FLAG_IMPL_FLAG_PTR(flag) &flag
+#define ABSL_FLAG_IMPL_HELP_ARG(name) \
+ absl::flags_internal::HelpArg<AbslFlagHelpGenFor##name>( \
+ FLAGS_help_storage_##name)
+#define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) \
+ absl::flags_internal::DefaultArg<Type, AbslFlagDefaultGenFor##name>(0)
+#else
+#define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag.GetImpl()
+#define ABSL_FLAG_IMPL_HELP_ARG(name) &AbslFlagHelpGenFor##name::NonConst
+#define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) &AbslFlagDefaultGenFor##name::Gen
+#endif
#if ABSL_FLAGS_STRIP_NAMES
#define ABSL_FLAG_IMPL_FLAGNAME(txt) ""
#define ABSL_FLAG_IMPL_FILENAME() ""
-#if !defined(_MSC_VER) || defined(__clang__)
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
- absl::flags_internal::FlagRegistrar<T, false>(&flag)
-#else
-#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
- absl::flags_internal::FlagRegistrar<T, false>(flag.GetImpl())
-#endif
+ absl::flags_internal::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(flag))
#else
#define ABSL_FLAG_IMPL_FLAGNAME(txt) txt
#define ABSL_FLAG_IMPL_FILENAME() __FILE__
-#if !defined(_MSC_VER) || defined(__clang__)
-#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
- absl::flags_internal::FlagRegistrar<T, true>(&flag)
-#else
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
- absl::flags_internal::FlagRegistrar<T, true>(flag.GetImpl())
-#endif
+ absl::flags_internal::FlagRegistrar<T, true>(ABSL_FLAG_IMPL_FLAG_PTR(flag))
#endif
// ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_HELP
@@ -301,15 +302,24 @@ ABSL_NAMESPACE_END
// between the two via the call to HelpArg in absl::Flag instantiation below.
// If help message expression is constexpr evaluable compiler will optimize
// away this whole struct.
-#define ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, txt) \
- struct AbslFlagHelpGenFor##name { \
- template <typename T = void> \
- static constexpr const char* Const() { \
- return absl::flags_internal::HelpConstexprWrap( \
- ABSL_FLAG_IMPL_FLAGHELP(txt)); \
- } \
- static std::string NonConst() { return ABSL_FLAG_IMPL_FLAGHELP(txt); } \
- }
+// TODO(rogeeff): place these generated structs into local namespace and apply
+// ABSL_INTERNAL_UNIQUE_SHORT_NAME.
+// TODO(rogeeff): Apply __attribute__((nodebug)) to FLAGS_help_storage_##name
+#define ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, txt) \
+ struct AbslFlagHelpGenFor##name { \
+ /* The expression is run in the caller as part of the */ \
+ /* default value argument. That keeps temporaries alive */ \
+ /* long enough for NonConst to work correctly. */ \
+ static constexpr absl::string_view Value( \
+ absl::string_view v = ABSL_FLAG_IMPL_FLAGHELP(txt)) { \
+ return v; \
+ } \
+ static std::string NonConst() { return std::string(Value()); } \
+ }; \
+ constexpr auto FLAGS_help_storage_##name ABSL_INTERNAL_UNIQUE_SMALL_NAME() \
+ ABSL_ATTRIBUTE_SECTION_VARIABLE(flags_help_cold) = \
+ absl::flags_internal::HelpStringAsArray<AbslFlagHelpGenFor##name>( \
+ 0);
#define ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \
struct AbslFlagDefaultGenFor##name { \
@@ -317,40 +327,23 @@ ABSL_NAMESPACE_END
static void Gen(void* p) { \
new (p) Type(AbslFlagDefaultGenFor##name{}.value); \
} \
- }
+ };
// ABSL_FLAG_IMPL
//
// Note: Name of registrar object is not arbitrary. It is used to "grab"
// global name for FLAGS_no<flag_name> symbol, thus preventing the possibility
// of defining two flags with names foo and nofoo.
-#if !defined(_MSC_VER) || defined(__clang__)
-
-#define ABSL_FLAG_IMPL(Type, name, default_value, help) \
- namespace absl /* block flags in namespaces */ {} \
- ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value); \
- ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help); \
- ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \
- ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_FILENAME(), \
- absl::flags_internal::HelpArg<AbslFlagHelpGenFor##name>(0), \
- absl::flags_internal::DefaultArg<Type, AbslFlagDefaultGenFor##name>(0)}; \
- extern absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name; \
- absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name = \
- ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name)
-#else
-// MSVC version uses aggregate initialization. We also do not try to
-// optimize away help wrapper.
-#define ABSL_FLAG_IMPL(Type, name, default_value, help) \
- namespace absl /* block flags in namespaces */ {} \
- ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value); \
- ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help); \
- ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \
- ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_FILENAME(), \
- &AbslFlagHelpGenFor##name::NonConst, &AbslFlagDefaultGenFor##name::Gen}; \
- extern absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name; \
- absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name = \
+#define ABSL_FLAG_IMPL(Type, name, default_value, help) \
+ namespace absl /* block flags in namespaces */ {} \
+ ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \
+ ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \
+ ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \
+ ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_FILENAME(), \
+ ABSL_FLAG_IMPL_HELP_ARG(name), ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name)}; \
+ extern absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name; \
+ absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name = \
ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name)
-#endif
// ABSL_RETIRED_FLAG
//