
Applied fixes enabled by the LLVM's .clang-tidy configs. Reverted files where fixes introduced compile errors: clang-tools-extra/clang-tidy/hicpp/NoAssemblerCheck.cpp clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp $ clang-tools-extra/clang-tidy/tool/run-clang-tidy.py -fix clang-tools-extra/clang-tidy/ Enabled checks: llvm-else-after-return llvm-header-guard llvm-include-order llvm-namespace-comment llvm-prefer-isa-or-dyn-cast-in-conditionals llvm-prefer-register-over-unsigned llvm-qualified-auto llvm-twine-local misc-definitions-in-headers misc-misplaced-const misc-new-delete-overloads misc-no-recursion misc-non-copyable-objects misc-redundant-expression misc-static-assert misc-throw-by-value-catch-by-reference misc-unconventional-assign-operator misc-uniqueptr-reset-release misc-unused-alias-decls misc-unused-using-decls readability-identifier-naming Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D95614
96 lines
3.4 KiB
C++
96 lines
3.4 KiB
C++
//===---------- ASTUtils.cpp - clang-tidy ---------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "ASTUtils.h"
|
|
|
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
|
#include "clang/ASTMatchers/ASTMatchers.h"
|
|
#include "clang/Lex/Lexer.h"
|
|
|
|
namespace clang {
|
|
namespace tidy {
|
|
namespace utils {
|
|
using namespace ast_matchers;
|
|
|
|
const FunctionDecl *getSurroundingFunction(ASTContext &Context,
|
|
const Stmt &Statement) {
|
|
return selectFirst<const FunctionDecl>(
|
|
"function", match(stmt(hasAncestor(functionDecl().bind("function"))),
|
|
Statement, Context));
|
|
}
|
|
|
|
bool IsBinaryOrTernary(const Expr *E) {
|
|
const Expr *EBase = E->IgnoreImpCasts();
|
|
if (isa<BinaryOperator>(EBase) || isa<ConditionalOperator>(EBase)) {
|
|
return true;
|
|
}
|
|
|
|
if (const auto *Operator = dyn_cast<CXXOperatorCallExpr>(EBase)) {
|
|
return Operator->isInfixBinaryOp();
|
|
}
|
|
|
|
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->getBeginLoc()) &&
|
|
!SM.isMacroArgExpansion(Flags->getBeginLoc()))
|
|
return false;
|
|
|
|
// Get the macro 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() == 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;
|
|
}
|
|
|
|
bool rangeIsEntirelyWithinMacroArgument(SourceRange Range,
|
|
const SourceManager *SM) {
|
|
// Check if the range is entirely contained within a macro argument.
|
|
SourceLocation MacroArgExpansionStartForRangeBegin;
|
|
SourceLocation MacroArgExpansionStartForRangeEnd;
|
|
bool RangeIsEntirelyWithinMacroArgument =
|
|
SM &&
|
|
SM->isMacroArgExpansion(Range.getBegin(),
|
|
&MacroArgExpansionStartForRangeBegin) &&
|
|
SM->isMacroArgExpansion(Range.getEnd(),
|
|
&MacroArgExpansionStartForRangeEnd) &&
|
|
MacroArgExpansionStartForRangeBegin == MacroArgExpansionStartForRangeEnd;
|
|
|
|
return RangeIsEntirelyWithinMacroArgument;
|
|
}
|
|
|
|
bool rangeContainsMacroExpansion(SourceRange Range, const SourceManager *SM) {
|
|
return rangeIsEntirelyWithinMacroArgument(Range, SM) ||
|
|
Range.getBegin().isMacroID() || Range.getEnd().isMacroID();
|
|
}
|
|
|
|
bool rangeCanBeFixed(SourceRange Range, const SourceManager *SM) {
|
|
return utils::rangeIsEntirelyWithinMacroArgument(Range, SM) ||
|
|
!utils::rangeContainsMacroExpansion(Range, SM);
|
|
}
|
|
|
|
} // namespace utils
|
|
} // namespace tidy
|
|
} // namespace clang
|