[Libreoffice-commits] dev-tools.git: clang/Makefile clang/readability-redundant-pp.cxx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Nov 6 08:09:41 UTC 2018


 clang/Makefile                     |    7 +
 clang/readability-redundant-pp.cxx |  150 +++++++++++++++++++++++++++++++++++++
 2 files changed, 155 insertions(+), 2 deletions(-)

New commits:
commit 3ccab9a9f66410e3beb8a527dd14c6aa41504a62
Author:     Miklos Vajna <vmiklos at collabora.co.uk>
AuthorDate: Tue Nov 6 09:08:27 2018 +0100
Commit:     Miklos Vajna <vmiklos at collabora.co.uk>
CommitDate: Tue Nov 6 09:09:23 2018 +0100

    clang: add readability-redundant-pp tool
    
    See
    <https://cgit.freedesktop.org/libreoffice/online/commit/?id=4a24055a74308b13f1f9b23f33a309bc42e63b5f>
    for motivation.

diff --git a/clang/Makefile b/clang/Makefile
index b6db521..ae5a54d 100644
--- a/clang/Makefile
+++ b/clang/Makefile
@@ -3,12 +3,12 @@
 CLANGDEFS=-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -fno-rtti
 CLANGWARNS=-Werror -Wall -Wno-missing-braces -Wnon-virtual-dtor -Wendif-labels -Wextra -Wundef -Wunused-macros -Wshadow -Woverloaded-virtual
 CLANGFLAGS = $(CLANGDEFS) $(CLANGWARNS) -g -std=c++11
-CLANGLIBS = -lclangAST -lclangBasic -lclangFrontend -lclangRewrite -lclangTooling -lLLVM
+CLANGLIBS = -lclangAST -lclangBasic -lclangFrontend -lclangRewrite -lclangTooling -lclangLex -lLLVM
 ifneq ($(GCOV),)
 CLANGFLAGS += --coverage
 endif
 
-all: bin/rename bin/find-unprefixed-members bin/find-harmful-auto
+all: bin/rename bin/find-unprefixed-members bin/find-harmful-auto bin/readability-redundant-pp
 
 bin/rename: rename.cxx Makefile
 	clang++ $(CLANGFLAGS) $(CLANGLIBS) -ldl -lpthread -o $@ $<
@@ -19,6 +19,9 @@ bin/find-unprefixed-members: find-unprefixed-members.cxx Makefile
 bin/find-harmful-auto: find-harmful-auto.cxx Makefile
 	clang++ $(CLANGFLAGS) $(CLANGLIBS) -ldl -lpthread -o $@ $<
 
+bin/readability-redundant-pp: readability-redundant-pp.cxx Makefile
+	clang++ $(CLANGFLAGS) $(CLANGLIBS) -ldl -lpthread -o $@ $<
+
 test: test.cxx test.hxx Makefile
 	clang++ -o test test.cxx
 
diff --git a/clang/readability-redundant-pp.cxx b/clang/readability-redundant-pp.cxx
new file mode 100644
index 0000000..0ec266e
--- /dev/null
+++ b/clang/readability-redundant-pp.cxx
@@ -0,0 +1,150 @@
+#include <iostream>
+#include <stack>
+
+#include <clang/Frontend/CompilerInstance.h>
+#include <clang/Frontend/FrontendActions.h>
+#include <clang/Tooling/CommonOptionsParser.h>
+#include <clang/Tooling/Refactoring.h>
+#include <llvm/Support/Signals.h>
+
+namespace
+{
+
+struct Entry
+{
+    clang::SourceLocation m_aLoc;
+    std::string m_aMacroName;
+};
+
+/// Finds preprocessor usage which is redundant (only #ifndef for now).
+class RedundantPPCallbacks : public clang::PPCallbacks
+{
+  public:
+    RedundantPPCallbacks(clang::Preprocessor& rPP);
+    void Ifndef(clang::SourceLocation aLoc, const clang::Token& rMacroNameTok,
+                const clang::MacroDefinition& rMacroDefinition) override;
+    void Endif(clang::SourceLocation aLoc,
+               clang::SourceLocation aIfLoc) override;
+    ~RedundantPPCallbacks() override;
+
+  private:
+    clang::DiagnosticBuilder reportWarning(llvm::StringRef aString,
+                                           clang::SourceLocation aLocation);
+    clang::DiagnosticBuilder report(clang::DiagnosticIDs::Level eLevel,
+                                    llvm::StringRef aString,
+                                    clang::SourceLocation aLocation);
+
+    clang::Preprocessor& m_rPP;
+    std::vector<Entry> m_aStack;
+};
+
+RedundantPPCallbacks::RedundantPPCallbacks(clang::Preprocessor& rPP)
+    : m_rPP(rPP)
+{
+}
+
+RedundantPPCallbacks::~RedundantPPCallbacks() {}
+
+void RedundantPPCallbacks::Ifndef(
+    clang::SourceLocation aLoc, const clang::Token& rMacroNameTok,
+    const clang::MacroDefinition& /*rMacroDefinition*/)
+{
+    if (m_rPP.getSourceManager().isInMainFile(aLoc))
+    {
+        std::string aMacroName = m_rPP.getSpelling(rMacroNameTok);
+        for (const auto& rEntry : m_aStack)
+        {
+            if (rEntry.m_aMacroName == aMacroName)
+            {
+                reportWarning("nested ifdef", aLoc);
+                report(clang::DiagnosticIDs::Note, "previous ifdef",
+                       rEntry.m_aLoc);
+            }
+        }
+    }
+
+    Entry aEntry;
+    aEntry.m_aLoc = aLoc;
+    aEntry.m_aMacroName = m_rPP.getSpelling(rMacroNameTok);
+    m_aStack.push_back(aEntry);
+}
+
+void RedundantPPCallbacks::Endif(clang::SourceLocation /*aLoc*/,
+                                 clang::SourceLocation aIfLoc)
+{
+    if (m_aStack.empty())
+        return;
+
+    if (aIfLoc == m_aStack.back().m_aLoc)
+        m_aStack.pop_back();
+}
+
+clang::DiagnosticBuilder
+RedundantPPCallbacks::reportWarning(llvm::StringRef aString,
+                                    clang::SourceLocation aLocation)
+{
+    clang::DiagnosticsEngine& rEngine = m_rPP.getDiagnostics();
+    clang::DiagnosticIDs::Level eLevel = clang::DiagnosticIDs::Level::Warning;
+    if (rEngine.getWarningsAsErrors())
+        eLevel = clang::DiagnosticIDs::Level::Error;
+    return report(eLevel, aString, aLocation);
+}
+
+clang::DiagnosticBuilder
+RedundantPPCallbacks::report(clang::DiagnosticIDs::Level eLevel,
+                             llvm::StringRef aString,
+                             clang::SourceLocation aLocation)
+{
+    clang::DiagnosticsEngine& rEngine = m_rPP.getDiagnostics();
+    return rEngine.Report(
+        aLocation,
+        rEngine.getDiagnosticIDs()->getCustomDiagID(eLevel, aString));
+}
+
+class RedundantPPConsumer : public clang::ASTConsumer
+{
+  public:
+    RedundantPPConsumer(clang::Preprocessor& rPP)
+    {
+        rPP.addPPCallbacks(llvm::make_unique<RedundantPPCallbacks>(rPP));
+    }
+};
+
+class RedundantPPAction : public clang::SyntaxOnlyAction
+{
+  public:
+    RedundantPPAction() {}
+
+  protected:
+    std::unique_ptr<clang::ASTConsumer>
+    CreateASTConsumer(clang::CompilerInstance& rInstance,
+                      StringRef /*aFile*/) override
+    {
+        return llvm::make_unique<RedundantPPConsumer>(
+            rInstance.getPreprocessor());
+    }
+};
+
+class RedundantPPFrontendActionFactory
+    : public clang::tooling::FrontendActionFactory
+{
+  public:
+    RedundantPPFrontendActionFactory() {}
+
+    RedundantPPAction* create() override { return new RedundantPPAction(); }
+};
+
+llvm::cl::OptionCategory aCategory("redundant-pp options");
+}
+
+int main(int argc, const char** argv)
+{
+    llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
+    clang::tooling::CommonOptionsParser aOptionsParser(argc, argv, aCategory);
+    clang::tooling::RefactoringTool aTool(aOptionsParser.getCompilations(),
+                                          aOptionsParser.getSourcePathList());
+    RedundantPPFrontendActionFactory aFactory;
+    return aTool.run(&aFactory);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list