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/.
18 the comma operator is best used sparingly
23 Stmt
const * lookThroughExprWithCleanups(Stmt
const * stmt
) {
24 if (auto const e
= dyn_cast_or_null
<ExprWithCleanups
>(stmt
)) {
25 return e
->getSubExpr();
31 public RecursiveASTVisitor
<CommaOperator
>, public loplugin::Plugin
34 explicit CommaOperator(loplugin::InstantiationData
const & data
):
37 virtual void run() override
39 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
42 bool TraverseForStmt(ForStmt
* stmt
) {
43 auto const saved1
= ignore1_
;
44 ignore1_
= lookThroughExprWithCleanups(stmt
->getInit());
45 auto const saved2
= ignore2_
;
46 ignore2_
= lookThroughExprWithCleanups(stmt
->getInc());
47 auto const ret
= RecursiveASTVisitor::TraverseForStmt(stmt
);
53 bool TraverseWhileStmt(WhileStmt
* stmt
) {
54 auto const saved1
= ignore1_
;
55 ignore1_
= lookThroughExprWithCleanups(stmt
->getCond());
56 auto const ret
= RecursiveASTVisitor::TraverseWhileStmt(stmt
);
61 bool TraverseParenExpr(ParenExpr
* expr
) {
62 auto const saved1
= ignore1_
;
63 ignore1_
= expr
->getSubExpr();
64 auto const ret
= RecursiveASTVisitor::TraverseParenExpr(expr
);
69 bool TraverseBinComma(BinaryOperator
* expr
) {
70 if (!WalkUpFromBinComma(expr
)) {
73 auto const saved1
= ignore1_
;
74 ignore1_
= expr
->getLHS();
75 auto const ret
= TraverseStmt(expr
->getLHS())
76 && TraverseStmt(expr
->getRHS());
81 bool VisitBinComma(const BinaryOperator
* );
84 Stmt
const * ignore1_
= nullptr;
85 Stmt
const * ignore2_
= nullptr;
88 bool CommaOperator::VisitBinComma(const BinaryOperator
* binaryOp
)
90 if (binaryOp
== ignore1_
|| binaryOp
== ignore2_
) {
93 if (ignoreLocation(binaryOp
)) {
96 // Ignore FD_SET expanding to "...} while(0, 0)" in some Microsoft
97 // winsock2.h (TODO: improve heuristic of determining that the whole
98 // binaryOp is part of a single macro body expansion):
99 if (compiler
.getSourceManager().isMacroBodyExpansion(
100 binaryOp
->getLocStart())
101 && compiler
.getSourceManager().isMacroBodyExpansion(
102 binaryOp
->getOperatorLoc())
103 && compiler
.getSourceManager().isMacroBodyExpansion(
104 binaryOp
->getLocEnd())
106 compiler
.getSourceManager().getSpellingLoc(
107 binaryOp
->getOperatorLoc())))
112 DiagnosticsEngine::Warning
, "comma operator hides code",
113 binaryOp
->getOperatorLoc())
114 << binaryOp
->getSourceRange();
119 loplugin::Plugin::Registration
< CommaOperator
> X("commaoperator", true);
123 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */