Roll abseil_revision 768eb2ca28..33caf1097e

Change Log:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+log/768eb2ca28..33caf1097e
Full diff:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+/768eb2ca28..33caf1097e

Bug: None
Change-Id: I96ffb18e05362b3d56a7d0e17ae1e98a678cb97a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2218307
Reviewed-by: Mirko Bonadei <mbonadei@chromium.org>
Commit-Queue: Danil Chapovalov <danilchap@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#772305}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 45eee1b94d45eec9cbe79131ac2b3b3bfb4fc289
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index a5c9bc0..ccd409f 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -135,7 +135,6 @@
   "random/exponential_distribution.h"
   "random/gaussian_distribution.cc"
   "random/gaussian_distribution.h"
-  "random/internal/distributions.h"
   "random/internal/distribution_caller.h"
   "random/internal/fast_uniform_bits.h"
   "random/internal/fastmath.h"
diff --git a/README.chromium b/README.chromium
index 0d080bd..c1d332e 100644
--- a/README.chromium
+++ b/README.chromium
@@ -4,7 +4,7 @@
 License: Apache 2.0
 License File: LICENSE
 Version: 0
-Revision: 768eb2ca2857342673fcd462792ce04b8bac3fa3
+Revision: 33caf1097ecce4fe892567462fa8821d477854b4
 Security Critical: yes
 
 Description:
diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel
index 3681082..2d6f799 100644
--- a/absl/flags/BUILD.bazel
+++ b/absl/flags/BUILD.bazel
@@ -27,28 +27,18 @@
 licenses(["notice"])  # Apache 2.0
 
 cc_library(
-    name = "flag_internal",
-    srcs = [
-        "internal/flag.cc",
-    ],
+    name = "path_util",
     hdrs = [
-        "internal/flag.h",
+        "internal/path_util.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
-    visibility = ["//absl/base:__subpackages__"],
+    visibility = [
+        "//absl/flags:__pkg__",
+    ],
     deps = [
-        ":config",
-        ":handle",
-        ":marshalling",
-        ":registry",
-        "//absl/base",
         "//absl/base:config",
-        "//absl/base:core_headers",
-        "//absl/memory",
-        "//absl/meta:type_traits",
         "//absl/strings",
-        "//absl/synchronization",
     ],
 )
 
@@ -75,22 +65,6 @@
 )
 
 cc_library(
-    name = "path_util",
-    hdrs = [
-        "internal/path_util.h",
-    ],
-    copts = ABSL_DEFAULT_COPTS,
-    linkopts = ABSL_DEFAULT_LINKOPTS,
-    visibility = [
-        "//absl/flags:__pkg__",
-    ],
-    deps = [
-        "//absl/base:config",
-        "//absl/strings",
-    ],
-)
-
-cc_library(
     name = "config",
     srcs = [
         "usage_config.cc",
@@ -131,23 +105,33 @@
 )
 
 cc_library(
-    name = "handle",
-    srcs = [
-        "internal/commandlineflag.cc",
-    ],
+    name = "commandlineflag_internal",
     hdrs = [
         "internal/commandlineflag.h",
     ],
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
-    visibility = [
-        "//absl/flags:__pkg__",
-    ],
+    visibility = ["//visibility:private"],
     deps = [
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:fast_type_id",
         "//absl/strings",
+    ],
+)
+
+cc_library(
+    name = "commandlineflag",
+    srcs = [
+        "commandlineflag.cc",
+    ],
+    hdrs = [
+        "commandlineflag.h",
+    ],
+    copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    deps = [
+        ":commandlineflag_internal",
         "//absl/types:optional",
     ],
 )
@@ -165,7 +149,7 @@
     visibility = [
         "//absl/flags:__pkg__",
     ],
-    deps = [":handle"],
+    deps = [":commandlineflag"],
 )
 
 cc_library(
@@ -184,8 +168,9 @@
         "//absl/flags:__pkg__",
     ],
     deps = [
+        ":commandlineflag",
+        ":commandlineflag_internal",
         ":config",
-        ":handle",
         ":private_handle_accessor",
         "//absl/base:config",
         "//absl/base:core_headers",
@@ -196,6 +181,32 @@
 )
 
 cc_library(
+    name = "flag_internal",
+    srcs = [
+        "internal/flag.cc",
+    ],
+    hdrs = [
+        "internal/flag.h",
+    ],
+    copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    visibility = ["//absl/base:__subpackages__"],
+    deps = [
+        ":commandlineflag",
+        ":config",
+        ":marshalling",
+        ":registry",
+        "//absl/base",
+        "//absl/base:config",
+        "//absl/base:core_headers",
+        "//absl/memory",
+        "//absl/meta:type_traits",
+        "//absl/strings",
+        "//absl/synchronization",
+    ],
+)
+
+cc_library(
     name = "flag",
     srcs = [
         "flag.cc",
@@ -209,7 +220,6 @@
     deps = [
         ":config",
         ":flag_internal",
-        ":handle",
         ":marshalling",
         ":registry",
         "//absl/base",
@@ -233,10 +243,10 @@
         "//absl/flags:__pkg__",
     ],
     deps = [
+        ":commandlineflag",
         ":config",
         ":flag",
         ":flag_internal",
-        ":handle",
         ":path_util",
         ":private_handle_accessor",
         ":program_name",
@@ -276,10 +286,10 @@
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
+        ":commandlineflag",
         ":config",
         ":flag",
         ":flag_internal",
-        ":handle",
         ":private_handle_accessor",
         ":program_name",
         ":registry",
@@ -299,14 +309,14 @@
     name = "commandlineflag_test",
     size = "small",
     srcs = [
-        "internal/commandlineflag_test.cc",
+        "commandlineflag_test.cc",
     ],
     copts = ABSL_TEST_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
+        ":commandlineflag",
         ":config",
         ":flag",
-        ":handle",
         ":private_handle_accessor",
         ":registry",
         "//absl/memory",
@@ -342,7 +352,6 @@
         ":config",
         ":flag",
         ":flag_internal",
-        ":handle",
         ":registry",
         "//absl/base:core_headers",
         "//absl/base:malloc_internal",
@@ -384,20 +393,6 @@
 )
 
 cc_test(
-    name = "path_util_test",
-    size = "small",
-    srcs = [
-        "internal/path_util_test.cc",
-    ],
-    copts = ABSL_TEST_COPTS,
-    linkopts = ABSL_DEFAULT_LINKOPTS,
-    deps = [
-        ":path_util",
-        "@com_google_googletest//:gtest_main",
-    ],
-)
-
-cc_test(
     name = "parse_test",
     size = "small",
     srcs = [
@@ -418,6 +413,20 @@
 )
 
 cc_test(
+    name = "path_util_test",
+    size = "small",
+    srcs = [
+        "internal/path_util_test.cc",
+    ],
+    copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    deps = [
+        ":path_util",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
+
+cc_test(
     name = "program_name_test",
     size = "small",
     srcs = [
@@ -442,7 +451,6 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":flag",
-        ":handle",
         ":marshalling",
         ":registry",
         "//absl/memory",
diff --git a/absl/flags/BUILD.gn b/absl/flags/BUILD.gn
index 1efeaae..599c8aa 100644
--- a/absl/flags/BUILD.gn
+++ b/absl/flags/BUILD.gn
@@ -9,28 +9,15 @@
 # If this is a problem, feel free to remove "testonly" and use "assert_no_deps"
 # on the main Chrome binary.
 
-absl_source_set("flag_internal") {
+absl_source_set("path_util") {
   testonly = true
-  sources = [ "internal/flag.cc" ]
-  public = [ "internal/flag.h" ]
+  public = [ "internal/path_util.h" ]
   deps = [
-    ":config",
-    ":handle",
-    ":marshalling",
-    ":registry",
-    "//third_party/abseil-cpp/absl/base",
     "//third_party/abseil-cpp/absl/base:config",
-    "//third_party/abseil-cpp/absl/base:core_headers",
-    "//third_party/abseil-cpp/absl/memory",
-    "//third_party/abseil-cpp/absl/meta:type_traits",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/synchronization",
   ]
   visibility = []
-  visibility += [
-    ":*",
-    "//third_party/abseil-cpp/absl/base/*",
-  ]
+  visibility += [ ":*" ]
 }
 
 absl_source_set("program_name") {
@@ -48,17 +35,6 @@
   visibility += [ ":*" ]
 }
 
-absl_source_set("path_util") {
-  testonly = true
-  public = [ "internal/path_util.h" ]
-  deps = [
-    "//third_party/abseil-cpp/absl/base:config",
-    "//third_party/abseil-cpp/absl/strings",
-  ]
-  visibility = []
-  visibility += [ ":*" ]
-}
-
 absl_source_set("config") {
   testonly = true
   sources = [ "usage_config.cc" ]
@@ -89,27 +65,35 @@
   ]
 }
 
-absl_source_set("handle") {
+absl_source_set("commandlineflag_internal") {
   testonly = true
-  sources = [ "internal/commandlineflag.cc" ]
   public = [ "internal/commandlineflag.h" ]
   deps = [
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/base:fast_type_id",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:optional",
   ]
   visibility = []
   visibility += [ ":*" ]
 }
 
+absl_source_set("commandlineflag") {
+  testonly = true
+  sources = [ "commandlineflag.cc" ]
+  public = [ "commandlineflag.h" ]
+  deps = [
+    ":commandlineflag_internal",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
+}
+
 absl_source_set("private_handle_accessor") {
   testonly = true
   sources = [ "internal/private_handle_accessor.cc" ]
   public = [ "internal/private_handle_accessor.h" ]
   deps = [
-      ":handle",
+      ":commandlineflag",
   ]
   visibility = []
   visibility += [ ":*" ]
@@ -126,8 +110,9 @@
     "internal/type_erased.h",
   ]
   deps = [
+    ":commandlineflag",
+    ":commandlineflag_internal",
     ":config",
-    ":handle",
     ":private_handle_accessor",
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
@@ -139,6 +124,30 @@
   visibility += [ ":*" ]
 }
 
+absl_source_set("flag_internal") {
+  testonly = true
+  sources = [ "internal/flag.cc" ]
+  public = [ "internal/flag.h" ]
+  deps = [
+    ":commandlineflag",
+    ":config",
+    ":marshalling",
+    ":registry",
+    "//third_party/abseil-cpp/absl/base",
+    "//third_party/abseil-cpp/absl/base:config",
+    "//third_party/abseil-cpp/absl/base:core_headers",
+    "//third_party/abseil-cpp/absl/memory",
+    "//third_party/abseil-cpp/absl/meta:type_traits",
+    "//third_party/abseil-cpp/absl/strings",
+    "//third_party/abseil-cpp/absl/synchronization",
+  ]
+  visibility = []
+  visibility += [
+    ":*",
+    "//third_party/abseil-cpp/absl/base/*",
+  ]
+}
+
 absl_source_set("flag") {
   testonly = true
   sources = [ "flag.cc" ]
@@ -149,7 +158,6 @@
   deps = [
     ":config",
     ":flag_internal",
-    ":handle",
     ":marshalling",
     ":registry",
     "//third_party/abseil-cpp/absl/base",
@@ -164,10 +172,10 @@
   sources = [ "internal/usage.cc" ]
   public = [ "internal/usage.h" ]
   deps = [
+    ":commandlineflag",
     ":config",
     ":flag",
     ":flag_internal",
-    ":handle",
     ":path_util",
     ":private_handle_accessor",
     ":program_name",
@@ -201,10 +209,10 @@
     "parse.h",
   ]
   deps = [
+    ":commandlineflag",
     ":config",
     ":flag",
     ":flag_internal",
-    ":handle",
     ":private_handle_accessor",
     ":program_name",
     ":registry",
diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt
index e6b17c9..6ecf3b4 100644
--- a/absl/flags/CMakeLists.txt
+++ b/absl/flags/CMakeLists.txt
@@ -17,24 +17,16 @@
 # Internal-only target, do not depend on directly.
 absl_cc_library(
   NAME
-    flags_internal
-  SRCS
-    "internal/flag.cc"
+    flags_path_util
   HDRS
-    "internal/flag.h"
+    "internal/path_util.h"
   COPTS
     ${ABSL_DEFAULT_COPTS}
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
-    absl::base
     absl::config
-    absl::flags_config
-    absl::flags_handle
-    absl::flags_marshalling
-    absl::flags_registry
-    absl::synchronization
-    absl::meta
+    absl::strings
   PUBLIC
 )
 
@@ -59,22 +51,6 @@
   PUBLIC
 )
 
-# Internal-only target, do not depend on directly.
-absl_cc_library(
-  NAME
-    flags_path_util
-  HDRS
-    "internal/path_util.h"
-  COPTS
-    ${ABSL_DEFAULT_COPTS}
-  LINKOPTS
-    ${ABSL_DEFAULT_LINKOPTS}
-  DEPS
-    absl::config
-    absl::strings
-  PUBLIC
-)
-
 absl_cc_library(
   NAME
     flags_config
@@ -118,9 +94,7 @@
 # Internal-only target, do not depend on directly.
 absl_cc_library(
   NAME
-    flags_handle
-  SRCS
-    "internal/commandlineflag.cc"
+    flags_commandlineflag_internal
   HDRS
     "internal/commandlineflag.h"
   COPTS
@@ -129,12 +103,25 @@
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
     absl::config
-    absl::fast_type_id
     absl::core_headers
-    absl::optional
-    absl::raw_logging_internal
+    absl::fast_type_id
     absl::strings
-    absl::synchronization
+)
+
+absl_cc_library(
+  NAME
+    flags_commandlineflag
+  SRCS
+    "commandlineflag.cc"
+  HDRS
+    "commandlineflag.h"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
+  LINKOPTS
+    ${ABSL_DEFAULT_LINKOPTS}
+  DEPS
+    absl::flags_commandlineflag_internal
+    absl::optional
 )
 
 # Internal-only target, do not depend on directly.
@@ -150,7 +137,7 @@
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
-    absl::flags_handle
+    absl::flags_commandlineflag
 )
 
 # Internal-only target, do not depend on directly.
@@ -169,8 +156,8 @@
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
     absl::config
+    absl::flags_commandlineflag
     absl::flags_config
-    absl::flags_handle
     absl::flags_private_handle_accessor
     absl::core_headers
     absl::raw_logging_internal
@@ -178,6 +165,29 @@
     absl::synchronization
 )
 
+# Internal-only target, do not depend on directly.
+absl_cc_library(
+  NAME
+    flags_internal
+  SRCS
+    "internal/flag.cc"
+  HDRS
+    "internal/flag.h"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
+  LINKOPTS
+    ${ABSL_DEFAULT_LINKOPTS}
+  DEPS
+    absl::base
+    absl::config
+    absl::flags_config
+    absl::flags_marshalling
+    absl::flags_registry
+    absl::synchronization
+    absl::meta
+  PUBLIC
+)
+
 absl_cc_library(
   NAME
     flags
@@ -192,8 +202,8 @@
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
     absl::config
+    absl::flags_commandlineflag
     absl::flags_config
-    absl::flags_handle
     absl::flags_internal
     absl::flags_marshalling
     absl::flags_registry
@@ -218,10 +228,10 @@
     absl::config
     absl::flags_config
     absl::flags
-    absl::flags_handle
-    absl::flags_private_handle_accessor
+    absl::flags_commandlineflag
     absl::flags_internal
     absl::flags_path_util
+    absl::flags_private_handle_accessor
     absl::flags_program_name
     absl::flags_registry
     absl::strings
@@ -264,9 +274,9 @@
     absl::core_headers
     absl::flags_config
     absl::flags
-    absl::flags_handle
-    absl::flags_private_handle_accessor
+    absl::flags_commandlineflag
     absl::flags_internal
+    absl::flags_private_handle_accessor
     absl::flags_program_name
     absl::flags_registry
     absl::flags_usage
@@ -281,13 +291,13 @@
   NAME
     flags_commandlineflag_test
   SRCS
-    "internal/commandlineflag_test.cc"
+    "commandlineflag_test.cc"
   COPTS
     ${ABSL_TEST_COPTS}
   DEPS
     absl::flags
+    absl::flags_commandlineflag
     absl::flags_config
-    absl::flags_handle
     absl::flags_private_handle_accessor
     absl::flags_registry
     absl::memory
@@ -319,7 +329,6 @@
     absl::core_headers
     absl::flags
     absl::flags_config
-    absl::flags_handle
     absl::flags_internal
     absl::flags_registry
     absl::strings
@@ -391,7 +400,6 @@
     ${ABSL_TEST_COPTS}
   DEPS
     absl::flags
-    absl::flags_handle
     absl::flags_marshalling
     absl::flags_registry
     absl::memory
diff --git a/absl/flags/internal/commandlineflag.cc b/absl/flags/commandlineflag.cc
similarity index 89%
rename from absl/flags/internal/commandlineflag.cc
rename to absl/flags/commandlineflag.cc
index 8411243..cea5723 100644
--- a/absl/flags/internal/commandlineflag.cc
+++ b/absl/flags/commandlineflag.cc
@@ -13,21 +13,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/flags/internal/commandlineflag.h"
+#include "absl/flags/commandlineflag.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
-namespace flags_internal {
-
-FlagStateInterface::~FlagStateInterface() {}
 
 bool CommandLineFlag::IsRetired() const { return false; }
-
 bool CommandLineFlag::ParseFrom(absl::string_view value, std::string* error) {
   return ParseFrom(value, flags_internal::SET_FLAGS_VALUE,
-                   flags_internal::kProgrammaticChange, error);
+                   flags_internal::kProgrammaticChange, *error);
 }
 
+namespace flags_internal {
+FlagStateInterface::~FlagStateInterface() {}
 }  // namespace flags_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/flags/commandlineflag.h b/absl/flags/commandlineflag.h
new file mode 100644
index 0000000..43055d0
--- /dev/null
+++ b/absl/flags/commandlineflag.h
@@ -0,0 +1,190 @@
+//
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: commandlineflag.h
+// -----------------------------------------------------------------------------
+//
+// This header file defines the `CommandLineFlag`, which acts as a type-erased
+// handle for accessing metadata about the Abseil Flag in question.
+//
+// Because an actual Abseil flag is of an unspecified type, you should not
+// manipulate or interact directly with objects of that type. Instead, use the
+// CommandLineFlag type as an intermediary.
+#ifndef ABSL_FLAGS_COMMANDLINEFLAG_H_
+#define ABSL_FLAGS_COMMANDLINEFLAG_H_
+
+#include "absl/flags/internal/commandlineflag.h"
+#include "absl/types/optional.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace flags_internal {
+class PrivateHandleAccessor;
+}  // namespace flags_internal
+
+// CommandLineFlag
+//
+// This type acts as a type-erased handle for an instance of an Abseil Flag and
+// holds reflection information pertaining to that flag. Use CommandLineFlag to
+// access a flag's name, location, help string etc.
+//
+// To obtain an absl::CommandLineFlag, invoke `absl::FindCommandLineFlag()`
+// passing it the flag name string.
+//
+// Example:
+//
+//   // Obtain reflection handle for a flag named "flagname".
+//   const absl::CommandLineFlag* my_flag_data =
+//        absl::FindCommandLineFlag("flagname");
+//
+//   // Now you can get flag info from that reflection handle.
+//   std::string flag_location = my_flag_data->Filename();
+//   ...
+class CommandLineFlag {
+ public:
+  constexpr CommandLineFlag() = default;
+
+  // Not copyable/assignable.
+  CommandLineFlag(const CommandLineFlag&) = delete;
+  CommandLineFlag& operator=(const CommandLineFlag&) = delete;
+
+  // absl::CommandLineFlag::IsOfType()
+  //
+  // Return true iff flag has type T.
+  template <typename T>
+  inline bool IsOfType() const {
+    return TypeId() == base_internal::FastTypeId<T>();
+  }
+
+  // absl::CommandLineFlag::TryGet()
+  //
+  // Attempts to retrieve the flag value. Returns value on success,
+  // absl::nullopt otherwise.
+  template <typename T>
+  absl::optional<T> TryGet() const {
+    if (IsRetired() || !IsOfType<T>()) {
+      return absl::nullopt;
+    }
+
+    // Implementation notes:
+    //
+    // We are wrapping a union around the value of `T` to serve three purposes:
+    //
+    //  1. `U.value` has correct size and alignment for a value of type `T`
+    //  2. The `U.value` constructor is not invoked since U's constructor does
+    //     not do it explicitly.
+    //  3. The `U.value` destructor is invoked since U's destructor does it
+    //     explicitly. This makes `U` a kind of RAII wrapper around non default
+    //     constructible value of T, which is destructed when we leave the
+    //     scope. We do need to destroy U.value, which is constructed by
+    //     CommandLineFlag::Read even though we left it in a moved-from state
+    //     after std::move.
+    //
+    // All of this serves to avoid requiring `T` being default constructible.
+    union U {
+      T value;
+      U() {}
+      ~U() { value.~T(); }
+    };
+    U u;
+
+    Read(&u.value);
+    return std::move(u.value);
+  }
+
+  // absl::CommandLineFlag::Name()
+  //
+  // Returns name of this flag.
+  virtual absl::string_view Name() const = 0;
+
+  // absl::CommandLineFlag::Filename()
+  //
+  // Returns name of the file where this flag is defined.
+  virtual std::string Filename() const = 0;
+
+  // absl::CommandLineFlag::Help()
+  //
+  // Returns help message associated with this flag.
+  virtual std::string Help() const = 0;
+
+  // absl::CommandLineFlag::IsRetired()
+  //
+  // Returns true iff this object corresponds to retired flag.
+  virtual bool IsRetired() const;
+
+  // absl::CommandLineFlag::DefaultValue()
+  //
+  // Returns the default value for this flag.
+  virtual std::string DefaultValue() const = 0;
+
+  // absl::CommandLineFlag::CurrentValue()
+  //
+  // Returns the current value for this flag.
+  virtual std::string CurrentValue() const = 0;
+
+  // absl::CommandLineFlag::ParseFrom()
+  //
+  // Sets the value of the flag based on specified string `value`. If the flag
+  // was successfully set to new value, it returns true. Otherwise, sets `error`
+  // to indicate the error, leaves the flag unchanged, and returns false.
+  bool ParseFrom(absl::string_view value, std::string* error);
+
+ protected:
+  ~CommandLineFlag() = default;
+
+ private:
+  friend class flags_internal::PrivateHandleAccessor;
+
+  // Sets the value of the flag based on specified string `value`. If the flag
+  // was successfully set to new value, it returns true. Otherwise, sets `error`
+  // to indicate the error, leaves the flag unchanged, and returns false. There
+  // are three ways to set the flag's value:
+  //  * Update the current flag value
+  //  * Update the flag's default value
+  //  * Update the current flag value if it was never set before
+  // The mode is selected based on `set_mode` parameter.
+  virtual bool ParseFrom(absl::string_view value,
+                         flags_internal::FlagSettingMode set_mode,
+                         flags_internal::ValueSource source,
+                         std::string& error) = 0;
+
+  // Returns id of the flag's value type.
+  virtual flags_internal::FlagFastTypeId TypeId() const = 0;
+
+  // Interface to save flag to some persistent state. Returns current flag state
+  // or nullptr if flag does not support saving and restoring a state.
+  virtual std::unique_ptr<flags_internal::FlagStateInterface> SaveState() = 0;
+
+  // Copy-construct a new value of the flag's type in a memory referenced by
+  // the dst based on the current flag's value.
+  virtual void Read(void* dst) const = 0;
+
+  // To be deleted. Used to return true if flag's current value originated from
+  // command line.
+  virtual bool IsSpecifiedOnCommandLine() const = 0;
+
+  // Validates supplied value usign validator or parseflag routine
+  virtual bool ValidateInputValue(absl::string_view value) const = 0;
+
+  // Checks that flags default value can be converted to string and back to the
+  // flag's value type.
+  virtual void CheckDefaultValueParsingRoundtrip() const = 0;
+};
+
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_FLAGS_COMMANDLINEFLAG_H_
diff --git a/absl/flags/internal/commandlineflag_test.cc b/absl/flags/commandlineflag_test.cc
similarity index 79%
rename from absl/flags/internal/commandlineflag_test.cc
rename to absl/flags/commandlineflag_test.cc
index 0b5aea3..4b9718e 100644
--- a/absl/flags/internal/commandlineflag_test.cc
+++ b/absl/flags/commandlineflag_test.cc
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/flags/internal/commandlineflag.h"
+#include "absl/flags/commandlineflag.h"
 
 #include <memory>
 #include <string>
@@ -70,9 +70,10 @@
   EXPECT_EQ(flag_01->Help(), "int_flag help");
   EXPECT_TRUE(!flag_01->IsRetired());
   EXPECT_TRUE(flag_01->IsOfType<int>());
-  EXPECT_TRUE(
-      absl::EndsWith(flag_01->Filename(),
-                     "absl/flags/internal/commandlineflag_test.cc"))
+  EXPECT_TRUE(!flag_01->IsOfType<bool>());
+  EXPECT_TRUE(!flag_01->IsOfType<std::string>());
+  EXPECT_TRUE(absl::EndsWith(flag_01->Filename(),
+                             "absl/flags/commandlineflag_test.cc"))
       << flag_01->Filename();
 
   auto* flag_02 = flags::FindCommandLineFlag("string_flag");
@@ -82,9 +83,10 @@
   EXPECT_EQ(flag_02->Help(), "string_flag help");
   EXPECT_TRUE(!flag_02->IsRetired());
   EXPECT_TRUE(flag_02->IsOfType<std::string>());
-  EXPECT_TRUE(
-      absl::EndsWith(flag_02->Filename(),
-                     "absl/flags/internal/commandlineflag_test.cc"))
+  EXPECT_TRUE(!flag_02->IsOfType<bool>());
+  EXPECT_TRUE(!flag_02->IsOfType<int>());
+  EXPECT_TRUE(absl::EndsWith(flag_02->Filename(),
+                             "absl/flags/commandlineflag_test.cc"))
       << flag_02->Filename();
 
   auto* flag_03 = flags::FindRetiredFlag("bool_retired_flag");
@@ -94,6 +96,8 @@
   EXPECT_EQ(flag_03->Help(), "");
   EXPECT_TRUE(flag_03->IsRetired());
   EXPECT_TRUE(flag_03->IsOfType<bool>());
+  EXPECT_TRUE(!flag_03->IsOfType<int>());
+  EXPECT_TRUE(!flag_03->IsOfType<std::string>());
   EXPECT_EQ(flag_03->Filename(), "RETIRED");
 }
 
@@ -125,57 +129,57 @@
       flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "11", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err));
+      *flag_01, "11", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err));
   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11);
   EXPECT_FALSE(
       flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "-123", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
+      *flag_01, "-123", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
+      err));
   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123);
   EXPECT_FALSE(
       flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
 
   EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
+      *flag_01, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
+      err));
   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123);
   EXPECT_EQ(err, "Illegal value 'xyz' specified for flag 'int_flag'");
   EXPECT_FALSE(
       flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
 
   EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "A1", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err));
+      *flag_01, "A1", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err));
   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123);
   EXPECT_EQ(err, "Illegal value 'A1' specified for flag 'int_flag'");
   EXPECT_FALSE(
       flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "0x10", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
+      *flag_01, "0x10", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
+      err));
   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 16);
   EXPECT_FALSE(
       flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "011", flags::SET_FLAGS_VALUE, flags::kCommandLine, &err));
+      *flag_01, "011", flags::SET_FLAGS_VALUE, flags::kCommandLine, err));
   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11);
   EXPECT_TRUE(flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
 
   EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err));
+      *flag_01, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err));
   EXPECT_EQ(err, "Illegal value '' specified for flag 'int_flag'");
 
   auto* flag_02 = flags::FindCommandLineFlag("string_flag");
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_02, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
+      *flag_02, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
+      err));
   EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "xyz");
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_02, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err));
+      *flag_02, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err));
   EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "");
 }
 
@@ -187,15 +191,15 @@
   auto* flag_01 = flags::FindCommandLineFlag("int_flag");
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "111", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
-      &err));
+      *flag_01, "111", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
+      err));
   EXPECT_EQ(flag_01->DefaultValue(), "111");
 
   auto* flag_02 = flags::FindCommandLineFlag("string_flag");
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_02, "abc", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
-      &err));
+      *flag_02, "abc", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
+      err));
   EXPECT_EQ(flag_02->DefaultValue(), "abc");
 }
 
@@ -207,25 +211,25 @@
   auto* flag_01 = flags::FindCommandLineFlag("int_flag");
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "22", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
-      &err))
+      *flag_01, "22", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
+      err))
       << err;
   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22);
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
-      &err));
+      *flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
+      err));
   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22);
   // EXPECT_EQ(err, "ERROR: int_flag is already set to 22");
 
   // Reset back to default value
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "201", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
-      &err));
+      *flag_01, "201", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
+      err));
 
   EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
-      flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
-      &err));
+      *flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
+      err));
   EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 201);
   // EXPECT_EQ(err, "ERROR: int_flag is already set to 201");
 }
diff --git a/absl/flags/flag.cc b/absl/flags/flag.cc
index f7a457b..531df12 100644
--- a/absl/flags/flag.cc
+++ b/absl/flags/flag.cc
@@ -16,8 +16,6 @@
 #include "absl/flags/flag.h"
 
 #include "absl/base/config.h"
-#include "absl/flags/internal/commandlineflag.h"
-#include "absl/flags/internal/flag.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
diff --git a/absl/flags/flag.h b/absl/flags/flag.h
index ca7d581..dd36e6c 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"
@@ -111,12 +110,12 @@
         impl_(nullptr) {}
 #endif
 
-  flags_internal::Flag<T>* GetImpl() const {
+  flags_internal::Flag<T>& GetImpl() const {
     if (!inited_.load(std::memory_order_acquire)) {
       absl::MutexLock l(flags_internal::GetGlobalConstructionGuard());
 
       if (inited_.load(std::memory_order_acquire)) {
-        return impl_;
+        return *impl_;
       }
 
       impl_ = new flags_internal::Flag<T>(
@@ -128,28 +127,28 @@
       inited_.store(true, std::memory_order_release);
     }
 
-    return impl_;
+    return *impl_;
   }
 
   // Public methods of `absl::Flag<T>` are NOT part of the Abseil Flags API.
   // See https://abseil.io/docs/cpp/guides/flags
-  bool IsRetired() const { return GetImpl()->IsRetired(); }
-  absl::string_view Name() const { return GetImpl()->Name(); }
-  std::string Help() const { return GetImpl()->Help(); }
-  bool IsModified() const { return GetImpl()->IsModified(); }
+  bool IsRetired() const { return GetImpl().IsRetired(); }
+  absl::string_view Name() const { return GetImpl().Name(); }
+  std::string Help() const { return GetImpl().Help(); }
+  bool IsModified() const { return GetImpl().IsModified(); }
   bool IsSpecifiedOnCommandLine() const {
-    return GetImpl()->IsSpecifiedOnCommandLine();
+    return GetImpl().IsSpecifiedOnCommandLine();
   }
-  std::string Filename() const { return GetImpl()->Filename(); }
-  std::string DefaultValue() const { return GetImpl()->DefaultValue(); }
-  std::string CurrentValue() const { return GetImpl()->CurrentValue(); }
+  std::string Filename() const { return GetImpl().Filename(); }
+  std::string DefaultValue() const { return GetImpl().DefaultValue(); }
+  std::string CurrentValue() const { return GetImpl().CurrentValue(); }
   template <typename U>
   inline bool IsOfType() const {
-    return GetImpl()->template IsOfType<U>();
+    return GetImpl().template IsOfType<U>();
   }
-  T Get() const { return GetImpl()->Get(); }
-  void Set(const T& v) { GetImpl()->Set(v); }
-  void InvokeCallback() { GetImpl()->InvokeCallback(); }
+  T Get() const { return GetImpl().Get(); }
+  void Set(const T& v) { GetImpl().Set(v); }
+  void InvokeCallback() { GetImpl().InvokeCallback(); }
 
   // The data members are logically private, but they need to be public for
   // this to be an aggregate type.
@@ -265,27 +264,29 @@
 // -----------------------------------------------------------------------------
 
 // 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 @@
 // 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 @@
     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 =                    \
+#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)
-#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 =                    \
-      ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name)
-#endif
 
 // ABSL_RETIRED_FLAG
 //
diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc
index 416a31e..58a0799 100644
--- a/absl/flags/flag_test.cc
+++ b/absl/flags/flag_test.cc
@@ -26,7 +26,6 @@
 #include "absl/base/attributes.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/usage_config.h"
@@ -151,21 +150,21 @@
 DEFINE_CONSTRUCTED_FLAG(UDT, &TestMakeDflt<UDT>, kGenFunc);
 
 template <typename T>
-bool TestConstructionFor(const flags::Flag<T>& f1, flags::Flag<T>* f2) {
+bool TestConstructionFor(const flags::Flag<T>& f1, flags::Flag<T>& f2) {
   EXPECT_EQ(f1.Name(), "f1");
   EXPECT_EQ(f1.Help(), "literal help");
   EXPECT_EQ(f1.Filename(), "file");
 
   flags::FlagRegistrar<T, false>(f2).OnUpdate(TestCallback);
 
-  EXPECT_EQ(f2->Name(), "f2");
-  EXPECT_EQ(f2->Help(), "dynamic help");
-  EXPECT_EQ(f2->Filename(), "file");
+  EXPECT_EQ(f2.Name(), "f2");
+  EXPECT_EQ(f2.Help(), "dynamic help");
+  EXPECT_EQ(f2.Filename(), "file");
 
   return true;
 }
 
-#define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, &f2##T);
+#define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, f2##T);
 
 TEST_F(FlagTest, TestConstruction) {
   TEST_CONSTRUCTED_FLAG(bool);
diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h
index fa05020..3c14978 100644
--- a/absl/flags/internal/commandlineflag.h
+++ b/absl/flags/internal/commandlineflag.h
@@ -23,7 +23,6 @@
 #include "absl/base/internal/fast_type_id.h"
 #include "absl/base/macros.h"
 #include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -67,117 +66,6 @@
   virtual void Restore() const = 0;
 };
 
-// Holds all information for a flag.
-class CommandLineFlag {
- public:
-  constexpr CommandLineFlag() = default;
-
-  // Not copyable/assignable.
-  CommandLineFlag(const CommandLineFlag&) = delete;
-  CommandLineFlag& operator=(const CommandLineFlag&) = delete;
-
-  // Non-polymorphic access methods.
-
-  // Return true iff flag has type T.
-  template <typename T>
-  inline bool IsOfType() const {
-    return TypeId() == base_internal::FastTypeId<T>();
-  }
-
-  // Attempts to retrieve the flag value. Returns value on success,
-  // absl::nullopt otherwise.
-  template <typename T>
-  absl::optional<T> TryGet() const {
-    if (IsRetired() || !IsOfType<T>()) {
-      return absl::nullopt;
-    }
-
-    // Implementation notes:
-    //
-    // We are wrapping a union around the value of `T` to serve three purposes:
-    //
-    //  1. `U.value` has correct size and alignment for a value of type `T`
-    //  2. The `U.value` constructor is not invoked since U's constructor does
-    //     not do it explicitly.
-    //  3. The `U.value` destructor is invoked since U's destructor does it
-    //     explicitly. This makes `U` a kind of RAII wrapper around non default
-    //     constructible value of T, which is destructed when we leave the
-    //     scope. We do need to destroy U.value, which is constructed by
-    //     CommandLineFlag::Read even though we left it in a moved-from state
-    //     after std::move.
-    //
-    // All of this serves to avoid requiring `T` being default constructible.
-    union U {
-      T value;
-      U() {}
-      ~U() { value.~T(); }
-    };
-    U u;
-
-    Read(&u.value);
-    return std::move(u.value);
-  }
-
-  // Polymorphic access methods
-
-  // Returns name of this flag.
-  virtual absl::string_view Name() const = 0;
-  // Returns name of the file where this flag is defined.
-  virtual std::string Filename() const = 0;
-  // Returns help message associated with this flag.
-  virtual std::string Help() const = 0;
-  // Returns true iff this object corresponds to retired flag.
-  virtual bool IsRetired() const;
-  virtual std::string DefaultValue() const = 0;
-  virtual std::string CurrentValue() const = 0;
-
-  // Sets the value of the flag based on specified string `value`. If the flag
-  // was successfully set to new value, it returns true. Otherwise, sets `error`
-  // to indicate the error, leaves the flag unchanged, and returns false.
-  bool ParseFrom(absl::string_view value, std::string* error);
-
- protected:
-  ~CommandLineFlag() = default;
-
- private:
-  friend class PrivateHandleAccessor;
-
-  // Sets the value of the flag based on specified string `value`. If the flag
-  // was successfully set to new value, it returns true. Otherwise, sets `error`
-  // to indicate the error, leaves the flag unchanged, and returns false. There
-  // are three ways to set the flag's value:
-  //  * Update the current flag value
-  //  * Update the flag's default value
-  //  * Update the current flag value if it was never set before
-  // The mode is selected based on `set_mode` parameter.
-  virtual bool ParseFrom(absl::string_view value,
-                         flags_internal::FlagSettingMode set_mode,
-                         flags_internal::ValueSource source,
-                         std::string* error) = 0;
-
-  // Returns id of the flag's value type.
-  virtual FlagFastTypeId TypeId() const = 0;
-
-  // Interface to save flag to some persistent state. Returns current flag state
-  // or nullptr if flag does not support saving and restoring a state.
-  virtual std::unique_ptr<FlagStateInterface> SaveState() = 0;
-
-  // Copy-construct a new value of the flag's type in a memory referenced by
-  // the dst based on the current flag's value.
-  virtual void Read(void* dst) const = 0;
-
-  // To be deleted. Used to return true if flag's current value originated from
-  // command line.
-  virtual bool IsSpecifiedOnCommandLine() const = 0;
-
-  // Validates supplied value usign validator or parseflag routine
-  virtual bool ValidateInputValue(absl::string_view value) const = 0;
-
-  // Checks that flags default value can be converted to string and back to the
-  // flag's value type.
-  virtual void CheckDefaultValueParsingRoundtrip() const = 0;
-};
-
 }  // namespace flags_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc
index 96c026d..ee97424 100644
--- a/absl/flags/internal/flag.cc
+++ b/absl/flags/internal/flag.cc
@@ -29,7 +29,6 @@
 #include "absl/base/config.h"
 #include "absl/base/const_init.h"
 #include "absl/base/optimization.h"
-#include "absl/flags/internal/commandlineflag.h"
 #include "absl/flags/usage_config.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
@@ -63,14 +62,14 @@
 // need to acquire these locks themselves.
 class MutexRelock {
  public:
-  explicit MutexRelock(absl::Mutex* mu) : mu_(mu) { mu_->Unlock(); }
-  ~MutexRelock() { mu_->Lock(); }
+  explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.Unlock(); }
+  ~MutexRelock() { mu_.Lock(); }
 
   MutexRelock(const MutexRelock&) = delete;
   MutexRelock& operator=(const MutexRelock&) = delete;
 
  private:
-  absl::Mutex* mu_;
+  absl::Mutex& mu_;
 };
 
 }  // namespace
@@ -83,7 +82,7 @@
 class FlagState : public flags_internal::FlagStateInterface {
  public:
   template <typename V>
-  FlagState(FlagImpl* flag_impl, const V& v, bool modified,
+  FlagState(FlagImpl& flag_impl, const V& v, bool modified,
             bool on_command_line, int64_t counter)
       : flag_impl_(flag_impl),
         value_(v),
@@ -92,9 +91,9 @@
         counter_(counter) {}
 
   ~FlagState() override {
-    if (flag_impl_->ValueStorageKind() != FlagValueStorageKind::kAlignedBuffer)
+    if (flag_impl_.ValueStorageKind() != FlagValueStorageKind::kAlignedBuffer)
       return;
-    flags_internal::Delete(flag_impl_->op_, value_.heap_allocated);
+    flags_internal::Delete(flag_impl_.op_, value_.heap_allocated);
   }
 
  private:
@@ -102,15 +101,15 @@
 
   // Restores the flag to the saved state.
   void Restore() const override {
-    if (!flag_impl_->RestoreState(*this)) return;
+    if (!flag_impl_.RestoreState(*this)) return;
 
-    ABSL_INTERNAL_LOG(
-        INFO, absl::StrCat("Restore saved value of ", flag_impl_->Name(),
-                           " to: ", flag_impl_->CurrentValue()));
+    ABSL_INTERNAL_LOG(INFO,
+                      absl::StrCat("Restore saved value of ", flag_impl_.Name(),
+                                   " to: ", flag_impl_.CurrentValue()));
   }
 
   // Flag and saved flag data.
-  FlagImpl* flag_impl_;
+  FlagImpl& flag_impl_;
   union SavedValue {
     explicit SavedValue(void* v) : heap_allocated(v) {}
     explicit SavedValue(int64_t v) : one_word(v) {}
@@ -327,7 +326,7 @@
   // and it also can be different by the time the callback invocation is
   // completed. Requires that *primary_lock be held in exclusive mode; it may be
   // released and reacquired by the implementation.
-  MutexRelock relock(DataGuard());
+  MutexRelock relock(*DataGuard());
   absl::MutexLock lock(&callback_->guard);
   cb();
 }
@@ -340,17 +339,17 @@
   switch (ValueStorageKind()) {
     case FlagValueStorageKind::kAlignedBuffer: {
       return absl::make_unique<FlagState>(
-          this, flags_internal::Clone(op_, AlignedBufferValue()), modified,
+          *this, flags_internal::Clone(op_, AlignedBufferValue()), modified,
           on_command_line, counter_);
     }
     case FlagValueStorageKind::kOneWordAtomic: {
       return absl::make_unique<FlagState>(
-          this, OneWordValue().load(std::memory_order_acquire), modified,
+          *this, OneWordValue().load(std::memory_order_acquire), modified,
           on_command_line, counter_);
     }
     case FlagValueStorageKind::kTwoWordsAtomic: {
       return absl::make_unique<FlagState>(
-          this, TwoWordsValue().load(std::memory_order_acquire), modified,
+          *this, TwoWordsValue().load(std::memory_order_acquire), modified,
           on_command_line, counter_);
     }
   }
@@ -411,14 +410,14 @@
 // parsed value. In case if any error is encountered in either step, the error
 // message is stored in 'err'
 std::unique_ptr<void, DynValueDeleter> FlagImpl::TryParse(
-    absl::string_view value, std::string* err) const {
+    absl::string_view value, std::string& err) const {
   std::unique_ptr<void, DynValueDeleter> tentative_value = MakeInitValue();
 
   std::string parse_err;
   if (!flags_internal::Parse(op_, value, tentative_value.get(), &parse_err)) {
     absl::string_view err_sep = parse_err.empty() ? "" : "; ";
-    *err = absl::StrCat("Illegal value '", value, "' specified for flag '",
-                        Name(), "'", err_sep, parse_err);
+    err = absl::StrCat("Illegal value '", value, "' specified for flag '",
+                       Name(), "'", err_sep, parse_err);
     return nullptr;
   }
 
@@ -474,7 +473,7 @@
 //  * Update the current flag value if it was never set before
 // The mode is selected based on 'set_mode' parameter.
 bool FlagImpl::ParseFrom(absl::string_view value, FlagSettingMode set_mode,
-                         ValueSource source, std::string* err) {
+                         ValueSource source, std::string& err) {
   absl::MutexLock l(DataGuard());
 
   switch (set_mode) {
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index e374ecd..e188580 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -28,8 +28,8 @@
 #include "absl/base/call_once.h"
 #include "absl/base/config.h"
 #include "absl/base/thread_annotations.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/config.h"
-#include "absl/flags/internal/commandlineflag.h"
 #include "absl/flags/internal/registry.h"
 #include "absl/flags/marshalling.h"
 #include "absl/memory/memory.h"
@@ -168,6 +168,28 @@
 // cases.
 using HelpGenFunc = std::string (*)();
 
+template <size_t N>
+struct FixedCharArray {
+  char value[N];
+
+  template <size_t... I>
+  static constexpr FixedCharArray<N> FromLiteralString(
+      absl::string_view str, absl::index_sequence<I...>) {
+    return (void)str, FixedCharArray<N>({{str[I]..., '\0'}});
+  }
+};
+
+template <typename Gen, size_t N = Gen::Value().size()>
+constexpr FixedCharArray<N + 1> HelpStringAsArray(int) {
+  return FixedCharArray<N + 1>::FromLiteralString(
+      Gen::Value(), absl::make_index_sequence<N>{});
+}
+
+template <typename Gen>
+constexpr std::false_type HelpStringAsArray(char) {
+  return std::false_type{};
+}
+
 union FlagHelpMsg {
   constexpr explicit FlagHelpMsg(const char* help_msg) : literal(help_msg) {}
   constexpr explicit FlagHelpMsg(HelpGenFunc help_gen) : gen_func(help_gen) {}
@@ -185,40 +207,28 @@
 
 extern const char kStrippedFlagHelp[];
 
-// HelpConstexprWrap is used by struct AbslFlagHelpGenFor##name generated by
-// ABSL_FLAG macro. It is only used to silence the compiler in the case where
-// help message expression is not constexpr and does not have type const char*.
-// If help message expression is indeed constexpr const char* HelpConstexprWrap
-// is just a trivial identity function.
-template <typename T>
-const char* HelpConstexprWrap(const T&) {
-  return nullptr;
-}
-constexpr const char* HelpConstexprWrap(const char* p) { return p; }
-constexpr const char* HelpConstexprWrap(char* p) { return p; }
-
 // These two HelpArg overloads allows us to select at compile time one of two
 // way to pass Help argument to absl::Flag. We'll be passing
-// AbslFlagHelpGenFor##name as T and integer 0 as a single argument to prefer
-// first overload if possible. If T::Const is evaluatable on constexpr
-// context (see non template int parameter below) we'll choose first overload.
-// In this case the help message expression is immediately evaluated and is used
-// to construct the absl::Flag. No additionl code is generated by ABSL_FLAG.
-// Otherwise SFINAE kicks in and first overload is dropped from the
+// AbslFlagHelpGenFor##name as Gen and integer 0 as a single argument to prefer
+// first overload if possible. If help message is evaluatable on constexpr
+// context We'll be able to make FixedCharArray out of it and we'll choose first
+// overload. In this case the help message expression is immediately evaluated
+// and is used to construct the absl::Flag. No additionl code is generated by
+// ABSL_FLAG Otherwise SFINAE kicks in and first overload is dropped from the
 // consideration, in which case the second overload will be used. The second
 // overload does not attempt to evaluate the help message expression
 // immediately and instead delays the evaluation by returing the function
 // pointer (&T::NonConst) genering the help message when necessary. This is
 // evaluatable in constexpr context, but the cost is an extra function being
 // generated in the ABSL_FLAG code.
-template <typename T, int = (T::Const(), 1)>
-constexpr FlagHelpArg HelpArg(int) {
-  return {FlagHelpMsg(T::Const()), FlagHelpKind::kLiteral};
+template <typename Gen, size_t N>
+constexpr FlagHelpArg HelpArg(const FixedCharArray<N>& value) {
+  return {FlagHelpMsg(value.value), FlagHelpKind::kLiteral};
 }
 
-template <typename T>
-constexpr FlagHelpArg HelpArg(char) {
-  return {FlagHelpMsg(&T::NonConst), FlagHelpKind::kGenFunc};
+template <typename Gen>
+constexpr FlagHelpArg HelpArg(std::false_type) {
+  return {FlagHelpMsg(&Gen::NonConst), FlagHelpKind::kGenFunc};
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -364,31 +374,31 @@
 
 template <typename T>
 struct FlagValue<T, FlagValueStorageKind::kAlignedBuffer> {
-  bool Get(T*) const { return false; }
+  bool Get(T&) const { return false; }
 
   alignas(T) char value[sizeof(T)];
 };
 
 template <typename T>
 struct FlagValue<T, FlagValueStorageKind::kOneWordAtomic> : FlagOneWordValue {
-  bool Get(T* dst) const {
+  bool Get(T& dst) const {
     int64_t one_word_val = value.load(std::memory_order_acquire);
     if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) {
       return false;
     }
-    std::memcpy(dst, static_cast<const void*>(&one_word_val), sizeof(T));
+    std::memcpy(&dst, static_cast<const void*>(&one_word_val), sizeof(T));
     return true;
   }
 };
 
 template <typename T>
 struct FlagValue<T, FlagValueStorageKind::kTwoWordsAtomic> : FlagTwoWordsValue {
-  bool Get(T* dst) const {
+  bool Get(T& dst) const {
     AlignedTwoWords two_words_val = value.load(std::memory_order_acquire);
     if (ABSL_PREDICT_FALSE(!two_words_val.IsInitialized())) {
       return false;
     }
-    std::memcpy(dst, static_cast<const void*>(&two_words_val), sizeof(T));
+    std::memcpy(&dst, static_cast<const void*>(&two_words_val), sizeof(T));
     return true;
   }
 };
@@ -419,7 +429,7 @@
 
 class FlagState;
 
-class FlagImpl final : public flags_internal::CommandLineFlag {
+class FlagImpl final : public CommandLineFlag {
  public:
   constexpr FlagImpl(const char* name, const char* filename, FlagOpFn op,
                      FlagHelpArg help, FlagValueStorageKind value_kind,
@@ -492,7 +502,7 @@
   // Attempts to parse supplied `value` string. If parsing is successful,
   // returns new value. Otherwise returns nullptr.
   std::unique_ptr<void, DynValueDeleter> TryParse(absl::string_view value,
-                                                  std::string* err) const
+                                                  std::string& err) const
       ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
   // Stores the flag value based on the pointer to the source.
   void StoreValue(const void* src) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
@@ -534,7 +544,7 @@
       ABSL_LOCKS_EXCLUDED(*DataGuard());
 
   bool ParseFrom(absl::string_view value, FlagSettingMode set_mode,
-                 ValueSource source, std::string* error) override
+                 ValueSource source, std::string& error) override
       ABSL_LOCKS_EXCLUDED(*DataGuard());
 
   // Immutable flag's state.
@@ -641,7 +651,7 @@
     impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>);
 #endif
 
-    if (!value_.Get(&u.value)) impl_.Read(&u.value);
+    if (!value_.Get(u.value)) impl_.Read(&u.value);
     return std::move(u.value);
   }
   void Set(const T& v) {
@@ -720,12 +730,12 @@
 template <typename T, bool do_register>
 class FlagRegistrar {
  public:
-  explicit FlagRegistrar(Flag<T>* flag) : flag_(flag) {
-    if (do_register) flags_internal::RegisterCommandLineFlag(&flag_->impl_);
+  explicit FlagRegistrar(Flag<T>& flag) : flag_(flag) {
+    if (do_register) flags_internal::RegisterCommandLineFlag(flag_.impl_);
   }
 
   FlagRegistrar OnUpdate(FlagCallbackFunc cb) && {
-    flag_->impl_.SetCallback(cb);
+    flag_.impl_.SetCallback(cb);
     return *this;
   }
 
@@ -735,7 +745,7 @@
   operator FlagRegistrarEmpty() const { return {}; }  // NOLINT
 
  private:
-  Flag<T>* flag_;  // Flag being registered (not owned).
+  Flag<T>& flag_;  // Flag being registered (not owned).
 };
 
 }  // namespace flags_internal
diff --git a/absl/flags/internal/private_handle_accessor.cc b/absl/flags/internal/private_handle_accessor.cc
index 64fe316..24b4913 100644
--- a/absl/flags/internal/private_handle_accessor.cc
+++ b/absl/flags/internal/private_handle_accessor.cc
@@ -24,8 +24,8 @@
 }
 
 std::unique_ptr<FlagStateInterface> PrivateHandleAccessor::SaveState(
-    CommandLineFlag* flag) {
-  return flag->SaveState();
+    CommandLineFlag& flag) {
+  return flag.SaveState();
 }
 
 bool PrivateHandleAccessor::IsSpecifiedOnCommandLine(
@@ -43,12 +43,12 @@
   flag.CheckDefaultValueParsingRoundtrip();
 }
 
-bool PrivateHandleAccessor::ParseFrom(CommandLineFlag* flag,
+bool PrivateHandleAccessor::ParseFrom(CommandLineFlag& flag,
                                       absl::string_view value,
                                       flags_internal::FlagSettingMode set_mode,
                                       flags_internal::ValueSource source,
-                                      std::string* error) {
-  return flag->ParseFrom(value, set_mode, source, error);
+                                      std::string& error) {
+  return flag.ParseFrom(value, set_mode, source, error);
 }
 
 }  // namespace flags_internal
diff --git a/absl/flags/internal/private_handle_accessor.h b/absl/flags/internal/private_handle_accessor.h
index 40591de..9a327a0 100644
--- a/absl/flags/internal/private_handle_accessor.h
+++ b/absl/flags/internal/private_handle_accessor.h
@@ -16,7 +16,7 @@
 #ifndef ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_
 #define ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_
 
-#include "absl/flags/internal/commandlineflag.h"
+#include "absl/flags/commandlineflag.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -31,7 +31,7 @@
   static FlagFastTypeId TypeId(const CommandLineFlag& flag);
 
   // Access to CommandLineFlag::SaveState.
-  static std::unique_ptr<FlagStateInterface> SaveState(CommandLineFlag* flag);
+  static std::unique_ptr<FlagStateInterface> SaveState(CommandLineFlag& flag);
 
   // Access to CommandLineFlag::IsSpecifiedOnCommandLine.
   static bool IsSpecifiedOnCommandLine(const CommandLineFlag& flag);
@@ -43,9 +43,9 @@
   // Access to CommandLineFlag::CheckDefaultValueParsingRoundtrip.
   static void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag);
 
-  static bool ParseFrom(CommandLineFlag* flag, absl::string_view value,
+  static bool ParseFrom(CommandLineFlag& flag, absl::string_view value,
                         flags_internal::FlagSettingMode set_mode,
-                        flags_internal::ValueSource source, std::string* error);
+                        flags_internal::ValueSource source, std::string& error);
 };
 
 }  // namespace flags_internal
diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc
index 3b941f0..4bcebfa 100644
--- a/absl/flags/internal/registry.cc
+++ b/absl/flags/internal/registry.cc
@@ -28,7 +28,7 @@
 #include "absl/base/config.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/base/thread_annotations.h"
-#include "absl/flags/internal/commandlineflag.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/internal/private_handle_accessor.h"
 #include "absl/flags/usage_config.h"
 #include "absl/strings/str_cat.h"
@@ -60,8 +60,8 @@
   FlagRegistry() = default;
   ~FlagRegistry() = default;
 
-  // Store a flag in this registry.  Takes ownership of *flag.
-  void RegisterFlag(CommandLineFlag* flag);
+  // Store a flag in this registry. Takes ownership of *flag.
+  void RegisterFlag(CommandLineFlag& flag);
 
   void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); }
   void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); }
@@ -74,12 +74,12 @@
   // found or not retired.  Does not emit a warning.
   CommandLineFlag* FindRetiredFlagLocked(absl::string_view name);
 
-  static FlagRegistry* GlobalRegistry();  // returns a singleton registry
+  static FlagRegistry& GlobalRegistry();  // returns a singleton registry
 
  private:
   friend class FlagSaverImpl;  // reads all the flags in order to copy them
   friend void ForEachFlagUnlocked(
-      std::function<void(CommandLineFlag*)> visitor);
+      std::function<void(CommandLineFlag&)> visitor);
 
   // The map from name to flag, for FindFlagLocked().
   using FlagMap = std::map<absl::string_view, CommandLineFlag*>;
@@ -94,64 +94,62 @@
   FlagRegistry& operator=(const FlagRegistry&);
 };
 
-FlagRegistry* FlagRegistry::GlobalRegistry() {
+FlagRegistry& FlagRegistry::GlobalRegistry() {
   static FlagRegistry* global_registry = new FlagRegistry;
-  return global_registry;
+  return *global_registry;
 }
 
 namespace {
 
 class FlagRegistryLock {
  public:
-  explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); }
-  ~FlagRegistryLock() { fr_->Unlock(); }
+  explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.Lock(); }
+  ~FlagRegistryLock() { fr_.Unlock(); }
 
  private:
-  FlagRegistry* const fr_;
+  FlagRegistry& fr_;
 };
 
-void DestroyRetiredFlag(CommandLineFlag* flag);
+void DestroyRetiredFlag(CommandLineFlag& flag);
+
 }  // namespace
 
-void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
-  FlagRegistryLock registry_lock(this);
+void FlagRegistry::RegisterFlag(CommandLineFlag& flag) {
+  FlagRegistryLock registry_lock(*this);
   std::pair<FlagIterator, bool> ins =
-      flags_.insert(FlagMap::value_type(flag->Name(), flag));
+      flags_.insert(FlagMap::value_type(flag.Name(), &flag));
   if (ins.second == false) {  // means the name was already in the map
-    CommandLineFlag* old_flag = ins.first->second;
-    if (flag->IsRetired() != old_flag->IsRetired()) {
+    CommandLineFlag& old_flag = *ins.first->second;
+    if (flag.IsRetired() != old_flag.IsRetired()) {
       // All registrations must agree on the 'retired' flag.
       flags_internal::ReportUsageError(
           absl::StrCat(
-              "Retired flag '", flag->Name(),
-              "' was defined normally in file '",
-              (flag->IsRetired() ? old_flag->Filename() : flag->Filename()),
-              "'."),
+              "Retired flag '", flag.Name(), "' was defined normally in file '",
+              (flag.IsRetired() ? old_flag.Filename() : flag.Filename()), "'."),
           true);
-    } else if (flags_internal::PrivateHandleAccessor::TypeId(*flag) !=
-               flags_internal::PrivateHandleAccessor::TypeId(*old_flag)) {
+    } else if (flags_internal::PrivateHandleAccessor::TypeId(flag) !=
+               flags_internal::PrivateHandleAccessor::TypeId(old_flag)) {
       flags_internal::ReportUsageError(
-          absl::StrCat("Flag '", flag->Name(),
+          absl::StrCat("Flag '", flag.Name(),
                        "' was defined more than once but with "
                        "differing types. Defined in files '",
-                       old_flag->Filename(), "' and '", flag->Filename(), "'."),
+                       old_flag.Filename(), "' and '", flag.Filename(), "'."),
           true);
-    } else if (old_flag->IsRetired()) {
+    } else if (old_flag.IsRetired()) {
       // Retired flag can just be deleted.
       DestroyRetiredFlag(flag);
       return;
-    } else if (old_flag->Filename() != flag->Filename()) {
+    } else if (old_flag.Filename() != flag.Filename()) {
       flags_internal::ReportUsageError(
-          absl::StrCat("Flag '", flag->Name(),
+          absl::StrCat("Flag '", flag.Name(),
                        "' was defined more than once (in files '",
-                       old_flag->Filename(), "' and '", flag->Filename(),
-                       "')."),
+                       old_flag.Filename(), "' and '", flag.Filename(), "')."),
           true);
     } else {
       flags_internal::ReportUsageError(
           absl::StrCat(
-              "Something wrong with flag '", flag->Name(), "' in file '",
-              flag->Filename(), "'. One possibility: file '", flag->Filename(),
+              "Something wrong with flag '", flag.Name(), "' in file '",
+              flag.Filename(), "'. One possibility: file '", flag.Filename(),
               "' is being linked both statically and dynamically into this "
               "executable. e.g. some files listed as srcs to a test and also "
               "listed as srcs of some shared lib deps of the same test."),
@@ -205,7 +203,7 @@
   // It's an error to call this more than once.
   void SaveFromRegistry() {
     assert(backup_registry_.empty());  // call only once!
-    flags_internal::ForEachFlag([&](flags_internal::CommandLineFlag* flag) {
+    flags_internal::ForEachFlag([&](CommandLineFlag& flag) {
       if (auto flag_state =
               flags_internal::PrivateHandleAccessor::SaveState(flag)) {
         backup_registry_.emplace_back(std::move(flag_state));
@@ -243,39 +241,39 @@
 
 CommandLineFlag* FindCommandLineFlag(absl::string_view name) {
   if (name.empty()) return nullptr;
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+  FlagRegistry& registry = FlagRegistry::GlobalRegistry();
   FlagRegistryLock frl(registry);
 
-  return registry->FindFlagLocked(name);
+  return registry.FindFlagLocked(name);
 }
 
 CommandLineFlag* FindRetiredFlag(absl::string_view name) {
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+  FlagRegistry& registry = FlagRegistry::GlobalRegistry();
   FlagRegistryLock frl(registry);
 
-  return registry->FindRetiredFlagLocked(name);
+  return registry.FindRetiredFlagLocked(name);
 }
 
 // --------------------------------------------------------------------
 
-void ForEachFlagUnlocked(std::function<void(CommandLineFlag*)> visitor) {
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
-  for (FlagRegistry::FlagConstIterator i = registry->flags_.begin();
-       i != registry->flags_.end(); ++i) {
-    visitor(i->second);
+void ForEachFlagUnlocked(std::function<void(CommandLineFlag&)> visitor) {
+  FlagRegistry& registry = FlagRegistry::GlobalRegistry();
+  for (FlagRegistry::FlagConstIterator i = registry.flags_.begin();
+       i != registry.flags_.end(); ++i) {
+    visitor(*i->second);
   }
 }
 
-void ForEachFlag(std::function<void(CommandLineFlag*)> visitor) {
-  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+void ForEachFlag(std::function<void(CommandLineFlag&)> visitor) {
+  FlagRegistry& registry = FlagRegistry::GlobalRegistry();
   FlagRegistryLock frl(registry);
   ForEachFlagUnlocked(visitor);
 }
 
 // --------------------------------------------------------------------
 
-bool RegisterCommandLineFlag(CommandLineFlag* flag) {
-  FlagRegistry::GlobalRegistry()->RegisterFlag(flag);
+bool RegisterCommandLineFlag(CommandLineFlag& flag) {
+  FlagRegistry::GlobalRegistry().RegisterFlag(flag);
   return true;
 }
 
@@ -283,7 +281,7 @@
 
 namespace {
 
-class RetiredFlagObj final : public flags_internal::CommandLineFlag {
+class RetiredFlagObj final : public CommandLineFlag {
  public:
   constexpr RetiredFlagObj(const char* name, FlagFastTypeId type_id)
       : name_(name), type_id_(type_id) {}
@@ -306,7 +304,7 @@
   }
 
   bool ParseFrom(absl::string_view, flags_internal::FlagSettingMode,
-                 flags_internal::ValueSource, std::string*) override {
+                 flags_internal::ValueSource, std::string&) override {
     return false;
   }
 
@@ -319,16 +317,16 @@
   const FlagFastTypeId type_id_;
 };
 
-void DestroyRetiredFlag(flags_internal::CommandLineFlag* flag) {
-  assert(flag->IsRetired());
-  delete static_cast<RetiredFlagObj*>(flag);
+void DestroyRetiredFlag(CommandLineFlag& flag) {
+  assert(flag.IsRetired());
+  delete static_cast<RetiredFlagObj*>(&flag);
 }
 
 }  // namespace
 
 bool Retire(const char* name, FlagFastTypeId type_id) {
   auto* flag = new flags_internal::RetiredFlagObj(name, type_id);
-  FlagRegistry::GlobalRegistry()->RegisterFlag(flag);
+  FlagRegistry::GlobalRegistry().RegisterFlag(*flag);
   return true;
 }
 
diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h
index af8ed6b..a118865 100644
--- a/absl/flags/internal/registry.h
+++ b/absl/flags/internal/registry.h
@@ -30,6 +30,8 @@
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
+class CommandLineFlag;
+
 namespace flags_internal {
 
 CommandLineFlag* FindCommandLineFlag(absl::string_view name);
@@ -37,14 +39,14 @@
 
 // Executes specified visitor for each non-retired flag in the registry.
 // Requires the caller hold the registry lock.
-void ForEachFlagUnlocked(std::function<void(CommandLineFlag*)> visitor);
+void ForEachFlagUnlocked(std::function<void(CommandLineFlag&)> visitor);
 // Executes specified visitor for each non-retired flag in the registry. While
 // callback are executed, the registry is locked and can't be changed.
-void ForEachFlag(std::function<void(CommandLineFlag*)> visitor);
+void ForEachFlag(std::function<void(CommandLineFlag&)> visitor);
 
 //-----------------------------------------------------------------------------
 
-bool RegisterCommandLineFlag(CommandLineFlag*);
+bool RegisterCommandLineFlag(CommandLineFlag&);
 
 //-----------------------------------------------------------------------------
 // Retired registrations:
diff --git a/absl/flags/internal/type_erased.cc b/absl/flags/internal/type_erased.cc
index c13fb9b..b2523b2 100644
--- a/absl/flags/internal/type_erased.cc
+++ b/absl/flags/internal/type_erased.cc
@@ -21,7 +21,7 @@
 
 #include "absl/base/config.h"
 #include "absl/base/internal/raw_logging.h"
-#include "absl/flags/internal/commandlineflag.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/internal/private_handle_accessor.h"
 #include "absl/flags/internal/registry.h"
 #include "absl/flags/usage_config.h"
@@ -58,7 +58,7 @@
 
   std::string error;
   if (!flags_internal::PrivateHandleAccessor::ParseFrom(
-          flag, value, set_mode, kProgrammaticChange, &error)) {
+          *flag, value, set_mode, kProgrammaticChange, error)) {
     // Errors here are all of the form: the provided name was a recognized
     // flag, but the value was invalid (bad type, or validation failed).
     flags_internal::ReportUsageError(error, false);
diff --git a/absl/flags/internal/type_erased.h b/absl/flags/internal/type_erased.h
index b43a0ff..fd9663e 100644
--- a/absl/flags/internal/type_erased.h
+++ b/absl/flags/internal/type_erased.h
@@ -19,7 +19,7 @@
 #include <string>
 
 #include "absl/base/config.h"
-#include "absl/flags/internal/commandlineflag.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/internal/registry.h"
 #include "absl/strings/string_view.h"
 
diff --git a/absl/flags/internal/type_erased_test.cc b/absl/flags/internal/type_erased_test.cc
index 4ce5981..bb0ff23 100644
--- a/absl/flags/internal/type_erased_test.cc
+++ b/absl/flags/internal/type_erased_test.cc
@@ -20,7 +20,6 @@
 
 #include "gtest/gtest.h"
 #include "absl/flags/flag.h"
-#include "absl/flags/internal/commandlineflag.h"
 #include "absl/flags/internal/registry.h"
 #include "absl/flags/marshalling.h"
 #include "absl/memory/memory.h"
diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc
index 10accc4..2a2231a 100644
--- a/absl/flags/internal/usage.cc
+++ b/absl/flags/internal/usage.cc
@@ -23,8 +23,8 @@
 #include <vector>
 
 #include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/flag.h"
-#include "absl/flags/internal/commandlineflag.h"
 #include "absl/flags/internal/flag.h"
 #include "absl/flags/internal/path_util.h"
 #include "absl/flags/internal/private_handle_accessor.h"
@@ -107,8 +107,8 @@
  public:
   // Pretty printer holds on to the std::ostream& reference to direct an output
   // to that stream.
-  FlagHelpPrettyPrinter(int max_line_len, std::ostream* out)
-      : out_(*out),
+  FlagHelpPrettyPrinter(int max_line_len, std::ostream& out)
+      : out_(out),
         max_line_len_(max_line_len),
         line_len_(0),
         first_line_(true) {}
@@ -182,8 +182,7 @@
   bool first_line_;
 };
 
-void FlagHelpHumanReadable(const flags_internal::CommandLineFlag& flag,
-                           std::ostream* out) {
+void FlagHelpHumanReadable(const CommandLineFlag& flag, std::ostream& out) {
   FlagHelpPrettyPrinter printer(80, out);  // Max line length is 80.
 
   // Flag name.
@@ -245,30 +244,28 @@
   // This map is used to output matching flags grouped by package and file
   // name.
   std::map<std::string,
-           std::map<std::string,
-                    std::vector<const flags_internal::CommandLineFlag*>>>
+           std::map<std::string, std::vector<const absl::CommandLineFlag*>>>
       matching_flags;
 
-  flags_internal::ForEachFlag([&](flags_internal::CommandLineFlag* flag) {
-    std::string flag_filename = flag->Filename();
+  flags_internal::ForEachFlag([&](absl::CommandLineFlag& flag) {
+    std::string flag_filename = flag.Filename();
 
     // Ignore retired flags.
-    if (flag->IsRetired()) return;
+    if (flag.IsRetired()) return;
 
     // If the flag has been stripped, pretend that it doesn't exist.
-    if (flag->Help() == flags_internal::kStrippedFlagHelp) return;
+    if (flag.Help() == flags_internal::kStrippedFlagHelp) return;
 
     // Make sure flag satisfies the filter
     if (!filter_cb || !filter_cb(flag_filename)) return;
 
     matching_flags[std::string(flags_internal::Package(flag_filename))]
                   [flag_filename]
-                      .push_back(flag);
+                      .push_back(&flag);
   });
 
-  absl::string_view
-      package_separator;             // controls blank lines between packages.
-  absl::string_view file_separator;  // controls blank lines between files.
+  absl::string_view package_separator;  // controls blank lines between packages
+  absl::string_view file_separator;     // controls blank lines between files
   for (const auto& package : matching_flags) {
     if (format == HelpFormat::kHumanReadable) {
       out << package_separator;
@@ -303,10 +300,10 @@
 
 // --------------------------------------------------------------------
 // Produces the help message describing specific flag.
-void FlagHelp(std::ostream& out, const flags_internal::CommandLineFlag& flag,
+void FlagHelp(std::ostream& out, const CommandLineFlag& flag,
               HelpFormat format) {
   if (format == HelpFormat::kHumanReadable)
-    flags_internal::FlagHelpHumanReadable(flag, &out);
+    flags_internal::FlagHelpHumanReadable(flag, out);
 }
 
 // --------------------------------------------------------------------
diff --git a/absl/flags/internal/usage.h b/absl/flags/internal/usage.h
index 6b080fd..0c62dc4 100644
--- a/absl/flags/internal/usage.h
+++ b/absl/flags/internal/usage.h
@@ -20,8 +20,8 @@
 #include <string>
 
 #include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/declare.h"
-#include "absl/flags/internal/commandlineflag.h"
 #include "absl/strings/string_view.h"
 
 // --------------------------------------------------------------------
@@ -37,7 +37,7 @@
 };
 
 // Outputs the help message describing specific flag.
-void FlagHelp(std::ostream& out, const flags_internal::CommandLineFlag& flag,
+void FlagHelp(std::ostream& out, const CommandLineFlag& flag,
               HelpFormat format = HelpFormat::kHumanReadable);
 
 // Produces the help messages for all flags matching the filter. A flag matches
diff --git a/absl/flags/marshalling.cc b/absl/flags/marshalling.cc
index 09baae8..81f9ceb 100644
--- a/absl/flags/marshalling.cc
+++ b/absl/flags/marshalling.cc
@@ -74,15 +74,16 @@
 }
 
 template <typename IntType>
-inline bool ParseFlagImpl(absl::string_view text, IntType* dst) {
+inline bool ParseFlagImpl(absl::string_view text, IntType& dst) {
   text = absl::StripAsciiWhitespace(text);
 
-  return absl::numbers_internal::safe_strtoi_base(text, dst, NumericBase(text));
+  return absl::numbers_internal::safe_strtoi_base(text, &dst,
+                                                  NumericBase(text));
 }
 
 bool AbslParseFlag(absl::string_view text, short* dst, std::string*) {
   int val;
-  if (!ParseFlagImpl(text, &val)) return false;
+  if (!ParseFlagImpl(text, val)) return false;
   if (static_cast<short>(val) != val)  // worked, but number out of range
     return false;
   *dst = static_cast<short>(val);
@@ -91,7 +92,7 @@
 
 bool AbslParseFlag(absl::string_view text, unsigned short* dst, std::string*) {
   unsigned int val;
-  if (!ParseFlagImpl(text, &val)) return false;
+  if (!ParseFlagImpl(text, val)) return false;
   if (static_cast<unsigned short>(val) !=
       val)  // worked, but number out of range
     return false;
@@ -100,28 +101,28 @@
 }
 
 bool AbslParseFlag(absl::string_view text, int* dst, std::string*) {
-  return ParseFlagImpl(text, dst);
+  return ParseFlagImpl(text, *dst);
 }
 
 bool AbslParseFlag(absl::string_view text, unsigned int* dst, std::string*) {
-  return ParseFlagImpl(text, dst);
+  return ParseFlagImpl(text, *dst);
 }
 
 bool AbslParseFlag(absl::string_view text, long* dst, std::string*) {
-  return ParseFlagImpl(text, dst);
+  return ParseFlagImpl(text, *dst);
 }
 
 bool AbslParseFlag(absl::string_view text, unsigned long* dst, std::string*) {
-  return ParseFlagImpl(text, dst);
+  return ParseFlagImpl(text, *dst);
 }
 
 bool AbslParseFlag(absl::string_view text, long long* dst, std::string*) {
-  return ParseFlagImpl(text, dst);
+  return ParseFlagImpl(text, *dst);
 }
 
 bool AbslParseFlag(absl::string_view text, unsigned long long* dst,
                    std::string*) {
-  return ParseFlagImpl(text, dst);
+  return ParseFlagImpl(text, *dst);
 }
 
 // --------------------------------------------------------------------
diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc
index fbf4267..1530078 100644
--- a/absl/flags/parse.cc
+++ b/absl/flags/parse.cc
@@ -34,9 +34,9 @@
 #include "absl/base/config.h"
 #include "absl/base/const_init.h"
 #include "absl/base/thread_annotations.h"
+#include "absl/flags/commandlineflag.h"
 #include "absl/flags/config.h"
 #include "absl/flags/flag.h"
-#include "absl/flags/internal/commandlineflag.h"
 #include "absl/flags/internal/flag.h"
 #include "absl/flags/internal/parse.h"
 #include "absl/flags/internal/private_handle_accessor.h"
@@ -222,7 +222,7 @@
 // Reads the environment variable with name `name` and stores results in
 // `value`. If variable is not present in environment returns false, otherwise
 // returns true.
-bool GetEnvVar(const char* var_name, std::string* var_value) {
+bool GetEnvVar(const char* var_name, std::string& var_value) {
 #ifdef _WIN32
   char buf[1024];
   auto get_res = GetEnvironmentVariableA(var_name, buf, sizeof(buf));
@@ -234,14 +234,14 @@
     return false;
   }
 
-  *var_value = std::string(buf, get_res);
+  var_value = std::string(buf, get_res);
 #else
   const char* val = ::getenv(var_name);
   if (val == nullptr) {
     return false;
   }
 
-  *var_value = val;
+  var_value = val;
 #endif
 
   return true;
@@ -306,17 +306,17 @@
 // back.
 void CheckDefaultValuesParsingRoundtrip() {
 #ifndef NDEBUG
-  flags_internal::ForEachFlag([&](CommandLineFlag* flag) {
-    if (flag->IsRetired()) return;
+  flags_internal::ForEachFlag([&](CommandLineFlag& flag) {
+    if (flag.IsRetired()) return;
 
 #define ABSL_FLAGS_INTERNAL_IGNORE_TYPE(T, _) \
-  if (flag->IsOfType<T>()) return;
+  if (flag.IsOfType<T>()) return;
 
     ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(ABSL_FLAGS_INTERNAL_IGNORE_TYPE)
 #undef ABSL_FLAGS_INTERNAL_IGNORE_TYPE
 
     flags_internal::PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip(
-        *flag);
+        flag);
   });
 #endif
 }
@@ -329,13 +329,13 @@
 // the first flagfile in the input list are processed before the second flagfile
 // etc.
 bool ReadFlagfiles(const std::vector<std::string>& flagfiles,
-                   std::vector<ArgsList>* input_args) {
+                   std::vector<ArgsList>& input_args) {
   bool success = true;
   for (auto it = flagfiles.rbegin(); it != flagfiles.rend(); ++it) {
     ArgsList al;
 
     if (al.ReadFromFlagfile(*it)) {
-      input_args->push_back(al);
+      input_args.push_back(al);
     } else {
       success = false;
     }
@@ -350,7 +350,7 @@
 // `flag_name` is a string from the input flag_names list. If successful we
 // append a single ArgList at the end of the input_args.
 bool ReadFlagsFromEnv(const std::vector<std::string>& flag_names,
-                      std::vector<ArgsList>* input_args,
+                      std::vector<ArgsList>& input_args,
                       bool fail_on_absent_in_env) {
   bool success = true;
   std::vector<std::string> args;
@@ -371,7 +371,7 @@
 
     const std::string envname = absl::StrCat("FLAGS_", flag_name);
     std::string envval;
-    if (!GetEnvVar(envname.c_str(), &envval)) {
+    if (!GetEnvVar(envname.c_str(), envval)) {
       if (fail_on_absent_in_env) {
         flags_internal::ReportUsageError(
             absl::StrCat(envname, " not found in environment"), true);
@@ -386,7 +386,7 @@
   }
 
   if (success) {
-    input_args->emplace_back(args);
+    input_args.emplace_back(args);
   }
 
   return success;
@@ -396,8 +396,8 @@
 
 // Returns success status, which is true if were able to handle all generator
 // flags (flagfile, fromenv, tryfromemv) successfully.
-bool HandleGeneratorFlags(std::vector<ArgsList>* input_args,
-                          std::vector<std::string>* flagfile_value) {
+bool HandleGeneratorFlags(std::vector<ArgsList>& input_args,
+                          std::vector<std::string>& flagfile_value) {
   bool success = true;
 
   absl::MutexLock l(&flags_internal::processing_checks_guard);
@@ -422,9 +422,9 @@
   if (flags_internal::flagfile_needs_processing) {
     auto flagfiles = absl::GetFlag(FLAGS_flagfile);
 
-    if (input_args->size() == 1) {
-      flagfile_value->insert(flagfile_value->end(), flagfiles.begin(),
-                             flagfiles.end());
+    if (input_args.size() == 1) {
+      flagfile_value.insert(flagfile_value.end(), flagfiles.begin(),
+                            flagfiles.end());
     }
 
     success &= ReadFlagfiles(flagfiles, input_args);
@@ -647,7 +647,7 @@
   bool success = true;
   while (!input_args.empty()) {
     // 10. First we process the built-in generator flags.
-    success &= HandleGeneratorFlags(&input_args, &flagfile_value);
+    success &= HandleGeneratorFlags(input_args, flagfile_value);
 
     // 30. Select top-most (most recent) arguments list. If it is empty drop it
     // and re-try.
@@ -733,7 +733,7 @@
 
     std::string error;
     if (!flags_internal::PrivateHandleAccessor::ParseFrom(
-            flag, value, SET_FLAGS_VALUE, kCommandLine, &error)) {
+            *flag, value, SET_FLAGS_VALUE, kCommandLine, error)) {
       flags_internal::ReportUsageError(error, true);
       success = false;
     } else {
diff --git a/absl/flags/parse_test.cc b/absl/flags/parse_test.cc
index e6a53ae..aea068e 100644
--- a/absl/flags/parse_test.cc
+++ b/absl/flags/parse_test.cc
@@ -171,8 +171,8 @@
 // temporary directory location. This way we can test inclusion of one flagfile
 // from another flagfile.
 const char* GetFlagfileFlag(const std::vector<FlagfileData>& ffd,
-                            std::string* flagfile_flag) {
-  *flagfile_flag = "--flagfile=";
+                            std::string& flagfile_flag) {
+  flagfile_flag = "--flagfile=";
   absl::string_view separator;
   for (const auto& flagfile_data : ffd) {
     std::string flagfile_name =
@@ -183,11 +183,11 @@
       flagfile_out << absl::Substitute(line, GetTestTempDir()) << "\n";
     }
 
-    absl::StrAppend(flagfile_flag, separator, flagfile_name);
+    absl::StrAppend(&flagfile_flag, separator, flagfile_name);
     separator = ",";
   }
 
-  return flagfile_flag->c_str();
+  return flagfile_flag.c_str();
 }
 
 }  // namespace
@@ -588,14 +588,14 @@
   const char* in_args1[] = {
       "testbin",
       GetFlagfileFlag({{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
-                      &flagfile_flag),
+                      flagfile_flag),
   };
   TestParse(in_args1, -1, 0.1, "q2w2  ", true);
 
   const char* in_args2[] = {
       "testbin",
       GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)}},
-                      &flagfile_flag),
+                      flagfile_flag),
   };
   TestParse(in_args2, 100, 0.1, "q2w2  ", false);
 }
@@ -609,7 +609,7 @@
       "testbin",
       GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)},
                        {"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
-                      &flagfile_flag),
+                      flagfile_flag),
   };
   TestParse(in_args1, -1, 0.1, "q2w2  ", true);
 }
@@ -622,7 +622,7 @@
   const char* in_args1[] = {
       "testbin", "--int_flag=3",
       GetFlagfileFlag({{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
-                      &flagfile_flag),
+                      flagfile_flag),
       "-double_flag=0.2"};
   TestParse(in_args1, -1, 0.2, "q2w2  ", true);
 }
@@ -640,7 +640,7 @@
   const char* in_args1[] = {
       "testbin",
       GetFlagfileFlag({{"parse_test.ff3", absl::MakeConstSpan(ff3_data)}},
-                      &flagfile_flag),
+                      flagfile_flag),
   };
   TestParse(in_args1, 100, 0.1, "q2w2  ", false);
 }
@@ -657,7 +657,7 @@
   const char* in_args1[] = {
       "testbin",
       GetFlagfileFlag({{"parse_test.ff4",
-                        absl::MakeConstSpan(ff4_data)}}, &flagfile_flag),
+                        absl::MakeConstSpan(ff4_data)}}, flagfile_flag),
   };
   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
                "Unknown command line flag 'unknown_flag'");
@@ -669,7 +669,7 @@
   const char* in_args2[] = {
       "testbin",
       GetFlagfileFlag({{"parse_test.ff5",
-                        absl::MakeConstSpan(ff5_data)}}, &flagfile_flag),
+                        absl::MakeConstSpan(ff5_data)}}, flagfile_flag),
   };
   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
                "Unknown command line flag 'int_flag 10'");
@@ -681,7 +681,7 @@
   const char* in_args3[] = {
       "testbin",
       GetFlagfileFlag({{"parse_test.ff6", absl::MakeConstSpan(ff6_data)}},
-                      &flagfile_flag),
+                      flagfile_flag),
   };
   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args3),
                "Flagfile can't contain position arguments or --");
@@ -702,7 +702,7 @@
   const char* in_args5[] = {
       "testbin",
       GetFlagfileFlag({{"parse_test.ff7", absl::MakeConstSpan(ff7_data)}},
-                      &flagfile_flag),
+                      flagfile_flag),
   };
   EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args5),
                "Unexpected line in the flagfile .*: \\*bin\\*");
diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel
index 9ba75b5..4b804c8 100644
--- a/absl/random/BUILD.bazel
+++ b/absl/random/BUILD.bazel
@@ -69,7 +69,7 @@
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/meta:type_traits",
-        "//absl/random/internal:distributions",
+        "//absl/random/internal:distribution_caller",
         "//absl/random/internal:fast_uniform_bits",
         "//absl/random/internal:fastmath",
         "//absl/random/internal:generate_real",
@@ -78,7 +78,6 @@
         "//absl/random/internal:uniform_helper",
         "//absl/random/internal:wide_multiply",
         "//absl/strings",
-        "//absl/types:span",
     ],
 )
 
diff --git a/absl/random/BUILD.gn b/absl/random/BUILD.gn
index 66e2bb3..12037e3 100644
--- a/absl/random/BUILD.gn
+++ b/absl/random/BUILD.gn
@@ -39,7 +39,7 @@
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/meta:type_traits",
-    "//third_party/abseil-cpp/absl/random/internal:distributions",
+    "//third_party/abseil-cpp/absl/random/internal:distribution_caller",
     "//third_party/abseil-cpp/absl/random/internal:fast_uniform_bits",
     "//third_party/abseil-cpp/absl/random/internal:fastmath",
     "//third_party/abseil-cpp/absl/random/internal:generate_real",
@@ -48,7 +48,6 @@
     "//third_party/abseil-cpp/absl/random/internal:uniform_helper",
     "//third_party/abseil-cpp/absl/random/internal:wide_multiply",
     "//third_party/abseil-cpp/absl/strings",
-    "//third_party/abseil-cpp/absl/types:span",
   ]
 }
 
diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt
index ec616dd..85a2ea3 100644
--- a/absl/random/CMakeLists.txt
+++ b/absl/random/CMakeLists.txt
@@ -183,7 +183,7 @@
     absl::config
     absl::core_headers
     absl::random_internal_generate_real
-    absl::random_internal_distributions
+    absl::random_internal_distribution_caller
     absl::random_internal_fast_uniform_bits
     absl::random_internal_fastmath
     absl::random_internal_iostream_state_saver
@@ -191,7 +191,6 @@
     absl::random_internal_uniform_helper
     absl::random_internal_wide_multiply
     absl::strings
-    absl::span
     absl::type_traits
 )
 
@@ -539,27 +538,6 @@
 # Internal-only target, do not depend on directly.
 absl_cc_library(
   NAME
-    random_internal_distributions
-  HDRS
-    "internal/distributions.h"
-  COPTS
-    ${ABSL_DEFAULT_COPTS}
-  LINKOPTS
-    ${ABSL_DEFAULT_LINKOPTS}
-  DEPS
-    absl::random_internal_distribution_caller
-    absl::random_internal_fast_uniform_bits
-    absl::random_internal_fastmath
-    absl::random_internal_traits
-    absl::random_internal_uniform_helper
-    absl::span
-    absl::strings
-    absl::type_traits
-)
-
-# Internal-only target, do not depend on directly.
-absl_cc_library(
-  NAME
     random_internal_fast_uniform_bits
   HDRS
     "internal/fast_uniform_bits.h"
@@ -745,7 +723,6 @@
     absl::random_internal_salted_seed_seq
     absl::random_internal_seed_material
     absl::span
-    absl::strings
     absl::type_traits
 )
 
@@ -1174,9 +1151,7 @@
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
-    absl::core_headers
-    absl::random_internal_fast_uniform_bits
-    absl::random_internal_iostream_state_saver
+    absl::config
     absl::random_internal_traits
     absl::type_traits
 )
diff --git a/absl/random/distributions.h b/absl/random/distributions.h
index 8680f6a..6775c5d 100644
--- a/absl/random/distributions.h
+++ b/absl/random/distributions.h
@@ -57,7 +57,7 @@
 #include "absl/random/beta_distribution.h"
 #include "absl/random/exponential_distribution.h"
 #include "absl/random/gaussian_distribution.h"
-#include "absl/random/internal/distributions.h"  // IWYU pragma: export
+#include "absl/random/internal/distribution_caller.h"  // IWYU pragma: export
 #include "absl/random/internal/uniform_helper.h"  // IWYU pragma: export
 #include "absl/random/log_uniform_int_distribution.h"
 #include "absl/random/poisson_distribution.h"
diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel
index 85d1fb8..813d926 100644
--- a/absl/random/internal/BUILD.bazel
+++ b/absl/random/internal/BUILD.bazel
@@ -49,21 +49,6 @@
 )
 
 cc_library(
-    name = "distributions",
-    hdrs = ["distributions.h"],
-    copts = ABSL_DEFAULT_COPTS,
-    linkopts = ABSL_DEFAULT_LINKOPTS,
-    deps = [
-        ":distribution_caller",
-        ":traits",
-        ":uniform_helper",
-        "//absl/base",
-        "//absl/meta:type_traits",
-        "//absl/strings",
-    ],
-)
-
-cc_library(
     name = "fast_uniform_bits",
     hdrs = [
         "fast_uniform_bits.h",
@@ -221,7 +206,6 @@
         ":seed_material",
         "//absl/base:core_headers",
         "//absl/meta:type_traits",
-        "//absl/strings",
         "//absl/types:optional",
         "//absl/types:span",
     ],
@@ -672,6 +656,8 @@
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
+        ":traits",
+        "//absl/base:config",
         "//absl/meta:type_traits",
     ],
 )
diff --git a/absl/random/internal/BUILD.gn b/absl/random/internal/BUILD.gn
index bfb5681..ede20e9 100644
--- a/absl/random/internal/BUILD.gn
+++ b/absl/random/internal/BUILD.gn
@@ -14,18 +14,6 @@
   deps = [ "//third_party/abseil-cpp/absl/base:config" ]
 }
 
-absl_source_set("distributions") {
-  public = [ "distributions.h" ]
-  deps = [
-    ":distribution_caller",
-    ":traits",
-    ":uniform_helper",
-    "//third_party/abseil-cpp/absl/base",
-    "//third_party/abseil-cpp/absl/meta:type_traits",
-    "//third_party/abseil-cpp/absl/strings",
-  ]
-}
-
 absl_source_set("fast_uniform_bits") {
   public = [ "fast_uniform_bits.h" ]
   deps = [ "//third_party/abseil-cpp/absl/base:config" ]
@@ -129,7 +117,6 @@
     ":seed_material",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/meta:type_traits",
-    "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:span",
   ]
@@ -259,5 +246,9 @@
 
 absl_source_set("uniform_helper") {
   public = [ "uniform_helper.h" ]
-  deps = [ "//third_party/abseil-cpp/absl/meta:type_traits" ]
+  deps = [
+    ":traits",
+    "//third_party/abseil-cpp/absl/base:config",
+    "//third_party/abseil-cpp/absl/meta:type_traits"
+  ]
 }
diff --git a/absl/random/internal/distributions.h b/absl/random/internal/distributions.h
deleted file mode 100644
index d7e3c01..0000000
--- a/absl/random/internal/distributions.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_
-#define ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_
-
-#include <type_traits>
-
-#include "absl/meta/type_traits.h"
-#include "absl/random/internal/distribution_caller.h"
-#include "absl/random/internal/traits.h"
-#include "absl/random/internal/uniform_helper.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// In the absence of an explicitly provided return-type, the template
-// "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on
-// the data-types of the endpoint-arguments {A lo, B hi}.
-//
-// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the
-// return-type, if one type can be implicitly converted into the other, in a
-// lossless way. The template "is_widening_convertible" implements the
-// compile-time logic for deciding if such a conversion is possible.
-//
-// If no such conversion between {A, B} exists, then the overload for
-// absl::Uniform() will be discarded, and the call will be ill-formed.
-// Return-type for absl::Uniform() when the return-type is inferred.
-template <typename A, typename B>
-using uniform_inferred_return_t =
-    absl::enable_if_t<absl::disjunction<is_widening_convertible<A, B>,
-                                        is_widening_convertible<B, A>>::value,
-                      typename std::conditional<
-                          is_widening_convertible<A, B>::value, B, A>::type>;
-
-}  // namespace random_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
-
-#endif  // ABSL_RANDOM_INTERNAL_DISTRIBUTIONS_H_
diff --git a/absl/random/internal/uniform_helper.h b/absl/random/internal/uniform_helper.h
index 663107c..5b2afec 100644
--- a/absl/random/internal/uniform_helper.h
+++ b/absl/random/internal/uniform_helper.h
@@ -19,10 +19,13 @@
 #include <limits>
 #include <type_traits>
 
+#include "absl/base/config.h"
 #include "absl/meta/type_traits.h"
+#include "absl/random/internal/traits.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
+
 template <typename IntType>
 class uniform_int_distribution;
 
@@ -58,6 +61,26 @@
     : public random_internal::TagTypeCompare<IntervalOpenOpenTag> {};
 
 namespace random_internal {
+
+// In the absence of an explicitly provided return-type, the template
+// "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on
+// the data-types of the endpoint-arguments {A lo, B hi}.
+//
+// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the
+// return-type, if one type can be implicitly converted into the other, in a
+// lossless way. The template "is_widening_convertible" implements the
+// compile-time logic for deciding if such a conversion is possible.
+//
+// If no such conversion between {A, B} exists, then the overload for
+// absl::Uniform() will be discarded, and the call will be ill-formed.
+// Return-type for absl::Uniform() when the return-type is inferred.
+template <typename A, typename B>
+using uniform_inferred_return_t =
+    absl::enable_if_t<absl::disjunction<is_widening_convertible<A, B>,
+                                        is_widening_convertible<B, A>>::value,
+                      typename std::conditional<
+                          is_widening_convertible<A, B>::value, B, A>::type>;
+
 // The functions
 //    uniform_lower_bound(tag, a, b)
 // and
@@ -149,12 +172,19 @@
   return std::nextafter(b, (std::numeric_limits<FloatType>::max)());
 }
 
+// UniformDistribution selects either absl::uniform_int_distribution
+// or absl::uniform_real_distribution depending on the NumType parameter.
 template <typename NumType>
 using UniformDistribution =
     typename std::conditional<std::is_integral<NumType>::value,
                               absl::uniform_int_distribution<NumType>,
                               absl::uniform_real_distribution<NumType>>::type;
 
+// UniformDistributionWrapper is used as the underlying distribution type
+// by the absl::Uniform template function. It selects the proper Abseil
+// uniform distribution and provides constructor overloads that match the
+// expected parameter order as well as adjusting distribtuion bounds based
+// on the tag.
 template <typename NumType>
 struct UniformDistributionWrapper : public UniformDistribution<NumType> {
   template <typename TagType>
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index 1ddd6ae..68f5398 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -705,6 +705,37 @@
   }
 }
 
+template <typename T, Cord::EnableIfString<T>>
+Cord::Cord(T&& src) {
+  if (
+      // String is short: copy data to avoid external block overhead.
+      src.size() <= kMaxBytesToCopy ||
+      // String is wasteful: copy data to avoid pinning too much unused memory.
+      src.size() < src.capacity() / 2
+  ) {
+    if (src.size() <= InlineRep::kMaxInline) {
+      contents_.set_data(src.data(), src.size(), false);
+    } else {
+      contents_.set_tree(NewTree(src.data(), src.size(), 0));
+    }
+  } else {
+    struct StringReleaser {
+      void operator()(absl::string_view /* data */) {}
+      std::string data;
+    };
+    const absl::string_view original_data = src;
+    CordRepExternal* rep =
+        static_cast<CordRepExternal*>(absl::cord_internal::NewExternalRep(
+            original_data, StringReleaser{std::move(src)}));
+    // Moving src may have invalidated its data pointer, so adjust it.
+    rep->base =
+        static_cast<StringReleaser*>(GetExternalReleaser(rep))->data.data();
+    contents_.set_tree(rep);
+  }
+}
+
+template Cord::Cord(std::string&& src);
+
 // The destruction code is separate so that the compiler can determine
 // that it does not need to call the destructor on a moved-from Cord.
 void Cord::DestroyCordSlow() {
@@ -742,6 +773,18 @@
   return *this;
 }
 
+template <typename T, Cord::EnableIfString<T>>
+Cord& Cord::operator=(T&& src) {
+  if (src.size() <= kMaxBytesToCopy) {
+    *this = absl::string_view(src);
+  } else {
+    *this = Cord(std::move(src));
+  }
+  return *this;
+}
+
+template Cord& Cord::operator=(std::string&& src);
+
 // TODO(sanjay): Move to Cord::InlineRep section of file.  For now,
 // we keep it here to make diffs easier.
 void Cord::InlineRep::AppendArray(const char* src_data, size_t src_size) {
@@ -853,6 +896,17 @@
 
 void Cord::Append(Cord&& src) { AppendImpl(std::move(src)); }
 
+template <typename T, Cord::EnableIfString<T>>
+void Cord::Append(T&& src) {
+  if (src.size() <= kMaxBytesToCopy) {
+    Append(absl::string_view(src));
+  } else {
+    Append(Cord(std::move(src)));
+  }
+}
+
+template void Cord::Append(std::string&& src);
+
 void Cord::Prepend(const Cord& src) {
   CordRep* src_tree = src.contents_.tree();
   if (src_tree != nullptr) {
@@ -882,6 +936,17 @@
   }
 }
 
+template <typename T, Cord::EnableIfString<T>>
+inline void Cord::Prepend(T&& src) {
+  if (src.size() <= kMaxBytesToCopy) {
+    Prepend(absl::string_view(src));
+  } else {
+    Prepend(Cord(std::move(src)));
+  }
+}
+
+template void Cord::Prepend(std::string&& src);
+
 static CordRep* RemovePrefixFrom(CordRep* node, size_t n) {
   if (n >= node->length) return nullptr;
   if (n == 0) return Ref(node);
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index 3be8d7d..dc98745 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -147,11 +147,8 @@
   // Creates a Cord from a `std::string&&` rvalue. These constructors are
   // templated to avoid ambiguities for types that are convertible to both
   // `absl::string_view` and `std::string`, such as `const char*`.
-  //
-  // Note that these functions reserve the right to use the `string&&`'s
-  // memory and that they will do so in the future.
   template <typename T, EnableIfString<T> = 0>
-  explicit Cord(T&& src) : Cord(absl::string_view(src)) {}
+  explicit Cord(T&& src);
   template <typename T, EnableIfString<T> = 0>
   Cord& operator=(T&& src);
 
@@ -1048,11 +1045,8 @@
   return *this;
 }
 
-template <typename T, Cord::EnableIfString<T>>
-inline Cord& Cord::operator=(T&& src) {
-  *this = absl::string_view(src);
-  return *this;
-}
+extern template Cord::Cord(std::string&& src);
+extern template Cord& Cord::operator=(std::string&& src);
 
 inline size_t Cord::size() const {
   // Length is 1st field in str.rep_
@@ -1098,19 +1092,8 @@
   contents_.AppendArray(src.data(), src.size());
 }
 
-template <typename T, Cord::EnableIfString<T>>
-inline void Cord::Append(T&& src) {
-  // Note that this function reserves the right to reuse the `string&&`'s
-  // memory and that it will do so in the future.
-  Append(absl::string_view(src));
-}
-
-template <typename T, Cord::EnableIfString<T>>
-inline void Cord::Prepend(T&& src) {
-  // Note that this function reserves the right to reuse the `string&&`'s
-  // memory and that it will do so in the future.
-  Prepend(absl::string_view(src));
-}
+extern template void Cord::Append(std::string&& src);
+extern template void Cord::Prepend(std::string&& src);
 
 inline int Cord::Compare(const Cord& rhs) const {
   if (!contents_.is_tree() && !rhs.contents_.is_tree()) {
diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc
index 49a6884..22cfef6 100644
--- a/absl/strings/str_format_test.cc
+++ b/absl/strings/str_format_test.cc
@@ -8,6 +8,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include "absl/strings/cord.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 
@@ -353,6 +354,7 @@
   EXPECT_EQ(StrFormat("%s", "C"), "C");
   EXPECT_EQ(StrFormat("%s", std::string("C++")), "C++");
   EXPECT_EQ(StrFormat("%s", string_view("view")), "view");
+  EXPECT_EQ(StrFormat("%s", absl::Cord("cord")), "cord");
   // Integral Conversion
   //     These format integral types: char, int, long, uint64_t, etc.
   EXPECT_EQ(StrFormat("%d", char{10}), "10");
diff --git a/absl/time/internal/cctz/include/cctz/time_zone.h b/absl/time/internal/cctz/include/cctz/time_zone.h
index d4ea90e..b33e0c0 100644
--- a/absl/time/internal/cctz/include/cctz/time_zone.h
+++ b/absl/time/internal/cctz/include/cctz/time_zone.h
@@ -292,6 +292,7 @@
 //   - %E#f - Fractional seconds with # digits of precision
 //   - %E*f - Fractional seconds with full precision (a literal '*')
 //   - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
+//   - %ET  - The RFC3339 "date-time" separator "T"
 //
 // Note that %E0S behaves like %S, and %E0f produces no characters. In
 // contrast %E*f always produces at least one digit, which may be '0'.
@@ -321,7 +322,7 @@
 // returns the corresponding time_point. Uses strftime()-like formatting
 // options, with the same extensions as cctz::format(), but with the
 // exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez
-// and %E*z also accept the same inputs.
+// and %E*z also accept the same inputs. %ET accepts either 'T' or 't'.
 //
 // %Y consumes as many numeric characters as it can, so the matching data
 // should always be terminated with a non-numeric. %E4Y always consumes
diff --git a/absl/time/internal/cctz/src/cctz_benchmark.cc b/absl/time/internal/cctz/src/cctz_benchmark.cc
index a402760..4e39188 100644
--- a/absl/time/internal/cctz/src/cctz_benchmark.cc
+++ b/absl/time/internal/cctz/src/cctz_benchmark.cc
@@ -97,8 +97,8 @@
 }
 BENCHMARK(BM_PrevWeekday);
 
-const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
-const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
+const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez";
+const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
 
 const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
 const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z";
@@ -991,12 +991,12 @@
 BENCHMARK(BM_Time_FromCivilDay0_Libc);
 
 const char* const kFormats[] = {
-    RFC1123_full,         // 0
-    RFC1123_no_wday,      // 1
-    RFC3339_full,         // 2
-    RFC3339_sec,          // 3
-    "%Y-%m-%dT%H:%M:%S",  // 4
-    "%Y-%m-%d",           // 5
+    RFC1123_full,           // 0
+    RFC1123_no_wday,        // 1
+    RFC3339_full,           // 2
+    RFC3339_sec,            // 3
+    "%Y-%m-%d%ET%H:%M:%S",  // 4
+    "%Y-%m-%d",             // 5
 };
 const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
 
diff --git a/absl/time/internal/cctz/src/time_zone_format.cc b/absl/time/internal/cctz/src/time_zone_format.cc
index 179975e..a442863 100644
--- a/absl/time/internal/cctz/src/time_zone_format.cc
+++ b/absl/time/internal/cctz/src/time_zone_format.cc
@@ -290,6 +290,7 @@
 //   - %E#S - Seconds with # digits of fractional precision
 //   - %E*S - Seconds with full fractional precision (a literal '*')
 //   - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
+//   - %ET  - The RFC3339 "date-time" separator "T"
 //
 // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
 // handled internally for performance reasons.  strftime(3) is slow due to
@@ -448,7 +449,14 @@
     if (*cur != 'E' || ++cur == end) continue;
 
     // Format our extensions.
-    if (*cur == 'z') {
+    if (*cur == 'T') {
+      // Formats %ET.
+      if (cur - 2 != pending) {
+        FormatTM(&result, std::string(pending, cur - 2), tm);
+      }
+      result.append("T");
+      pending = ++cur;
+    } else if (*cur == 'z') {
       // Formats %Ez.
       if (cur - 2 != pending) {
         FormatTM(&result, std::string(pending, cur - 2), tm);
@@ -551,7 +559,7 @@
       } else {
         dp = nullptr;
       }
-    } else if (first == 'Z') {  // Zulu
+    } else if (first == 'Z' || first == 'z') {  // Zulu
       *offset = 0;
     } else {
       dp = nullptr;
@@ -607,7 +615,7 @@
 // Uses strptime(3) to parse the given input.  Supports the same extended
 // format specifiers as format(), although %E#S and %E*S are treated
 // identically (and similarly for %E#f and %E*f).  %Ez and %E*z also accept
-// the same inputs.
+// the same inputs. %ET accepts either 'T' or 't'.
 //
 // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
 // handled internally so that we can normally avoid strptime() altogether
@@ -742,6 +750,15 @@
         data = (*data == '%' ? data + 1 : nullptr);
         continue;
       case 'E':
+        if (fmt[0] == 'T') {
+          if (*data == 'T' || *data == 't') {
+            ++data;
+            ++fmt;
+          } else {
+            data = nullptr;
+          }
+          continue;
+        }
         if (fmt[0] == 'z' || (fmt[0] == '*' && fmt[1] == 'z')) {
           data = ParseOffset(data, ":", &offset);
           if (data != nullptr) saw_offset = true;
diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc
index 87382e1..13a4227 100644
--- a/absl/time/internal/cctz/src/time_zone_format_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_format_test.cc
@@ -48,8 +48,8 @@
     EXPECT_STREQ(zone, al.abbr);                                  \
   } while (0)
 
-const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
-const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
+const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez";
+const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
 
 const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
 const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z";
@@ -1379,10 +1379,20 @@
   EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00+00:00", tz, &tp));
   ExpectTime(tp, tz, 2014, 2, 12, 20, 21, 0, 0, false, "UTC");
 
-  // Check that %Ez also accepts "Z" as a synonym for "+00:00".
+  // Check that %ET also accepts "t".
   time_point<chrono::nanoseconds> tp2;
-  EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp2));
+  EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12t20:21:00+00:00", tz, &tp2));
   EXPECT_EQ(tp, tp2);
+
+  // Check that %Ez also accepts "Z" as a synonym for "+00:00".
+  time_point<chrono::nanoseconds> tp3;
+  EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp3));
+  EXPECT_EQ(tp, tp3);
+
+  // Check that %Ez also accepts "z" as a synonym for "+00:00".
+  time_point<chrono::nanoseconds> tp4;
+  EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00z", tz, &tp4));
+  EXPECT_EQ(tp, tp4);
 }
 
 TEST(Parse, MaxRange) {
diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
index 0b0c1a3..8f7ab15 100644
--- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -933,7 +933,7 @@
 
 // NOTE: Run this with -ftrapv to detect overflow problems.
 TEST(MakeTime, SysSecondsLimits) {
-  const char RFC3339[] = "%Y-%m-%dT%H:%M:%S%Ez";
+  const char RFC3339[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
   const time_zone utc = utc_time_zone();
   const time_zone east = fixed_time_zone(chrono::hours(14));
   const time_zone west = fixed_time_zone(-chrono::hours(14));