bump product version to 6.4.0.3
[LibreOffice.git] / compilerplugins / clang / readability-redundant-pp.cxx
blob2411dfb75f629846fb756111d823f6b12643c7ea
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * Based on LLVM/Clang.
7 * This file is distributed under the University of Illinois Open Source
8 * License. See LICENSE.TXT for details.
12 #include <iostream>
13 #include <stack>
15 #include "plugin.hxx"
17 #include <clang/Frontend/CompilerInstance.h>
18 #include <clang/Frontend/FrontendActions.h>
19 #include <clang/Tooling/CommonOptionsParser.h>
20 #include <clang/Tooling/Refactoring.h>
21 #include <llvm/Support/Signals.h>
23 /// Finds preprocessor usage which is redundant (only #ifndef for now).
25 namespace loplugin
27 struct Entry
29 clang::SourceLocation m_aLoc;
30 std::string m_aMacroName;
33 class RedundantPreprocessor : public clang::PPCallbacks, public Plugin
35 public:
36 explicit RedundantPreprocessor(const InstantiationData& data);
37 virtual void run() override;
38 void Ifndef(clang::SourceLocation aLoc, const clang::Token& rMacroNameTok,
39 const clang::MacroDefinition& rMacroDefinition) override;
40 void Ifdef(clang::SourceLocation aLoc, const clang::Token& rMacroNameTok,
41 const clang::MacroDefinition& rMacroDefinition) override;
42 void Endif(clang::SourceLocation aLoc, clang::SourceLocation aIfLoc) override;
43 enum
45 isPPCallback = true
48 private:
49 clang::Preprocessor& m_rPP;
50 std::vector<Entry> m_aDefStack;
51 std::vector<Entry> m_aNotDefStack;
54 RedundantPreprocessor::RedundantPreprocessor(const InstantiationData& data)
55 : Plugin(data)
56 , m_rPP(compiler.getPreprocessor())
58 compiler.getPreprocessor().addPPCallbacks(std::unique_ptr<PPCallbacks>(this));
61 void RedundantPreprocessor::run()
63 // nothing, only check preprocessor usage
66 void RedundantPreprocessor::Ifdef(clang::SourceLocation aLoc, const clang::Token& rMacroNameTok,
67 const clang::MacroDefinition& /*rMacroDefinition*/)
69 if (ignoreLocation(aLoc))
70 return;
72 if (m_rPP.getSourceManager().isInMainFile(aLoc))
74 std::string aMacroName = m_rPP.getSpelling(rMacroNameTok);
75 for (const auto& rEntry : m_aDefStack)
77 if (rEntry.m_aMacroName == aMacroName)
79 report(DiagnosticsEngine::Warning, "nested ifdef", aLoc);
80 report(DiagnosticsEngine::Note, "previous ifdef", rEntry.m_aLoc);
85 Entry aEntry;
86 aEntry.m_aLoc = aLoc;
87 aEntry.m_aMacroName = m_rPP.getSpelling(rMacroNameTok);
88 m_aDefStack.push_back(aEntry);
91 void RedundantPreprocessor::Ifndef(clang::SourceLocation aLoc, const clang::Token& rMacroNameTok,
92 const clang::MacroDefinition& /*rMacroDefinition*/)
94 if (ignoreLocation(aLoc))
95 return;
97 if (m_rPP.getSourceManager().isInMainFile(aLoc))
99 std::string aMacroName = m_rPP.getSpelling(rMacroNameTok);
100 for (const auto& rEntry : m_aNotDefStack)
102 if (rEntry.m_aMacroName == aMacroName)
104 report(DiagnosticsEngine::Warning, "nested ifndef", aLoc);
105 report(DiagnosticsEngine::Note, "previous ifndef", rEntry.m_aLoc);
110 Entry aEntry;
111 aEntry.m_aLoc = aLoc;
112 aEntry.m_aMacroName = m_rPP.getSpelling(rMacroNameTok);
113 m_aNotDefStack.push_back(aEntry);
116 void RedundantPreprocessor::Endif(clang::SourceLocation /*aLoc*/, clang::SourceLocation aIfLoc)
118 if (!m_aDefStack.empty())
120 if (aIfLoc == m_aDefStack.back().m_aLoc)
121 m_aDefStack.pop_back();
123 if (!m_aNotDefStack.empty())
125 if (aIfLoc == m_aNotDefStack.back().m_aLoc)
126 m_aNotDefStack.pop_back();
130 static Plugin::Registration<RedundantPreprocessor> X("redundantpreprocessor");
133 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */