Update git submodules
[LibreOffice.git] / compilerplugins / clang / blockblock.cxx
blobbfcb0206df0f24beab2d2691e820321dffccac66
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 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #ifndef LO_CLANG_SHARED_PLUGINS
12 #include <cassert>
13 #include <string>
14 #include <iostream>
15 #include <fstream>
16 #include <set>
17 #include "config_clang.h"
18 #include "plugin.hxx"
20 /**
21 Check for places where we declare a block directly inside a block
23 namespace {
25 class BlockBlock:
26 public loplugin::FilteringPlugin<BlockBlock>
28 public:
29 explicit BlockBlock(loplugin::InstantiationData const & data):
30 FilteringPlugin(data) {}
32 virtual bool preRun() override
34 StringRef fn(handler.getMainFileName());
35 if (loplugin::isSamePathname(fn, SRCDIR "/sal/osl/unx/file_misc.cxx"))
36 return false;
37 return true;
40 void run() override {
41 if (preRun()) {
42 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
46 bool VisitCompoundStmt(CompoundStmt const * );
47 bool VisitCaseStmt(CaseStmt const * );
50 bool BlockBlock::VisitCompoundStmt(CompoundStmt const * compound)
52 if (ignoreLocation(compound))
53 return true;
54 if (compound->size() != 1)
55 return true;
56 auto inner = *compound->body_begin();
57 if (!isa<CompoundStmt>(inner))
58 return true;
59 if (compiler.getSourceManager().isMacroBodyExpansion(compound->getBeginLoc()))
60 return true;
61 if (compiler.getSourceManager().isMacroBodyExpansion(inner->getBeginLoc()))
62 return true;
63 if (containsPreprocessingConditionalInclusion(compound->getSourceRange())) {
64 return true;
66 report(
67 DiagnosticsEngine::Warning,
68 "block directly inside block",
69 compound->getBeginLoc())
70 << compound->getSourceRange();
71 report(
72 DiagnosticsEngine::Note,
73 "inner block here",
74 inner->getBeginLoc())
75 << inner->getSourceRange();
76 return true;
79 bool BlockBlock::VisitCaseStmt(CaseStmt const * caseStmt)
81 if (ignoreLocation(caseStmt))
82 return true;
83 auto compoundStmt = dyn_cast<CompoundStmt>(caseStmt->getSubStmt());
84 if (!compoundStmt)
85 return true;
86 if (compoundStmt->size() != 2)
87 return true;
88 auto it = compoundStmt->body_begin();
89 auto inner1 = *it;
90 if (!isa<CompoundStmt>(inner1))
91 return true;
92 ++it;
93 if (!isa<BreakStmt>(*it))
94 return true;
95 report(
96 DiagnosticsEngine::Warning,
97 "block directly inside block",
98 compoundStmt->getBeginLoc())
99 << compoundStmt->getSourceRange();
100 return true;
103 loplugin::Plugin::Registration< BlockBlock > blockblock("blockblock", true);
107 #endif // LO_CLANG_SHARED_PLUGINS
109 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */