about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CMake/AbseilDll.cmake492
-rw-r--r--CMake/AbseilHelpers.cmake231
-rw-r--r--CMake/Googletest/DownloadGTest.cmake10
-rw-r--r--CMakeLists.txt7
-rw-r--r--absl/CMakeLists.txt6
-rw-r--r--absl/base/attributes.h14
-rw-r--r--absl/base/config.h19
-rw-r--r--absl/base/internal/raw_logging.cc5
-rw-r--r--absl/base/internal/raw_logging.h5
-rw-r--r--absl/base/internal/sysinfo.cc28
-rw-r--r--absl/base/internal/thread_identity.cc12
-rw-r--r--absl/base/internal/thread_identity.h9
-rw-r--r--absl/base/options.h9
-rw-r--r--absl/container/btree_map.h24
-rw-r--r--absl/container/btree_test.cc59
-rw-r--r--absl/container/internal/btree_container.h65
-rw-r--r--absl/container/internal/hashtablez_sampler.cc9
-rw-r--r--absl/container/internal/hashtablez_sampler.h13
-rw-r--r--absl/container/internal/hashtablez_sampler_test.cc2
-rw-r--r--absl/container/internal/raw_hash_set_test.cc51
-rw-r--r--absl/copts/AbseilConfigureCopts.cmake7
-rw-r--r--absl/debugging/symbolize_test.cc2
-rw-r--r--absl/flags/BUILD.bazel17
-rw-r--r--absl/flags/flag.cc9
-rw-r--r--absl/flags/flag.h24
-rw-r--r--absl/flags/flag_benchmark.cc111
-rw-r--r--absl/hash/internal/hash.h3
-rw-r--r--absl/numeric/int128.cc4
-rw-r--r--absl/numeric/int128.h2
-rw-r--r--absl/random/BUILD.bazel2
-rw-r--r--absl/random/CMakeLists.txt1
-rw-r--r--absl/random/gaussian_distribution.h3
-rw-r--r--absl/strings/BUILD.bazel5
-rw-r--r--absl/strings/CMakeLists.txt5
-rw-r--r--absl/strings/ascii.cc6
-rw-r--r--absl/strings/ascii.h7
-rw-r--r--absl/strings/internal/charconv_bigint.cc4
-rw-r--r--absl/strings/internal/charconv_bigint.h6
-rw-r--r--absl/strings/internal/str_format/bind.h4
-rw-r--r--absl/strings/internal/str_format/extension.h6
-rw-r--r--absl/strings/numbers.cc7
-rw-r--r--absl/strings/numbers.h9
-rw-r--r--absl/strings/string_view.h25
-rw-r--r--absl/time/format.cc13
-rw-r--r--absl/time/internal/cctz/src/time_zone_fixed.cc28
-rw-r--r--absl/time/internal/cctz/src/time_zone_format_test.cc4
-rw-r--r--absl/time/internal/cctz/src/time_zone_info.cc6
-rw-r--r--absl/time/internal/cctz/src/time_zone_lookup_test.cc15
-rw-r--r--absl/time/time.h87
49 files changed, 1197 insertions, 295 deletions
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
new file mode 100644
index 000000000000..8184d500ba77
--- /dev/null
+++ b/CMake/AbseilDll.cmake
@@ -0,0 +1,492 @@
+include(CMakeParseArguments)
+
+set(ABSL_INTERNAL_DLL_FILES
+  "algorithm/algorithm.h"
+  "algorithm/container.h"
+  "base/attributes.h"
+  "base/call_once.h"
+  "base/casts.h"
+  "base/config.h"
+  "base/const_init.h"
+  "base/dynamic_annotations.cc"
+  "base/dynamic_annotations.h"
+  "base/internal/atomic_hook.h"
+  "base/internal/bits.h"
+  "base/internal/cycleclock.cc"
+  "base/internal/cycleclock.h"
+  "base/internal/direct_mmap.h"
+  "base/internal/endian.h"
+  "base/internal/exponential_biased.cc"
+  "base/internal/exponential_biased.h"
+  "base/internal/hide_ptr.h"
+  "base/internal/identity.h"
+  "base/internal/invoke.h"
+  "base/internal/inline_variable.h"
+  "base/internal/low_level_alloc.cc"
+  "base/internal/low_level_alloc.h"
+  "base/internal/low_level_scheduling.h"
+  "base/internal/per_thread_tls.h"
+  "base/internal/periodic_sampler.cc"
+  "base/internal/periodic_sampler.h"
+  "base/internal/pretty_function.h"
+  "base/internal/raw_logging.cc"
+  "base/internal/raw_logging.h"
+  "base/internal/scheduling_mode.h"
+  "base/internal/scoped_set_env.cc"
+  "base/internal/scoped_set_env.h"
+  "base/internal/spinlock.cc"
+  "base/internal/spinlock.h"
+  "base/internal/spinlock_wait.cc"
+  "base/internal/spinlock_wait.h"
+  "base/internal/sysinfo.cc"
+  "base/internal/sysinfo.h"
+  "base/internal/thread_annotations.h"
+  "base/internal/thread_identity.cc"
+  "base/internal/thread_identity.h"
+  "base/internal/throw_delegate.cc"
+  "base/internal/throw_delegate.h"
+  "base/internal/tsan_mutex_interface.h"
+  "base/internal/unaligned_access.h"
+  "base/internal/unscaledcycleclock.cc"
+  "base/internal/unscaledcycleclock.h"
+  "base/log_severity.cc"
+  "base/log_severity.h"
+  "base/macros.h"
+  "base/optimization.h"
+  "base/options.h"
+  "base/policy_checks.h"
+  "base/port.h"
+  "base/thread_annotations.h"
+  "container/btree_map.h"
+  "container/btree_set.h"
+  "container/fixed_array.h"
+  "container/flat_hash_map.h"
+  "container/flat_hash_set.h"
+  "container/inlined_vector.h"
+  "container/internal/btree.h"
+  "container/internal/btree_container.h"
+  "container/internal/common.h"
+  "container/internal/compressed_tuple.h"
+  "container/internal/container_memory.h"
+  "container/internal/counting_allocator.h"
+  "container/internal/hash_function_defaults.h"
+  "container/internal/hash_policy_traits.h"
+  "container/internal/hashtable_debug.h"
+  "container/internal/hashtable_debug_hooks.h"
+  "container/internal/hashtablez_sampler.cc"
+  "container/internal/hashtablez_sampler.h"
+  "container/internal/hashtablez_sampler_force_weak_definition.cc"
+  "container/internal/have_sse.h"
+  "container/internal/inlined_vector.h"
+  "container/internal/layout.h"
+  "container/internal/node_hash_policy.h"
+  "container/internal/raw_hash_map.h"
+  "container/internal/raw_hash_set.cc"
+  "container/internal/raw_hash_set.h"
+  "container/internal/tracked.h"
+  "container/node_hash_map.h"
+  "container/node_hash_set.h"
+  "debugging/failure_signal_handler.cc"
+  "debugging/failure_signal_handler.h"
+  "debugging/leak_check.h"
+  "debugging/leak_check_disable.cc"
+  "debugging/stacktrace.cc"
+  "debugging/stacktrace.h"
+  "debugging/symbolize.cc"
+  "debugging/symbolize.h"
+  "debugging/internal/address_is_readable.cc"
+  "debugging/internal/address_is_readable.h"
+  "debugging/internal/demangle.cc"
+  "debugging/internal/demangle.h"
+  "debugging/internal/elf_mem_image.cc"
+  "debugging/internal/elf_mem_image.h"
+  "debugging/internal/examine_stack.cc"
+  "debugging/internal/examine_stack.h"
+  "debugging/internal/stack_consumption.cc"
+  "debugging/internal/stack_consumption.h"
+  "debugging/internal/stacktrace_config.h"
+  "debugging/internal/symbolize.h"
+  "debugging/internal/vdso_support.cc"
+  "debugging/internal/vdso_support.h"
+  "functional/function_ref.h"
+  "functional/internal/function_ref.h"
+  "hash/hash.h"
+  "hash/internal/city.h"
+  "hash/internal/city.cc"
+  "hash/internal/hash.h"
+  "hash/internal/hash.cc"
+  "hash/internal/spy_hash_state.h"
+  "memory/memory.h"
+  "meta/type_traits.h"
+  "numeric/int128.cc"
+  "numeric/int128.h"
+  "random/bernoulli_distribution.h"
+  "random/beta_distribution.h"
+  "random/bit_gen_ref.h"
+  "random/discrete_distribution.cc"
+  "random/discrete_distribution.h"
+  "random/distribution_format_traits.h"
+  "random/distributions.h"
+  "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"
+  "random/internal/gaussian_distribution_gentables.cc"
+  "random/internal/generate_real.h"
+  "random/internal/iostream_state_saver.h"
+  "random/internal/nonsecure_base.h"
+  "random/internal/pcg_engine.h"
+  "random/internal/platform.h"
+  "random/internal/pool_urbg.cc"
+  "random/internal/pool_urbg.h"
+  "random/internal/randen.cc"
+  "random/internal/randen.h"
+  "random/internal/randen_detect.cc"
+  "random/internal/randen_detect.h"
+  "random/internal/randen_engine.h"
+  "random/internal/randen_hwaes.cc"
+  "random/internal/randen_hwaes.h"
+  "random/internal/randen_slow.cc"
+  "random/internal/randen_slow.h"
+  "random/internal/randen_traits.h"
+  "random/internal/salted_seed_seq.h"
+  "random/internal/seed_material.cc"
+  "random/internal/seed_material.h"
+  "random/internal/sequence_urbg.h"
+  "random/internal/traits.h"
+  "random/internal/uniform_helper.h"
+  "random/internal/wide_multiply.h"
+  "random/log_uniform_int_distribution.h"
+  "random/poisson_distribution.h"
+  "random/random.h"
+  "random/seed_gen_exception.cc"
+  "random/seed_gen_exception.h"
+  "random/seed_sequences.cc"
+  "random/seed_sequences.h"
+  "random/uniform_int_distribution.h"
+  "random/uniform_real_distribution.h"
+  "random/zipf_distribution.h"
+  "strings/ascii.cc"
+  "strings/ascii.h"
+  "strings/charconv.cc"
+  "strings/charconv.h"
+  "strings/escaping.cc"
+  "strings/escaping.h"
+  "strings/internal/charconv_bigint.cc"
+  "strings/internal/charconv_bigint.h"
+  "strings/internal/charconv_parse.cc"
+  "strings/internal/charconv_parse.h"
+  "strings/internal/escaping.cc"
+  "strings/internal/escaping.h"
+  "strings/internal/stl_type_traits.h"
+  "strings/match.cc"
+  "strings/match.h"
+  "strings/numbers.cc"
+  "strings/numbers.h"
+  "strings/str_format.h"
+  "strings/str_cat.cc"
+  "strings/str_cat.h"
+  "strings/str_join.h"
+  "strings/str_replace.cc"
+  "strings/str_replace.h"
+  "strings/str_split.cc"
+  "strings/str_split.h"
+  "strings/string_view.cc"
+  "strings/string_view.h"
+  "strings/strip.h"
+  "strings/substitute.cc"
+  "strings/substitute.h"
+  "strings/internal/char_map.h"
+  "strings/internal/memutil.cc"
+  "strings/internal/memutil.h"
+  "strings/internal/ostringstream.cc"
+  "strings/internal/ostringstream.h"
+  "strings/internal/pow10_helper.cc"
+  "strings/internal/pow10_helper.h"
+  "strings/internal/resize_uninitialized.h"
+  "strings/internal/str_format/arg.cc"
+  "strings/internal/str_format/arg.h"
+  "strings/internal/str_format/bind.cc"
+  "strings/internal/str_format/bind.h"
+  "strings/internal/str_format/checker.h"
+  "strings/internal/str_format/extension.cc"
+  "strings/internal/str_format/extension.h"
+  "strings/internal/str_format/float_conversion.cc"
+  "strings/internal/str_format/float_conversion.h"
+  "strings/internal/str_format/output.cc"
+  "strings/internal/str_format/output.h"
+  "strings/internal/str_format/parser.cc"
+  "strings/internal/str_format/parser.h"
+  "strings/internal/str_join_internal.h"
+  "strings/internal/str_split_internal.h"
+  "strings/internal/utf8.cc"
+  "strings/internal/utf8.h"
+  "synchronization/barrier.cc"
+  "synchronization/barrier.h"
+  "synchronization/blocking_counter.cc"
+  "synchronization/blocking_counter.h"
+  "synchronization/mutex.cc"
+  "synchronization/mutex.h"
+  "synchronization/notification.cc"
+  "synchronization/notification.h"
+  "synchronization/internal/create_thread_identity.cc"
+  "synchronization/internal/create_thread_identity.h"
+  "synchronization/internal/graphcycles.cc"
+  "synchronization/internal/graphcycles.h"
+  "synchronization/internal/kernel_timeout.h"
+  "synchronization/internal/per_thread_sem.cc"
+  "synchronization/internal/per_thread_sem.h"
+  "synchronization/internal/thread_pool.h"
+  "synchronization/internal/waiter.cc"
+  "synchronization/internal/waiter.h"
+  "time/civil_time.cc"
+  "time/civil_time.h"
+  "time/clock.cc"
+  "time/clock.h"
+  "time/duration.cc"
+  "time/format.cc"
+  "time/time.cc"
+  "time/time.h"
+  "time/internal/cctz/include/cctz/civil_time.h"
+  "time/internal/cctz/include/cctz/civil_time_detail.h"
+  "time/internal/cctz/include/cctz/time_zone.h"
+  "time/internal/cctz/include/cctz/zone_info_source.h"
+  "time/internal/cctz/src/civil_time_detail.cc"
+  "time/internal/cctz/src/time_zone_fixed.cc"
+  "time/internal/cctz/src/time_zone_fixed.h"
+  "time/internal/cctz/src/time_zone_format.cc"
+  "time/internal/cctz/src/time_zone_if.cc"
+  "time/internal/cctz/src/time_zone_if.h"
+  "time/internal/cctz/src/time_zone_impl.cc"
+  "time/internal/cctz/src/time_zone_impl.h"
+  "time/internal/cctz/src/time_zone_info.cc"
+  "time/internal/cctz/src/time_zone_info.h"
+  "time/internal/cctz/src/time_zone_libc.cc"
+  "time/internal/cctz/src/time_zone_libc.h"
+  "time/internal/cctz/src/time_zone_lookup.cc"
+  "time/internal/cctz/src/time_zone_posix.cc"
+  "time/internal/cctz/src/time_zone_posix.h"
+  "time/internal/cctz/src/tzfile.h"
+  "time/internal/cctz/src/zone_info_source.cc"
+  "types/any.h"
+  "types/bad_any_cast.cc"
+  "types/bad_any_cast.h"
+  "types/bad_optional_access.cc"
+  "types/bad_optional_access.h"
+  "types/bad_variant_access.cc"
+  "types/bad_variant_access.h"
+  "types/compare.h"
+  "types/internal/conformance_aliases.h"
+  "types/internal/conformance_archetype.h"
+  "types/internal/conformance_profile.h"
+  "types/internal/variant.h"
+  "types/optional.h"
+  "types/internal/optional.h"
+  "types/span.h"
+  "types/internal/span.h"
+  "types/variant.h"
+  "utility/utility.h"
+)
+
+set(ABSL_INTERNAL_DLL_TARGETS
+  "stacktrace"
+  "symbolize"
+  "examine_stack"
+  "failure_signal_handler"
+  "debugging_internal"
+  "demangle_internal"
+  "leak_check"
+  "leak_check_disable"
+  "stack_consumption"
+  "debugging"
+  "hash"
+  "spy_hash_state"
+  "city"
+  "memory"
+  "strings"
+  "strings_internal"
+  "str_format"
+  "str_format_internal"
+  "pow10_helper"
+  "int128"
+  "numeric"
+  "utility"
+  "any"
+  "bad_any_cast"
+  "bad_any_cast_impl"
+  "span"
+  "optional"
+  "bad_optional_access"
+  "bad_variant_access"
+  "variant"
+  "compare"
+  "algorithm"
+  "algorithm_container"
+  "graphcycles_internal"
+  "kernel_timeout_internal"
+  "synchronization"
+  "thread_pool"
+  "bind_front"
+  "function_ref"
+  "atomic_hook"
+  "log_severity"
+  "raw_logging_internal"
+  "spinlock_wait"
+  "config"
+  "dynamic_annotations"
+  "core_headers"
+  "malloc_internal"
+  "base_internal"
+  "base"
+  "throw_delegate"
+  "pretty_function"
+  "endian"
+  "bits"
+  "exponential_biased"
+  "periodic_sampler"
+  "scoped_set_env"
+  "type_traits"
+  "meta"
+  "random_random"
+  "random_bit_gen_ref"
+  "random_distributions"
+  "random_seed_gen_exception"
+  "random_seed_sequences"
+  "random_internal_traits"
+  "random_internal_distribution_caller"
+  "random_internal_distributions"
+  "random_internal_fast_uniform_bits"
+  "random_internal_seed_material"
+  "random_internal_pool_urbg"
+  "random_internal_explicit_seed_seq"
+  "random_internal_sequence_urbg"
+  "random_internal_salted_seed_seq"
+  "random_internal_iostream_state_saver"
+  "random_internal_generate_real"
+  "random_internal_wide_multiply"
+  "random_internal_fastmath"
+  "random_internal_nonsecure_base"
+  "random_internal_pcg_engine"
+  "random_internal_randen_engine"
+  "random_internal_platform"
+  "random_internal_randen"
+  "random_internal_randen_slow"
+  "random_internal_randen_hwaes"
+  "random_internal_randen_hwaes_impl"
+  "random_internal_uniform_helper"
+  "time"
+  "civil_time"
+  "time_zone"
+  "container"
+  "btree"
+  "compressed_tuple"
+  "fixed_array"
+  "inlined_vector_internal"
+  "inlined_vector"
+  "counting_allocator"
+  "flat_hash_map"
+  "flat_hash_set"
+  "node_hash_map"
+  "node_hash_set"
+  "container_memory"
+  "hash_function_defaults"
+  "hash_policy_traits"
+  "hashtablez_sampler"
+  "hashtable_debug"
+  "hashtable_debug_hooks"
+  "have_sse"
+  "node_hash_policy"
+  "raw_hash_map"
+  "container_common"
+  "raw_hash_set"
+  "layout"
+  "tracked"
+)
+
+function(absl_internal_dll_contains)
+  cmake_parse_arguments(ABSL_INTERNAL_DLL
+    ""
+    "OUTPUT;TARGET"
+    ""
+    ${ARGN}
+  )
+
+  STRING(REGEX REPLACE "^absl::" "" _target ${ABSL_INTERNAL_DLL_TARGET})
+
+  list(FIND
+    ABSL_INTERNAL_DLL_TARGETS
+    "${_target}"
+    _index)
+
+  if (${_index} GREATER -1)
+    set(${ABSL_INTERNAL_DLL_OUTPUT} 1 PARENT_SCOPE)
+  else()
+    set(${ABSL_INTERNAL_DLL_OUTPUT} 0 PARENT_SCOPE)
+  endif()
+endfunction()
+
+function(absl_internal_dll_targets)
+  cmake_parse_arguments(ABSL_INTERNAL_DLL
+  ""
+  "OUTPUT"
+  "DEPS"
+  ${ARGN}
+  )
+
+  set(_deps "")
+  foreach(dep IN LISTS ABSL_INTERNAL_DLL_DEPS)
+    absl_internal_dll_contains(TARGET ${dep} OUTPUT _contains)
+    if (_contains)
+      list(APPEND _deps abseil_dll)
+    else()
+      list(APPEND _deps ${dep})
+    endif()
+  endforeach()
+
+  # Because we may have added the DLL multiple times
+  list(REMOVE_DUPLICATES _deps)
+  set(${ABSL_INTERNAL_DLL_OUTPUT} "${_deps}" PARENT_SCOPE)
+endfunction()
+
+function(absl_make_dll)
+  add_library(
+    abseil_dll
+    SHARED
+      "${ABSL_INTERNAL_DLL_FILES}"
+  )
+  target_link_libraries(
+    abseil_dll
+    PRIVATE
+      ${ABSL_DEFAULT_LINKOPTS}
+  )
+  set_property(TARGET abseil_dll PROPERTY LINKER_LANGUAGE "CXX")
+  target_include_directories(
+    abseil_dll
+    PUBLIC
+      "$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
+      $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
+  )
+
+  target_compile_options(
+    abseil_dll
+    PRIVATE
+      ${ABSL_DEFAULT_COPTS}
+  )
+
+  target_compile_definitions(
+    abseil_dll
+    PRIVATE
+      ABSL_BUILD_DLL
+      NOMINMAX
+    INTERFACE
+      ${ABSL_CC_LIB_DEFINES}
+  )
+  install(TARGETS abseil_dll EXPORT ${PROJECT_NAME}Targets
+        RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR}
+        LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR}
+        ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR}
+  )
+endfunction()
diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake
index 28fefaa67efe..7571ef1b15ce 100644
--- a/CMake/AbseilHelpers.cmake
+++ b/CMake/AbseilHelpers.cmake
@@ -16,6 +16,7 @@
 
 include(CMakeParseArguments)
 include(AbseilConfigureCopts)
+include(AbseilDll)
 include(AbseilInstallDirs)
 
 # The IDE folder for Abseil that will be used if Abseil is included in a CMake
@@ -80,98 +81,169 @@ function(absl_cc_library)
     ${ARGN}
   )
 
-  if(NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS)
-    if(ABSL_ENABLE_INSTALL)
-      set(_NAME "${ABSL_CC_LIB_NAME}")
-    else()
-      set(_NAME "absl_${ABSL_CC_LIB_NAME}")
+  if(ABSL_CC_LIB_TESTONLY AND NOT ABSL_RUN_TESTS)
+    return()
+  endif()
+
+  if(ABSL_ENABLE_INSTALL)
+    set(_NAME "${ABSL_CC_LIB_NAME}")
+  else()
+    set(_NAME "absl_${ABSL_CC_LIB_NAME}")
+  endif()
+
+  # Check if this is a header-only library
+  # Note that as of February 2019, many popular OS's (for example, Ubuntu
+  # 16.04 LTS) only come with cmake 3.5 by default.  For this reason, we can't
+  # use list(FILTER...)
+  set(ABSL_CC_SRCS "${ABSL_CC_LIB_SRCS}")
+  foreach(src_file IN LISTS ABSL_CC_SRCS)
+    if(${src_file} MATCHES ".*\\.(h|inc)")
+      list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}")
     endif()
+  endforeach()
 
-    # Check if this is a header-only library
-    # Note that as of February 2019, many popular OS's (for example, Ubuntu
-    # 16.04 LTS) only come with cmake 3.5 by default.  For this reason, we can't
-    # use list(FILTER...)
-    set(ABSL_CC_SRCS "${ABSL_CC_LIB_SRCS}")
-    foreach(src_file IN LISTS ABSL_CC_SRCS)
-      if(${src_file} MATCHES ".*\\.(h|inc)")
-        list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}")
-      endif()
-    endforeach()
-    if("${ABSL_CC_SRCS}" STREQUAL "")
+  if("${ABSL_CC_SRCS}" STREQUAL "")
+    set(ABSL_CC_LIB_IS_INTERFACE 1)
+  else()
+    set(ABSL_CC_LIB_IS_INTERFACE 0)
+  endif()
+
+  # Determine this build target's relationship to the DLL. It's one of three things:
+  # 1. "dll"     -- This target is part of the DLL
+  # 2. "dll_dep" -- This target is not part of the DLL, but depends on the DLL.
+  #                 Note that we assume any target not in the DLL depends on the
+  #                 DLL. This is not a technical necessity but a convenience
+  #                 which happens to be true, because nearly every target is
+  #                 part of the DLL.
+  # 3. "static"  -- This target does not depend on the DLL and should be built
+  #                 statically.
+  if (${ABSL_BUILD_DLL})
+    absl_internal_dll_contains(TARGET ${_NAME} OUTPUT _in_dll)
+    if (${_in_dll})
+      # This target should be replaced by the DLL
+      set(_build_type "dll")
       set(ABSL_CC_LIB_IS_INTERFACE 1)
     else()
-      set(ABSL_CC_LIB_IS_INTERFACE 0)
+      # Building a DLL, but this target is not part of the DLL
+      set(_build_type "dll_dep")
     endif()
+  else()
+    set(_build_type "static")
+  endif()
 
-    if(NOT ABSL_CC_LIB_IS_INTERFACE)
-      # CMake creates static libraries by default. Users can specify
-      # -DBUILD_SHARED_LIBS=ON during initial configuration to build shared
-      # libraries instead.
-      add_library(${_NAME} "")
+  if(NOT ABSL_CC_LIB_IS_INTERFACE)
+    if(${_build_type} STREQUAL "dll_dep")
+      # This target depends on the DLL. When adding dependencies to this target,
+      # any depended-on-target which is contained inside the DLL is replaced
+      # with a dependency on the DLL.
+      add_library(${_NAME} STATIC "")
       target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS})
-      target_include_directories(${_NAME}
-        PUBLIC
-          "$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
-          $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
+      absl_internal_dll_targets(
+        DEPS ${ABSL_CC_LIB_DEPS}
+        OUTPUT _dll_deps
       )
-      target_compile_options(${_NAME}
-        PRIVATE ${ABSL_CC_LIB_COPTS})
       target_link_libraries(${_NAME}
-        PUBLIC ${ABSL_CC_LIB_DEPS}
+        PUBLIC ${_dll_deps}
         PRIVATE
           ${ABSL_CC_LIB_LINKOPTS}
           ${ABSL_DEFAULT_LINKOPTS}
       )
-      target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES})
 
-      # Add all Abseil targets to a a folder in the IDE for organization.
-      if(ABSL_CC_LIB_PUBLIC)
-        set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER})
-      elseif(ABSL_CC_LIB_TESTONLY)
-        set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test)
+      if (ABSL_CC_LIB_TESTONLY)
+        set(_gtest_link_define "GTEST_LINKED_AS_SHARED_LIBRARY=1")
       else()
-        set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal)
+        set(_gtest_link_define)
       endif()
 
-      # INTERFACE libraries can't have the CXX_STANDARD property set
-      set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD})
-      set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
-
-      # When being installed, we lose the absl_ prefix.  We want to put it back
-      # to have properly named lib files.  This is a no-op when we are not being
-      # installed.
-      set_target_properties(${_NAME} PROPERTIES
-        OUTPUT_NAME "absl_${_NAME}"
+      target_compile_definitions(${_NAME}
+        PUBLIC
+          ABSL_CONSUME_DLL
+          "${_gtest_link_define}"
       )
-    else()
-      # Generating header-only library
-      add_library(${_NAME} INTERFACE)
-      target_include_directories(${_NAME}
-        INTERFACE
-          "$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
-          $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
-        )
+
+    elseif(${_build_type} STREQUAL "static")
+      add_library(${_NAME} STATIC "")
+      target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS})
       target_link_libraries(${_NAME}
-        INTERFACE
-          ${ABSL_CC_LIB_DEPS}
-          ${ABSL_CC_LIB_LINKOPTS}
-          ${ABSL_DEFAULT_LINKOPTS}
+      PUBLIC ${ABSL_CC_LIB_DEPS}
+      PRIVATE
+        ${ABSL_CC_LIB_LINKOPTS}
+        ${ABSL_DEFAULT_LINKOPTS}
       )
-      target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES})
+    else()
+      message(FATAL_ERROR "Invalid build type: ${_build_type}")
     endif()
 
-    # TODO currently we don't install googletest alongside abseil sources, so
-    # installed abseil can't be tested.
-    if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL)
-      install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets
-            RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR}
-            LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR}
-            ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR}
+    # Linker language can be inferred from sources, but in the case of DLLs we
+    # don't have any .cc files so it would be ambiguous. We could set it
+    # explicitly only in the case of DLLs but, because "CXX" is always the
+    # correct linker language for static or for shared libraries, we set it
+    # unconditionally.
+    set_property(TARGET ${_NAME} PROPERTY LINKER_LANGUAGE "CXX")
+
+    target_include_directories(${_NAME}
+      PUBLIC
+        "$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
+        $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
+    )
+    target_compile_options(${_NAME}
+      PRIVATE ${ABSL_CC_LIB_COPTS})
+    target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES})
+
+    # Add all Abseil targets to a a folder in the IDE for organization.
+    if(ABSL_CC_LIB_PUBLIC)
+      set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER})
+    elseif(ABSL_CC_LIB_TESTONLY)
+      set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test)
+    else()
+      set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal)
+    endif()
+
+    # INTERFACE libraries can't have the CXX_STANDARD property set
+    set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD})
+    set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
+
+    # When being installed, we lose the absl_ prefix.  We want to put it back
+    # to have properly named lib files.  This is a no-op when we are not being
+    # installed.
+    if(ABSL_ENABLE_INSTALL)
+      set_target_properties(${_NAME} PROPERTIES
+        OUTPUT_NAME "absl_${_NAME}"
       )
     endif()
+  else()
+    # Generating header-only library
+    add_library(${_NAME} INTERFACE)
+    target_include_directories(${_NAME}
+      INTERFACE
+        "$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
+        $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
+      )
 
-    add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME})
+    if (${_build_type} STREQUAL "dll")
+        set(ABSL_CC_LIB_DEPS abseil_dll)
+    endif()
+
+    target_link_libraries(${_NAME}
+      INTERFACE
+        ${ABSL_CC_LIB_DEPS}
+        ${ABSL_CC_LIB_LINKOPTS}
+        ${ABSL_DEFAULT_LINKOPTS}
+    )
+    target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES})
+  endif()
+
+  # TODO currently we don't install googletest alongside abseil sources, so
+  # installed abseil can't be tested.
+  if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL)
+    install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets
+          RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR}
+          LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR}
+          ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR}
+    )
   endif()
+
+    add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME})
 endfunction()
 
 # absl_cc_test()
@@ -224,23 +296,42 @@ function(absl_cc_test)
   )
 
   set(_NAME "absl_${ABSL_CC_TEST_NAME}")
+
   add_executable(${_NAME} "")
   target_sources(${_NAME} PRIVATE ${ABSL_CC_TEST_SRCS})
   target_include_directories(${_NAME}
     PUBLIC ${ABSL_COMMON_INCLUDE_DIRS}
     PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS}
   )
-  target_compile_definitions(${_NAME}
-    PUBLIC ${ABSL_CC_TEST_DEFINES}
-  )
+
+  if (${ABSL_BUILD_DLL})
+    target_compile_definitions(${_NAME}
+      PUBLIC
+        ${ABSL_CC_TEST_DEFINES}
+        ABSL_CONSUME_DLL
+        GTEST_LINKED_AS_SHARED_LIBRARY=1
+    )
+
+    # Replace dependencies on targets inside the DLL with abseil_dll itself.
+    absl_internal_dll_targets(
+      DEPS ${ABSL_CC_TEST_DEPS}
+      OUTPUT ABSL_CC_TEST_DEPS
+    )
+  else()
+    target_compile_definitions(${_NAME}
+      PUBLIC
+        ${ABSL_CC_TEST_DEFINES}
+    )
+  endif()
   target_compile_options(${_NAME}
     PRIVATE ${ABSL_CC_TEST_COPTS}
   )
+
   target_link_libraries(${_NAME}
     PUBLIC ${ABSL_CC_TEST_DEPS}
     PRIVATE ${ABSL_CC_TEST_LINKOPTS}
   )
-  # Add all Abseil targets to a a folder in the IDE for organization.
+  # Add all Abseil targets to a folder in the IDE for organization.
   set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test)
 
   set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD})
diff --git a/CMake/Googletest/DownloadGTest.cmake b/CMake/Googletest/DownloadGTest.cmake
index 3c682aef07f3..8a00b4550c7e 100644
--- a/CMake/Googletest/DownloadGTest.cmake
+++ b/CMake/Googletest/DownloadGTest.cmake
@@ -7,6 +7,13 @@ configure_file(
   ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt
 )
 
+set(ABSL_SAVE_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+set(ABSL_SAVE_CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+if (BUILD_SHARED_LIBS)
+  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_CREATE_SHARED_LIBRARY=1")
+endif()
+
 # Configure and build the downloaded googletest source
 execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
   RESULT_VARIABLE result
@@ -22,6 +29,9 @@ if(result)
   message(FATAL_ERROR "Build step for googletest failed: ${result}")
 endif()
 
+set(CMAKE_CXX_FLAGS ${ABSL_SAVE_CMAKE_CXX_FLAGS})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ABSL_SAVE_CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+
 # Prevent overriding the parent project's compiler/linker settings on Windows
 set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 86f56344e74e..fdfb2cfa864f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,12 @@ cmake_policy(SET CMP0048 NEW)
 
 project(absl CXX)
 
+# Output directory is correct by default for most build setups. However, when
+# building Abseil as a DLL, it is important to have the DLL in the same
+# directory as the executable using it. Thus, we put all executables in a single
+# /bin directory.
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
 # when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp))
 # in the source tree of a project that uses it, install rules are disabled.
 if(NOT "^${CMAKE_SOURCE_DIR}$" STREQUAL "^${PROJECT_SOURCE_DIR}$")
@@ -47,6 +53,7 @@ list(APPEND CMAKE_MODULE_PATH
 
 include(AbseilInstallDirs)
 include(CMakePackageConfigHelpers)
+include(AbseilDll)
 include(AbseilHelpers)
 
 
diff --git a/absl/CMakeLists.txt b/absl/CMakeLists.txt
index 3e78397c9762..a1b1f8d8db9b 100644
--- a/absl/CMakeLists.txt
+++ b/absl/CMakeLists.txt
@@ -14,8 +14,6 @@
 # limitations under the License.
 #
 
-
-
 add_subdirectory(base)
 add_subdirectory(algorithm)
 add_subdirectory(container)
@@ -31,3 +29,7 @@ add_subdirectory(synchronization)
 add_subdirectory(time)
 add_subdirectory(types)
 add_subdirectory(utility)
+
+if (${ABSL_BUILD_DLL})
+  absl_make_dll()
+endif()
diff --git a/absl/base/attributes.h b/absl/base/attributes.h
index acd1c5269829..8f77db77d23a 100644
--- a/absl/base/attributes.h
+++ b/absl/base/attributes.h
@@ -563,7 +563,19 @@
 
 // ABSL_ATTRIBUTE_PACKED
 //
-// Prevents the compiler from padding a structure to natural alignment
+// Instructs the compiler not to use natural alignment for a tagged data
+// structure, but instead to reduce its alignment to 1. This attribute can
+// either be applied to members of a structure or to a structure in its
+// entirety. Applying this attribute (judiciously) to a structure in its
+// entirety to optimize the memory footprint of very commonly-used structs is
+// fine. Do not apply this attribute to a structure in its entirety if the
+// purpose is to control the offsets of the members in the structure. Instead,
+// apply this attribute only to structure members that need it.
+//
+// When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the
+// natural alignment of structure members not annotated is preserved. Aligned
+// member accesses are faster than non-aligned member accesses even if the
+// targeted microprosessor supports non-aligned accesses.
 #if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__))
 #define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__))
 #else
diff --git a/absl/base/config.h b/absl/base/config.h
index c4e8dce403bb..eac5d268e10a 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -643,4 +643,23 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
 
 #undef ABSL_INTERNAL_HAS_KEYWORD
 
+// ABSL_DLL
+//
+// When building Abseil as a DLL, this macro expands to `__declspec(dllexport)`
+// so we can annotate symbols appropriately as being exported. When used in
+// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so
+// that consumers know the symbol is defined inside the DLL. In all other cases,
+// the macro expands to nothing.
+#if defined(_MSC_VER)
+#if defined(ABSL_BUILD_DLL)
+#define ABSL_DLL __declspec(dllexport)
+#elif defined(ABSL_CONSUME_DLL)
+#define ABSL_DLL __declspec(dllimport)
+#else
+#define ABSL_DLL
+#endif
+#else
+#define ABSL_DLL
+#endif  // defined(_MSC_VER)
+
 #endif  // ABSL_BASE_CONFIG_H_
diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc
index d79c5486658e..e36eb29abf97 100644
--- a/absl/base/internal/raw_logging.cc
+++ b/absl/base/internal/raw_logging.cc
@@ -225,8 +225,9 @@ bool RawLoggingFullySupported() {
 #endif  // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
 }
 
-ABSL_CONST_INIT absl::base_internal::AtomicHook<InternalLogFunction>
-    internal_log_function(DefaultInternalLog);
+ABSL_CONST_INIT ABSL_DLL
+    absl::base_internal::AtomicHook<InternalLogFunction>
+        internal_log_function(DefaultInternalLog);
 
 void RegisterInternalLogFunction(InternalLogFunction func) {
   internal_log_function.Store(func);
diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h
index cff45058b3d5..ac74f97dc3ae 100644
--- a/absl/base/internal/raw_logging.h
+++ b/absl/base/internal/raw_logging.h
@@ -22,9 +22,11 @@
 #include <string>
 
 #include "absl/base/attributes.h"
+#include "absl/base/config.h"
 #include "absl/base/internal/atomic_hook.h"
 #include "absl/base/log_severity.h"
 #include "absl/base/macros.h"
+#include "absl/base/optimization.h"
 #include "absl/base/port.h"
 
 // This is similar to LOG(severity) << format..., but
@@ -168,7 +170,8 @@ using InternalLogFunction = void (*)(absl::LogSeverity severity,
                                      const char* file, int line,
                                      const std::string& message);
 
-extern base_internal::AtomicHook<InternalLogFunction> internal_log_function;
+ABSL_DLL extern base_internal::AtomicHook<InternalLogFunction>
+    internal_log_function;
 
 void RegisterInternalLogFunction(InternalLogFunction func);
 
diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc
index 7945322f582e..a0930e978183 100644
--- a/absl/base/internal/sysinfo.cc
+++ b/absl/base/internal/sysinfo.cc
@@ -58,10 +58,6 @@ namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace base_internal {
 
-static once_flag init_system_info_once;
-static int num_cpus = 0;
-static double nominal_cpu_frequency = 1.0;  // 0.0 might be dangerous.
-
 static int GetNumCPUs() {
 #if defined(__myriad2__)
   return 1;
@@ -265,21 +261,27 @@ static double GetNominalCPUFrequency() {
 
 #endif
 
-// InitializeSystemInfo() may be called before main() and before
-// malloc is properly initialized, therefore this must not allocate
-// memory.
-static void InitializeSystemInfo() {
-  num_cpus = GetNumCPUs();
-  nominal_cpu_frequency = GetNominalCPUFrequency();
-}
+ABSL_CONST_INIT static once_flag init_num_cpus_once;
+ABSL_CONST_INIT static int num_cpus = 0;
 
+// NumCPUs() may be called before main() and before malloc is properly
+// initialized, therefore this must not allocate memory.
 int NumCPUs() {
-  base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo);
+  base_internal::LowLevelCallOnce(
+      &init_num_cpus_once, []() { num_cpus = GetNumCPUs(); });
   return num_cpus;
 }
 
+// A default frequency of 0.0 might be dangerous if it is used in division.
+ABSL_CONST_INIT static once_flag init_nominal_cpu_frequency_once;
+ABSL_CONST_INIT static double nominal_cpu_frequency = 1.0;
+
+// NominalCPUFrequency() may be called before main() and before malloc is
+// properly initialized, therefore this must not allocate memory.
 double NominalCPUFrequency() {
-  base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo);
+  base_internal::LowLevelCallOnce(
+      &init_nominal_cpu_frequency_once,
+      []() { nominal_cpu_frequency = GetNominalCPUFrequency(); });
   return nominal_cpu_frequency;
 }
 
diff --git a/absl/base/internal/thread_identity.cc b/absl/base/internal/thread_identity.cc
index 6a28f246dbdb..d63a04ae91d5 100644
--- a/absl/base/internal/thread_identity.cc
+++ b/absl/base/internal/thread_identity.cc
@@ -113,6 +113,18 @@ void SetCurrentThreadIdentity(
 #endif
 }
 
+#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
+    ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
+
+// Please see the comment on `CurrentThreadIdentityIfPresent` in
+// thread_identity.h. Because DLLs cannot expose thread_local variables in
+// headers, we opt for the correct-but-slower option of placing the definition
+// of this function only in a translation unit inside DLL.
+#if defined(ABSL_BUILD_DLL) || defined(ABSL_CONSUME_DLL)
+ThreadIdentity* CurrentThreadIdentityIfPresent() { return thread_identity_ptr; }
+#endif
+#endif
+
 void ClearCurrentThreadIdentity() {
 #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
     ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h
index 5dfd0715dc5d..ceb109b41c6a 100644
--- a/absl/base/internal/thread_identity.h
+++ b/absl/base/internal/thread_identity.h
@@ -30,6 +30,7 @@
 #include <atomic>
 #include <cstdint>
 
+#include "absl/base/config.h"
 #include "absl/base/internal/per_thread_tls.h"
 
 namespace absl {
@@ -234,9 +235,17 @@ ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr;
 #error Thread-local storage not detected on this platform
 #endif
 
+// thread_local variables cannot be in headers exposed by DLLs. However, it is
+// important for performance reasons in general that
+// `CurrentThreadIdentityIfPresent` be inlined. This is not possible across a
+// DLL boundary so, with DLLs, we opt to have the function not be inlined. Note
+// that `CurrentThreadIdentityIfPresent` is declared above so we can exclude
+// this entire inline definition when compiling as a DLL.
+#if !defined(ABSL_BUILD_DLL) && !defined(ABSL_CONSUME_DLL)
 inline ThreadIdentity* CurrentThreadIdentityIfPresent() {
   return thread_identity_ptr;
 }
+#endif
 
 #elif ABSL_THREAD_IDENTITY_MODE != \
     ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
diff --git a/absl/base/options.h b/absl/base/options.h
index 592b33b734d7..6868c77b103a 100644
--- a/absl/base/options.h
+++ b/absl/base/options.h
@@ -66,7 +66,13 @@
 // NOTE: the defaults within this file all assume that Abseil can select the
 // proper Abseil implementation at compile-time, which will not be sufficient
 // to guarantee ABI stability to package managers.
-//
+
+// Include a standard library header to allow configuration based on the
+// standard library in use.
+#ifdef __cplusplus
+#include <ciso646>
+#endif
+
 // -----------------------------------------------------------------------------
 // Type Compatibility Options
 // -----------------------------------------------------------------------------
@@ -158,7 +164,6 @@
 
 #define ABSL_OPTION_USE_STD_STRING_VIEW 2
 
-
 // ABSL_OPTION_USE_STD_VARIANT
 //
 // This option controls whether absl::variant is implemented as an alias to
diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h
index cbfcb58c4129..d23f4ee5e648 100644
--- a/absl/container/btree_map.h
+++ b/absl/container/btree_map.h
@@ -226,6 +226,30 @@ class btree_map
   //   Inserts the elements within the initializer list `ilist`.
   using Base::insert;
 
+  // btree_map::insert_or_assign()
+  //
+  // Inserts an element of the specified value into the `btree_map` provided
+  // that a value with the given key does not already exist, or replaces the
+  // corresponding mapped type with the forwarded `obj` argument if a key for
+  // that value already exists, returning an iterator pointing to the newly
+  // inserted element. Overloads are listed below.
+  //
+  // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj):
+  // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj):
+  //
+  //   Inserts/Assigns (or moves) the element of the specified key into the
+  //   `btree_map`. If the returned bool is true, insertion took place, and if
+  //   it's false, assignment took place.
+  //
+  // iterator insert_or_assign(const_iterator hint,
+  //                           const key_type& k, M&& obj):
+  // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj):
+  //
+  //   Inserts/Assigns (or moves) the element of the specified key into the
+  //   `btree_map` using the position of `hint` as a non-binding suggestion
+  //   for where to begin the insertion search.
+  using Base::insert_or_assign;
+
   // btree_map::emplace()
   //
   // Inserts an element of the specified value by constructing it in-place
diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc
index 8692b9c2b9d7..af8ee00b3524 100644
--- a/absl/container/btree_test.cc
+++ b/absl/container/btree_test.cc
@@ -2345,6 +2345,65 @@ TEST(Btree, EraseIf) {
   }
 }
 
+TEST(Btree, InsertOrAssign) {
+  absl::btree_map<int, int> m = {{1, 1}, {3, 3}};
+  using value_type = typename decltype(m)::value_type;
+
+  auto ret = m.insert_or_assign(4, 4);
+  EXPECT_EQ(*ret.first, value_type(4, 4));
+  EXPECT_TRUE(ret.second);
+  ret = m.insert_or_assign(3, 100);
+  EXPECT_EQ(*ret.first, value_type(3, 100));
+  EXPECT_FALSE(ret.second);
+
+  auto hint_ret = m.insert_or_assign(ret.first, 3, 200);
+  EXPECT_EQ(*hint_ret, value_type(3, 200));
+  hint_ret = m.insert_or_assign(m.find(1), 0, 1);
+  EXPECT_EQ(*hint_ret, value_type(0, 1));
+  // Test with bad hint.
+  hint_ret = m.insert_or_assign(m.end(), -1, 1);
+  EXPECT_EQ(*hint_ret, value_type(-1, 1));
+
+  EXPECT_THAT(m, ElementsAre(Pair(-1, 1), Pair(0, 1), Pair(1, 1), Pair(3, 200),
+                             Pair(4, 4)));
+}
+
+TEST(Btree, InsertOrAssignMovableOnly) {
+  absl::btree_map<int, MovableOnlyInstance> m;
+  using value_type = typename decltype(m)::value_type;
+
+  auto ret = m.insert_or_assign(4, MovableOnlyInstance(4));
+  EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(4)));
+  EXPECT_TRUE(ret.second);
+  ret = m.insert_or_assign(4, MovableOnlyInstance(100));
+  EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(100)));
+  EXPECT_FALSE(ret.second);
+
+  auto hint_ret = m.insert_or_assign(ret.first, 3, MovableOnlyInstance(200));
+  EXPECT_EQ(*hint_ret, value_type(3, MovableOnlyInstance(200)));
+
+  EXPECT_EQ(m.size(), 2);
+}
+
+TEST(Btree, BitfieldArgument) {
+  union {
+    int n : 1;
+  };
+  n = 0;
+  absl::btree_map<int, int> m;
+  m.erase(n);
+  m.count(n);
+  m.find(n);
+  m.contains(n);
+  m.equal_range(n);
+  m.insert_or_assign(n, n);
+  m.insert_or_assign(m.end(), n, n);
+  m.try_emplace(n);
+  m.try_emplace(m.end(), n);
+  m.at(n);
+  m[n];
+}
+
 }  // namespace
 }  // namespace container_internal
 ABSL_NAMESPACE_END
diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h
index 04795c2e3f0a..3e6ff4b892f1 100644
--- a/absl/container/internal/btree_container.h
+++ b/absl/container/internal/btree_container.h
@@ -372,7 +372,7 @@ class btree_map_container : public btree_set_container<Tree> {
   using super_type = btree_set_container<Tree>;
   using params_type = typename Tree::params_type;
 
- protected:
+ private:
   template <class K>
   using key_arg = typename super_type::template key_arg<K>;
 
@@ -390,6 +390,69 @@ class btree_map_container : public btree_set_container<Tree> {
   btree_map_container() {}
 
   // Insertion routines.
+  // Note: the nullptr template arguments and extra `const M&` overloads allow
+  // for supporting bitfield arguments.
+  // Note: when we call `std::forward<M>(obj)` twice, it's safe because
+  // insert_unique/insert_hint_unique are guaranteed to not consume `obj` when
+  // `ret.second` is false.
+  template <class M>
+  std::pair<iterator, bool> insert_or_assign(const key_type &k, const M &obj) {
+    const std::pair<iterator, bool> ret = this->tree_.insert_unique(k, k, obj);
+    if (!ret.second) ret.first->second = obj;
+    return ret;
+  }
+  template <class M, key_type * = nullptr>
+  std::pair<iterator, bool> insert_or_assign(key_type &&k, const M &obj) {
+    const std::pair<iterator, bool> ret =
+        this->tree_.insert_unique(k, std::move(k), obj);
+    if (!ret.second) ret.first->second = obj;
+    return ret;
+  }
+  template <class M, M * = nullptr>
+  std::pair<iterator, bool> insert_or_assign(const key_type &k, M &&obj) {
+    const std::pair<iterator, bool> ret =
+        this->tree_.insert_unique(k, k, std::forward<M>(obj));
+    if (!ret.second) ret.first->second = std::forward<M>(obj);
+    return ret;
+  }
+  template <class M, key_type * = nullptr, M * = nullptr>
+  std::pair<iterator, bool> insert_or_assign(key_type &&k, M &&obj) {
+    const std::pair<iterator, bool> ret =
+        this->tree_.insert_unique(k, std::move(k), std::forward<M>(obj));
+    if (!ret.second) ret.first->second = std::forward<M>(obj);
+    return ret;
+  }
+  template <class M>
+  iterator insert_or_assign(const_iterator position, const key_type &k,
+                            const M &obj) {
+    const std::pair<iterator, bool> ret =
+        this->tree_.insert_hint_unique(iterator(position), k, k, obj);
+    if (!ret.second) ret.first->second = obj;
+    return ret.first;
+  }
+  template <class M, key_type * = nullptr>
+  iterator insert_or_assign(const_iterator position, key_type &&k,
+                            const M &obj) {
+    const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique(
+        iterator(position), k, std::move(k), obj);
+    if (!ret.second) ret.first->second = obj;
+    return ret.first;
+  }
+  template <class M, M * = nullptr>
+  iterator insert_or_assign(const_iterator position, const key_type &k,
+                            M &&obj) {
+    const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique(
+        iterator(position), k, k, std::forward<M>(obj));
+    if (!ret.second) ret.first->second = std::forward<M>(obj);
+    return ret.first;
+  }
+  template <class M, key_type * = nullptr, M * = nullptr>
+  iterator insert_or_assign(const_iterator position, key_type &&k, M &&obj) {
+    const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique(
+        iterator(position), k, std::move(k), std::forward<M>(obj));
+    if (!ret.second) ret.first->second = std::forward<M>(obj);
+    return ret.first;
+  }
   template <typename... Args>
   std::pair<iterator, bool> try_emplace(const key_type &k, Args &&... args) {
     return this->tree_.insert_unique(
diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc
index e15f44443f59..564472517844 100644
--- a/absl/container/internal/hashtablez_sampler.cc
+++ b/absl/container/internal/hashtablez_sampler.cc
@@ -39,17 +39,16 @@ ABSL_CONST_INIT std::atomic<bool> g_hashtablez_enabled{
 ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_sample_parameter{1 << 10};
 ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_max_samples{1 << 20};
 
-#if ABSL_PER_THREAD_TLS == 1
+#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
 ABSL_PER_THREAD_TLS_KEYWORD absl::base_internal::ExponentialBiased
     g_exponential_biased_generator;
 #endif
 
 }  // namespace
 
-#if ABSL_PER_THREAD_TLS == 1
+#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
 ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0;
-#endif  // ABSL_PER_THREAD_TLS == 1
-
+#endif  // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
 
 HashtablezSampler& HashtablezSampler::Global() {
   static auto* sampler = new HashtablezSampler();
@@ -192,7 +191,7 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) {
     return HashtablezSampler::Global().Register();
   }
 
-#if ABSL_PER_THREAD_TLS == 0
+#if !defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
   *next_sample = std::numeric_limits<int64_t>::max();
   return nullptr;
 #else
diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h
index c4f9629fcb47..34d5e5723c0f 100644
--- a/absl/container/internal/hashtablez_sampler.h
+++ b/absl/container/internal/hashtablez_sampler.h
@@ -180,14 +180,23 @@ class HashtablezInfoHandle {
   HashtablezInfo* info_;
 };
 
-#if ABSL_PER_THREAD_TLS == 1
+#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
+#error ABSL_INTERNAL_HASHTABLEZ_SAMPLE cannot be directly set
+#endif  // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
+
+#if (ABSL_PER_THREAD_TLS == 1) && !defined(ABSL_BUILD_DLL) && \
+    !defined(ABSL_CONSUME_DLL)
+#define ABSL_INTERNAL_HASHTABLEZ_SAMPLE
+#endif
+
+#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
 extern ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample;
 #endif  // ABSL_PER_THREAD_TLS
 
 // Returns an RAII sampling handle that manages registration and unregistation
 // with the global sampler.
 inline HashtablezInfoHandle Sample() {
-#if ABSL_PER_THREAD_TLS == 1
+#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
   if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) {
     return HashtablezInfoHandle(nullptr);
   }
diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc
index 102b23757cf6..36f5ccdd02a7 100644
--- a/absl/container/internal/hashtablez_sampler_test.cc
+++ b/absl/container/internal/hashtablez_sampler_test.cc
@@ -169,7 +169,7 @@ TEST(HashtablezInfoTest, RecordRehash) {
   EXPECT_EQ(info.num_erases.load(), 0);
 }
 
-#if ABSL_PER_THREAD_TLS == 1
+#if defined(ABSL_HASHTABLEZ_SAMPLE)
 TEST(HashtablezSamplerTest, SmallSampleParameter) {
   SetHashtablezEnabled(true);
   SetHashtablezSampleParameter(100);
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 38e5e0e8d3bd..a96ae68ac76c 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -418,53 +418,6 @@ TEST(Table, Empty) {
   EXPECT_TRUE(t.empty());
 }
 
-#ifdef __GNUC__
-template <class T>
-ABSL_ATTRIBUTE_ALWAYS_INLINE inline void DoNotOptimize(const T& v) {
-  asm volatile("" : : "r,m"(v) : "memory");
-}
-#endif
-
-TEST(Table, Prefetch) {
-  IntTable t;
-  t.emplace(1);
-  // Works for both present and absent keys.
-  t.prefetch(1);
-  t.prefetch(2);
-
-  // Do not run in debug mode, when prefetch is not implemented, or when
-  // sanitizers are enabled, or on WebAssembly.
-#if defined(NDEBUG) && defined(__GNUC__) && defined(__x86_64__) &&          \
-    !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) &&            \
-    !defined(THREAD_SANITIZER) && !defined(UNDEFINED_BEHAVIOR_SANITIZER) && \
-    !defined(__EMSCRIPTEN__)
-  const auto now = [] { return absl::base_internal::CycleClock::Now(); };
-
-  // Make size enough to not fit in L2 cache (16.7 Mb)
-  static constexpr int size = 1 << 22;
-  for (int i = 0; i < size; ++i) t.insert(i);
-
-  int64_t no_prefetch = 0, prefetch = 0;
-  for (int iter = 0; iter < 10; ++iter) {
-    int64_t time = now();
-    for (int i = 0; i < size; ++i) {
-      DoNotOptimize(t.find(i));
-    }
-    no_prefetch += now() - time;
-
-    time = now();
-    for (int i = 0; i < size; ++i) {
-      t.prefetch(i + 20);
-      DoNotOptimize(t.find(i));
-    }
-    prefetch += now() - time;
-  }
-
-  // no_prefetch is at least 30% slower.
-  EXPECT_GE(1.0 * no_prefetch / prefetch, 1.3);
-#endif
-}
-
 TEST(Table, LookupEmpty) {
   IntTable t;
   auto it = t.find(0);
@@ -1842,7 +1795,7 @@ TEST(TableDeathTest, EraseOfEndAsserts) {
   EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg);
 }
 
-#if ABSL_PER_THREAD_TLS == 1
+#if defined(ABSL_HASHTABLEZ_SAMPLE)
 TEST(RawHashSamplerTest, Sample) {
   // Enable the feature even if the prod default is off.
   SetHashtablezEnabled(true);
@@ -1863,7 +1816,7 @@ TEST(RawHashSamplerTest, Sample) {
   EXPECT_NEAR((end_size - start_size) / static_cast<double>(tables.size()),
               0.01, 0.005);
 }
-#endif
+#endif  // ABSL_HASHTABLEZ_SAMPLER
 
 TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) {
   // Enable the feature even if the prod default is off.
diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake
index 7543928aa676..77d4ace8be42 100644
--- a/absl/copts/AbseilConfigureCopts.cmake
+++ b/absl/copts/AbseilConfigureCopts.cmake
@@ -5,6 +5,13 @@ set(ABSL_LSAN_LINKOPTS "")
 set(ABSL_HAVE_LSAN OFF)
 set(ABSL_DEFAULT_LINKOPTS "")
 
+if (BUILD_SHARED_LIBS AND MSVC)
+  set(ABSL_BUILD_DLL TRUE)
+  set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+else()
+  set(ABSL_BUILD_DLL FALSE)
+endif()
+
 if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64")
   if (MSVC)
     set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}")
diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc
index 0bac60b9ea29..a1d03aab531b 100644
--- a/absl/debugging/symbolize_test.cc
+++ b/absl/debugging/symbolize_test.cc
@@ -473,6 +473,7 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithReturnAddress() {
 }
 
 #elif defined(_WIN32)
+#if !defined(ABSL_CONSUME_DLL)
 
 TEST(Symbolize, Basics) {
   EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func)));
@@ -511,6 +512,7 @@ TEST(Symbolize, SymbolizeWithDemangling) {
   EXPECT_TRUE(strstr(result, "Foo::func") != nullptr) << result;
 }
 
+#endif  // !defined(ABSL_CONSUME_DLL)
 #else  // Symbolizer unimplemented
 
 TEST(Symbolize, Unimplemented) {
diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel
index 6c7b2b6e7950..cbdbae52ed83 100644
--- a/absl/flags/BUILD.bazel
+++ b/absl/flags/BUILD.bazel
@@ -324,6 +324,23 @@ cc_test(
     ],
 )
 
+cc_binary(
+    name = "flag_benchmark",
+    testonly = 1,
+    srcs = [
+        "flag_benchmark.cc",
+    ],
+    copts = ABSL_TEST_COPTS,
+    tags = ["benchmark"],
+    visibility = ["//visibility:private"],
+    deps = [
+        ":flag",
+        "//absl/time",
+        "//absl/types:optional",
+        "@com_github_google_benchmark//:benchmark_main",
+    ],
+)
+
 cc_test(
     name = "marshalling_test",
     size = "small",
diff --git a/absl/flags/flag.cc b/absl/flags/flag.cc
index 9af800796a61..e67f7304c6ff 100644
--- a/absl/flags/flag.cc
+++ b/absl/flags/flag.cc
@@ -22,7 +22,14 @@
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 
-// This global nutex protects on-demand construction of flag objects in MSVC
+#ifndef NDEBUG
+#define ABSL_FLAGS_GET(T) \
+  T GetFlag(const absl::Flag<T>& flag) { return flag.Get(); }
+ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_GET)
+#undef ABSL_FLAGS_GET
+#endif
+
+// This global mutex protects on-demand construction of flag objects in MSVC
 // builds.
 #if defined(_MSC_VER) && !defined(__clang__)
 
diff --git a/absl/flags/flag.h b/absl/flags/flag.h
index cc22cdb923e6..bd61668ff4f1 100644
--- a/absl/flags/flag.h
+++ b/absl/flags/flag.h
@@ -186,25 +186,29 @@ class Flag {
 //
 //   // FLAGS_firstname is a Flag of type `std::string`
 //   std::string first_name = absl::GetFlag(FLAGS_firstname);
-template <typename T,
-          typename std::enable_if<
-              !flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0>
-ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
-  return flag.Get();
-}
-
+#ifndef NDEBUG
 // We want to validate the type mismatch between type definition and
 // declaration. The lock-free implementation does not allow us to do it,
 // so in debug builds we always use the slower implementation, which always
 // validates the type.
-#ifndef NDEBUG
+template <typename T>
+ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
+  return flag.Get();
+}
+// We currently need an external linkage for built-in types because shared
+// libraries have different addresses of flags_internal::FlagOps<T> which
+// might cause log spam when checking the same flag type.
+#define ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT(T) \
+  ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag);
+ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT)
+#undef ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT
+#else
 template <typename T,
           typename std::enable_if<
-              flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0>
+              !flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0>
 ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
   return flag.Get();
 }
-#else
 // Overload for `GetFlag()` for types that support lock-free reads.
 template <typename T,
           typename std::enable_if<
diff --git a/absl/flags/flag_benchmark.cc b/absl/flags/flag_benchmark.cc
new file mode 100644
index 000000000000..87f731704c87
--- /dev/null
+++ b/absl/flags/flag_benchmark.cc
@@ -0,0 +1,111 @@
+//
+// 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.
+
+#include "absl/flags/flag.h"
+#include "absl/time/time.h"
+#include "absl/types/optional.h"
+#include "benchmark/benchmark.h"
+
+namespace {
+using String = std::string;
+using VectorOfStrings = std::vector<std::string>;
+using AbslDuration = absl::Duration;
+
+// We do not want to take over marshalling for the types absl::optional<int>,
+// absl::optional<std::string> which we do not own. Instead we introduce unique
+// "aliases" to these types, which we do.
+using AbslOptionalInt = absl::optional<int>;
+struct OptionalInt : AbslOptionalInt {
+  using AbslOptionalInt::AbslOptionalInt;
+};
+// Next two functions represent Abseil Flags marshalling for OptionalInt.
+bool AbslParseFlag(absl::string_view src, OptionalInt* flag,
+                   std::string* error) {
+  int val;
+  if (src.empty())
+    flag->reset();
+  else if (!absl::ParseFlag(src, &val, error))
+    return false;
+  *flag = val;
+  return true;
+}
+std::string AbslUnparseFlag(const OptionalInt& flag) {
+  return !flag ? "" : absl::UnparseFlag(*flag);
+}
+
+using AbslOptionalString = absl::optional<std::string>;
+struct OptionalString : AbslOptionalString {
+  using AbslOptionalString::AbslOptionalString;
+};
+// Next two functions represent Abseil Flags marshalling for OptionalString.
+bool AbslParseFlag(absl::string_view src, OptionalString* flag,
+                   std::string* error) {
+  std::string val;
+  if (src.empty())
+    flag->reset();
+  else if (!absl::ParseFlag(src, &val, error))
+    return false;
+  *flag = val;
+  return true;
+}
+std::string AbslUnparseFlag(const OptionalString& flag) {
+  return !flag ? "" : absl::UnparseFlag(*flag);
+}
+
+struct UDT {
+  UDT() = default;
+  UDT(const UDT&) {}
+  UDT& operator=(const UDT&) { return *this; }
+};
+// Next two functions represent Abseil Flags marshalling for UDT.
+bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
+std::string AbslUnparseFlag(const UDT&) { return ""; }
+
+}  // namespace
+
+#define BENCHMARKED_TYPES(A) \
+  A(bool)                    \
+  A(int16_t)                 \
+  A(uint16_t)                \
+  A(int32_t)                 \
+  A(uint32_t)                \
+  A(int64_t)                 \
+  A(uint64_t)                \
+  A(double)                  \
+  A(float)                   \
+  A(String)                  \
+  A(VectorOfStrings)         \
+  A(OptionalInt)             \
+  A(OptionalString)          \
+  A(AbslDuration)            \
+  A(UDT)
+
+#define FLAG_DEF(T) ABSL_FLAG(T, T##_flag, {}, "");
+
+BENCHMARKED_TYPES(FLAG_DEF)
+
+namespace {
+
+#define BM_GetFlag(T)                                            \
+  void BM_GetFlag_##T(benchmark::State& state) {                 \
+    for (auto _ : state) {                                       \
+      benchmark::DoNotOptimize(absl::GetFlag(FLAGS_##T##_flag)); \
+    }                                                            \
+  }                                                              \
+  BENCHMARK(BM_GetFlag_##T);
+
+BENCHMARKED_TYPES(BM_GetFlag)
+
+}  // namespace
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index 8639181f1336..ae7a60cd55ad 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -708,7 +708,8 @@ struct is_hashable
     : std::integral_constant<bool, HashSelect::template Apply<T>::value> {};
 
 // CityHashState
-class CityHashState : public HashStateBase<CityHashState> {
+class ABSL_DLL CityHashState
+    : public HashStateBase<CityHashState> {
   // absl::uint128 is not an alias or a thin wrapper around the intrinsic.
   // We use the intrinsic when available to improve performance.
 #ifdef ABSL_HAVE_INTRINSIC_INT128
diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc
index a20a77e7eb0d..b605a87042c1 100644
--- a/absl/numeric/int128.cc
+++ b/absl/numeric/int128.cc
@@ -25,8 +25,8 @@
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 
-const uint128 kuint128max = MakeUint128(std::numeric_limits<uint64_t>::max(),
-                                        std::numeric_limits<uint64_t>::max());
+ABSL_DLL const uint128 kuint128max = MakeUint128(
+    std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max());
 
 namespace {
 
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h
index 718f70b19782..636e3a5bc7ac 100644
--- a/absl/numeric/int128.h
+++ b/absl/numeric/int128.h
@@ -234,7 +234,7 @@ class
 // Prefer to use the constexpr `Uint128Max()`.
 //
 // TODO(absl-team) deprecate kuint128max once migration tool is released.
-extern const uint128 kuint128max;
+ABSL_DLL extern const uint128 kuint128max;
 
 // allow uint128 to be logged
 std::ostream& operator<<(std::ostream& os, uint128 v);
diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel
index 2585b39742e2..f78fbc7eedb8 100644
--- a/absl/random/BUILD.bazel
+++ b/absl/random/BUILD.bazel
@@ -67,6 +67,7 @@ cc_library(
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/base:base_internal",
+        "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/meta:type_traits",
         "//absl/random/internal:distributions",
@@ -183,6 +184,7 @@ cc_test(
     timeout = "eternal",  # Android can take a very long time
     srcs = ["beta_distribution_test.cc"],
     copts = ABSL_TEST_COPTS,
+    flaky = 1,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":distributions",
diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt
index 46dbc3efbc83..efa55d8fa73b 100644
--- a/absl/random/CMakeLists.txt
+++ b/absl/random/CMakeLists.txt
@@ -183,6 +183,7 @@ absl_cc_library(
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
     absl::base_internal
+    absl::config
     absl::core_headers
     absl::random_internal_generate_real
     absl::random_internal_distributions
diff --git a/absl/random/gaussian_distribution.h b/absl/random/gaussian_distribution.h
index c1427b06d549..4b07a5c0af9d 100644
--- a/absl/random/gaussian_distribution.h
+++ b/absl/random/gaussian_distribution.h
@@ -28,6 +28,7 @@
 #include <limits>
 #include <type_traits>
 
+#include "absl/base/config.h"
 #include "absl/random/internal/fast_uniform_bits.h"
 #include "absl/random/internal/generate_real.h"
 #include "absl/random/internal/iostream_state_saver.h"
@@ -43,7 +44,7 @@ namespace random_internal {
 // The specific algorithm has some of the improvements suggested by the
 // 2005 paper, "An Improved Ziggurat Method to Generate Normal Random Samples",
 // Jurgen A Doornik.  (https://www.doornik.com/research/ziggurat.pdf)
-class gaussian_distribution_base {
+class ABSL_DLL gaussian_distribution_base {
  public:
   template <typename URBG>
   inline double zignor(URBG& g);  // NOLINT(runtime/references)
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index dc7e1bfd280e..d5a362d05777 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -37,7 +37,6 @@ cc_library(
         "internal/charconv_bigint.h",
         "internal/charconv_parse.cc",
         "internal/charconv_parse.h",
-        "internal/escaping.cc",
         "internal/memutil.cc",
         "internal/memutil.h",
         "internal/stl_type_traits.h",
@@ -55,7 +54,6 @@ cc_library(
         "ascii.h",
         "charconv.h",
         "escaping.h",
-        "internal/escaping.h",
         "match.h",
         "numbers.h",
         "str_cat.h",
@@ -85,11 +83,13 @@ cc_library(
 cc_library(
     name = "internal",
     srcs = [
+        "internal/escaping.cc",
         "internal/ostringstream.cc",
         "internal/utf8.cc",
     ],
     hdrs = [
         "internal/char_map.h",
+        "internal/escaping.h",
         "internal/ostringstream.h",
         "internal/resize_uninitialized.h",
         "internal/utf8.h",
@@ -99,6 +99,7 @@ cc_library(
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:endian",
+        "//absl/base:raw_logging_internal",
         "//absl/meta:type_traits",
     ],
 )
diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt
index 36702f7106d9..3feb5e94c4e0 100644
--- a/absl/strings/CMakeLists.txt
+++ b/absl/strings/CMakeLists.txt
@@ -38,8 +38,6 @@ absl_cc_library(
     "internal/charconv_bigint.h"
     "internal/charconv_parse.cc"
     "internal/charconv_parse.h"
-    "internal/escaping.cc"
-    "internal/escaping.h"
     "internal/memutil.cc"
     "internal/memutil.h"
     "internal/stl_type_traits.h"
@@ -74,6 +72,8 @@ absl_cc_library(
     strings_internal
   HDRS
     "internal/char_map.h"
+    "internal/escaping.cc"
+    "internal/escaping.h"
     "internal/ostringstream.h"
     "internal/resize_uninitialized.h"
     "internal/utf8.h"
@@ -86,6 +86,7 @@ absl_cc_library(
     absl::config
     absl::core_headers
     absl::endian
+    absl::raw_logging_internal
     absl::type_traits
 )
 
diff --git a/absl/strings/ascii.cc b/absl/strings/ascii.cc
index abea3e4fd38c..93bb03e95815 100644
--- a/absl/strings/ascii.cc
+++ b/absl/strings/ascii.cc
@@ -57,7 +57,7 @@ namespace ascii_internal {
 // of these bits is tightly coupled to this implementation, the individual bits
 // are not named. Note that bitfields for all characters above ASCII 127 are
 // zero-initialized.
-const unsigned char kPropertyBits[256] = {
+ABSL_DLL const unsigned char kPropertyBits[256] = {
     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x00
     0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40,
     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x10
@@ -79,7 +79,7 @@ const unsigned char kPropertyBits[256] = {
 // Array of characters for the ascii_tolower() function. For values 'A'
 // through 'Z', return the lower-case character; otherwise, return the
 // identity of the passed character.
-const char kToLower[256] = {
+ABSL_DLL const char kToLower[256] = {
   '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
   '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
   '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
@@ -117,7 +117,7 @@ const char kToLower[256] = {
 // Array of characters for the ascii_toupper() function. For values 'a'
 // through 'z', return the upper-case character; otherwise, return the
 // identity of the passed character.
-const char kToUpper[256] = {
+ABSL_DLL const char kToUpper[256] = {
   '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
   '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
   '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
diff --git a/absl/strings/ascii.h b/absl/strings/ascii.h
index 792aabe5364a..b46bc71f35b9 100644
--- a/absl/strings/ascii.h
+++ b/absl/strings/ascii.h
@@ -56,6 +56,7 @@
 #include <string>
 
 #include "absl/base/attributes.h"
+#include "absl/base/config.h"
 #include "absl/strings/string_view.h"
 
 namespace absl {
@@ -63,13 +64,13 @@ ABSL_NAMESPACE_BEGIN
 namespace ascii_internal {
 
 // Declaration for an array of bitfields holding character information.
-extern const unsigned char kPropertyBits[256];
+ABSL_DLL extern const unsigned char kPropertyBits[256];
 
 // Declaration for the array of characters to upper-case characters.
-extern const char kToUpper[256];
+ABSL_DLL extern const char kToUpper[256];
 
 // Declaration for the array of characters to lower-case characters.
-extern const char kToLower[256];
+ABSL_DLL extern const char kToLower[256];
 
 }  // namespace ascii_internal
 
diff --git a/absl/strings/internal/charconv_bigint.cc b/absl/strings/internal/charconv_bigint.cc
index 860c27b25681..66f33e7207b3 100644
--- a/absl/strings/internal/charconv_bigint.cc
+++ b/absl/strings/internal/charconv_bigint.cc
@@ -158,12 +158,12 @@ const uint32_t* LargePowerOfFiveData(int i) {
 int LargePowerOfFiveSize(int i) { return 2 * i; }
 }  // namespace
 
-const uint32_t kFiveToNth[14] = {
+ABSL_DLL const uint32_t kFiveToNth[14] = {
     1,     5,      25,      125,     625,      3125,      15625,
     78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125,
 };
 
-const uint32_t kTenToNth[10] = {
+ABSL_DLL const uint32_t kTenToNth[10] = {
     1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
 };
 
diff --git a/absl/strings/internal/charconv_bigint.h b/absl/strings/internal/charconv_bigint.h
index 108e1eb29049..999e9ae3a295 100644
--- a/absl/strings/internal/charconv_bigint.h
+++ b/absl/strings/internal/charconv_bigint.h
@@ -20,6 +20,7 @@
 #include <iostream>
 #include <string>
 
+#include "absl/base/config.h"
 #include "absl/strings/ascii.h"
 #include "absl/strings/internal/charconv_parse.h"
 #include "absl/strings/string_view.h"
@@ -33,8 +34,9 @@ constexpr int kMaxSmallPowerOfFive = 13;
 // The largest power that 10 that can be raised to, and still fit in a uint32_t.
 constexpr int kMaxSmallPowerOfTen = 9;
 
-extern const uint32_t kFiveToNth[kMaxSmallPowerOfFive + 1];
-extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1];
+ABSL_DLL extern const uint32_t
+    kFiveToNth[kMaxSmallPowerOfFive + 1];
+ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1];
 
 // Large, fixed-width unsigned integer.
 //
diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h
index 2bf0c0855034..cf41b19748ba 100644
--- a/absl/strings/internal/str_format/bind.h
+++ b/absl/strings/internal/str_format/bind.h
@@ -122,8 +122,8 @@ class FormatSpecTemplate
 #endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
 
   template <Conv... C, typename = typename std::enable_if<
-                           sizeof...(C) == sizeof...(Args) &&
-                           AllOf(Contains(ArgumentToConv<Args>(),
+                           AllOf(sizeof...(C) == sizeof...(Args),
+                             Contains(ArgumentToConv<Args>(),
                                           C)...)>::type>
   FormatSpecTemplate(const ExtendedParsedFormat<C...>& pc)  // NOLINT
       : Base(&pc) {}
diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h
index 51d7dd6fcf2b..0a7640354fd4 100644
--- a/absl/strings/internal/str_format/extension.h
+++ b/absl/strings/internal/str_format/extension.h
@@ -17,10 +17,12 @@
 #define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
 
 #include <limits.h>
+
 #include <cstddef>
 #include <cstring>
 #include <ostream>
 
+#include "absl/base/config.h"
 #include "absl/base/port.h"
 #include "absl/strings/internal/str_format/output.h"
 #include "absl/strings/string_view.h"
@@ -134,7 +136,7 @@ struct Flags {
   }
 };
 
-struct LengthMod {
+struct ABSL_DLL LengthMod {
  public:
   enum Id : uint8_t {
     h, hh, l, ll, L, j, z, t, q, none
@@ -196,7 +198,7 @@ struct LengthMod {
   X_VAL(n) X_SEP X_VAL(p)
 // clang-format on
 
-struct ConversionChar {
+struct ABSL_DLL ConversionChar {
  public:
   enum Id : uint8_t {
     c, C, s, S,              // text
diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc
index a0e5a7fd4e7d..68c26dd6f8c1 100644
--- a/absl/strings/numbers.cc
+++ b/absl/strings/numbers.cc
@@ -900,9 +900,10 @@ inline bool safe_uint_internal(absl::string_view text, IntType* value_p,
 namespace numbers_internal {
 
 // Digit conversion.
-ABSL_CONST_INIT const char kHexChar[] = "0123456789abcdef";
+ABSL_CONST_INIT ABSL_DLL const char kHexChar[] =
+    "0123456789abcdef";
 
-ABSL_CONST_INIT const char kHexTable[513] =
+ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] =
     "000102030405060708090a0b0c0d0e0f"
     "101112131415161718191a1b1c1d1e1f"
     "202122232425262728292a2b2c2d2e2f"
@@ -920,7 +921,7 @@ ABSL_CONST_INIT const char kHexTable[513] =
     "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
     "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
 
-ABSL_CONST_INIT const char two_ASCII_digits[100][2] = {
+ABSL_CONST_INIT ABSL_DLL const char two_ASCII_digits[100][2] = {
     {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'},
     {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'},
     {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'},
diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h
index 612046838b8d..d872cca5dc48 100644
--- a/absl/strings/numbers.h
+++ b/absl/strings/numbers.h
@@ -36,6 +36,7 @@
 #include <string>
 #include <type_traits>
 
+#include "absl/base/config.h"
 #include "absl/base/internal/bits.h"
 #ifdef __SSE4_2__
 // TODO(jorg): Remove this when we figure out the right way
@@ -106,9 +107,11 @@ ABSL_NAMESPACE_BEGIN
 namespace numbers_internal {
 
 // Digit conversion.
-extern const char kHexChar[17];    // 0123456789abcdef
-extern const char kHexTable[513];  // 000102030405060708090a0b0c0d0e0f1011...
-extern const char two_ASCII_digits[100][2];  // 00, 01, 02, 03...
+ABSL_DLL extern const char kHexChar[17];  // 0123456789abcdef
+ABSL_DLL extern const char
+    kHexTable[513];  // 000102030405060708090a0b0c0d0e0f1011...
+ABSL_DLL extern const char
+    two_ASCII_digits[100][2];  // 00, 01, 02, 03...
 
 // Writes a two-character representation of 'i' to 'buf'. 'i' must be in the
 // range 0 <= i < 100, and buf must have space for two characters. Example:
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h
index 4f7dd6b3a17b..01965b0eb63f 100644
--- a/absl/strings/string_view.h
+++ b/absl/strings/string_view.h
@@ -28,7 +28,19 @@
 #define ABSL_STRINGS_STRING_VIEW_H_
 
 #include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <iosfwd>
+#include <iterator>
+#include <limits>
+#include <string>
+
 #include "absl/base/config.h"
+#include "absl/base/internal/throw_delegate.h"
+#include "absl/base/macros.h"
+#include "absl/base/optimization.h"
+#include "absl/base/port.h"
 
 #ifdef ABSL_USES_STD_STRING_VIEW
 
@@ -49,19 +61,6 @@ ABSL_NAMESPACE_END
 #define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp
 #endif  // ABSL_HAVE_BUILTIN(__builtin_memcmp)
 
-#include <cassert>
-#include <cstddef>
-#include <cstring>
-#include <iosfwd>
-#include <iterator>
-#include <limits>
-#include <string>
-
-#include "absl/base/internal/throw_delegate.h"
-#include "absl/base/macros.h"
-#include "absl/base/optimization.h"
-#include "absl/base/port.h"
-
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 
diff --git a/absl/time/format.cc b/absl/time/format.cc
index 5997ef0c220f..ee088f33c394 100644
--- a/absl/time/format.cc
+++ b/absl/time/format.cc
@@ -24,11 +24,14 @@ namespace cctz = absl::time_internal::cctz;
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 
-extern const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
-extern const char RFC3339_sec[] =  "%Y-%m-%dT%H:%M:%S%Ez";
-
-extern const char RFC1123_full[] = "%a, %d %b %E4Y %H:%M:%S %z";
-extern const char RFC1123_no_wday[] =  "%d %b %E4Y %H:%M:%S %z";
+ABSL_DLL extern const char RFC3339_full[] =
+    "%Y-%m-%dT%H:%M:%E*S%Ez";
+ABSL_DLL extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
+
+ABSL_DLL extern const char RFC1123_full[] =
+    "%a, %d %b %E4Y %H:%M:%S %z";
+ABSL_DLL extern const char RFC1123_no_wday[] =
+    "%d %b %E4Y %H:%M:%S %z";
 
 namespace {
 
diff --git a/absl/time/internal/cctz/src/time_zone_fixed.cc b/absl/time/internal/cctz/src/time_zone_fixed.cc
index a342e37d521f..303c0244a824 100644
--- a/absl/time/internal/cctz/src/time_zone_fixed.cc
+++ b/absl/time/internal/cctz/src/time_zone_fixed.cc
@@ -89,29 +89,29 @@ std::string FixedOffsetToName(const seconds& offset) {
     // offsets and to (somewhat) limit the total number of zones.
     return "UTC";
   }
-  int seconds = static_cast<int>(offset.count());
-  const char sign = (seconds < 0 ? '-' : '+');
-  int minutes = seconds / 60;
-  seconds %= 60;
+  int offset_seconds = static_cast<int>(offset.count());
+  const char sign = (offset_seconds < 0 ? '-' : '+');
+  int offset_minutes = offset_seconds / 60;
+  offset_seconds %= 60;
   if (sign == '-') {
-    if (seconds > 0) {
-      seconds -= 60;
-      minutes += 1;
+    if (offset_seconds > 0) {
+      offset_seconds -= 60;
+      offset_minutes += 1;
     }
-    seconds = -seconds;
-    minutes = -minutes;
+    offset_seconds = -offset_seconds;
+    offset_minutes = -offset_minutes;
   }
-  int hours = minutes / 60;
-  minutes %= 60;
+  int offset_hours = offset_minutes / 60;
+  offset_minutes %= 60;
   const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
   char buf[prefix_len + sizeof("-24:00:00")];
   char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf);
   *ep++ = sign;
-  ep = Format02d(ep, hours);
+  ep = Format02d(ep, offset_hours);
   *ep++ = ':';
-  ep = Format02d(ep, minutes);
+  ep = Format02d(ep, offset_minutes);
   *ep++ = ':';
-  ep = Format02d(ep, seconds);
+  ep = Format02d(ep, offset_seconds);
   *ep++ = '\0';
   assert(ep == buf + sizeof(buf));
   return buf;
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 de75629a777f..caebcc4d95d6 100644
--- a/absl/time/internal/cctz/src/time_zone_format_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_format_test.cc
@@ -1252,9 +1252,9 @@ TEST(Parse, ExtendedSubecondsScan) {
         const auto expected = chrono::system_clock::from_time_t(0) +
                               chrono::nanoseconds(micros * 1000 + ns);
         for (int ps = 0; ps < 1000; ps += 250) {
-          std::ostringstream oss;
+          std::ostringstream ps_oss;
           oss << std::setfill('0') << std::setw(3) << ps;
-          const std::string input = nanos + oss.str() + "999";
+          const std::string input = nanos + ps_oss.str() + "999";
           EXPECT_TRUE(parse("%E*f", input, tz, &tp));
           EXPECT_EQ(expected + chrono::nanoseconds(ps) / 1000, tp) << input;
         }
diff --git a/absl/time/internal/cctz/src/time_zone_info.cc b/absl/time/internal/cctz/src/time_zone_info.cc
index 971542d0754c..f1697cdf04d0 100644
--- a/absl/time/internal/cctz/src/time_zone_info.cc
+++ b/absl/time/internal/cctz/src/time_zone_info.cc
@@ -641,9 +641,9 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open(
   if (fp == nullptr) return nullptr;
   std::size_t length = 0;
   if (fseek(fp, 0, SEEK_END) == 0) {
-    long pos = ftell(fp);
-    if (pos >= 0) {
-      length = static_cast<std::size_t>(pos);
+    long offset = ftell(fp);
+    if (offset >= 0) {
+      length = static_cast<std::size_t>(offset);
     }
     rewind(fp);
   }
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 227b127860ac..99137a082af0 100644
--- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -1028,16 +1028,17 @@ TEST(MakeTime, LocalTimeLibC) {
     ASSERT_EQ(0, setenv("TZ", *np, 1));  // change what "localtime" means
     const auto zi = local_time_zone();
     const auto lc = LoadZone("libc:localtime");
-    time_zone::civil_transition trans;
+    time_zone::civil_transition transition;
     for (auto tp = zi.lookup(civil_second()).trans;
-         zi.next_transition(tp, &trans); tp = zi.lookup(trans.to).trans) {
-      const auto fcl = zi.lookup(trans.from);
-      const auto tcl = zi.lookup(trans.to);
+         zi.next_transition(tp, &transition);
+         tp = zi.lookup(transition.to).trans) {
+      const auto fcl = zi.lookup(transition.from);
+      const auto tcl = zi.lookup(transition.to);
       civil_second cs;  // compare cs in zi and lc
       if (fcl.kind == time_zone::civil_lookup::UNIQUE) {
         if (tcl.kind == time_zone::civil_lookup::UNIQUE) {
           // Both unique; must be an is_dst or abbr change.
-          ASSERT_EQ(trans.from, trans.to);
+          ASSERT_EQ(transition.from, transition.to);
           const auto trans = fcl.trans;
           const auto tal = zi.lookup(trans);
           const auto tprev = trans - absl::time_internal::cctz::seconds(1);
@@ -1048,11 +1049,11 @@ TEST(MakeTime, LocalTimeLibC) {
           continue;
         }
         ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind);
-        cs = trans.to;
+        cs = transition.to;
       } else {
         ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind);
         ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind);
-        cs = trans.from;
+        cs = transition.from;
       }
       if (cs.year() > 2037) break;  // limit test time (and to 32-bit time_t)
       const auto cl_zi = zi.lookup(cs);
diff --git a/absl/time/time.h b/absl/time/time.h
index 1be5727c0dbc..33a4a630c296 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -527,59 +527,30 @@ std::chrono::seconds ToChronoSeconds(Duration d);
 std::chrono::minutes ToChronoMinutes(Duration d);
 std::chrono::hours ToChronoHours(Duration d);
 
-
 // FormatDuration()
 //
-// Returns a string represention of the duration in a format consisting of a
-// possibly-signed prefix and a sequence of decimal numbers, each with an
-// optional fractional part and a unit suffix.
-//
-// Valid unit suffixes are "ns", "us" "ms", "s", "m", and "h".
-//
-// Simple examples include "300ms", "-1.5h", and "2h45m". Returns "inf" or
-// "-inf" for +/- `InfiniteDuration()` values and "0" for `ZeroDuration()`
-// values.
-//
-// This string format is used both as an input for parsing (when handling
-// command-line flags of type `absl::Duration`) and as an output in
-// `FormatDuration()`
+// Returns a string representing the duration in the form "72h3m0.5s".
+// Returns "inf" or "-inf" for +/- `InfiniteDuration()`.
 std::string FormatDuration(Duration d);
 
+// Output stream operator.
+inline std::ostream& operator<<(std::ostream& os, Duration d) {
+  return os << FormatDuration(d);
+}
+
 // ParseDuration()
 //
-// Parses a `dur_string` of the format noted above into an `absl::Duration`
-// value.
-//
-// Parses "0" as a zero-length duration value. Parses "-inf" or "+inf" as
-// infinite durations values.
+// Parses a duration string consisting of a possibly signed sequence of
+// decimal numbers, each with an optional fractional part and a unit
+// suffix.  The valid suffixes are "ns", "us" "ms", "s", "m", and "h".
+// Simple examples include "300ms", "-1.5h", and "2h45m".  Parses "0" as
+// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`.
 bool ParseDuration(const std::string& dur_string, Duration* d);
 
-// AbslParseFlag()
-//
-// Parses the command-line flag string representation `text` (using the format
-// noted above) into an `absl::Duration` destination, setting `error` on
-// failure.
-//
-// Example:
-//
-//   --timeout=6h30m
-//   --timeout=inf       // Equivalent to `InfiniteDuration()`
-//   --timeout=0         // Equivalent to `ZeroDuration()`
+// Support for flag values of type Duration. Duration flags must be specified
+// in a format that is valid input for absl::ParseDuration().
 bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error);
-
-// AbslUnparseFlag()
-//
-// Unparses an `absl::Duration` into a command-line string representation using
-// the format noted above.
 std::string AbslUnparseFlag(Duration d);
-
-// operator<<()
-//
-// Output stream operator, returning a stream in the format noted above.
-inline std::ostream& operator<<(std::ostream& os, Duration d) {
-  return os << FormatDuration(d);
-}
-
 ABSL_DEPRECATED("Use AbslParseFlag() instead.")
 bool ParseFlag(const std::string& text, Duration* dst, std::string* error);
 ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
@@ -842,29 +813,18 @@ Time FromChrono(const std::chrono::system_clock::time_point& tp);
 //   // tp == std::chrono::system_clock::from_time_t(123);
 std::chrono::system_clock::time_point ToChronoTime(Time);
 
-// AbslParseFlag()
-//
-// Parses the command-line flag string representation `text` into an
-// `absl::Time` destination, setting `error` on failure. Time flag string
-// representations must be specified in a format that matches
-// `absl::RFC3339_full`.
-//
-// Example:
+// Support for flag values of type Time. Time flags must be specified in a
+// format that matches absl::RFC3339_full. For example:
 //
 //   --start_time=2016-01-02T03:04:05.678+08:00
 //
 // Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required.
 //
 // Additionally, if you'd like to specify a time as a count of
-// seconds/milliseconds/etc from the Unix epoch, use an `absl::Duration` flag
-// and add that duration to `absl::UnixEpoch()` to get an `absl::Time`.
+// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag
+// and add that duration to absl::UnixEpoch() to get an absl::Time.
 bool AbslParseFlag(absl::string_view text, Time* t, std::string* error);
-
-// AbslUnparseFlag()
-//
-// Unparses an `absl::Time` into a command-line string format as noted above.
 std::string AbslUnparseFlag(Time t);
-
 ABSL_DEPRECATED("Use AbslParseFlag() instead.")
 bool ParseFlag(const std::string& text, Time* t, std::string* error);
 ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
@@ -1243,15 +1203,18 @@ struct tm ToTM(Time t, TimeZone tz);
 // time with UTC offset.  Also note the use of "%Y": RFC3339 mandates that
 // years have exactly four digits, but we allow them to take their natural
 // width.
-extern const char RFC3339_full[];  // %Y-%m-%dT%H:%M:%E*S%Ez
-extern const char RFC3339_sec[];   // %Y-%m-%dT%H:%M:%S%Ez
+ABSL_DLL extern const char
+    RFC3339_full[];  // %Y-%m-%dT%H:%M:%E*S%Ez
+ABSL_DLL extern const char RFC3339_sec[];  // %Y-%m-%dT%H:%M:%S%Ez
 
 // RFC1123_full
 // RFC1123_no_wday
 //
 // FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings.
-extern const char RFC1123_full[];     // %a, %d %b %E4Y %H:%M:%S %z
-extern const char RFC1123_no_wday[];  // %d %b %E4Y %H:%M:%S %z
+ABSL_DLL extern const char
+    RFC1123_full[];  // %a, %d %b %E4Y %H:%M:%S %z
+ABSL_DLL extern const char
+    RFC1123_no_wday[];  // %d %b %E4Y %H:%M:%S %z
 
 // FormatTime()
 //