1*10602c2bSCongcong Cai //===--- AvoidNestedConditionalOperatorCheck.cpp - clang-tidy -------------===// 28e21557dSCongcong Cai // 38e21557dSCongcong Cai // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 48e21557dSCongcong Cai // See https://llvm.org/LICENSE.txt for license information. 58e21557dSCongcong Cai // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68e21557dSCongcong Cai // 78e21557dSCongcong Cai //===----------------------------------------------------------------------===// 88e21557dSCongcong Cai 98e21557dSCongcong Cai #include "AvoidNestedConditionalOperatorCheck.h" 108e21557dSCongcong Cai #include "clang/ASTMatchers/ASTMatchFinder.h" 118e21557dSCongcong Cai #include "clang/ASTMatchers/ASTMatchers.h" 128e21557dSCongcong Cai #include "clang/Basic/DiagnosticIDs.h" 138e21557dSCongcong Cai 148e21557dSCongcong Cai using namespace clang::ast_matchers; 158e21557dSCongcong Cai 168e21557dSCongcong Cai namespace clang::tidy::readability { 178e21557dSCongcong Cai registerMatchers(MatchFinder * Finder)188e21557dSCongcong Caivoid AvoidNestedConditionalOperatorCheck::registerMatchers( 198e21557dSCongcong Cai MatchFinder *Finder) { 208e21557dSCongcong Cai Finder->addMatcher( 218e21557dSCongcong Cai conditionalOperator( 228e21557dSCongcong Cai anyOf( 238e21557dSCongcong Cai hasCondition(ignoringParenCasts( 248e21557dSCongcong Cai conditionalOperator().bind("nested-conditional-operator"))), 258e21557dSCongcong Cai hasTrueExpression(ignoringParenCasts( 268e21557dSCongcong Cai conditionalOperator().bind("nested-conditional-operator"))), 278e21557dSCongcong Cai hasFalseExpression(ignoringParenCasts( 288e21557dSCongcong Cai conditionalOperator().bind("nested-conditional-operator"))))) 298e21557dSCongcong Cai .bind("conditional-operator"), 308e21557dSCongcong Cai this); 318e21557dSCongcong Cai } 328e21557dSCongcong Cai check(const MatchFinder::MatchResult & Result)338e21557dSCongcong Caivoid AvoidNestedConditionalOperatorCheck::check( 348e21557dSCongcong Cai const MatchFinder::MatchResult &Result) { 358e21557dSCongcong Cai const auto *CO = 368e21557dSCongcong Cai Result.Nodes.getNodeAs<ConditionalOperator>("conditional-operator"); 378e21557dSCongcong Cai const auto *NCO = Result.Nodes.getNodeAs<ConditionalOperator>( 388e21557dSCongcong Cai "nested-conditional-operator"); 398e21557dSCongcong Cai assert(CO); 408e21557dSCongcong Cai assert(NCO); 418e21557dSCongcong Cai 428e21557dSCongcong Cai if (CO->getBeginLoc().isMacroID() || NCO->getBeginLoc().isMacroID()) 438e21557dSCongcong Cai return; 448e21557dSCongcong Cai 458e21557dSCongcong Cai diag(NCO->getBeginLoc(), 468e21557dSCongcong Cai "conditional operator is used as sub-expression of parent conditional " 478e21557dSCongcong Cai "operator, refrain from using nested conditional operators"); 488e21557dSCongcong Cai diag(CO->getBeginLoc(), "parent conditional operator here", 498e21557dSCongcong Cai DiagnosticIDs::Note); 508e21557dSCongcong Cai } 518e21557dSCongcong Cai 528e21557dSCongcong Cai } // namespace clang::tidy::readability 53