labath updated this revision to Diff 402636.
labath marked an inline comment as done.
labath edited the summary of this revision.
labath added a comment.

- use uint64_t for channel mask
- ensure constants are in ascending order


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117490/new/

https://reviews.llvm.org/D117490

Files:
  lldb/include/lldb/Interpreter/ScriptedInterface.h
  lldb/include/lldb/Utility/Log.h
  lldb/include/lldb/Utility/Logging.h
  lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
  lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
  lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
  lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
  lldb/source/Utility/Log.cpp
  lldb/source/Utility/Logging.cpp
  lldb/tools/lldb-server/lldb-gdbserver.cpp
  lldb/unittests/Utility/LogTest.cpp

Index: lldb/unittests/Utility/LogTest.cpp
===================================================================
--- lldb/unittests/Utility/LogTest.cpp
+++ lldb/unittests/Utility/LogTest.cpp
@@ -18,13 +18,24 @@
 using namespace lldb;
 using namespace lldb_private;
 
-enum { FOO = 1, BAR = 2 };
+enum class TestChannel : Log::MaskType {
+  FOO = Log::ChannelFlag<0>,
+  BAR = Log::ChannelFlag<1>,
+  LLVM_MARK_AS_BITMASK_ENUM(BAR),
+};
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
 static constexpr Log::Category test_categories[] = {
-    {{"foo"}, {"log foo"}, FOO}, {{"bar"}, {"log bar"}, BAR},
+    {{"foo"}, {"log foo"}, TestChannel::FOO},
+    {{"bar"}, {"log bar"}, TestChannel::BAR},
 };
-static constexpr uint32_t default_flags = FOO;
 
-static Log::Channel test_channel(test_categories, default_flags);
+static Log::Channel test_channel(test_categories, TestChannel::FOO);
+
+namespace lldb_private {
+template <> Log::Channel &LogChannelFor<TestChannel>() { return test_channel; }
+} // namespace lldb_private
 
 // Wrap enable, disable and list functions to make them easier to test.
 static bool EnableChannel(std::shared_ptr<llvm::raw_ostream> stream_sp,
@@ -93,7 +104,7 @@
   std::string error;
   ASSERT_TRUE(EnableChannel(m_stream_sp, 0, "chan", {}, error));
 
-  m_log = test_channel.GetLogIfAll(FOO);
+  m_log = GetLog(TestChannel::FOO);
   ASSERT_NE(nullptr, m_log);
 }
 
@@ -124,18 +135,18 @@
 TEST(LogTest, Unregister) {
   llvm::llvm_shutdown_obj obj;
   Log::Register("chan", test_channel);
-  EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO));
+  EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
   std::string message;
   std::shared_ptr<llvm::raw_string_ostream> stream_sp(
       new llvm::raw_string_ostream(message));
   EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {"foo"}, llvm::nulls()));
-  EXPECT_NE(nullptr, test_channel.GetLogIfAny(FOO));
+  EXPECT_NE(nullptr, GetLog(TestChannel::FOO));
   Log::Unregister("chan");
-  EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO));
+  EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
 }
 
 TEST_F(LogChannelTest, Enable) {
-  EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO));
+  EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
   std::string message;
   std::shared_ptr<llvm::raw_string_ostream> stream_sp(
       new llvm::raw_string_ostream(message));
@@ -144,20 +155,22 @@
   EXPECT_EQ("Invalid log channel 'chanchan'.\n", error);
 
   EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, error));
-  EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
-  EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
+  EXPECT_NE(nullptr, GetLog(TestChannel::FOO));
+  EXPECT_EQ(nullptr, GetLog(TestChannel::BAR));
 
   EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"bar"}, error));
-  EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
+  EXPECT_NE(nullptr, test_channel.GetLogIfAll(
+                         Log::MaskType(TestChannel::FOO | TestChannel::BAR)));
 
   EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"baz"}, error));
   EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'"))
       << "error: " << error;
-  EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
+  EXPECT_NE(nullptr, test_channel.GetLogIfAll(
+                         Log::MaskType(TestChannel::FOO | TestChannel::BAR)));
 }
 
 TEST_F(LogChannelTest, EnableOptions) {
-  EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO));
+  EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
   std::string message;
   std::shared_ptr<llvm::raw_string_ostream> stream_sp(
       new llvm::raw_string_ostream(message));
@@ -165,32 +178,33 @@
   EXPECT_TRUE(
       EnableChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan", {}, error));
 
-  Log *log = test_channel.GetLogIfAll(FOO);
+  Log *log = GetLog(TestChannel::FOO);
   ASSERT_NE(nullptr, log);
   EXPECT_TRUE(log->GetVerbose());
 }
 
 TEST_F(LogChannelTest, Disable) {
-  EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO));
+  EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
   std::string message;
   std::shared_ptr<llvm::raw_string_ostream> stream_sp(
       new llvm::raw_string_ostream(message));
   std::string error;
   EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"foo", "bar"}, error));
-  EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
+  EXPECT_NE(nullptr, test_channel.GetLogIfAll(
+                         Log::MaskType(TestChannel::FOO | TestChannel::BAR)));
 
   EXPECT_TRUE(DisableChannel("chan", {"bar"}, error));
-  EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
-  EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
+  EXPECT_NE(nullptr, GetLog(TestChannel::FOO));
+  EXPECT_EQ(nullptr, GetLog(TestChannel::BAR));
 
   EXPECT_TRUE(DisableChannel("chan", {"baz"}, error));
   EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'"))
       << "error: " << error;
-  EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
-  EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
+  EXPECT_NE(nullptr, GetLog(TestChannel::FOO));
+  EXPECT_EQ(nullptr, GetLog(TestChannel::BAR));
 
   EXPECT_TRUE(DisableChannel("chan", {}, error));
-  EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO | BAR));
+  EXPECT_EQ(nullptr, GetLog(TestChannel::FOO | TestChannel::BAR));
 }
 
 TEST_F(LogChannelTest, List) {
@@ -309,5 +323,5 @@
 
   // The mask should be either zero of "FOO". In either case, we should not trip
   // any undefined behavior (run the test under TSAN to verify this).
-  EXPECT_THAT(mask, testing::AnyOf(0, FOO));
+  EXPECT_THAT(mask, testing::AnyOf(0, Log::MaskType(TestChannel::FOO)));
 }
Index: lldb/tools/lldb-server/lldb-gdbserver.cpp
===================================================================
--- lldb/tools/lldb-server/lldb-gdbserver.cpp
+++ lldb/tools/lldb-server/lldb-gdbserver.cpp
@@ -27,6 +27,7 @@
 #include "lldb/Host/Socket.h"
 #include "lldb/Host/common/NativeProcessProtocol.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Utility/Logging.h"
 #include "lldb/Utility/Status.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Option/ArgList.h"
Index: lldb/source/Utility/Logging.cpp
===================================================================
--- lldb/source/Utility/Logging.cpp
+++ lldb/source/Utility/Logging.cpp
@@ -16,49 +16,74 @@
 using namespace lldb_private;
 
 static constexpr Log::Category g_categories[] = {
-  {{"api"}, {"log API calls and return values"}, LIBLLDB_LOG_API},
-  {{"ast"}, {"log AST"}, LIBLLDB_LOG_AST},
-  {{"break"}, {"log breakpoints"}, LIBLLDB_LOG_BREAKPOINTS},
-  {{"commands"}, {"log command argument parsing"}, LIBLLDB_LOG_COMMANDS},
-  {{"comm"}, {"log communication activities"}, LIBLLDB_LOG_COMMUNICATION},
-  {{"conn"}, {"log connection details"}, LIBLLDB_LOG_CONNECTION},
-  {{"demangle"}, {"log mangled names to catch demangler crashes"}, LIBLLDB_LOG_DEMANGLE},
-  {{"dyld"}, {"log shared library related activities"}, LIBLLDB_LOG_DYNAMIC_LOADER},
-  {{"event"}, {"log broadcaster, listener and event queue activities"}, LIBLLDB_LOG_EVENTS},
-  {{"expr"}, {"log expressions"}, LIBLLDB_LOG_EXPRESSIONS},
-  {{"formatters"}, {"log data formatters related activities"}, LIBLLDB_LOG_DATAFORMATTERS},
-  {{"host"}, {"log host activities"}, LIBLLDB_LOG_HOST},
-  {{"jit"}, {"log JIT events in the target"}, LIBLLDB_LOG_JIT_LOADER},
-  {{"language"}, {"log language runtime events"}, LIBLLDB_LOG_LANGUAGE},
-  {{"mmap"}, {"log mmap related activities"}, LIBLLDB_LOG_MMAP},
-  {{"module"}, {"log module activities such as when modules are created, destroyed, replaced, and more"}, LIBLLDB_LOG_MODULES},
-  {{"object"}, {"log object construction/destruction for important objects"}, LIBLLDB_LOG_OBJECT},
-  {{"os"}, {"log OperatingSystem plugin related activities"}, LIBLLDB_LOG_OS},
-  {{"platform"}, {"log platform events and activities"}, LIBLLDB_LOG_PLATFORM},
-  {{"process"}, {"log process events and activities"}, LIBLLDB_LOG_PROCESS},
-  {{"script"}, {"log events about the script interpreter"}, LIBLLDB_LOG_SCRIPT},
-  {{"state"}, {"log private and public process state changes"}, LIBLLDB_LOG_STATE},
-  {{"step"}, {"log step related activities"}, LIBLLDB_LOG_STEP},
-  {{"symbol"}, {"log symbol related issues and warnings"}, LIBLLDB_LOG_SYMBOLS},
-  {{"system-runtime"}, {"log system runtime events"}, LIBLLDB_LOG_SYSTEM_RUNTIME},
-  {{"target"}, {"log target events and activities"}, LIBLLDB_LOG_TARGET},
-  {{"temp"}, {"log internal temporary debug messages"}, LIBLLDB_LOG_TEMPORARY},
-  {{"thread"}, {"log thread events and activities"}, LIBLLDB_LOG_THREAD},
-  {{"types"}, {"log type system related activities"}, LIBLLDB_LOG_TYPES},
-  {{"unwind"}, {"log stack unwind activities"}, LIBLLDB_LOG_UNWIND},
-  {{"watch"}, {"log watchpoint related activities"}, LIBLLDB_LOG_WATCHPOINTS},
+    {{"api"}, {"log API calls and return values"}, LLDBLog::API},
+    {{"ast"}, {"log AST"}, LLDBLog::AST},
+    {{"break"}, {"log breakpoints"}, LLDBLog::Breakpoints},
+    {{"commands"}, {"log command argument parsing"}, LLDBLog::Commands},
+    {{"comm"}, {"log communication activities"}, LLDBLog::Communication},
+    {{"conn"}, {"log connection details"}, LLDBLog::Connection},
+    {{"demangle"},
+     {"log mangled names to catch demangler crashes"},
+     LLDBLog::Demangle},
+    {{"dyld"},
+     {"log shared library related activities"},
+     LLDBLog::DynamicLoader},
+    {{"event"},
+     {"log broadcaster, listener and event queue activities"},
+     LLDBLog::Events},
+    {{"expr"}, {"log expressions"}, LLDBLog::Expressions},
+    {{"formatters"},
+     {"log data formatters related activities"},
+     LLDBLog::DataFormatters},
+    {{"host"}, {"log host activities"}, LLDBLog::Host},
+    {{"jit"}, {"log JIT events in the target"}, LLDBLog::JITLoader},
+    {{"language"}, {"log language runtime events"}, LLDBLog::Language},
+    {{"mmap"}, {"log mmap related activities"}, LLDBLog::MMap},
+    {{"module"},
+     {"log module activities such as when modules are created, destroyed, "
+      "replaced, and more"},
+     LLDBLog::Modules},
+    {{"object"},
+     {"log object construction/destruction for important objects"},
+     LLDBLog::Object},
+    {{"os"}, {"log OperatingSystem plugin related activities"}, LLDBLog::OS},
+    {{"platform"}, {"log platform events and activities"}, LLDBLog::Platform},
+    {{"process"}, {"log process events and activities"}, LLDBLog::Process},
+    {{"script"}, {"log events about the script interpreter"}, LLDBLog::Script},
+    {{"state"},
+     {"log private and public process state changes"},
+     LLDBLog::State},
+    {{"step"}, {"log step related activities"}, LLDBLog::Step},
+    {{"symbol"}, {"log symbol related issues and warnings"}, LLDBLog::Symbols},
+    {{"system-runtime"}, {"log system runtime events"}, LLDBLog::SystemRuntime},
+    {{"target"}, {"log target events and activities"}, LLDBLog::Target},
+    {{"temp"}, {"log internal temporary debug messages"}, LLDBLog::Temporary},
+    {{"thread"}, {"log thread events and activities"}, LLDBLog::Thread},
+    {{"types"}, {"log type system related activities"}, LLDBLog::Types},
+    {{"unwind"}, {"log stack unwind activities"}, LLDBLog::Unwind},
+    {{"watch"}, {"log watchpoint related activities"}, LLDBLog::Watchpoints},
 };
 
-static Log::Channel g_log_channel(g_categories, LIBLLDB_LOG_DEFAULT);
+static Log::Channel g_log_channel(g_categories,
+                                  LLDBLog::Process | LLDBLog::Thread |
+                                      LLDBLog::DynamicLoader |
+                                      LLDBLog::Breakpoints |
+                                      LLDBLog::Watchpoints | LLDBLog::Step |
+                                      LLDBLog::State | LLDBLog::Symbols |
+                                      LLDBLog::Target | LLDBLog::Commands);
+
+template <> Log::Channel &lldb_private::LogChannelFor<LLDBLog>() {
+  return g_log_channel;
+}
 
 void lldb_private::InitializeLldbChannel() {
   Log::Register("lldb", g_log_channel);
 }
 
-Log *lldb_private::GetLogIfAllCategoriesSet(uint32_t mask) {
-  return g_log_channel.GetLogIfAll(mask);
+Log *lldb_private::GetLogIfAllCategoriesSet(LLDBLog mask) {
+  return GetLog(mask);
 }
 
-Log *lldb_private::GetLogIfAnyCategoriesSet(uint32_t mask) {
-  return g_log_channel.GetLogIfAny(mask);
+Log *lldb_private::GetLogIfAnyCategoriesSet(LLDBLog mask) {
+  return GetLog(mask);
 }
Index: lldb/source/Utility/Log.cpp
===================================================================
--- lldb/source/Utility/Log.cpp
+++ lldb/source/Utility/Log.cpp
@@ -88,7 +88,7 @@
                  uint32_t options, uint32_t flags) {
   llvm::sys::ScopedWriter lock(m_mutex);
 
-  uint32_t mask = m_mask.fetch_or(flags, std::memory_order_relaxed);
+  MaskType mask = m_mask.fetch_or(flags, std::memory_order_relaxed);
   if (mask | flags) {
     m_options.store(options, std::memory_order_relaxed);
     m_stream_sp = stream_sp;
@@ -99,7 +99,7 @@
 void Log::Disable(uint32_t flags) {
   llvm::sys::ScopedWriter lock(m_mutex);
 
-  uint32_t mask = m_mask.fetch_and(~flags, std::memory_order_relaxed);
+  MaskType mask = m_mask.fetch_and(~flags, std::memory_order_relaxed);
   if (!(mask & ~flags)) {
     m_stream_sp.reset();
     m_channel.log_ptr.store(nullptr, std::memory_order_relaxed);
Index: lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
@@ -11,25 +11,32 @@
 
 #include "lldb/Utility/Log.h"
 
-#define DWARF_LOG_DEBUG_INFO (1u << 1)
-#define DWARF_LOG_DEBUG_LINE (1u << 2)
-#define DWARF_LOG_LOOKUPS (1u << 3)
-#define DWARF_LOG_TYPE_COMPLETION (1u << 4)
-#define DWARF_LOG_DEBUG_MAP (1u << 5)
-#define DWARF_LOG_ALL (UINT32_MAX)
-#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)
-
 namespace lldb_private {
-class LogChannelDWARF {
-  static Log::Channel g_channel;
 
+enum class DWARFLog : Log::MaskType {
+  DebugInfo = Log::ChannelFlag<0>,
+  DebugLine = Log::ChannelFlag<1>,
+  DebugMap = Log::ChannelFlag<2>,
+  Lookups = Log::ChannelFlag<3>,
+  TypeCompletion = Log::ChannelFlag<4>,
+  LLVM_MARK_AS_BITMASK_ENUM(TypeCompletion)
+};
+#define DWARF_LOG_DEBUG_INFO ::lldb_private::DWARFLog::DebugInfo
+#define DWARF_LOG_DEBUG_LINE ::lldb_private::DWARFLog::DebugLine
+#define DWARF_LOG_LOOKUPS ::lldb_private::DWARFLog::Lookups
+#define DWARF_LOG_TYPE_COMPLETION ::lldb_private::DWARFLog::TypeCompletion
+#define DWARF_LOG_DEBUG_MAP ::lldb_private::DWARFLog::DebugMap
+
+class LogChannelDWARF {
 public:
   static void Initialize();
   static void Terminate();
 
-  static Log *GetLogIfAll(uint32_t mask) { return g_channel.GetLogIfAll(mask); }
-  static Log *GetLogIfAny(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
+  static Log *GetLogIfAll(DWARFLog mask) { return GetLog(mask); }
+  static Log *GetLogIfAny(DWARFLog mask) { return GetLog(mask); }
 };
-}
+
+template <> Log::Channel &LogChannelFor<DWARFLog>();
+} // namespace lldb_private
 
 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H
Index: lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
@@ -13,18 +13,20 @@
 static constexpr Log::Category g_categories[] = {
     {{"comp"},
      {"log insertions of object files into DWARF debug maps"},
-     DWARF_LOG_TYPE_COMPLETION},
-    {{"info"}, {"log the parsing of .debug_info"}, DWARF_LOG_DEBUG_INFO},
-    {{"line"}, {"log the parsing of .debug_line"}, DWARF_LOG_DEBUG_LINE},
+     DWARFLog::TypeCompletion},
+    {{"info"}, {"log the parsing of .debug_info"}, DWARFLog::DebugInfo},
+    {{"line"}, {"log the parsing of .debug_line"}, DWARFLog::DebugLine},
     {{"lookups"},
      {"log any lookups that happen by name, regex, or address"},
-     DWARF_LOG_LOOKUPS},
-    {{"map"},
-     {"log struct/unions/class type completions"},
-     DWARF_LOG_DEBUG_MAP},
+     DWARFLog::Lookups},
+    {{"map"}, {"log struct/unions/class type completions"}, DWARFLog::DebugMap},
 };
 
-Log::Channel LogChannelDWARF::g_channel(g_categories, DWARF_LOG_DEFAULT);
+static Log::Channel g_channel(g_categories, DWARFLog::DebugInfo);
+
+template <> Log::Channel &lldb_private::LogChannelFor<DWARFLog>() {
+  return g_channel;
+}
 
 void LogChannelDWARF::Initialize() {
   Log::Register("dwarf", g_channel);
Index: lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -39,7 +39,7 @@
       m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown),
       m_queue_serial_number(LLDB_INVALID_QUEUE_ID),
       m_associated_with_libdispatch_queue(eLazyBoolCalculate) {
-  Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+  Log *log = GetLog(GDBRLog::Thread);
   LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(),
            GetID());
   // At this point we can clone reg_info for architectures supporting
@@ -54,7 +54,7 @@
 
 ThreadGDBRemote::~ThreadGDBRemote() {
   ProcessSP process_sp(GetProcess());
-  Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+  Log *log = GetLog(GDBRLog::Thread);
   LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this,
            process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID());
   DestroyThread();
@@ -222,7 +222,7 @@
 StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
   StructuredData::ObjectSP object_sp;
   const lldb::user_id_t tid = GetProtocolID();
-  Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+  Log *log = GetLog(GDBRLog::Thread);
   LLDB_LOGF(log, "Fetching extended information for thread %4.4" PRIx64, tid);
   ProcessSP process_sp(GetProcess());
   if (process_sp) {
@@ -236,7 +236,7 @@
 void ThreadGDBRemote::WillResume(StateType resume_state) {
   int signo = GetResumeSignal();
   const lldb::user_id_t tid = GetProtocolID();
-  Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+  Log *log = GetLog(GDBRLog::Thread);
   LLDB_LOGF(log, "Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
             StateAsCString(resume_state));
 
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -11,35 +11,52 @@
 
 #include "lldb/Utility/Log.h"
 
-#define GDBR_LOG_PROCESS (1u << 1)
-#define GDBR_LOG_THREAD (1u << 2)
-#define GDBR_LOG_PACKETS (1u << 3)
-#define GDBR_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define GDBR_LOG_MEMORY_DATA_SHORT                                             \
-  (1u << 5) // Log short memory reads/writes bytes
-#define GDBR_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
-#define GDBR_LOG_BREAKPOINTS (1u << 7)
-#define GDBR_LOG_WATCHPOINTS (1u << 8)
-#define GDBR_LOG_STEP (1u << 9)
-#define GDBR_LOG_COMM (1u << 10)
-#define GDBR_LOG_ASYNC (1u << 11)
-#define GDBR_LOG_ALL (UINT32_MAX)
-#define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS
-
 namespace lldb_private {
 namespace process_gdb_remote {
 
-class ProcessGDBRemoteLog {
-  static Log::Channel g_channel;
+enum class GDBRLog : Log::MaskType {
+  Async = Log::ChannelFlag<0>,
+  Breakpoints = Log::ChannelFlag<1>,
+  Comm = Log::ChannelFlag<2>,
+  Memory = Log::ChannelFlag<3>,          // Log memory reads/writes calls
+  MemoryDataLong = Log::ChannelFlag<4>,  // Log all memory reads/writes bytes
+  MemoryDataShort = Log::ChannelFlag<5>, // Log short memory reads/writes bytes
+  Packets = Log::ChannelFlag<6>,
+  Process = Log::ChannelFlag<7>,
+  Step = Log::ChannelFlag<8>,
+  Thread = Log::ChannelFlag<9>,
+  Watchpoints = Log::ChannelFlag<10>,
+  LLVM_MARK_AS_BITMASK_ENUM(Watchpoints)
+};
 
+#define GDBR_LOG_PROCESS ::lldb_private::process_gdb_remote::GDBRLog::Process
+#define GDBR_LOG_THREAD ::lldb_private::process_gdb_remote::GDBRLog::Thread
+#define GDBR_LOG_PACKETS ::lldb_private::process_gdb_remote::GDBRLog::Packets
+#define GDBR_LOG_MEMORY ::lldb_private::process_gdb_remote::GDBRLog::Memory
+#define GDBR_LOG_MEMORY_DATA_SHORT                                             \
+  ::lldb_private::process_gdb_remote::GDBRLog::MemoryDataShort
+#define GDBR_LOG_MEMORY_DATA_LONG                                              \
+  ::lldb_private::process_gdb_remote::GDBRLog::MemoryDataLong
+#define GDBR_LOG_BREAKPOINTS                                                   \
+  ::lldb_private::process_gdb_remote::GDBRLog::Breakpoints
+#define GDBR_LOG_WATCHPOINTS                                                   \
+  ::lldb_private::process_gdb_remote::GDBRLog::Watchpoints
+#define GDBR_LOG_STEP ::lldb_private::process_gdb_remote::GDBRLog::Step
+#define GDBR_LOG_COMM ::lldb_private::process_gdb_remote::GDBRLog::Comm
+#define GDBR_LOG_ASYNC ::lldb_private::process_gdb_remote::GDBRLog::Async
+
+class ProcessGDBRemoteLog {
 public:
   static void Initialize();
 
-  static Log *GetLogIfAllCategoriesSet(uint32_t mask) { return g_channel.GetLogIfAll(mask); }
-  static Log *GetLogIfAnyCategoryIsSet(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
+  static Log *GetLogIfAllCategoriesSet(GDBRLog mask) { return GetLog(mask); }
+  static Log *GetLogIfAnyCategoryIsSet(GDBRLog mask) { return GetLog(mask); }
 };
 
 } // namespace process_gdb_remote
+
+template <> Log::Channel &LogChannelFor<process_gdb_remote::GDBRLog>();
+
 } // namespace lldb_private
 
 #endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
@@ -15,25 +15,29 @@
 using namespace lldb_private::process_gdb_remote;
 
 static constexpr Log::Category g_categories[] = {
-    {{"async"}, {"log asynchronous activity"}, GDBR_LOG_ASYNC},
-    {{"break"}, {"log breakpoints"}, GDBR_LOG_BREAKPOINTS},
-    {{"comm"}, {"log communication activity"}, GDBR_LOG_COMM},
-    {{"packets"}, {"log gdb remote packets"}, GDBR_LOG_PACKETS},
-    {{"memory"}, {"log memory reads and writes"}, GDBR_LOG_MEMORY},
+    {{"async"}, {"log asynchronous activity"}, GDBRLog::Async},
+    {{"break"}, {"log breakpoints"}, GDBRLog::Breakpoints},
+    {{"comm"}, {"log communication activity"}, GDBRLog::Comm},
+    {{"packets"}, {"log gdb remote packets"}, GDBRLog::Packets},
+    {{"memory"}, {"log memory reads and writes"}, GDBRLog::Memory},
     {{"data-short"},
      {"log memory bytes for memory reads and writes for short transactions "
       "only"},
-     GDBR_LOG_MEMORY_DATA_SHORT},
+     GDBRLog::MemoryDataShort},
     {{"data-long"},
      {"log memory bytes for memory reads and writes for all transactions"},
-     GDBR_LOG_MEMORY_DATA_LONG},
-    {{"process"}, {"log process events and activities"}, GDBR_LOG_PROCESS},
-    {{"step"}, {"log step related activities"}, GDBR_LOG_STEP},
-    {{"thread"}, {"log thread events and activities"}, GDBR_LOG_THREAD},
-    {{"watch"}, {"log watchpoint related activities"}, GDBR_LOG_WATCHPOINTS},
+     GDBRLog::MemoryDataLong},
+    {{"process"}, {"log process events and activities"}, GDBRLog::Process},
+    {{"step"}, {"log step related activities"}, GDBRLog::Step},
+    {{"thread"}, {"log thread events and activities"}, GDBRLog::Thread},
+    {{"watch"}, {"log watchpoint related activities"}, GDBRLog::Watchpoints},
 };
 
-Log::Channel ProcessGDBRemoteLog::g_channel(g_categories, GDBR_LOG_DEFAULT);
+static Log::Channel g_channel(g_categories, GDBRLog::Packets);
+
+template <> Log::Channel &lldb_private::LogChannelFor<GDBRLog>() {
+  return g_channel;
+}
 
 void ProcessGDBRemoteLog::Initialize() {
   static llvm::once_flag g_once_flag;
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -529,7 +529,7 @@
 }
 
 Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
-  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  Log *log = GetLog(GDBRLog::Process);
 
   Status error(WillLaunchOrAttach());
   if (error.Fail())
@@ -606,8 +606,7 @@
                 ReadModuleFromMemory(FileSpec(namebuf), standalone_value);
           }
 
-          Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
-              LIBLLDB_LOG_DYNAMIC_LOADER));
+          Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
           if (module_sp.get()) {
             target.GetImages().AppendIfNeeded(module_sp, false);
 
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1086,7 +1086,7 @@
 }
 
 void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
-  Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
+  Log *log = GetLog(GDBRLog::Comm);
 
   bool interrupt = false;
   bool done = false;
Index: lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
===================================================================
--- lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
+++ lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
@@ -13,27 +13,35 @@
 
 #include "lldb/Utility/Log.h"
 
-#define POSIX_LOG_PROCESS (1u << 1)
-#define POSIX_LOG_THREAD (1u << 2)
-#define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define POSIX_LOG_PTRACE (1u << 5)
-#define POSIX_LOG_REGISTERS (1u << 6)
-#define POSIX_LOG_BREAKPOINTS (1u << 7)
-#define POSIX_LOG_WATCHPOINTS (1u << 8)
-#define POSIX_LOG_ALL (UINT32_MAX)
-#define POSIX_LOG_DEFAULT POSIX_LOG_PROCESS
-
 namespace lldb_private {
-class ProcessPOSIXLog {
-  static Log::Channel g_channel;
 
+enum class POSIXLog : Log::MaskType {
+  Breakpoints = Log::ChannelFlag<0>,
+  Memory = Log::ChannelFlag<1>,
+  Process = Log::ChannelFlag<2>,
+  Ptrace = Log::ChannelFlag<3>,
+  Registers = Log::ChannelFlag<4>,
+  Thread = Log::ChannelFlag<5>,
+  Watchpoints = Log::ChannelFlag<6>,
+  LLVM_MARK_AS_BITMASK_ENUM(Watchpoints)
+};
+
+#define POSIX_LOG_PROCESS ::lldb_private::POSIXLog::Process
+#define POSIX_LOG_THREAD ::lldb_private::POSIXLog::Thread
+#define POSIX_LOG_MEMORY ::lldb_private::POSIXLog::Memory
+#define POSIX_LOG_PTRACE ::lldb_private::POSIXLog::Ptrace
+#define POSIX_LOG_REGISTERS ::lldb_private::POSIXLog::Registers
+#define POSIX_LOG_BREAKPOINTS ::lldb_private::POSIXLog::Breakpoints
+#define POSIX_LOG_WATCHPOINTS ::lldb_private::POSIXLog::Watchpoints
+
+class ProcessPOSIXLog {
 public:
   static void Initialize();
 
-  static Log *GetLogIfAllCategoriesSet(uint32_t mask) {
-    return g_channel.GetLogIfAll(mask);
-  }
+  static Log *GetLogIfAllCategoriesSet(POSIXLog mask) { return GetLog(mask); }
 };
-}
+
+template <> Log::Channel &LogChannelFor<POSIXLog>();
+} // namespace lldb_private
 
 #endif // liblldb_ProcessPOSIXLog_h_
Index: lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
===================================================================
--- lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
+++ lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
@@ -13,16 +13,20 @@
 using namespace lldb_private;
 
 static constexpr Log::Category g_categories[] = {
-  {{"break"}, {"log breakpoints"}, POSIX_LOG_BREAKPOINTS},
-  {{"memory"}, {"log memory reads and writes"}, POSIX_LOG_MEMORY},
-  {{"process"}, {"log process events and activities"}, POSIX_LOG_PROCESS},
-  {{"ptrace"}, {"log all calls to ptrace"}, POSIX_LOG_PTRACE},
-  {{"registers"}, {"log register read/writes"}, POSIX_LOG_REGISTERS},
-  {{"thread"}, {"log thread events and activities"}, POSIX_LOG_THREAD},
-  {{"watch"}, {"log watchpoint related activities"}, POSIX_LOG_WATCHPOINTS},
+    {{"break"}, {"log breakpoints"}, POSIXLog::Breakpoints},
+    {{"memory"}, {"log memory reads and writes"}, POSIXLog::Memory},
+    {{"process"}, {"log process events and activities"}, POSIXLog::Process},
+    {{"ptrace"}, {"log all calls to ptrace"}, POSIXLog::Ptrace},
+    {{"registers"}, {"log register read/writes"}, POSIXLog::Registers},
+    {{"thread"}, {"log thread events and activities"}, POSIXLog::Thread},
+    {{"watch"}, {"log watchpoint related activities"}, POSIXLog::Watchpoints},
 };
 
-Log::Channel ProcessPOSIXLog::g_channel(g_categories, POSIX_LOG_DEFAULT);
+static Log::Channel g_channel(g_categories, POSIXLog::Process);
+
+template <> Log::Channel &lldb_private::LogChannelFor<POSIXLog>() {
+  return g_channel;
+}
 
 void ProcessPOSIXLog::Initialize() {
   static llvm::once_flag g_once_flag;
Index: lldb/include/lldb/Utility/Logging.h
===================================================================
--- lldb/include/lldb/Utility/Logging.h
+++ lldb/include/lldb/Utility/Logging.h
@@ -9,57 +9,89 @@
 #ifndef LLDB_UTILITY_LOGGING_H
 #define LLDB_UTILITY_LOGGING_H
 
+#include "lldb/Utility/Log.h"
+#include "llvm/ADT/BitmaskEnum.h"
 #include <cstdint>
 
-// Log Bits specific to logging in lldb
-#define LIBLLDB_LOG_PROCESS (1u << 1)
-#define LIBLLDB_LOG_THREAD (1u << 2)
-#define LIBLLDB_LOG_DYNAMIC_LOADER (1u << 3)
-#define LIBLLDB_LOG_EVENTS (1u << 4)
-#define LIBLLDB_LOG_BREAKPOINTS (1u << 5)
-#define LIBLLDB_LOG_WATCHPOINTS (1u << 6)
-#define LIBLLDB_LOG_STEP (1u << 7)
-#define LIBLLDB_LOG_EXPRESSIONS (1u << 8)
-#define LIBLLDB_LOG_TEMPORARY (1u << 9)
-#define LIBLLDB_LOG_STATE (1u << 10)
-#define LIBLLDB_LOG_OBJECT (1u << 11)
-#define LIBLLDB_LOG_COMMUNICATION (1u << 12)
-#define LIBLLDB_LOG_CONNECTION (1u << 13)
-#define LIBLLDB_LOG_HOST (1u << 14)
-#define LIBLLDB_LOG_UNWIND (1u << 15)
-#define LIBLLDB_LOG_API (1u << 16)
-#define LIBLLDB_LOG_SCRIPT (1u << 17)
-#define LIBLLDB_LOG_COMMANDS (1U << 18)
-#define LIBLLDB_LOG_TYPES (1u << 19)
-#define LIBLLDB_LOG_SYMBOLS (1u << 20)
-#define LIBLLDB_LOG_MODULES (1u << 21)
-#define LIBLLDB_LOG_TARGET (1u << 22)
-#define LIBLLDB_LOG_MMAP (1u << 23)
-#define LIBLLDB_LOG_OS (1u << 24)
-#define LIBLLDB_LOG_PLATFORM (1u << 25)
-#define LIBLLDB_LOG_SYSTEM_RUNTIME (1u << 26)
-#define LIBLLDB_LOG_JIT_LOADER (1u << 27)
-#define LIBLLDB_LOG_LANGUAGE (1u << 28)
-#define LIBLLDB_LOG_DATAFORMATTERS (1u << 29)
-#define LIBLLDB_LOG_DEMANGLE (1u << 30)
-#define LIBLLDB_LOG_AST (1u << 31)
-#define LIBLLDB_LOG_ALL (UINT32_MAX)
-#define LIBLLDB_LOG_DEFAULT                                                    \
-  (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD | LIBLLDB_LOG_DYNAMIC_LOADER |     \
-   LIBLLDB_LOG_BREAKPOINTS | LIBLLDB_LOG_WATCHPOINTS | LIBLLDB_LOG_STEP |      \
-   LIBLLDB_LOG_STATE | LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_TARGET |              \
-   LIBLLDB_LOG_COMMANDS)
-
 namespace lldb_private {
 
-class Log;
+enum class LLDBLog : Log::MaskType {
+  API = Log::ChannelFlag<0>,
+  AST = Log::ChannelFlag<1>,
+  Breakpoints = Log::ChannelFlag<2>,
+  Commands = Log::ChannelFlag<3>,
+  Communication = Log::ChannelFlag<4>,
+  Connection = Log::ChannelFlag<5>,
+  DataFormatters = Log::ChannelFlag<6>,
+  Demangle = Log::ChannelFlag<7>,
+  DynamicLoader = Log::ChannelFlag<8>,
+  Events = Log::ChannelFlag<9>,
+  Expressions = Log::ChannelFlag<10>,
+  Host = Log::ChannelFlag<11>,
+  JITLoader = Log::ChannelFlag<12>,
+  Language = Log::ChannelFlag<13>,
+  MMap = Log::ChannelFlag<14>,
+  Modules = Log::ChannelFlag<15>,
+  Object = Log::ChannelFlag<16>,
+  OS = Log::ChannelFlag<17>,
+  Platform = Log::ChannelFlag<18>,
+  Process = Log::ChannelFlag<19>,
+  Script = Log::ChannelFlag<20>,
+  State = Log::ChannelFlag<21>,
+  Step = Log::ChannelFlag<22>,
+  Symbols = Log::ChannelFlag<23>,
+  SystemRuntime = Log::ChannelFlag<24>,
+  Target = Log::ChannelFlag<25>,
+  Temporary = Log::ChannelFlag<26>,
+  Thread = Log::ChannelFlag<27>,
+  Types = Log::ChannelFlag<28>,
+  Unwind = Log::ChannelFlag<29>,
+  Watchpoints = Log::ChannelFlag<30>,
+  LLVM_MARK_AS_BITMASK_ENUM(Watchpoints),
+};
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+// Log Bits specific to logging in lldb
+#define LIBLLDB_LOG_PROCESS ::lldb_private::LLDBLog::Process
+#define LIBLLDB_LOG_THREAD ::lldb_private::LLDBLog::Thread
+#define LIBLLDB_LOG_DYNAMIC_LOADER ::lldb_private::LLDBLog::DynamicLoader
+#define LIBLLDB_LOG_EVENTS ::lldb_private::LLDBLog::Events
+#define LIBLLDB_LOG_BREAKPOINTS ::lldb_private::LLDBLog::Breakpoints
+#define LIBLLDB_LOG_WATCHPOINTS ::lldb_private::LLDBLog::Watchpoints
+#define LIBLLDB_LOG_STEP ::lldb_private::LLDBLog::Step
+#define LIBLLDB_LOG_EXPRESSIONS ::lldb_private::LLDBLog::Expressions
+#define LIBLLDB_LOG_TEMPORARY ::lldb_private::LLDBLog::Temporary
+#define LIBLLDB_LOG_STATE ::lldb_private::LLDBLog::State
+#define LIBLLDB_LOG_OBJECT ::lldb_private::LLDBLog::Object
+#define LIBLLDB_LOG_COMMUNICATION ::lldb_private::LLDBLog::Communication
+#define LIBLLDB_LOG_CONNECTION ::lldb_private::LLDBLog::Connection
+#define LIBLLDB_LOG_HOST ::lldb_private::LLDBLog::Host
+#define LIBLLDB_LOG_UNWIND ::lldb_private::LLDBLog::Unwind
+#define LIBLLDB_LOG_API ::lldb_private::LLDBLog::API
+#define LIBLLDB_LOG_SCRIPT ::lldb_private::LLDBLog::Script
+#define LIBLLDB_LOG_COMMANDS ::lldb_private::LLDBLog::Commands
+#define LIBLLDB_LOG_TYPES ::lldb_private::LLDBLog::Types
+#define LIBLLDB_LOG_SYMBOLS ::lldb_private::LLDBLog::Symbols
+#define LIBLLDB_LOG_MODULES ::lldb_private::LLDBLog::Modules
+#define LIBLLDB_LOG_TARGET ::lldb_private::LLDBLog::Target
+#define LIBLLDB_LOG_MMAP ::lldb_private::LLDBLog::MMap
+#define LIBLLDB_LOG_OS ::lldb_private::LLDBLog::OS
+#define LIBLLDB_LOG_PLATFORM ::lldb_private::LLDBLog::Platform
+#define LIBLLDB_LOG_SYSTEM_RUNTIME ::lldb_private::LLDBLog::SystemRuntime
+#define LIBLLDB_LOG_JIT_LOADER ::lldb_private::LLDBLog::JITLoader
+#define LIBLLDB_LOG_LANGUAGE ::lldb_private::LLDBLog::Language
+#define LIBLLDB_LOG_DATAFORMATTERS ::lldb_private::LLDBLog::DataFormatters
+#define LIBLLDB_LOG_DEMANGLE ::lldb_private::LLDBLog::Demangle
+#define LIBLLDB_LOG_AST ::lldb_private::LLDBLog::AST
 
-Log *GetLogIfAllCategoriesSet(uint32_t mask);
+Log *GetLogIfAllCategoriesSet(LLDBLog mask);
 
-Log *GetLogIfAnyCategoriesSet(uint32_t mask);
+Log *GetLogIfAnyCategoriesSet(LLDBLog mask);
 
 void InitializeLldbChannel();
 
+template <> Log::Channel &LogChannelFor<LLDBLog>();
 } // namespace lldb_private
 
 #endif // LLDB_UTILITY_LOGGING_H
Index: lldb/include/lldb/Utility/Log.h
===================================================================
--- lldb/include/lldb/Utility/Log.h
+++ lldb/include/lldb/Utility/Log.h
@@ -10,7 +10,6 @@
 #define LLDB_UTILITY_LOG_H
 
 #include "lldb/Utility/Flags.h"
-#include "lldb/Utility/Logging.h"
 #include "lldb/lldb-defines.h"
 
 #include "llvm/ADT/ArrayRef.h"
@@ -48,11 +47,31 @@
 
 class Log final {
 public:
+  /// The underlying type of all log channel enums. Declare them as:
+  /// enum class MyLog : MaskType {
+  ///   Channel0 = Log::ChannelFlag<0>,
+  ///   Channel1 = Log::ChannelFlag<1>,
+  ///   ...,
+  ///   LLVM_MARK_AS_BITMASK_ENUM(LastChannel),
+  /// };
+  using MaskType = uint64_t;
+
+  template <MaskType Bit>
+  static constexpr MaskType ChannelFlag = MaskType(1) << Bit;
+
   // Description of a log channel category.
   struct Category {
     llvm::StringLiteral name;
     llvm::StringLiteral description;
-    uint32_t flag;
+    MaskType flag;
+
+    template <typename Cat>
+    constexpr Category(llvm::StringLiteral name,
+                       llvm::StringLiteral description, Cat mask)
+        : name(name), description(description), flag(MaskType(mask)) {
+      static_assert(
+          std::is_same<Log::MaskType, std::underlying_type_t<Cat>>::value, "");
+    }
   };
 
   // This class describes a log channel. It also encapsulates the behavior
@@ -63,18 +82,22 @@
 
   public:
     const llvm::ArrayRef<Category> categories;
-    const uint32_t default_flags;
+    const MaskType default_flags;
 
+    template <typename Cat>
     constexpr Channel(llvm::ArrayRef<Log::Category> categories,
-                      uint32_t default_flags)
+                      Cat default_flags)
         : log_ptr(nullptr), categories(categories),
-          default_flags(default_flags) {}
+          default_flags(MaskType(default_flags)) {
+      static_assert(
+          std::is_same<Log::MaskType, std::underlying_type_t<Cat>>::value, "");
+    }
 
     // This function is safe to call at any time. If the channel is disabled
     // after (or concurrently with) this function returning a non-null Log
     // pointer, it is still safe to attempt to write to the Log object -- the
     // output will be discarded.
-    Log *GetLogIfAll(uint32_t mask) {
+    Log *GetLogIfAll(MaskType mask) {
       Log *log = log_ptr.load(std::memory_order_relaxed);
       if (log && log->GetMask().AllSet(mask))
         return log;
@@ -85,7 +108,7 @@
     // after (or concurrently with) this function returning a non-null Log
     // pointer, it is still safe to attempt to write to the Log object -- the
     // output will be discarded.
-    Log *GetLogIfAny(uint32_t mask) {
+    Log *GetLogIfAny(MaskType mask) {
       Log *log = log_ptr.load(std::memory_order_relaxed);
       if (log && log->GetMask().AnySet(mask))
         return log;
@@ -180,7 +203,7 @@
 
   std::shared_ptr<llvm::raw_ostream> m_stream_sp;
   std::atomic<uint32_t> m_options{0};
-  std::atomic<uint32_t> m_mask{0};
+  std::atomic<MaskType> m_mask{0};
 
   void WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file,
                    llvm::StringRef function);
@@ -215,6 +238,19 @@
   void operator=(const Log &) = delete;
 };
 
+// Must be specialized for a particular log type.
+template <typename Cat> Log::Channel &LogChannelFor() = delete;
+
+/// Retrieve the Log object for the channel associated with the given log enum.
+///
+/// Returns a valid Log object if any of the provided categories are enabled.
+/// Otherwise, returns nullptr.
+template <typename Cat> Log *GetLog(Cat mask) {
+  static_assert(std::is_same<Log::MaskType, std::underlying_type_t<Cat>>::value,
+                "");
+  return LogChannelFor<Cat>().GetLogIfAny(Log::MaskType(mask));
+}
+
 } // namespace lldb_private
 
 /// The LLDB_LOG* macros defined below are the way to emit log messages.
@@ -272,3 +308,6 @@
   } while (0)
 
 #endif // LLDB_UTILITY_LOG_H
+
+// TODO: Remove this and fix includes everywhere.
+#include "lldb/Utility/Logging.h"
Index: lldb/include/lldb/Interpreter/ScriptedInterface.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptedInterface.h
+++ lldb/include/lldb/Interpreter/ScriptedInterface.h
@@ -31,8 +31,7 @@
 
   template <typename Ret>
   Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_msg,
-                       Status &error,
-                       uint32_t log_caterogy = LIBLLDB_LOG_PROCESS) {
+                       Status &error, LLDBLog log_caterogy = LLDBLog::Process) {
     LLDB_LOGF(GetLogIfAllCategoriesSet(log_caterogy), "%s ERROR = %s",
               caller_name.data(), error_msg.data());
     error.SetErrorString(llvm::Twine(caller_name + llvm::Twine(" ERROR = ") +
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to