1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
19 the comma operator is best used sparingly
24 Stmt
const * lookThroughExprWithCleanups(Stmt
const * stmt
) {
25 if (auto const e
= dyn_cast_or_null
<ExprWithCleanups
>(stmt
)) {
26 return e
->getSubExpr();
32 public loplugin::FilteringPlugin
<CommaOperator
>
35 explicit CommaOperator(loplugin::InstantiationData
const & data
):
36 FilteringPlugin(data
) {}
38 virtual void run() override
40 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
43 bool TraverseForStmt(ForStmt
* stmt
) {
44 auto const saved1
= ignore1_
;
45 ignore1_
= lookThroughExprWithCleanups(stmt
->getInit());
46 auto const saved2
= ignore2_
;
47 ignore2_
= lookThroughExprWithCleanups(stmt
->getInc());
48 auto const ret
= RecursiveASTVisitor::TraverseForStmt(stmt
);
54 bool TraverseWhileStmt(WhileStmt
* stmt
) {
55 auto const saved1
= ignore1_
;
56 ignore1_
= lookThroughExprWithCleanups(stmt
->getCond());
57 auto const ret
= RecursiveASTVisitor::TraverseWhileStmt(stmt
);
62 bool TraverseParenExpr(ParenExpr
* expr
) {
63 auto const saved1
= ignore1_
;
64 ignore1_
= expr
->getSubExpr();
65 auto const ret
= RecursiveASTVisitor::TraverseParenExpr(expr
);
70 bool TraverseBinaryOperator(BinaryOperator
* expr
) {
71 if (expr
->getOpcode() != BO_Comma
) {
72 return RecursiveASTVisitor::TraverseBinaryOperator(expr
);
74 if (!WalkUpFromBinaryOperator(expr
)) {
77 auto const saved1
= ignore1_
;
78 ignore1_
= expr
->getLHS();
79 auto const ret
= TraverseStmt(expr
->getLHS())
80 && TraverseStmt(expr
->getRHS());
85 bool VisitBinaryOperator(const BinaryOperator
* );
88 Stmt
const * ignore1_
= nullptr;
89 Stmt
const * ignore2_
= nullptr;
92 bool CommaOperator::VisitBinaryOperator(const BinaryOperator
* binaryOp
)
94 if (binaryOp
->getOpcode() != BO_Comma
) {
97 if (binaryOp
== ignore1_
|| binaryOp
== ignore2_
) {
100 if (ignoreLocation(binaryOp
)) {
103 // Ignore FD_SET expanding to "...} while(0, 0)" in some Microsoft
104 // winsock2.h (TODO: improve heuristic of determining that the whole
105 // binaryOp is part of a single macro body expansion):
106 if (compiler
.getSourceManager().isMacroBodyExpansion(
107 binaryOp
->getBeginLoc())
108 && compiler
.getSourceManager().isMacroBodyExpansion(
109 binaryOp
->getOperatorLoc())
110 && compiler
.getSourceManager().isMacroBodyExpansion(
111 binaryOp
->getEndLoc())
113 compiler
.getSourceManager().getSpellingLoc(
114 binaryOp
->getOperatorLoc())))
119 DiagnosticsEngine::Warning
, "comma operator hides code",
120 binaryOp
->getOperatorLoc())
121 << binaryOp
->getSourceRange();
126 loplugin::Plugin::Registration
< CommaOperator
> X("commaoperator", true);
130 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */