// // 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/reflection.h" #include <assert.h> #include <atomic> #include <string> #include "absl/base/config.h" #include "absl/base/no_destructor.h" #include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.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" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" namespace absl { ABSL_NAMESPACE_BEGIN namespace flags_internal { // -------------------------------------------------------------------- // FlagRegistry // A FlagRegistry singleton object holds all flag objects indexed by their // names so that if you know a flag's name, you can access or set it. If the // function is named FooLocked(), you must own the registry lock before // calling the function; otherwise, you should *not* hold the lock, and the // function will acquire it itself if needed. // -------------------------------------------------------------------- class FlagRegistry { … }; namespace { class FlagRegistryLock { … }; } // namespace CommandLineFlag* FlagRegistry::FindFlag(absl::string_view name) { … } void FlagRegistry::RegisterFlag(CommandLineFlag& flag, const char* filename) { … } FlagRegistry& FlagRegistry::GlobalRegistry() { … } // -------------------------------------------------------------------- void ForEachFlag(std::function<void(CommandLineFlag&)> visitor) { … } // -------------------------------------------------------------------- bool RegisterCommandLineFlag(CommandLineFlag& flag, const char* filename) { … } void FinalizeRegistry() { … } // -------------------------------------------------------------------- namespace { // These are only used as constexpr global objects. // They do not use a virtual destructor to simplify their implementation. // They are not destroyed except at program exit, so leaks do not matter. #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" #endif class RetiredFlagObj final : public CommandLineFlag { … }; #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif } // namespace void Retire(const char* name, FlagFastTypeId type_id, char* buf) { … } // -------------------------------------------------------------------- class FlagSaverImpl { … }; } // namespace flags_internal FlagSaver::FlagSaver() : … { … } FlagSaver::~FlagSaver() { … } // -------------------------------------------------------------------- CommandLineFlag* FindCommandLineFlag(absl::string_view name) { … } // -------------------------------------------------------------------- absl::flat_hash_map<absl::string_view, absl::CommandLineFlag*> GetAllFlags() { … } ABSL_NAMESPACE_END } // namespace absl