From 0f8ae514592c46dc8465bc5830d7a830b68affe2 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Sat, 17 Oct 2015 19:05:00 +0100 Subject: Added support for include-what-you-use in a very simplistic fashion to the Scons build. This isn't exactly production ready because the qt headers are a nightmarish web of interdependencies but it's useful for checking. I've also removed a few unused include files it detected and corrected some things that upset clang in a big way. --- src/SConscript | 14 +++++++++++--- src/bbcode.cpp | 4 +--- src/browserdialog.cpp | 2 -- src/browserview.h | 4 +++- src/downloadmanager.cpp | 1 - src/helper.h | 2 +- src/loadmechanism.cpp | 2 +- src/loadmechanism.h | 2 +- src/modinfo.cpp | 1 - src/modinfo.h | 4 ++-- src/nxmaccessmanager.cpp | 1 - src/settings.cpp | 1 - src/settings.h | 10 +++++----- 13 files changed, 25 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index f09db093..cd2d8a52 100644 --- a/src/SConscript +++ b/src/SConscript @@ -67,7 +67,6 @@ env.Uic(env.Glob('*.ui')) env.RequireLibraries('uibase', 'shared', 'bsatk', 'esptk') - env.AppendUnique(LIBS = [ 'shell32', 'user32', @@ -114,8 +113,9 @@ env.AppendUnique(LINKFLAGS = [ # modeltest is optional and it doesn't compile anyway... cpp_files = [ - x for x in Glob('*.cpp') - if x.name != 'modeltest.cpp' and x.name != 'aboutdialog.cpp' + x for x in env.Glob('*.cpp', source = True) + if x.name != 'modeltest.cpp' and x.name != 'aboutdialog.cpp' and \ + not x.name.startswith('moc_') # I think this is a strange bug ] about_env = env.Clone() @@ -143,6 +143,14 @@ env.AppendUnique(LIBS = 'zlibstatic') prog = env.Program('ModOrganizer', cpp_files + env.Glob('*.qrc') + other_sources) +############################################################################### +# I'd like to automatically add this to every .o generation. +if 'IWYU' in env: + for f in cpp_files + [ env.File('aboutdialog.cpp') ]: + env.AddPostAction(prog, "-$IWYU $IWYU_FLAGS -Xiwyu --mapping_file=$IWYU_MAPPING_FILE $IWYU_COMCOM " + str(f)) + env.Depends(prog, env['IWYU_MAPPING_FILE']) +############################################################################### + env.InstallModule(prog) for subdir in ('tutorials', 'stylesheets'): diff --git a/src/bbcode.cpp b/src/bbcode.cpp index 0f9170d4..56369538 100644 --- a/src/bbcode.cpp +++ b/src/bbcode.cpp @@ -21,8 +21,6 @@ along with Mod Organizer. If not, see . #include #include -#include -#include namespace BBCode { @@ -80,7 +78,7 @@ public: if (tagName == "color") { QString color = tagIter->second.first.cap(1); QString content = tagIter->second.first.cap(2); - if (color.at(0) == "#") { + if (color.at(0) == '#') { return temp.replace(tagIter->second.first, QString("%2").arg(color, content)); } else { auto colIter = m_ColorMap.find(color.toLower()); diff --git a/src/browserdialog.cpp b/src/browserdialog.cpp index c382c112..5e6bec00 100644 --- a/src/browserdialog.cpp +++ b/src/browserdialog.cpp @@ -25,8 +25,6 @@ along with Mod Organizer. If not, see . #include "report.h" #include "persistentcookiejar.h" -#include "json.h" - #include #include #include "settings.h" diff --git a/src/browserview.h b/src/browserview.h index f8b132b8..6a89752a 100644 --- a/src/browserview.h +++ b/src/browserview.h @@ -21,9 +21,11 @@ along with Mod Organizer. If not, see . #define NEXUSVIEW_H +class QEvent; +class QUrl; +class QWidget; #include #include -#include /** * @brief web view used to display a nexus page diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index bc78cdc6..1aaf4122 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -25,7 +25,6 @@ along with Mod Organizer. If not, see . #include #include #include "utility.h" -#include "json.h" #include "selectiondialog.h" #include "bbcode.h" #include diff --git a/src/helper.h b/src/helper.h index 36f10db1..410e2527 100644 --- a/src/helper.h +++ b/src/helper.h @@ -21,7 +21,7 @@ along with Mod Organizer. If not, see . #define HELPER_H -#include +#include /** diff --git a/src/loadmechanism.cpp b/src/loadmechanism.cpp index 4d06bea9..c01955f2 100644 --- a/src/loadmechanism.cpp +++ b/src/loadmechanism.cpp @@ -56,7 +56,7 @@ void LoadMechanism::writeHintFile(const QDir &targetDirectory) } -void LoadMechanism::removeHintFile(QDir &targetDirectory) +void LoadMechanism::removeHintFile(QDir targetDirectory) { targetDirectory.remove("mo_path.txt"); } diff --git a/src/loadmechanism.h b/src/loadmechanism.h index 43a8dd6c..c04473ab 100644 --- a/src/loadmechanism.h +++ b/src/loadmechanism.h @@ -91,7 +91,7 @@ private: void writeHintFile(const QDir &targetDirectory); // remove the hint file if it exists. does nothing if the file doesn't exist - void removeHintFile(QDir &targetDirectory); + void removeHintFile(QDir targetDirectory); // compare the two files by md5-hash, returns true if they are identical bool hashIdentical(const QString &fileNameLHS, const QString &fileNameRHS); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index e0d888e6..ae64b81f 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -25,7 +25,6 @@ along with Mod Organizer. If not, see . #include "report.h" #include "modinfodialog.h" #include "overwriteinfodialog.h" -#include "json.h" #include "messagedialog.h" #include "filenamestring.h" diff --git a/src/modinfo.h b/src/modinfo.h index da97b09b..d9de60e8 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -1047,7 +1047,7 @@ public: virtual QString notes() const { return ""; } virtual QDateTime creationTime() const { return QDateTime(); } virtual QString absolutePath() const; - virtual MOBase::VersionInfo getNewestVersion() const { return ""; } + virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } virtual QString getInstallationFile() const { return ""; } virtual int getFixedPriority() const { return INT_MAX; } virtual int getNexusID() const { return -1; } @@ -1099,7 +1099,7 @@ public: virtual QString notes() const { return ""; } virtual QDateTime creationTime() const; virtual QString absolutePath() const; - virtual MOBase::VersionInfo getNewestVersion() const { return ""; } + virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } virtual QString getInstallationFile() const { return ""; } virtual int getNexusID() const { return -1; } virtual std::vector getIniTweaks() const { return std::vector(); } diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index 0763bb71..6ec282f6 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -25,7 +25,6 @@ along with Mod Organizer. If not, see . #include "persistentcookiejar.h" #include "settings.h" #include -#include #include #include #include diff --git a/src/settings.cpp b/src/settings.cpp index 4c2a34c8..b51ba71e 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -22,7 +22,6 @@ along with Mod Organizer. If not, see . #include "settingsdialog.h" #include "utility.h" #include "helper.h" -#include "json.h" #include #include #include diff --git a/src/settings.h b/src/settings.h index def1dc5c..580ffe42 100644 --- a/src/settings.h +++ b/src/settings.h @@ -328,7 +328,7 @@ private: }; /** Display/store the configuration in the 'general' tab of the settings dialogue */ - class GeneralTab : SettingsTab + class GeneralTab : public SettingsTab { public: GeneralTab(Settings *m_parent, SettingsDialog &m_dialog); @@ -347,7 +347,7 @@ private: }; /** Display/store the configuration in the 'nexus' tab of the settings dialogue */ - class NexusTab : SettingsTab + class NexusTab : public SettingsTab { public: NexusTab(Settings *m_parent, SettingsDialog &m_dialog); @@ -365,7 +365,7 @@ private: }; /** Display/store the configuration in the 'steam' tab of the settings dialogue */ - class SteamTab : SettingsTab + class SteamTab : public SettingsTab { public: SteamTab(Settings *m_parent, SettingsDialog &m_dialog); @@ -378,7 +378,7 @@ private: }; /** Display/store the configuration in the 'plugins' tab of the settings dialogue */ - class PluginsTab : SettingsTab + class PluginsTab : public SettingsTab { public: PluginsTab(Settings *m_parent, SettingsDialog &m_dialog); @@ -391,7 +391,7 @@ private: }; /** Display/store the configuration in the 'workarounds' tab of the settings dialogue */ - class WorkaroundsTab : SettingsTab + class WorkaroundsTab : public SettingsTab { public: WorkaroundsTab(Settings *m_parent, SettingsDialog &m_dialog); -- cgit v1.3.1 From b1cfc45853705163da0641eb8cf1cd77783e009d Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Sun, 25 Oct 2015 08:36:30 +0000 Subject: Make the IWYU generation generic --- SConstruct | 117 +++++++++++++++++++++++++++++++++++++++------------------ qtmappings.imp | 117 +++++++++++++++++++++++++++++++++++++++++---------------- src/SConscript | 8 ---- 3 files changed, 164 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/SConstruct b/SConstruct index 94097f3c..fbc7e3fe 100644 --- a/SConstruct +++ b/SConstruct @@ -245,6 +245,83 @@ def DisableQtModules(self, *modules): for module in modules: self['CPPPATH'].remove(os.path.join('$QTDIR', 'include', 'QT' + module)) +def setup_IWYU(env): + import SCons.Defaults + import SCons.Builder + original_shared = SCons.Defaults.SharedObjectEmitter + original_static = SCons.Defaults.StaticObjectEmitter + + def DoIWYU(env, source, target): + for i in range(len(source)): + s = source[i] + dir, name = os.path.split(str(s)) # I'm sure theres a way of getting this from scons + # Don't bother looking at moc files and 7zip source + if not name.startswith('moc_') and \ + not dir.startswith(env['SEVENZIPPATH']): + # Put the .iwyu in the same place as the .obj + targ = os.path.splitext(str(target[i]))[0] + env.IWYU(targ + '.iwyu', s) + + def shared_emitter(target, source, env): + DoIWYU(env, source, target) + return original_shared(target, source, env) + + def static_emitter(target, source, env): + DoIWYU(env, source, target) + return original_static(target, source, env) + + SCons.Defaults.SharedObjectEmitter = shared_emitter + SCons.Defaults.StaticObjectEmitter = static_emitter + + def emitter(target, source, env): + env.Depends(target, '$IWYU_MAPPING_FILE') + return target, source + + iwyu = SCons.Builder.Builder( + action=[ + '-$IWYU $IWYU_FLAGS -Xiwyu --mapping_file=$IWYU_MAPPING_FILE $IWYU_COMCOM $SOURCE', + Touch('$TARGET') + ], + emitter=emitter, + suffix='.iwyu', + src_suffix='.cpp') + + env.Append(BUILDERS={'IWYU': iwyu}) + + # Sigh - IWYU is a right bum as it doesn't recognise /I so I have to duplicate most of the usual stuff. Worse, half the + # flags are irrelevant immaterial and incompetent and I can't use an environment clone because it takes stuff from the + # wrong environment. + + # There has to be a better way of doing this. 'begins with Q means system header'??? + # Also, I can't get this to show issues in the issue window which sucks + env['IWYU_FLAGS'] = [ + # This might turn down the output a bit. I hope + '-Xiwyu', '--transitive_includes_only', + '-D_MT', '-D_DLL', '-m32', + # This is something to do with clang, windows and boost headers + '-DBOOST_USE_WINDOWS_H', + # There's a lot of this, disabled for now + '-Wno-inconsistent-missing-override', + '--system-header-prefix=Q', + '--system-header-prefix=boost/', + # Attempt to get QT to recognise clang output. So far it has not worked well. + '-fdiagnostics-format=msvc', + '-fno-show-column', + # clang says it sets this to 1700 but pretty sure vc12 is 1800 + '-fmsc-version=1800', + ] + if env['CONFIG'] == 'debug': + env['IWYU_FLAGS'] += [ '-D_DEBUG' ] + + env['IWYU_DEFPREFIX'] = '-D' + env['IWYU_DEFSUFFIX'] = '' + env['IWYU_INCPREFIX'] = '-I' + env['IWYU_INCSUFFIX'] = '' + env['IWYU_COMCOM'] = '$IWYU_CPPDEFFLAGS $IWYU_CPPINCFLAGS $CCPDBFLAGS' + env['IWYU_CPPDEFFLAGS'] = '${_defines(IWYU_DEFPREFIX, CPPDEFINES, IWYU_DEFSUFFIX, __env__)}' + env['IWYU_CPPINCFLAGS'] = '$( ${_concat(IWYU_INCPREFIX, CPPPATH, IWYU_INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' + env['IWYU_MAPPING_FILE'] = env.File('#/qtmappings.imp') + # Create base environment vars = setup_config_variables() @@ -361,44 +438,10 @@ else: env.AppendUnique(CPPFLAGS = [ '/O2', '/MD' ]) env.AppendUnique(LINKFLAGS = [ '/OPT:REF', '/OPT:ICF' ]) -# Add in env variables for include-what-you-use -################################################################ -# I really want to make this a post action for building a .o +# Set up include what you use. Add this as an extra compile step. Note it +# doesn't currently generate an output file (use the output instead!). if 'IWYU' in env: - # Sigh - IWYU is a right bum as it doesn't recognise /I so I have to duplicate most of the usual stuff. Worse, half the - # flags are irrelevant immaterial and incompetent and I can't use an environment clone because it takes stuff from the - # wrong environment. - - # There has to be a better way of doing this. 'begins with Q means system header'??? - # Also, I can't get this to show issues in the issue window which sucks - env['IWYU_FLAGS'] = [ - # This might turn down the output a bit. I hope - '-Xiwyu', '--transitive_includes_only', - '-D_MT', '-D_DLL', '-m32', - # This is something to do with clang, windows and boost headers - '-DBOOST_USE_WINDOWS_H', - # There's a lot of this, disabled for now - '-Wno-inconsistent-missing-override', - '--system-header-prefix=Q', - '--system-header-prefix=boost/', - # Attempt to get QT to recognise clang output. So far it has not worked well. - '-fdiagnostics-format=msvc', - '-fno-show-column', - # clang says it sets this to 1700 but pretty sure vc12 is 1800 - '-fmsc-version=1800', - ] - if env['CONFIG'] == 'debug': - env['IWYU_FLAGS'] += [ '-D_DEBUG' ] - - env['IWYU_DEFPREFIX'] = '-D' - env['IWYU_DEFSUFFIX'] = '' - env['IWYU_INCPREFIX'] = '-I' - env['IWYU_INCSUFFIX'] = '' - env['IWYU_COMCOM'] = '$IWYU_CPPDEFFLAGS $IWYU_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS' - env['IWYU_CPPDEFFLAGS'] = '${_defines(IWYU_DEFPREFIX, CPPDEFINES, IWYU_DEFSUFFIX, __env__)}' - env['IWYU_CPPINCFLAGS'] = '$( ${_concat(IWYU_INCPREFIX, CPPPATH, IWYU_INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' - env['IWYU_MAPPING_FILE'] = env.File('#/qtmappings.imp') - + setup_IWYU(env) # /OPT:REF removes unreferenced code # for release, use /OPT:ICF (comdat folding: coalesce identical blocks of code) diff --git a/qtmappings.imp b/qtmappings.imp index db59f67f..17073ddd 100644 --- a/qtmappings.imp +++ b/qtmappings.imp @@ -1,19 +1,23 @@ [ # Overrides. Some classes are defined by the spec to reside in their own headers but actually use the same # header as another class. It might make some sense using this for every class in QT... + { symbol: [ "QAbstractItemModel", "private", "", "public" ] }, { symbol: [ "QAbstractTableModel", "private", "", "public" ] }, { symbol: [ "QAtomicInt", "private", "", "public"] }, + { symbol: [ "QCloseEvent", "private", "", "public" ] }, { symbol: [ "QDate", "private", "", "public"] }, { symbol: [ "QDragEnterEvent", "private", "", "public" ] }, + { symbol: [ "QDropEvent", "private", "", "public" ] }, { symbol: [ "QIntValidator", "private", "", "public" ] }, { symbol: [ "QKeyEvent", "private", "", "public" ] }, { symbol: [ "QListWidgetItem", "private", "", "public" ] }, { symbol: [ "QModelIndex", "private", "", "public" ] }, - { symbol: [ "QModelIndexList", "private", "", "public" ] }, + { symbol: [ "QModelIndexList", "private", "", "public" ] }, { symbol: [ "QMouseEvent", "private", "", "public" ] }, { symbol: [ "@QMutableHashIterator(::.*)?", "private", "", "public" ] }, + { symbol: [ "QPersistentModelIndex", "private", "", "public" ] }, + { symbol: [ "QResizeEvent", "private", "", "public" ] }, { symbol: [ "QScopedArrayPointer", "private", "", "public" ] }, - { symbol: [ "QResizeEvent", "private", "", "public" ] }, { symbol: [ "QStyleOptionSlider", "private", "", "public" ] }, { symbol: [ "QStyleOptionViewItem", "private", "", "public" ] }, { symbol: [ "QTableWidgetItem", "private", "", "public" ] }, @@ -32,7 +36,6 @@ { include: [ "@\"(QtConcurrent/)?qtconcurrentrun\\.h\"", "private", "", "public" ] }, - { include: [ "@\"(QtCore/)?qabstractitemmodel\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qabstractproxymodel\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qalgorithms\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qbytearray\\.h\"", "private", "", "public" ] }, @@ -41,6 +44,7 @@ { include: [ "@\"(QtCore/)?qcoreevent\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qdatastream\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qdatetime\\.h\"", "private", "", "public" ] }, + { include: [ "@\"(QtCore/)?qdebug\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qdir\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qdiriterator\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qfile\\.h\"", "private", "", "public" ] }, @@ -67,17 +71,17 @@ { include: [ "@\"(QtCore/)?qset\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qsharedpointer_impl\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qsize\\.h\"", "private", "", "public" ] }, + { include: [ "@\"(QtCore/)?qstandardpaths\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qstring\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qstringlist\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qurl\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtCore/)?qvariant\\.h\"", "private", "", "public" ] }, - { include: [ "@\"(QtCore/)?qdebug\\.h\"", "private", "", "public" ] }, - { include: [ "@\"(QtCore/)?qstandardpaths\\.h\"", "private", "", "public" ] }, - + { include: [ "@\"(QtGui/)?qbrush\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtGui/)?qcolor\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtGui/)?qcursor\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtGui/)?qfont\\.h\"", "private", "", "public" ] }, + { include: [ "@\"(QtGui/)?qfontmetrics\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtGui/)?qicon\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtGui/)?qimage\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtGui/)?qkeysequence\\.h\"", "private", "", "public" ] }, @@ -85,7 +89,6 @@ { include: [ "@\"(QtGui/)?qpalette\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtGui/)?qpen\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtGui/)?qpixmap\\.h\"", "private", "", "public" ] }, - { include: [ "@\"(QtGui/)?qfontmetrics\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtNetwork/)?qhostaddress\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtNetwork/)?qnetworkaccessmanager\\.h\"", "private", "", "public" ] }, @@ -105,14 +108,16 @@ { include: [ "@\"(QtWidgets/)?qstyleoption\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtWidgets/)?qtabbar\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtWidgets/)?qtabwidget\\.h\"", "private", "", "public" ] }, - { include: [ "@\"(QtWidgets/)?qwidget\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtWidgets/)?qtextedit\\.h\"", "private", "", "public" ] }, + { include: [ "@\"(QtWidgets/)?qwidget\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtWebKit/)?qwebsettings\\.h\"", "private", "", "public" ] }, { include: [ "@\"(QtWebKitWidgets/)?qwebpage\\.h\"", "private", "", "public" ] }, + # I need to find out where these are and group them as above. { include: [ "\"qapplication.h\"", "private", "", "public" ] }, + { include: [ "\"qbuffer.h\"", "private", "", "public" ] }, { include: [ "\"qcheckbox.h\"", "private", "", "public" ] }, { include: [ "\"qclipboard.h\"", "private", "", "public" ] }, { include: [ "\"qcombobox.h\"", "private", "", "public" ] }, @@ -123,11 +128,13 @@ { include: [ "\"qfiledialog.h\"", "private", "", "public" ] }, { include: [ "\"qfilesystemmodel.h\"", "private", "", "public" ] }, { include: [ "\"qfilesystemwatcher.h\"", "private", "", "public" ] }, + { include: [ "\"qgroupbox.h\"", "private", "", "public" ] }, { include: [ "\"qheaderview.h\"", "private", "", "public" ] }, { include: [ "\"qinputdialog.h\"", "private", "", "public" ] }, { include: [ "\"qitemdelegate.h\"", "private", "", "public" ] }, { include: [ "\"qjsonarray.h\"", "private", "", "public" ] }, { include: [ "\"qjsondocument.h\"", "private", "", "public" ] }, + { include: [ "\"qjsonobject.h\"", "private", "", "public" ] }, { include: [ "\"qlabel.h\"", "private", "", "public" ] }, { include: [ "\"qlcdnumber.h\"", "private", "", "public" ] }, { include: [ "\"qlistwidget.h\"", "private", "", "public" ] }, @@ -144,12 +151,14 @@ { include: [ "\"qnetworkdiskcache.h\"", "private", "", "public" ] }, { include: [ "\"qnetworkinterface.h\"", "private", "", "public" ] }, { include: [ "\"qnetworkreply.h\"", "private", "", "public" ] }, + { include: [ "\"qpixmapcache.h\"", "private", "", "public" ] }, { include: [ "\"qprocess.h\"", "private", "", "public" ] }, { include: [ "\"qprogressbar.h\"", "private", "", "public" ] }, { include: [ "\"qprogressdialog.h\"", "private", "", "public" ] }, { include: [ "\"qproxystyle.h\"", "private", "", "public" ] }, { include: [ "\"qpushbutton.h\"", "private", "", "public" ] }, { include: [ "\"qqueue.h\"", "private", "", "public" ] }, + { include: [ "\"qradiobutton.h\"", "private", "", "public" ] }, { include: [ "\"qscrollbar.h\"", "private", "", "public" ] }, { include: [ "\"qsettings.h\"", "private", "", "public" ] }, { include: [ "\"qsharedmemory.h\"", "private", "", "public" ] }, @@ -157,18 +166,24 @@ { include: [ "\"qsignalmapper.h\"", "private", "", "public" ] }, { include: [ "\"qsortfilterproxymodel.h\"", "private", "", "public" ] }, { include: [ "\"qsplashscreen.h\"", "private", "", "public" ] }, + { include: [ "\"qsplitter.h\"", "private", "", "public" ] }, { include: [ "\"qsslsocket.h\"", "private", "", "public" ] }, { include: [ "\"qstackedwidget.h\"", "private", "", "public" ] }, + { include: [ "\"qstatusbar.h\"", "private", "", "public" ] }, { include: [ "\"qstyleditemdelegate.h\"", "private", "", "public" ] }, { include: [ "\"qstylefactory.h\"", "private", "", "public" ] }, + { include: [ "\"qsyntaxhighlighter.h\"", "private", "", "public" ] }, { include: [ "\"qtablewidget.h\"", "private", "", "public" ] }, { include: [ "\"qtemporaryfile.h\"", "private", "", "public" ] }, { include: [ "\"qtextbrowser.h\"", "private", "", "public" ] }, { include: [ "\"qtextcodec.h\"", "private", "", "public" ] }, { include: [ "\"qtextstream.h\"", "private", "", "public" ] }, - { include: [ "\"qtgroupingproxy.h\"", "private", "", "public" ] }, { include: [ "\"qthread.h\"", "private", "", "public" ] }, { include: [ "\"qtimer.h\"", "private", "", "public" ] }, + { include: [ "\"qtoolbar.h\"", "private", "", "public" ] }, + { include: [ "\"qtoolbutton.h\"", "private", "", "public" ] }, + { include: [ "\"qtooltip.h\"", "private", "", "public" ] }, + { include: [ "\"qtranslator.h\"", "private", "", "public" ] }, { include: [ "\"qtreeview.h\"", "private", "", "public" ] }, { include: [ "\"qtreewidget.h\"", "private", "", "public" ] }, { include: [ "\"qurlquery.h\"", "private", "", "public" ] }, @@ -178,48 +193,68 @@ { include: [ "\"qwebhistory.h\"", "private", "", "public" ] }, { include: [ "\"qwebview.h\"", "private", "", "public" ] }, { include: [ "\"qwhatsthis.h\"", "private", "", "public" ] }, + { include: [ "\"qwidgetaction.h\"", "private", "", "public" ] }, + { include: [ "\"qimagereader.h\"", "private", "", "public" ] }, -# Microsft visual C? + + # Microsft visual C? + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, { include: [ "", "private", "", "public" ] }, { include: [ "", "private", "", "public" ] }, # Windows +# Looks like the doucmentation says the 1st char is u/c the rest are l/c # You have to be kidding me. ULONG is defined in winsmcrd.h? { symbol: [ "ULONG", "private", "", "private" ] }, -# These are all in windef.h apparently. Which m/s then says 'use windows.h' + { include: [ "", "private", "", "private" ] }, # Stringapiset.h + { include: [ "", "private", "", "public" ] }, # Windows.h + +# These are all in windef.h apparently. Which m/s then says 'use Windows.h' { include: [ "", "private", "", "private" ] }, # or in winnt apparently { include: [ "", "private", "", "private" ] }, { include: [ "", "private", "", "private" ] }, { include: [ "", "private", "", "private" ] }, # Similary, but for winbase.h - { include: [ "", "private", "", "private" ] }, - { include: [ "", "private", "", "private" ] }, + { include: [ "", "private", "", "private" ] }, { include: [ "", "private", "", "private" ] }, + { include: [ "", "private", "", "private" ] }, + { include: [ "", "private", "", "private" ] }, + { include: [ "", "private", "", "private" ] }, + { include: [ "", "private", "", "private" ] }, -# These ones say xxxx.h (include windows.h) on the ms web site - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, # check this - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, +# These ones say xxxx.h (include Windows.h) on the ms web site + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, # VerRsrc.h + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, -# These ones are in windows.h but the documentation post windows 8 says they are individual headers, +# These ones are in Windows.h but the documentation post windows 8 says they are individual headers, # which looks like M/S are trying to get their act together. Maybe. - { include: [ "", "private", "", "public" ] }, #recheck - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, -# These ones are *not* defined to be in windows.h, but it seems to work. These should probably be cleaned up - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, +# These ones are *not* defined to be in Windows.h, but it seems to work. These should probably be cleaned up + { include: [ "", "private", "", "public" ] }, + # These 3 should go to Shellapi.h + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, +# combaseapi.h is for objbase.h but objbase.h appears to come free with Windows.h +# Windows.h is a pile of ... + { include: [ "", "private", "", "private" ] }, + { include: [ "", "private", "", "public" ] }, + +# Huh? This one is sane? + { include: [ "", "private", "", "public" ] }, # And for boost??? # These are probably correct but might need a revisit as if you look at the boost documentation pages, it @@ -229,7 +264,10 @@ { include: [ "@\"boost/bind/.*\"", "private", "", "public" ] }, { include: [ "@\"boost/algorithm/string/.*\"", "private", "", "public" ] }, { include: [ "@\"boost/assign/.*\"", "private", "", "public" ] }, + { include: [ "@\"boost/filesystem/.*\"", "private", "", "public" ] }, + { include: [ "@\"boost/format/.*\"", "private", "", "public" ] }, { include: [ "@\"boost/function/.*\"", "private", "", "public" ] }, + { include: [ "@\"boost/python/.*\"", "private", "", "public" ] }, { include: [ "@\"boost/signals2/.*\"", "private", "", "public" ] }, { include: [ "\"boost/smart_ptr/scoped_array.hpp\"", "private", "", "public" ] }, { include: [ "\"boost/smart_ptr/shared_ptr.hpp\"", "private", "", "public" ] }, @@ -239,7 +277,17 @@ ] +# Warning: QtGroupingProxy is not provided by Qt + +#include "qdeclarativecontext.h" // for QDeclarativeContext +#include "qdeclarativeview.h" // for QDeclarativeView, etc +#include "qgraphicsitem.h" // for QGraphicsObject + +#include "qpluginloader.h" +#include "qnetworkproxy.h" + # Ones I don't yet know how to deal with +#include #include "boost/fusion/container/vector/vector10_fwd.hpp" // for fusion #include "boost/iterator/iterator_facade.hpp" // for operator!= #include // for operator delete[], etc @@ -248,10 +296,13 @@ #include "QtCore/qtypeinfo.h" // for swap #include "QtCore/qtypetraits.h" #include "QtCore/qtypetraits.h" // for remove_reference<>::type -#include "QtGui/qfontmetrics.h" -#include "QtGui/qvalidator.h" // for QIntValidator #include "QtGui/qwindowdefs_win.h" // for HINSTANCE #include "QtWidgets/qabstractitemdelegate.h" #include "boost/iterator/iterator_facade.hpp" #include // for _Simple_types<>::value_type #include // for _Tree_const_iterator + +# typical error on stdout (?) +#source\hookdll\dllmain.cpp(220) : warning C4244: '=' : conversion from 'int' to 'char', possible loss of data +# error from include-what-you-use (on stderr? at least it's in red) +#source\hookdll\dllmain.cpp(2220) : warning: case value not in enumerated type 'FILE_INFORMATION_CLASS' (aka '_FILE_INFORMATION_CLASS') [-Wswitch] diff --git a/src/SConscript b/src/SConscript index cd2d8a52..d88bee30 100644 --- a/src/SConscript +++ b/src/SConscript @@ -143,14 +143,6 @@ env.AppendUnique(LIBS = 'zlibstatic') prog = env.Program('ModOrganizer', cpp_files + env.Glob('*.qrc') + other_sources) -############################################################################### -# I'd like to automatically add this to every .o generation. -if 'IWYU' in env: - for f in cpp_files + [ env.File('aboutdialog.cpp') ]: - env.AddPostAction(prog, "-$IWYU $IWYU_FLAGS -Xiwyu --mapping_file=$IWYU_MAPPING_FILE $IWYU_COMCOM " + str(f)) - env.Depends(prog, env['IWYU_MAPPING_FILE']) -############################################################################### - env.InstallModule(prog) for subdir in ('tutorials', 'stylesheets'): -- cgit v1.3.1 From 8f64a1d13671dde96873c6245de850b133d7ad32 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Sun, 25 Oct 2015 21:07:02 +0000 Subject: Proper integraton of IWYU into the build (including massaging clang errors into the issues tab). Note: There is at least one ug in QT that stops thing s copiling because it doesn't undertand clangs version --- massage_messages.py | 12 ++++++++++++ qtmappings.imp | 32 ++++++++++++++++++++++---------- src/modinfo.h | 4 ++-- 3 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 massage_messages.py (limited to 'src') diff --git a/massage_messages.py b/massage_messages.py new file mode 100644 index 00000000..656c48bd --- /dev/null +++ b/massage_messages.py @@ -0,0 +1,12 @@ +# Attempt to massage the messages from clang so that QT recognises them +# expected: source\bsatk\bsafile.cpp(101) : fatal error C1189: #error : "we may have to compress/decompress!" +# clang: source\bsatk\bsafile.cpp(101) : error: "we may have to compress/decompress!" + +import fileinput +import re + +for line in fileinput.input(): + # Look for '\) : ([^:])?:' + # Replace with ') : \1 I0000: + line.rstrip() + print re.sub(r'\)\s*:\s*([^:]*):', r') : \1 I0000:', line) \ No newline at end of file diff --git a/qtmappings.imp b/qtmappings.imp index 17073ddd..deea653f 100644 --- a/qtmappings.imp +++ b/qtmappings.imp @@ -195,7 +195,10 @@ { include: [ "\"qwhatsthis.h\"", "private", "", "public" ] }, { include: [ "\"qwidgetaction.h\"", "private", "", "public" ] }, { include: [ "\"qimagereader.h\"", "private", "", "public" ] }, - + { include: [ "\"qdeclarativecontext.h\"", "private", "", "public" ] }, + { include: [ "\"qdeclarativeview.h\"", "private", "", "public" ] }, +# looks wrong +# { include: [ "\"qgraphicsitem.h\"", "private", "", "public" ] }, # Microsft visual C? @@ -210,7 +213,7 @@ { symbol: [ "ULONG", "private", "", "private" ] }, { include: [ "", "private", "", "private" ] }, # Stringapiset.h - { include: [ "", "private", "", "public" ] }, # Windows.h + { include: [ "", "private", "", "public" ] }, # These are all in windef.h apparently. Which m/s then says 'use Windows.h' { include: [ "", "private", "", "private" ] }, # or in winnt apparently @@ -227,6 +230,7 @@ { include: [ "", "private", "", "private" ] }, # These ones say xxxx.h (include Windows.h) on the ms web site + { include: [ "", "private", "", "public" ] }, { include: [ "", "private", "", "public" ] }, { include: [ "", "private", "", "public" ] }, # VerRsrc.h { include: [ "", "private", "", "public" ] }, @@ -245,14 +249,26 @@ { include: [ "", "private", "", "public" ] }, # These 3 should go to Shellapi.h { include: [ "", "private", "", "public" ] }, - { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, # official name according to website { include: [ "", "private", "", "public" ] }, + # + { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "public" ] }, { include: [ "", "private", "", "public" ] }, -# combaseapi.h is for objbase.h but objbase.h appears to come free with Windows.h -# Windows.h is a pile of ... - { include: [ "", "private", "", "private" ] }, + +# Files that are included by other files which seem to then come for free in Windows.h but +# shouldn't. Again, should be cleaned up. + + { include: [ "", "private", "", "private" ] }, + { include: [ "", "private", "", "private" ] }, { include: [ "", "private", "", "public" ] }, + { include: [ "", "private", "", "private" ] }, + { include: [ "", "private", "", "public" ] }, + + { include: [ "", "private", "", "private" ] }, + { include: [ "", "private", "", "public" ] }, + # Huh? This one is sane? { include: [ "", "private", "", "public" ] }, @@ -279,15 +295,11 @@ # Warning: QtGroupingProxy is not provided by Qt -#include "qdeclarativecontext.h" // for QDeclarativeContext -#include "qdeclarativeview.h" // for QDeclarativeView, etc -#include "qgraphicsitem.h" // for QGraphicsObject #include "qpluginloader.h" #include "qnetworkproxy.h" # Ones I don't yet know how to deal with -#include #include "boost/fusion/container/vector/vector10_fwd.hpp" // for fusion #include "boost/iterator/iterator_facade.hpp" // for operator!= #include // for operator delete[], etc diff --git a/src/modinfo.h b/src/modinfo.h index d9de60e8..da97b09b 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -1047,7 +1047,7 @@ public: virtual QString notes() const { return ""; } virtual QDateTime creationTime() const { return QDateTime(); } virtual QString absolutePath() const; - virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } + virtual MOBase::VersionInfo getNewestVersion() const { return ""; } virtual QString getInstallationFile() const { return ""; } virtual int getFixedPriority() const { return INT_MAX; } virtual int getNexusID() const { return -1; } @@ -1099,7 +1099,7 @@ public: virtual QString notes() const { return ""; } virtual QDateTime creationTime() const; virtual QString absolutePath() const; - virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } + virtual MOBase::VersionInfo getNewestVersion() const { return ""; } virtual QString getInstallationFile() const { return ""; } virtual int getNexusID() const { return -1; } virtual std::vector getIniTweaks() const { return std::vector(); } -- cgit v1.3.1 From f1aaf92afb58e9fee330ede36b9775fe2a6e5a27 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Sat, 31 Oct 2015 19:40:33 +0000 Subject: Improve diagnostics if IWYU is enabled Few small cleanups from clang --- SConstruct | 24 +++++++++++++----- massage_messages.py | 66 ++++++++++++++++++++++++++++++++++++++++++++++-- src/modinfo.h | 4 +-- src/nexusinterface.cpp | 4 +-- src/shared/stackdata.cpp | 2 +- 5 files changed, 87 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/SConstruct b/SConstruct index fbc7e3fe..01e7b2fd 100644 --- a/SConstruct +++ b/SConstruct @@ -260,7 +260,7 @@ def setup_IWYU(env): not dir.startswith(env['SEVENZIPPATH']): # Put the .iwyu in the same place as the .obj targ = os.path.splitext(str(target[i]))[0] - env.IWYU(targ + '.iwyu', s) + env.Depends(env.IWYU(targ + '.iwyu', s), target[i]) def shared_emitter(target, source, env): DoIWYU(env, source, target) @@ -274,12 +274,13 @@ def setup_IWYU(env): SCons.Defaults.StaticObjectEmitter = static_emitter def emitter(target, source, env): - env.Depends(target, '$IWYU_MAPPING_FILE') + env.Depends(target, ('$IWYU_MAPPING_FILE', '$IWYU_MASSAGE')) return target, source + # Note to self: command 2>&1 | other command appears to work as I would hope iwyu = SCons.Builder.Builder( action=[ - '-$IWYU $IWYU_FLAGS -Xiwyu --mapping_file=$IWYU_MAPPING_FILE $IWYU_COMCOM $SOURCE', + '-$IWYU $IWYU_FLAGS -Xiwyu --mapping_file=$IWYU_MAPPING_FILE $IWYU_COMCOM $SOURCE 2>&1 | $IWYU_MASSAGE', Touch('$TARGET') ], emitter=emitter, @@ -308,8 +309,14 @@ def setup_IWYU(env): '-fdiagnostics-format=msvc', '-fno-show-column', # clang says it sets this to 1700 but pretty sure vc12 is 1800 - '-fmsc-version=1800', - ] + #'-fmsc-version=1800', '-D_MSC_VER=1800', + '-fmsc-version=1700', + # clang and qt don't agree about these because clang says its gcc 4.2 and + # QT doesn't realise it's clang + '-DQ_COMPILER_INITIALIZER_LISTS', + '-DQ_COMPILER_DECLTYPE', + '-DQ_COMPILER_VARIADIC_TEMPLATES', +] if env['CONFIG'] == 'debug': env['IWYU_FLAGS'] += [ '-D_DEBUG' ] @@ -317,10 +324,14 @@ def setup_IWYU(env): env['IWYU_DEFSUFFIX'] = '' env['IWYU_INCPREFIX'] = '-I' env['IWYU_INCSUFFIX'] = '' - env['IWYU_COMCOM'] = '$IWYU_CPPDEFFLAGS $IWYU_CPPINCFLAGS $CCPDBFLAGS' + env['IWYU_INCLUDEPREFIX'] = '-include' # Amazingly this works without a space + env['IWYU_INCLUDESUFFIX'] = '' + env['IWYU_COMCOM'] = '$IWYU_CPPDEFFLAGS $IWYU_CPPINCFLAGS $IWYU_PCHFILES $CCPDBFLAGS' env['IWYU_CPPDEFFLAGS'] = '${_defines(IWYU_DEFPREFIX, CPPDEFINES, IWYU_DEFSUFFIX, __env__)}' env['IWYU_CPPINCFLAGS'] = '$( ${_concat(IWYU_INCPREFIX, CPPPATH, IWYU_INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' + env['IWYU_PCHFILES'] = '$( ${_concat(IWYU_INCLUDEPREFIX, PCHSTOP, IWYU_INCLUDESUFFIX, __env__, target=TARGET, source=SOURCE)} $)' env['IWYU_MAPPING_FILE'] = env.File('#/qtmappings.imp') + env['IWYU_MASSAGE'] = env.File('#/massage_messages.py') # Create base environment @@ -442,6 +453,7 @@ else: # doesn't currently generate an output file (use the output instead!). if 'IWYU' in env: setup_IWYU(env) + # /OPT:REF removes unreferenced code # for release, use /OPT:ICF (comdat folding: coalesce identical blocks of code) diff --git a/massage_messages.py b/massage_messages.py index 656c48bd..c1b31c96 100644 --- a/massage_messages.py +++ b/massage_messages.py @@ -5,8 +5,70 @@ import fileinput import re +removing = None + +includes = dict + +foundline = 0 + for line in fileinput.input(): # Look for '\) : ([^:])?:' # Replace with ') : \1 I0000: - line.rstrip() - print re.sub(r'\)\s*:\s*([^:]*):', r') : \1 I0000:', line) \ No newline at end of file + line = line.rstrip() + if removing: + if line == '': + removing = None + print + continue + else: + # Really we should stash these so that if we get a 'class xxx' in the + # add lines we can print it here. also we could do the case fixing. + m = re.match(r'- #include [<"](.*)[">] +// lines (.*)-', line) + if m: + # If there is an added line with the same class, print it here + print '%s(%s) : warning I0001: Unnecessary include of %s' % (removing, m.group(2), m.group(1)) + foundline = m.group(1) + else: + m = re.match(r'- (.*); +// lines (.*)-', line) + if m: + print '%s(%s) : warning I0002: Unnecessary forward ref of %s' % (removing, m.group(2), m.group(1)) + foundline = m.group(1) + else: + print '********* I got confused **********' + + line = re.sub(r'\)\s*:\s*([^:]*):', r') : \1 I1234:', line) + # Sadly qt doesn't seem to support 'info' in the issues tab. + line = re.sub(r': note I1234:', r': warning I1234:', line) + print line + if line.endswith(' should remove these lines:'): + removing = (line.split(' '))[0] + elif line.endswith(' should add these lines:'): + adding = (line.split(' '))[0] + +# also process the other lines +""" + +source/organizer/aboutdialog.h should add these lines: +#include // for Q_OBJECT, slots +#include // for QString +class QListWidgetItem; +class QWidget; + +source/organizer/aboutdialog.h should remove these lines: +- #include // lines 25-25 +- #include // lines 28-28 +- #include // lines 27-27 +- class DownloadManager; // lines 47-47 + +The full include-list for source/organizer/aboutdialog.h: +#include // for QDialog +#include // for Q_OBJECT, slots +#include // for QString +#include // for map +class QListWidgetItem; +class QWidget; +namespace Ui { class AboutDialog; } // lines 31-31 +--- +""" + +# added lines should come after the first entry with a line number. diff --git a/src/modinfo.h b/src/modinfo.h index da97b09b..d9de60e8 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -1047,7 +1047,7 @@ public: virtual QString notes() const { return ""; } virtual QDateTime creationTime() const { return QDateTime(); } virtual QString absolutePath() const; - virtual MOBase::VersionInfo getNewestVersion() const { return ""; } + virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } virtual QString getInstallationFile() const { return ""; } virtual int getFixedPriority() const { return INT_MAX; } virtual int getNexusID() const { return -1; } @@ -1099,7 +1099,7 @@ public: virtual QString notes() const { return ""; } virtual QDateTime creationTime() const; virtual QString absolutePath() const; - virtual MOBase::VersionInfo getNewestVersion() const { return ""; } + virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } virtual QString getInstallationFile() const { return ""; } virtual int getNexusID() const { return -1; } virtual std::vector getIniTweaks() const { return std::vector(); } diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index dc027be4..b4775e2d 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -217,8 +217,8 @@ void NexusInterface::interpretNexusFileName(const QString &fileName, QString &mo QString r3Highlight(fileName); r3Highlight.insert(result.position(3) + result.length(3), "* ").insert(result.position(3), " *"); - selection.addChoice(candidate.c_str(), r3Highlight, strtol(candidate.c_str(), nullptr, 10)); - selection.addChoice(candidate2.c_str() + offset, r2Highlight, abs(strtol(candidate2.c_str() + offset, nullptr, 10))); + selection.addChoice(candidate.c_str(), r3Highlight, static_cast(strtol(candidate.c_str(), nullptr, 10))); + selection.addChoice(candidate2.c_str() + offset, r2Highlight, static_cast(abs(strtol(candidate2.c_str() + offset, nullptr, 10)))); if (selection.exec() == QDialog::Accepted) { modID = selection.getChoiceData().toInt(); } else { diff --git a/src/shared/stackdata.cpp b/src/shared/stackdata.cpp index 6c5a0968..18daaf7b 100644 --- a/src/shared/stackdata.cpp +++ b/src/shared/stackdata.cpp @@ -24,7 +24,7 @@ static void initDbgIfNecess() firstCall = false; } if (!::SymInitialize(process, NULL, TRUE)) { - printf("failed to initialize symbols: %d", ::GetLastError()); + printf("failed to initialize symbols: %lu", ::GetLastError()); } initialized.insert(::GetCurrentProcessId()); } -- cgit v1.3.1 From a284cbf232f34cc1a83b85ec45baafc1ce6518ec Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Mon, 9 Nov 2015 18:16:58 +0000 Subject: Yet more changes for include what you use, including a moderate hack for compiling stackdata with clang --- SConstruct | 43 +++++++++++++++++++++++-------------------- massage_messages.py | 41 +++++++++++++++++++++++++++++------------ src/shared/stackdata.cpp | 3 ++- 3 files changed, 54 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/SConstruct b/SConstruct index 7af00c82..57111773 100644 --- a/SConstruct +++ b/SConstruct @@ -337,8 +337,7 @@ def setup_IWYU(env): # except it eats errors iwyu = SCons.Builder.Builder( action=[ - '$IWYU_MASSAGE $IWYU $IWYU_FLAGS $IWYU_MAPPINGS $IWYU_COMCOM $SOURCE', - Touch('$TARGET') + '$IWYU_MASSAGE $TARGET $IWYU $IWYU_FLAGS $IWYU_MAPPINGS $IWYU_COMCOM $SOURCE' ], emitter=emitter, suffix='.iwyu', @@ -346,27 +345,26 @@ def setup_IWYU(env): env.Append(BUILDERS={'IWYU': iwyu}) - # Sigh - IWYU is a right bum as it doesn't recognise /I so I have to duplicate most of the usual stuff. Worse, half the - # flags are irrelevant immaterial and incompetent and I can't use an environment clone because it takes stuff from the - # wrong environment. + # Sigh - IWYU is a right bum as it doesn't recognise /I so I have to + # duplicate most of the usual stuff - # There has to be a better way of doing this. 'begins with Q means system header'??? - # Also, I can't get this to show issues in the issue window which sucks env['IWYU_FLAGS'] = [ # This might turn down the output a bit. I hope '-Xiwyu', '--transitive_includes_only', + # Seem to be needed for a windows build '-D_MT', '-D_DLL', '-m32', # This is something to do with clang, windows and boost headers '-DBOOST_USE_WINDOWS_H', # There's a lot of this, disabled for now '-Wno-inconsistent-missing-override', + # Mark boost and Qt headers as system headers to disable a lot of noise. + # I'm sure there has to be a better way than saying 'prefix=Q' '--system-header-prefix=Q', '--system-header-prefix=boost/', - # clang says it sets this to 1700 but pretty sure vc12 is 1800 - #'-fmsc-version=1800', '-D_MSC_VER=1800', - '-fmsc-version=1700', - # clang and qt don't agree about these because clang says its gcc 4.2 and - # QT doesn't realise it's clang + # Should be able to get this info from our setup really + '-fmsc-version=1800', '-D_MSC_VER=1800', + # clang and qt don't agree about these because clang says its gcc 4.2 + # and QT doesn't realise it's clang '-DQ_COMPILER_INITIALIZER_LISTS', '-DQ_COMPILER_DECLTYPE', '-DQ_COMPILER_VARIADIC_TEMPLATES', @@ -376,22 +374,27 @@ def setup_IWYU(env): env['IWYU_DEFPREFIX'] = '-D' env['IWYU_DEFSUFFIX'] = '' + env['IWYU_CPPDEFFLAGS'] = '${_defines(IWYU_DEFPREFIX, CPPDEFINES, IWYU_DEFSUFFIX, __env__)}' + env['IWYU_INCPREFIX'] = '-I' env['IWYU_INCSUFFIX'] = '' - env['IWYU_INCLUDEPREFIX'] = '-include' # Amazingly this works without a space - env['IWYU_INCLUDESUFFIX'] = '' - env['IWYU_COMCOM'] = '$IWYU_CPPDEFFLAGS $IWYU_CPPINCFLAGS $IWYU_PCHFILES $CCPDBFLAGS' - env['IWYU_CPPDEFFLAGS'] = '${_defines(IWYU_DEFPREFIX, CPPDEFINES, IWYU_DEFSUFFIX, __env__)}' env['IWYU_CPPINCFLAGS'] = '$( ${_concat(IWYU_INCPREFIX, CPPPATH, IWYU_INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' - env['IWYU_PCHFILES'] = '$( ${_concat(IWYU_INCLUDEPREFIX, PCHSTOP, IWYU_INCLUDESUFFIX, __env__, target=TARGET, source=SOURCE)} $)' + + env['IWYU_PCH_PREFIX'] = '-include' # Amazingly this works without a space + env['IWYU_PCH_SUFFIX'] = '' + env['IWYU_PCHFILES'] = '$( ${_concat(IWYU_PCH_PREFIX, PCHSTOP, IWYU_PCH_SUFFIX, __env__, target=TARGET, source=SOURCE)} $)' + + env['IWYU_COMCOM'] = '$IWYU_CPPDEFFLAGS $IWYU_CPPINCFLAGS $IWYU_PCHFILES $CCPDBFLAGS' + env['IWYU_MAPPING_PREFIX'] = ['-Xiwyu', '--mapping_file='] + env['IWYU_MAPPING_SUFFIX'] = '' + env['IWYU_MAPPINGS'] = '$( ${_concat_list(IWYU_MAPPING_PREFIX, IWYU_MAPPING_FILE, IWYU_MAPPING_SUFFIX, __env__, f=lambda l: [ str(x) for x in l], target=TARGET, source=SOURCE)} $)' + env['IWYU_MAPPING_FILE'] = [ env.File('#/modorganizer/qt5_4.imp'), env.File('#/modorganizer/win.imp'), env.File('#/modorganizer/mappings.imp') ] - env['IWYU_MAPPING_PREFIX'] = ['-Xiwyu', '--mapping_file='] - env['IWYU_MAPPING_SUFFIX'] = '' - env['IWYU_MAPPINGS'] = '$( ${_concat_list(IWYU_MAPPING_PREFIX, IWYU_MAPPING_FILE, IWYU_MAPPING_SUFFIX, __env__, f=lambda l: [ str(x) for x in l], target=TARGET, source=SOURCE)} $)' + env['IWYU_MASSAGE'] = env.File('#/modorganizer/massage_messages.py') # Create base environment diff --git a/massage_messages.py b/massage_messages.py index 708c09cc..249068ba 100644 --- a/massage_messages.py +++ b/massage_messages.py @@ -34,7 +34,9 @@ includes = dict foundline = 0 -def process_next_line(line): +errors = False + +def process_next_line(line, outfile): """ Read a line of output/error from include-what-you use Turn clang errors into a form QT creator recognises Raise warnings for unneeded includes @@ -42,37 +44,48 @@ def process_next_line(line): global removing global includes global foundline + global errors line = line.rstrip() + print >> outfile, line if removing: if line == '': removing = None print return else: - # Really we should stash these so that if we get a 'class xxx' in the - # add lines we can print it here. also we could do the case fixing. + # Really we should stash these so that if we get a 'class xxx' in + # the add lines we can print it here. also we could do the case + # fixing. m = re.match(r'- #include [<"](.*)[">] +// lines (.*)-', line) if m: # If there is an added line with the same class, print it here - print '%s(%s) : warning I0001: Unnecessary include of %s' % (removing, m.group(2), m.group(1)) + print '%s(%s) : warning I0001: Unnecessary include of %s' %\ + (removing, m.group(2), m.group(1)) foundline = m.group(1) else: m = re.match(r'- (.*) +// lines (.*)-', line) if m: - print '%s(%s) : warning I0002: Unnecessary forward ref of %s' % (removing, m.group(2), m.group(1)) + print '%s(%s) : warning I0002: '\ + 'Unnecessary forward ref of %s' %\ + (removing, m.group(2), m.group(1)) foundline = m.group(1) else: print '********* I got confused **********' if line.startswith('In file included from'): - line = re.sub(r'^(In file included from)(.*):(\d+):', r' \2(\3) : \1 here', line) - # Note This doesnt appear to work if you get a string of them, not sure why. + line = re.sub(r'^(In file included from)(.*):(\d+):', + r' \2(\3) : \1 here', + line) + # Note; QT Creator seems to be unwilling to let you double click the + # line to select the code in question if you get a string of these, not + # sure why. elif ': note:' in line: line = ' ' + re.sub(r':(\d+):\d+: note:', r'(\1) : note:', line) else: # Replace clang :line:column: type: with ms (line) : type nnnn: line = re.sub(r':(\d+):\d+: ([^:]*):', r'(\1) : \2 I1234:', line) - + if ' : error I1234:' in line: + errors = True print line if line.endswith(' should remove these lines:'): @@ -84,16 +97,20 @@ def process_next_line(line): # added lines should come after the first entry with a line number. -process = subprocess.Popen(sys.argv[1:], +outfile = open(sys.argv[1], 'w') +process = subprocess.Popen(sys.argv[2:], stdout = subprocess.PIPE, stderr = subprocess.STDOUT) while True: output = process.stdout.readline() if output == '' and process.poll() is not None: break if output: - process_next_line(output) + process_next_line(output, outfile) + rc = process.poll() # The return code you get appears to be more to do with the amount of output -# generated than any real error. We should error if any ': error:' lines are -# detected +# generated than any real error, so instead we should error if any ': error:' +# lines are detected +if errors: + sys.exit(1) diff --git a/src/shared/stackdata.cpp b/src/shared/stackdata.cpp index 18daaf7b..b336593a 100644 --- a/src/shared/stackdata.cpp +++ b/src/shared/stackdata.cpp @@ -99,7 +99,8 @@ void StackData::initTrace() { CONTEXT context; std::memset(&context, 0, sizeof(CONTEXT)); context.ContextFlags = CONTEXT_CONTROL; -#if BOOST_ARCH_X86_64 + //Why only for 64 bit? +#if BOOST_ARCH_X86_64 || defined(__clang__) ::RtlCaptureContext(&context); #else __asm -- cgit v1.3.1