summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-tidy/utils/ASTUtils.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/utils/ASTUtils.cpp28
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
OpenPOWER on IntegriCloud