diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy/utils/ASTUtils.cpp')
-rw-r--r-- | clang-tools-extra/clang-tidy/utils/ASTUtils.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp b/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp index eff45b5be14..1efcec9c9fa 100644 --- a/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp @@ -11,6 +11,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" namespace clang { namespace tidy { @@ -39,6 +40,33 @@ bool IsBinaryOrTernary(const Expr *E) { return false; } +bool exprHasBitFlagWithSpelling(const Expr *Flags, const SourceManager &SM, + const LangOptions &LangOpts, + StringRef FlagName) { + // If the Flag is an integer constant, check it. + if (isa<IntegerLiteral>(Flags)) { + if (!SM.isMacroBodyExpansion(Flags->getLocStart()) && + !SM.isMacroArgExpansion(Flags->getLocStart())) + return false; + + // Get the marco name. + auto MacroName = Lexer::getSourceText( + CharSourceRange::getTokenRange(Flags->getSourceRange()), SM, LangOpts); + + return MacroName == FlagName; + } + // If it's a binary OR operation. + if (const auto *BO = dyn_cast<BinaryOperator>(Flags)) + if (BO->getOpcode() == clang::BinaryOperatorKind::BO_Or) + return exprHasBitFlagWithSpelling(BO->getLHS()->IgnoreParenCasts(), SM, + LangOpts, FlagName) || + exprHasBitFlagWithSpelling(BO->getRHS()->IgnoreParenCasts(), SM, + LangOpts, FlagName); + + // Otherwise, assume it has the flag. + return true; +} + } // namespace utils } // namespace tidy } // namespace clang |