blob: d2de299b648c650ef566ab0582de298d7f793cce [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Log.cpp -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011#include <stdio.h>
12#include <stdarg.h>
13#include <stdlib.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014
15// C++ Includes
16#include <map>
17#include <string>
18
19// Other libraries and framework includes
20// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/Log.h"
22#include "lldb/Core/PluginManager.h"
23#include "lldb/Core/StreamFile.h"
24#include "lldb/Core/StreamString.h"
25#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Host/Mutex.h"
Zachary Turner39de3112014-09-09 20:54:56 +000027#include "lldb/Host/ThisThread.h"
28#include "lldb/Host/TimeValue.h"
Caroline Tice20ad3c42010-10-29 21:48:37 +000029#include "lldb/Interpreter/Args.h"
Zachary Turner50232572015-03-18 21:31:45 +000030#include "lldb/Utility/NameMatches.h"
Zachary Turner39de3112014-09-09 20:54:56 +000031
32#include "llvm/ADT/SmallString.h"
Zachary Turnera893d302015-03-06 20:45:43 +000033#include "llvm/Support/raw_ostream.h"
34#include "llvm/Support/Signals.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035using namespace lldb;
36using namespace lldb_private;
37
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038Log::Log () :
39 m_stream_sp(),
40 m_options(0),
41 m_mask_bits(0)
42{
43}
44
Greg Clayton5160ce52013-03-27 23:08:40 +000045Log::Log (const StreamSP &stream_sp) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046 m_stream_sp(stream_sp),
47 m_options(0),
48 m_mask_bits(0)
49{
50}
51
52Log::~Log ()
53{
54}
55
56Flags &
57Log::GetOptions()
58{
59 return m_options;
60}
61
62const Flags &
63Log::GetOptions() const
64{
65 return m_options;
66}
67
68Flags &
69Log::GetMask()
70{
71 return m_mask_bits;
72}
73
74const Flags &
75Log::GetMask() const
76{
77 return m_mask_bits;
78}
79
Zachary Turnerc1592652015-04-29 22:55:28 +000080void
81Log::PutCString(const char *cstr)
82{
83 Printf("%s", cstr);
84}
85
86//----------------------------------------------------------------------
87// Simple variable argument logging with flags.
88//----------------------------------------------------------------------
89void
90Log::Printf(const char *format, ...)
91{
92 va_list args;
93 va_start(args, format);
94 VAPrintf(format, args);
95 va_end(args);
96}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097
98//----------------------------------------------------------------------
99// All logging eventually boils down to this function call. If we have
100// a callback registered, then we call the logging callback. If we have
101// a valid file handle, we also log to the file.
102//----------------------------------------------------------------------
103void
Zachary Turnerc1592652015-04-29 22:55:28 +0000104Log::VAPrintf(const char *format, va_list args)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105{
Greg Claytone98008c2014-02-13 23:34:38 +0000106 // Make a copy of our stream shared pointer in case someone disables our
107 // log while we are logging and releases the stream
108 StreamSP stream_sp(m_stream_sp);
109 if (stream_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 {
111 static uint32_t g_sequence_id = 0;
112 StreamString header;
Greg Clayton64195a22011-02-23 00:35:02 +0000113 // Enabling the thread safe logging actually deadlocks right now.
114 // Need to fix this at some point.
115// static Mutex g_LogThreadedMutex(Mutex::eMutexTypeRecursive);
116// Mutex::Locker locker (g_LogThreadedMutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117
118 // Add a sequence ID if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000119 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000120 header.Printf ("%u ", ++g_sequence_id);
121
122 // Timestamp if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000123 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124 {
Virgile Bello0a3b1512013-09-04 13:56:11 +0000125 TimeValue now = TimeValue::Now();
Jason Molenda3c2daca2013-09-11 21:00:37 +0000126 header.Printf ("%9d.%6.6d ", now.seconds(), now.nanoseconds());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127 }
128
129 // Add the process and thread if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000130 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
Daniel Malead01b2952012-11-29 21:49:15 +0000131 header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132
Ed Mastecc913d142014-05-21 13:46:46 +0000133 // Add the thread name if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000134 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135 {
Zachary Turner39de3112014-09-09 20:54:56 +0000136 llvm::SmallString<32> thread_name;
137 ThisThread::GetName(thread_name);
Greg Clayton85719632013-02-27 22:51:58 +0000138 if (!thread_name.empty())
139 header.Printf ("%s ", thread_name.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140 }
141
142 header.PrintfVarArg (format, args);
Greg Claytone98008c2014-02-13 23:34:38 +0000143 stream_sp->Printf("%s\n", header.GetData());
Greg Clayton3a18e312012-10-08 22:41:53 +0000144
Zachary Turnera893d302015-03-06 20:45:43 +0000145 if (m_options.Test(LLDB_LOG_OPTION_BACKTRACE))
146 {
147 std::string back_trace;
148 llvm::raw_string_ostream stream(back_trace);
149 llvm::sys::PrintStackTrace(stream);
150 stream_sp->PutCString(back_trace.c_str());
151 }
Greg Claytone98008c2014-02-13 23:34:38 +0000152 stream_sp->Flush();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153 }
154}
155
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156//----------------------------------------------------------------------
157// Print debug strings if and only if the global debug option is set to
158// a non-zero value.
159//----------------------------------------------------------------------
160void
Zachary Turnerc1592652015-04-29 22:55:28 +0000161Log::Debug(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162{
Zachary Turnerc1592652015-04-29 22:55:28 +0000163 if (!GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
164 return;
165
166 va_list args;
167 va_start(args, format);
168 VAPrintf(format, args);
169 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170}
171
172
173//----------------------------------------------------------------------
174// Print debug strings if and only if the global debug option is set to
175// a non-zero value.
176//----------------------------------------------------------------------
177void
Zachary Turnerc1592652015-04-29 22:55:28 +0000178Log::DebugVerbose(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179{
Zachary Turnerc1592652015-04-29 22:55:28 +0000180 if (!GetOptions().AllSet(LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
181 return;
182
183 va_list args;
184 va_start(args, format);
185 VAPrintf(format, args);
186 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187}
188
189
190//----------------------------------------------------------------------
191// Log only if all of the bits are set
192//----------------------------------------------------------------------
193void
Zachary Turnerc1592652015-04-29 22:55:28 +0000194Log::LogIf(uint32_t bits, const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195{
Zachary Turnerc1592652015-04-29 22:55:28 +0000196 if (!m_options.AllSet(bits))
197 return;
198
199 va_list args;
200 va_start(args, format);
201 VAPrintf(format, args);
202 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000203}
204
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205//----------------------------------------------------------------------
206// Printing of errors that are not fatal.
207//----------------------------------------------------------------------
208void
Zachary Turnerc1592652015-04-29 22:55:28 +0000209Log::Error(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 va_list args;
Zachary Turnerc1592652015-04-29 22:55:28 +0000212 va_start(args, format);
Zachary Turner610e5292015-05-07 21:39:33 +0000213 VAError(format, args);
Zachary Turnerc1592652015-04-29 22:55:28 +0000214 va_end(args);
Zachary Turner610e5292015-05-07 21:39:33 +0000215}
216
217
218void
219Log::VAError(const char *format, va_list args)
220{
221 char *arg_msg = nullptr;
222 ::vasprintf(&arg_msg, format, args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000223
Zachary Turnerc1592652015-04-29 22:55:28 +0000224 if (arg_msg == nullptr)
225 return;
226
Pavel Labathd351bcc2015-04-30 10:47:56 +0000227 Printf("error: %s", arg_msg);
Zachary Turnerc1592652015-04-29 22:55:28 +0000228 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229}
230
Zachary Turner610e5292015-05-07 21:39:33 +0000231
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232//----------------------------------------------------------------------
233// Printing of errors that ARE fatal. Exit with ERR exit code
234// immediately.
235//----------------------------------------------------------------------
236void
Zachary Turnerc1592652015-04-29 22:55:28 +0000237Log::FatalError(int err, const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238{
Zachary Turnerc1592652015-04-29 22:55:28 +0000239 char *arg_msg = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240 va_list args;
Zachary Turnerc1592652015-04-29 22:55:28 +0000241 va_start(args, format);
242 ::vasprintf(&arg_msg, format, args);
243 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244
Zachary Turnerc1592652015-04-29 22:55:28 +0000245 if (arg_msg != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246 {
Zachary Turnerb74e2792015-04-29 23:24:12 +0000247 Printf("error: %s", arg_msg);
Zachary Turnerc1592652015-04-29 22:55:28 +0000248 ::free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 }
Zachary Turnerc1592652015-04-29 22:55:28 +0000250 ::exit(err);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251}
252
253
254//----------------------------------------------------------------------
255// Printing of warnings that are not fatal only if verbose mode is
256// enabled.
257//----------------------------------------------------------------------
258void
Zachary Turnerc1592652015-04-29 22:55:28 +0000259Log::Verbose(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260{
Zachary Turnerc1592652015-04-29 22:55:28 +0000261 if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
262 return;
263
264 va_list args;
265 va_start(args, format);
266 VAPrintf(format, args);
267 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268}
269
270//----------------------------------------------------------------------
271// Printing of warnings that are not fatal only if verbose mode is
272// enabled.
273//----------------------------------------------------------------------
274void
Zachary Turnerc1592652015-04-29 22:55:28 +0000275Log::WarningVerbose(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276{
Zachary Turnerc1592652015-04-29 22:55:28 +0000277 if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
278 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279
Zachary Turnerc1592652015-04-29 22:55:28 +0000280 char *arg_msg = nullptr;
281 va_list args;
282 va_start(args, format);
283 ::vasprintf(&arg_msg, format, args);
284 va_end(args);
285
286 if (arg_msg == nullptr)
287 return;
288
Zachary Turnerb74e2792015-04-29 23:24:12 +0000289 Printf("warning: %s", arg_msg);
Zachary Turnerc1592652015-04-29 22:55:28 +0000290 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291}
292//----------------------------------------------------------------------
293// Printing of warnings that are not fatal.
294//----------------------------------------------------------------------
295void
Zachary Turnerc1592652015-04-29 22:55:28 +0000296Log::Warning(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297{
Zachary Turnerc1592652015-04-29 22:55:28 +0000298 char *arg_msg = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000299 va_list args;
Zachary Turnerc1592652015-04-29 22:55:28 +0000300 va_start(args, format);
301 ::vasprintf(&arg_msg, format, args);
302 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303
Zachary Turnerc1592652015-04-29 22:55:28 +0000304 if (arg_msg == nullptr)
305 return;
306
Zachary Turnerb74e2792015-04-29 23:24:12 +0000307 Printf("warning: %s", arg_msg);
Zachary Turnerc1592652015-04-29 22:55:28 +0000308 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309}
310
Greg Clayton57abc5d2013-05-10 21:47:16 +0000311typedef std::map <ConstString, Log::Callbacks> CallbackMap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312typedef CallbackMap::iterator CallbackMapIter;
313
314typedef std::map <ConstString, LogChannelSP> LogChannelMap;
315typedef LogChannelMap::iterator LogChannelMapIter;
316
317
318// Surround our callback map with a singleton function so we don't have any
319// global initializers.
320static CallbackMap &
321GetCallbackMap ()
322{
323 static CallbackMap g_callback_map;
324 return g_callback_map;
325}
326
327static LogChannelMap &
328GetChannelMap ()
329{
330 static LogChannelMap g_channel_map;
331 return g_channel_map;
332}
333
334void
Greg Clayton57abc5d2013-05-10 21:47:16 +0000335Log::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336{
337 GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
338}
339
340bool
Greg Clayton57abc5d2013-05-10 21:47:16 +0000341Log::UnregisterLogChannel (const ConstString &channel)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342{
343 return GetCallbackMap().erase(channel) != 0;
344}
345
346bool
Greg Clayton57abc5d2013-05-10 21:47:16 +0000347Log::GetLogChannelCallbacks (const ConstString &channel, Log::Callbacks &log_callbacks)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348{
349 CallbackMap &callback_map = GetCallbackMap ();
350 CallbackMapIter pos = callback_map.find(channel);
351 if (pos != callback_map.end())
352 {
353 log_callbacks = pos->second;
354 return true;
355 }
Greg Clayton72b77eb2011-02-04 21:13:05 +0000356 ::memset (&log_callbacks, 0, sizeof(log_callbacks));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357 return false;
358}
359
360void
361Log::EnableAllLogChannels
362(
363 StreamSP &log_stream_sp,
364 uint32_t log_options,
Jim Ingham228063c2012-02-21 02:23:08 +0000365 const char **categories,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366 Stream *feedback_strm
367)
368{
369 CallbackMap &callback_map = GetCallbackMap ();
370 CallbackMapIter pos, end = callback_map.end();
371
372 for (pos = callback_map.begin(); pos != end; ++pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000373 pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374
375 LogChannelMap &channel_map = GetChannelMap ();
376 LogChannelMapIter channel_pos, channel_end = channel_map.end();
377 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
378 {
Jim Ingham228063c2012-02-21 02:23:08 +0000379 channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380 }
381
382}
383
384void
Greg Claytonab65b342011-04-13 22:47:15 +0000385Log::AutoCompleteChannelName (const char *channel_name, StringList &matches)
386{
387 LogChannelMap &map = GetChannelMap ();
388 LogChannelMapIter pos, end = map.end();
389 for (pos = map.begin(); pos != end; ++pos)
390 {
391 const char *pos_channel_name = pos->first.GetCString();
392 if (channel_name && channel_name[0])
393 {
394 if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name))
395 {
396 matches.AppendString(pos_channel_name);
397 }
398 }
399 else
400 matches.AppendString(pos_channel_name);
401
402 }
403}
404
405void
Caroline Tice20ad3c42010-10-29 21:48:37 +0000406Log::DisableAllLogChannels (Stream *feedback_strm)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407{
408 CallbackMap &callback_map = GetCallbackMap ();
409 CallbackMapIter pos, end = callback_map.end();
Jim Ingham228063c2012-02-21 02:23:08 +0000410 const char *categories[1] = {NULL};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411
412 for (pos = callback_map.begin(); pos != end; ++pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000413 pos->second.disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414
415 LogChannelMap &channel_map = GetChannelMap ();
416 LogChannelMapIter channel_pos, channel_end = channel_map.end();
417 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000418 channel_pos->second->Disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000419}
420
421void
Greg Clayton99d0faf2010-11-18 23:32:35 +0000422Log::Initialize()
423{
424 Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
Greg Clayton57abc5d2013-05-10 21:47:16 +0000425 Log::RegisterLogChannel (ConstString("lldb"), log_callbacks);
Greg Clayton99d0faf2010-11-18 23:32:35 +0000426}
427
428void
429Log::Terminate ()
430{
431 DisableAllLogChannels (NULL);
432}
433
434void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435Log::ListAllLogChannels (Stream *strm)
436{
437 CallbackMap &callback_map = GetCallbackMap ();
438 LogChannelMap &channel_map = GetChannelMap ();
439
440 if (callback_map.empty() && channel_map.empty())
441 {
442 strm->PutCString ("No logging channels are currently registered.\n");
443 return;
444 }
445
446 CallbackMapIter pos, end = callback_map.end();
447 for (pos = callback_map.begin(); pos != end; ++pos)
448 pos->second.list_categories (strm);
449
450 uint32_t idx = 0;
451 const char *name;
452 for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
453 {
454 LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
455 if (log_channel_sp)
456 log_channel_sp->ListCategories (strm);
457 }
458}
459
460bool
461Log::GetVerbose() const
462{
Jim Inghamd8d148e2011-01-22 01:24:30 +0000463 // FIXME: This has to be centralized between the stream and the log...
464 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
465 return true;
466
Greg Claytone98008c2014-02-13 23:34:38 +0000467 // Make a copy of our stream shared pointer in case someone disables our
468 // log while we are logging and releases the stream
469 StreamSP stream_sp(m_stream_sp);
470 if (stream_sp)
471 return stream_sp->GetVerbose();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472 return false;
473}
474
475//------------------------------------------------------------------
476// Returns true if the debug flag bit is set in this stream.
477//------------------------------------------------------------------
478bool
479Log::GetDebug() const
480{
Greg Claytone98008c2014-02-13 23:34:38 +0000481 // Make a copy of our stream shared pointer in case someone disables our
482 // log while we are logging and releases the stream
483 StreamSP stream_sp(m_stream_sp);
484 if (stream_sp)
485 return stream_sp->GetDebug();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486 return false;
487}
488
489
490LogChannelSP
491LogChannel::FindPlugin (const char *plugin_name)
492{
493 LogChannelSP log_channel_sp;
494 LogChannelMap &channel_map = GetChannelMap ();
495 ConstString log_channel_name (plugin_name);
496 LogChannelMapIter pos = channel_map.find (log_channel_name);
497 if (pos == channel_map.end())
498 {
Greg Clayton57abc5d2013-05-10 21:47:16 +0000499 ConstString const_plugin_name (plugin_name);
500 LogChannelCreateInstance create_callback = PluginManager::GetLogChannelCreateCallbackForPluginName (const_plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000501 if (create_callback)
502 {
503 log_channel_sp.reset(create_callback());
504 if (log_channel_sp)
505 {
506 // Cache the one and only loaded instance of each log channel
507 // plug-in after it has been loaded once.
508 channel_map[log_channel_name] = log_channel_sp;
509 }
510 }
511 }
512 else
513 {
514 // We have already loaded an instance of this log channel class,
515 // so just return the cached instance.
516 log_channel_sp = pos->second;
517 }
518 return log_channel_sp;
519}
520
521LogChannel::LogChannel () :
Greg Clayton5160ce52013-03-27 23:08:40 +0000522 m_log_ap ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523{
524}
525
526LogChannel::~LogChannel ()
527{
528}
529
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000530