clang/Makefile | 7 + clang/readability-redundant-pp.cxx | 150 +++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 2 deletions(-)
New commits: commit 3ccab9a9f66410e3beb8a527dd14c6aa41504a62 Author: Miklos Vajna <vmik...@collabora.co.uk> AuthorDate: Tue Nov 6 09:08:27 2018 +0100 Commit: Miklos Vajna <vmik...@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: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits