summaryrefslogtreecommitdiffstats
path: root/languages/cpp/completiondebug.h
diff options
context:
space:
mode:
Diffstat (limited to 'languages/cpp/completiondebug.h')
-rw-r--r--languages/cpp/completiondebug.h221
1 files changed, 221 insertions, 0 deletions
diff --git a/languages/cpp/completiondebug.h b/languages/cpp/completiondebug.h
new file mode 100644
index 00000000..088b3b99
--- /dev/null
+++ b/languages/cpp/completiondebug.h
@@ -0,0 +1,221 @@
+/***************************************************************************
+copyright : (C) 2006 by David Nolden
+email : david.nolden.kdevelop@art-master.de
+***************************************************************************/
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef __COMPLETIONDEBUG_H__
+#define __COMPLETIONDEBUG_H__
+
+///With verbose shut on, the whole type-resolution-process is nicely traced for easy debugging(at cost of speed).
+//#define VERBOSE
+//#define VERBOSEMAJOR
+
+///When defined, a backtrace is printed the first time the maximum depth is reached for the first time.
+//#define DEPTHBACKTRACE
+
+#include <qstringlist.h>
+#include <kdebug.h>
+
+namespace CompletionDebug {
+template <class StreamType>
+class KDDebugState {
+ private:
+ StreamType m_stream;
+ kndbgstream m_nstream;
+ QStringList m_prefixStack;
+ int m_counter;
+ int m_depth;
+ bool m_enabled;
+ bool m_hadWarning;
+
+ public:
+ typedef StreamType KStreamType;
+ KDDebugState();
+
+ KDDebugState( StreamType stream ) : m_stream( stream ), m_counter( 0 ), m_depth( 0 ), m_enabled( true ), m_hadWarning( false ) {}
+
+ void push( const QString & txt ) {
+ m_prefixStack.push_back( txt );
+ pushDepth();
+ }
+
+ void pop() {
+ m_prefixStack.pop_back();
+ popDepth();
+ };
+
+ inline void pushDepth() {
+ m_depth++;
+ }
+
+ inline void popDepth() {
+ m_depth--;
+ }
+
+ bool hadWarning() {
+ return m_hadWarning;
+ }
+
+ void setHadWarning( bool had ) {
+ m_hadWarning = had;
+ }
+
+ StreamType& dbg() {
+#ifndef VERBOSE
+ if ( !m_enabled )
+ return m_nstream;
+#endif
+
+ m_stream << "(" << m_counter << ")";
+ for ( QStringList::iterator it = m_prefixStack.begin(); it != m_prefixStack.end() ; ++it )
+ m_stream << *it;
+
+ m_counter++;
+ return m_stream;
+ }
+
+ void setState( bool enabled ) {
+ m_enabled = enabled;
+ }
+
+ bool state() {
+ return m_enabled;
+ }
+
+#ifndef NDEBUG
+ void outputPrefix( kdbgstream& target ) {
+ target << "(" << m_counter << ")";
+ for ( QStringList::iterator it = m_prefixStack.begin(); it != m_prefixStack.end() ; ++it )
+ target << *it;
+
+ m_counter++;
+ }
+#endif
+
+ void clearCounter() {
+ m_counter = 0;
+ }
+
+ int depth() {
+ return m_depth;
+ }
+};
+#ifndef NDEBUG
+template <>
+KDDebugState<kdbgstream>::KDDebugState();
+#endif
+template <>
+KDDebugState<kndbgstream>::KDDebugState();
+#if defined(VERBOSE) && !defined(NDEBUG)
+typedef KDDebugState<kdbgstream> DBGStreamType;
+#else
+typedef KDDebugState<kndbgstream> DBGStreamType;
+#endif
+///Class to help indent the debug-output correctly
+extern DBGStreamType dbgState;
+extern const int completionMaxDepth;
+class LogDebug {
+ private:
+ DBGStreamType& m_state;
+ int m_max;
+ public:
+ LogDebug( const char* prefix = "#", int max = completionMaxDepth, DBGStreamType& st = dbgState ) : m_state( st ), m_max( max ) {
+ m_state.push( prefix );
+ };
+ ~LogDebug() {
+ m_state.pop();
+ }
+
+ DBGStreamType::KStreamType& dbg() {
+ return m_state.dbg();
+ }
+
+ int depth() {
+ return m_state.depth();
+ }
+
+ operator bool() {
+ bool r = depth() < m_max;
+
+ if ( !r && !m_state.hadWarning() ) {
+ m_state.setHadWarning( true );
+ dbg() << "recursion is too deep" << endl;
+#ifdef DEPTHBACKTRACE
+ kdDebug( 9007 ) << kdBacktrace() << endl;
+#endif
+ }
+ return r;
+ }
+};
+
+
+///does not care about the logging, but still counts the depth
+class DepthDebug {
+ DBGStreamType& m_state;
+ int m_max;
+ public:
+ DepthDebug( const char* prefix = "#", int max = completionMaxDepth, DBGStreamType& st = dbgState ) : m_state( st ), m_max( max ) {
+ Q_UNUSED( prefix );
+ m_state.pushDepth();
+ };
+
+ ~DepthDebug() {
+ m_state.popDepth();
+ }
+
+ kndbgstream dbg() {
+ return kndDebug();
+ }
+
+ int depth() {
+ return m_state.depth();
+ }
+
+ operator bool() {
+ bool r = depth() < m_max;
+
+ if ( !r && !m_state.hadWarning() ) {
+ m_state.setHadWarning( true );
+ dbg() << "recursion is too deep" << endl;
+#ifdef DEPTHBACKTRACE
+ kdDebug( 9007 ) << kdBacktrace() << endl;
+#endif
+ }
+ return r;
+ }
+};
+
+#ifndef VERBOSEMAJOR
+#define ifVerboseMajor(x) /**/
+#else
+#define ifVerboseMajor(x) x
+#endif
+
+bool dbgActive();
+
+#ifdef VERBOSE
+
+typedef LogDebug Debug;
+DBGStreamType::KStreamType& dbg();
+#define ifVerbose( x) {if( dbgActive() ) {x;}}
+#else
+
+DBGStreamType::KStreamType& dbg();
+typedef DepthDebug Debug;
+#define ifVerbose(x) /**/
+#endif
+#ifndef NDEBUG
+kdbgstream dbgMajor();
+#else
+kndbgstream dbgMajor();
+#endif
+}
+#endif
+// kate: indent-mode csands; tab-width 2;