[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [clazy] /: Introduce qt4-compat mode
From:       Sergio Martins <null () kde ! org>
Date:       2017-05-01 0:50:59
Message-ID: E1d4zYJ-0003bE-Kt () code ! kde ! org
[Download RAW message or body]

Git commit eec99828a7665288e682dc03df8c401c31fd4da7 by Sergio Martins.
Committed on 01/05/2017 at 00:48.
Pushed by smartins into branch 'master'.

Introduce qt4-compat mode

If you pass -Xclang -plugin-arg-clang-lazy -Xclang qt4-compat then
Qt5-only checks will be disabled.

BUG: 379311

M  +1    -0    Changelog
M  +6    -0    README.md
M  +5    -2    src/Clazy.cpp
M  +2    -1    src/ClazyContext.h
M  +6    -0    src/ClazyStandaloneMain.cpp
M  +12   -3    src/checkmanager.cpp
M  +14   -2    src/checkmanager.h
M  +1    -1    src/checks/level0/qenums.cpp
M  +1    -1    src/checks/level0/qgetenv.cpp
M  +1    -1    src/checks/level2/oldstyleconnect.cpp
M  +1    -1    src/checks/level2/qstring-allocations.cpp
M  +9    -0    tests/clazy/config.json
A  +7    -0    tests/clazy/qt4compat1.cpp     [License: UNKNOWN]  *
A  +2    -0    tests/clazy/qt4compat1.cpp.expected
A  +7    -0    tests/clazy/qt4compat2.cpp     [License: UNKNOWN]  *
A  +0    -0    tests/clazy/qt4compat2.cpp.expected
M  +9    -0    tests/run_tests.py

The files marked with a * at the end have a non valid license. Please read: \
http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are \
listed at that page.


https://commits.kde.org/clazy/eec99828a7665288e682dc03df8c401c31fd4da7

diff --git a/Changelog b/Changelog
index d3804a0..58473f0 100644
--- a/Changelog
+++ b/Changelog
@@ -28,6 +28,7 @@
   - clazy-standalone executable. Allows to run clazy against a JSON compilation \
                database
     instead of as a plugin. clang-tidy doesn't support loading external modules \
(https://bugs.llvm.org/show_bug.cgi?id=32739)  so this is a good workaround.
+  - qt-compat mode. Allows to disable Qt5 specific checks by passing -Xclang \
                -plugin-arg-clang-lazy -Xclang qt4-compat
   - New checks:
     install-event-filter
     qcolor-from-literal
diff --git a/README.md b/README.md
index 517db41..f8a72db 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,7 @@ Table of contents
    * [clang-standalone and JSON database \
                support](#clang-standalone-and-json-database-support)
    * [Enabling Fixits](#enabling-fixits)
    * [Troubleshooting](#troubleshooting)
+   * [Qt4 compatibility mode](#qt4-compatibility-mode)
    * [Reducing warning noise](#reducing-warning-noise)
    * [Reporting bugs and wishes](#reporting-bugs-and-wishes)
    * [Authors](#authors)
@@ -332,6 +333,11 @@ For better results don't use parallel builds, otherwise a fixit \
                being applied in
 - fatal error: 'stddef.h' file not found, while using `clazy-standalone`
   Be sure the clazy-standalone binary is located in the same folder as the clang \
binary.  
+# Qt4 compatibility mode
+
+When running on codebases that must still compile with Qt4, you can pass `-Xclang \
-plugin-arg-clang-lazy -Xclang qt4-compat` +to disable checks that only make sense \
with Qt5. +
 # Reducing warning noise
 
 If you think you found a false-positive, file a bug report.
diff --git a/src/Clazy.cpp b/src/Clazy.cpp
index 0ce3d00..24c752b 100644
--- a/src/Clazy.cpp
+++ b/src/Clazy.cpp
@@ -191,10 +191,13 @@ bool ClazyASTAction::ParseArgs(const CompilerInstance &, const \
std::vector<std::  m_checkManager->enableAllFixIts();
     }
 
+    if (parseArgument("qt4-compat", args))
+        m_options |= ClazyContext::ClazyOption_Qt4Compat;
+
     // This argument is for debugging purposes
     const bool dbgPrintRequestedChecks = parseArgument("print-requested-checks", \
args);  
-    m_checks = m_checkManager->requestedChecks(args);
+    m_checks = m_checkManager->requestedChecks(args, m_options);
 
     if (args.size() > 1) {
         // Too many arguments.
@@ -341,7 +344,7 @@ unique_ptr<ASTConsumer> \
ClazyStandaloneASTAction::CreateASTConsumer(CompilerInst  cm->enableAllFixIts();
 
     vector<string> checks; checks.push_back(m_checkList);
-    const RegisteredCheck::List requestedChecks = cm->requestedChecks(checks);
+    const RegisteredCheck::List requestedChecks = cm->requestedChecks(checks, \
m_options);  
     if (requestedChecks.size() == 0) {
         llvm::errs() << "No checks were requested!\n" << "\n";
diff --git a/src/ClazyContext.h b/src/ClazyContext.h
index 28cc75b..b8f74c6 100644
--- a/src/ClazyContext.h
+++ b/src/ClazyContext.h
@@ -53,7 +53,8 @@ public:
         ClazyOption_None = 0,
         ClazyOption_FixitsAreInplace = 1,
         ClazyOption_FixitsEnabled = 2,
-        ClazyOption_AllFixitsEnabled = 4
+        ClazyOption_AllFixitsEnabled = 4,
+        ClazyOption_Qt4Compat = 8
     };
     typedef int ClazyOptions;
 
diff --git a/src/ClazyStandaloneMain.cpp b/src/ClazyStandaloneMain.cpp
index 696b65c..fa8a021 100644
--- a/src/ClazyStandaloneMain.cpp
+++ b/src/ClazyStandaloneMain.cpp
@@ -43,6 +43,9 @@ static cl::opt<bool> s_noInplaceFixits("no-inplace-fixits", \
cl::desc("Fixits wil  static cl::opt<bool> s_enableAllFixits("enable-all-fixits", \
                cl::desc("Enables all fixits"),
                                        cl::init(""), cl::cat(s_clazyCategory));
 
+static cl::opt<bool> s_qt4Compat("qt4-compat", cl::desc("Turns off checks not \
compatible with Qt 4"), +                                 cl::init(false), \
cl::cat(s_clazyCategory)); +
 static cl::extrahelp s_commonHelp(CommonOptionsParser::HelpMessage);
 
 class ClazyToolAction : public clang::tooling::FrontendActionFactory
@@ -60,6 +63,9 @@ public:
         if (s_enableAllFixits.getValue())
             options |= ClazyContext::ClazyOption_AllFixitsEnabled;
 
+        if (s_qt4Compat.getValue())
+            options |= ClazyContext::ClazyOption_Qt4Compat;
+
         return new ClazyStandaloneASTAction(s_checks.getValue(), options);
     }
 };
diff --git a/src/checkmanager.cpp b/src/checkmanager.cpp
index aa6b0db..7ce3ad8 100644
--- a/src/checkmanager.cpp
+++ b/src/checkmanager.cpp
@@ -73,7 +73,8 @@ bool CheckManager::isReservedCheckName(const string &name) const
 }
 
 int CheckManager::registerCheck(const std::string &name, const string &className,
-                                CheckLevel level, const FactoryFunction &factory)
+                                CheckLevel level, const FactoryFunction &factory,
+                                RegisteredCheck::Options options)
 {
     assert(factory != nullptr);
     assert(!name.empty());
@@ -82,7 +83,7 @@ int CheckManager::registerCheck(const std::string &name, const \
string &className  llvm::errs() << "Check name not allowed" << name;
         assert(false);
     } else {
-        m_registeredChecks.push_back({name, className, level, factory});
+        m_registeredChecks.push_back({name, className, level, factory, options});
     }
 
     return 0;
@@ -208,7 +209,8 @@ static bool takeArgument(const string &arg, vector<string> &args)
     return false;
 }
 
-RegisteredCheck::List CheckManager::requestedChecks(std::vector<std::string> &args)
+RegisteredCheck::List CheckManager::requestedChecks(std::vector<std::string> &args,
+                                                    ClazyContext::ClazyOptions \
options)  {
     RegisteredCheck::List result;
 
@@ -250,6 +252,13 @@ RegisteredCheck::List \
CheckManager::requestedChecks(std::vector<std::string> &ar  \
clazy_std::sort_and_remove_dups(result, checkLessThan);  \
CheckManager::removeChecksFromList(result, userDisabledChecks);  
+    if (options & ClazyContext::ClazyOption_Qt4Compat) {
+        // #5 Remove Qt4 incompatible checks
+        result.erase(remove_if(result.begin(), result.end(), [](const \
RegisteredCheck &c){ +           return c.options & \
RegisteredCheck::Option_Qt4Incompatible; +        }));
+    }
+
     return result;
 }
 
diff --git a/src/checkmanager.h b/src/checkmanager.h
index 1fe41fc..d5eff42 100644
--- a/src/checkmanager.h
+++ b/src/checkmanager.h
@@ -45,11 +45,19 @@ struct CLAZYLIB_EXPORT RegisteredFixIt {
 using FactoryFunction = std::function<CheckBase*(ClazyContext *context)>;
 
 struct CLAZYLIB_EXPORT RegisteredCheck {
+    enum Option {
+        Option_None = 0,
+        Option_Qt4Incompatible
+    };
+
     typedef std::vector<RegisteredCheck> List;
+    typedef int Options;
+
     std::string name;
     std::string className;
     CheckLevel level;
     FactoryFunction factory;
+    Options options;
     bool operator==(const RegisteredCheck &other) const { return name == other.name; \
}  };
 
@@ -75,7 +83,8 @@ public:
         return &s_instance;
     }
 
-    int registerCheck(const std::string &name, const std::string &className, \
CheckLevel level, const FactoryFunction &); +    int registerCheck(const std::string \
&name, const std::string &className, +                      CheckLevel level, const \
                FactoryFunction &, RegisteredCheck::Options = \
                RegisteredCheck::Option_None);
     int registerFixIt(int id, const std::string &fititName, const std::string \
&checkName);  
     RegisteredCheck::List availableChecks(CheckLevel maxLevel) const;
@@ -93,7 +102,7 @@ public:
      * Returns all the requested checks.
      * This is a union of the requested checks via env variable and via arguments \
                passed to compiler
      */
-    RegisteredCheck::List requestedChecks(std::vector<std::string> &args);
+    RegisteredCheck::List requestedChecks(std::vector<std::string> &args, \
ClazyContext::ClazyOptions options);  
     CheckBase::List createChecks(const RegisteredCheck::List &requestedChecks, \
ClazyContext *context);  
@@ -122,6 +131,9 @@ private:
 #define CLAZY_STRINGIFY2(X) #X
 #define CLAZY_STRINGIFY(X) CLAZY_STRINGIFY2(X)
 
+#define REGISTER_CHECK_WITH_FLAGS(CHECK_NAME, CLASS_NAME, LEVEL, OPTIONS) \
+    volatile int ClazyAnchor_##CLASS_NAME = \
CheckManager::instance()->registerCheck(CHECK_NAME, CLAZY_STRINGIFY(CLASS_NAME), \
LEVEL, [](ClazyContext *context){ return new CLASS_NAME(CHECK_NAME, context); }, \
OPTIONS); +
 #define REGISTER_CHECK(CHECK_NAME, CLASS_NAME, LEVEL) \
     volatile int ClazyAnchor_##CLASS_NAME = \
CheckManager::instance()->registerCheck(CHECK_NAME, CLAZY_STRINGIFY(CLASS_NAME), \
LEVEL, [](ClazyContext *context){ return new CLASS_NAME(CHECK_NAME, context); });  
diff --git a/src/checks/level0/qenums.cpp b/src/checks/level0/qenums.cpp
index d5d2c76..aa4f668 100644
--- a/src/checks/level0/qenums.cpp
+++ b/src/checks/level0/qenums.cpp
@@ -54,4 +54,4 @@ void Qenums::VisitMacroExpands(const Token &MacroNameTok, const \
SourceRange &ran  emitWarning(range.getBegin(), "Use Q_ENUM instead of Q_ENUMS");
 }
 
-REGISTER_CHECK("qenums", Qenums, CheckLevel0)
+REGISTER_CHECK_WITH_FLAGS("qenums", Qenums, CheckLevel0, \
                RegisteredCheck::Option_Qt4Incompatible)
diff --git a/src/checks/level0/qgetenv.cpp b/src/checks/level0/qgetenv.cpp
index 125d7d6..0eb33f8 100644
--- a/src/checks/level0/qgetenv.cpp
+++ b/src/checks/level0/qgetenv.cpp
@@ -105,5 +105,5 @@ void QGetEnv::VisitStmt(clang::Stmt *stmt)
 
 
 const char *const s_checkName = "qgetenv";
-REGISTER_CHECK(s_checkName, QGetEnv, CheckLevel0)
+REGISTER_CHECK_WITH_FLAGS(s_checkName, QGetEnv, CheckLevel0, \
RegisteredCheck::Option_Qt4Incompatible)  REGISTER_FIXIT(FixitAll, "fix-qgetenv", \
                s_checkName)
diff --git a/src/checks/level2/oldstyleconnect.cpp \
b/src/checks/level2/oldstyleconnect.cpp index 4185bfc..1c06ed4 100644
--- a/src/checks/level2/oldstyleconnect.cpp
+++ b/src/checks/level2/oldstyleconnect.cpp
@@ -419,5 +419,5 @@ vector<FixItHint> OldStyleConnect::fixits(int classification, \
CallExpr *call)  }
 
 const char *const s_checkName = "old-style-connect";
-REGISTER_CHECK(s_checkName, OldStyleConnect, CheckLevel2)
+REGISTER_CHECK_WITH_FLAGS(s_checkName, OldStyleConnect, CheckLevel2, \
RegisteredCheck::Option_Qt4Incompatible)  REGISTER_FIXIT(FixItConnects, \
                "fix-old-style-connect", s_checkName)
diff --git a/src/checks/level2/qstring-allocations.cpp \
b/src/checks/level2/qstring-allocations.cpp index 9c21700..4d63e75 100644
--- a/src/checks/level2/qstring-allocations.cpp
+++ b/src/checks/level2/qstring-allocations.cpp
@@ -570,7 +570,7 @@ vector<string> QStringAllocations::supportedOptions() const
 }
 
 const char *const s_checkName = "qstring-allocations";
-REGISTER_CHECK(s_checkName, QStringAllocations, CheckLevel2)
+REGISTER_CHECK_WITH_FLAGS(s_checkName, QStringAllocations, CheckLevel2, \
RegisteredCheck::Option_Qt4Incompatible)  REGISTER_FIXIT(QLatin1StringAllocations, \
"fix-qlatin1string-allocations", s_checkName)  \
REGISTER_FIXIT(FromLatin1_FromUtf8Allocations, "fix-fromLatin1_fromUtf8-allocations", \
s_checkName)  REGISTER_FIXIT(CharPtrAllocations, "fix-fromCharPtrAllocations", \
                s_checkName)
diff --git a/tests/clazy/config.json b/tests/clazy/config.json
index b108701..5753b45 100644
--- a/tests/clazy/config.json
+++ b/tests/clazy/config.json
@@ -26,6 +26,15 @@
             "flags"    : "-Werror",
             "checks"   : ["foreach"],
             "env"      : { "CLAZY_NO_WERROR" : "1" }
+        },
+        {
+            "filename" : "qt4compat1.cpp",
+            "checks"   : ["old-style-connect"]
+        },
+        {
+            "filename" : "qt4compat2.cpp",
+            "checks"   : ["old-style-connect"],
+            "qt4compat": true
         }
     ]
 }
diff --git a/tests/clazy/qt4compat1.cpp b/tests/clazy/qt4compat1.cpp
new file mode 100644
index 0000000..4a85bb6
--- /dev/null
+++ b/tests/clazy/qt4compat1.cpp
@@ -0,0 +1,7 @@
+#include <QtCore/QObject>
+
+void test()
+{
+    QObject o;
+    o.connect(&o, SIGNAL(foo()), SLOT(bar()));
+}
diff --git a/tests/clazy/qt4compat1.cpp.expected \
b/tests/clazy/qt4compat1.cpp.expected new file mode 100644
index 0000000..096ad91
--- /dev/null
+++ b/tests/clazy/qt4compat1.cpp.expected
@@ -0,0 +1,2 @@
+clazy/qt4compat1.cpp:6:5: warning: Old Style Connect [-Wclazy-old-style-connect]
+clazy/qt4compat1.cpp:6:19: warning: FixIt failed, requires manual intervention:  No \
                such method foo in class QObject [-Wclazy-old-style-connect]
diff --git a/tests/clazy/qt4compat2.cpp b/tests/clazy/qt4compat2.cpp
new file mode 100644
index 0000000..4a85bb6
--- /dev/null
+++ b/tests/clazy/qt4compat2.cpp
@@ -0,0 +1,7 @@
+#include <QtCore/QObject>
+
+void test()
+{
+    QObject o;
+    o.connect(&o, SIGNAL(foo()), SLOT(bar()));
+}
diff --git a/tests/clazy/qt4compat2.cpp.expected \
b/tests/clazy/qt4compat2.cpp.expected new file mode 100644
index 0000000..e69de29
diff --git a/tests/run_tests.py b/tests/run_tests.py
index 82d5068..a4c2979 100755
--- a/tests/run_tests.py
+++ b/tests/run_tests.py
@@ -32,6 +32,7 @@ class Test:
         self.flags = ""
         self.must_fail = False
         self.blacklist_platforms = []
+        self.qt4compat = False
 
     def isScript(self):
         return self.filename.endswith(".sh")
@@ -142,6 +143,8 @@ def load_json(check_name):
                 test.must_fail = t['must_fail']
             if 'expects_failure' in t:
                 test.expects_failure = t['expects_failure']
+            if 'qt4compat' in t:
+                test.qt4compat = t['qt4compat']
 
             if not test.checks:
                 test.checks.append(test.check.name)
@@ -195,6 +198,9 @@ def clazy_standalone_command(test, qt):
     if not test.isFixedFile:
         result = " -enable-all-fixits " + result
 
+    if test.qt4compat:
+        result = " -qt4-compat " + result
+
     return result
 
 def clazy_command(qt, test, filename):
@@ -206,6 +212,9 @@ def clazy_command(qt, test, filename):
     else:
         result = "clang -Xclang -load -Xclang " + libraryName() + " -Xclang \
-add-plugin -Xclang clang-lazy " + more_clazy_args() + qt.compiler_flags()  
+    if test.qt4compat:
+        result = result + " -Xclang -plugin-arg-clang-lazy -Xclang qt4-compat "
+
     if test.link:
         result = result + " " + link_flags()
     else:


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic