blob: 1efcec9c9fab821d190e71f131565ae1c63a6917 [file] [log] [blame]
Haojian Wuada28622016-10-17 08:33:59 +00001//===---------- ASTUtils.cpp - clang-tidy ---------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ASTUtils.h"
11
12#include "clang/ASTMatchers/ASTMatchFinder.h"
13#include "clang/ASTMatchers/ASTMatchers.h"
Yan Wangb38045d2017-07-12 17:43:36 +000014#include "clang/Lex/Lexer.h"
Haojian Wuada28622016-10-17 08:33:59 +000015
16namespace clang {
17namespace tidy {
18namespace utils {
19using namespace ast_matchers;
20
21const FunctionDecl *getSurroundingFunction(ASTContext &Context,
22 const Stmt &Statement) {
23 return selectFirst<const FunctionDecl>(
24 "function", match(stmt(hasAncestor(functionDecl().bind("function"))),
25 Statement, Context));
26}
Aaron Ballman72163a92017-04-24 14:57:09 +000027
28bool IsBinaryOrTernary(const Expr *E) {
29 const Expr *E_base = E->IgnoreImpCasts();
30 if (clang::isa<clang::BinaryOperator>(E_base) ||
31 clang::isa<clang::ConditionalOperator>(E_base)) {
32 return true;
33 }
34
35 if (const auto *Operator =
36 clang::dyn_cast<clang::CXXOperatorCallExpr>(E_base)) {
37 return Operator->isInfixBinaryOp();
38 }
39
40 return false;
41}
42
Yan Wangb38045d2017-07-12 17:43:36 +000043bool exprHasBitFlagWithSpelling(const Expr *Flags, const SourceManager &SM,
44 const LangOptions &LangOpts,
45 StringRef FlagName) {
46 // If the Flag is an integer constant, check it.
47 if (isa<IntegerLiteral>(Flags)) {
48 if (!SM.isMacroBodyExpansion(Flags->getLocStart()) &&
49 !SM.isMacroArgExpansion(Flags->getLocStart()))
50 return false;
51
52 // Get the marco name.
53 auto MacroName = Lexer::getSourceText(
54 CharSourceRange::getTokenRange(Flags->getSourceRange()), SM, LangOpts);
55
56 return MacroName == FlagName;
57 }
58 // If it's a binary OR operation.
59 if (const auto *BO = dyn_cast<BinaryOperator>(Flags))
60 if (BO->getOpcode() == clang::BinaryOperatorKind::BO_Or)
61 return exprHasBitFlagWithSpelling(BO->getLHS()->IgnoreParenCasts(), SM,
62 LangOpts, FlagName) ||
63 exprHasBitFlagWithSpelling(BO->getRHS()->IgnoreParenCasts(), SM,
64 LangOpts, FlagName);
65
66 // Otherwise, assume it has the flag.
67 return true;
68}
69
Haojian Wuada28622016-10-17 08:33:59 +000070} // namespace utils
71} // namespace tidy
72} // namespace clang