Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ namespace clang::tidy::bugprone {

namespace {

// Preserve same name as AST_MATCHER(isCompleteAndHasNoZeroValue)
// NOLINTNEXTLINE(llvm-prefer-static-over-anonymous-namespace)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why exception is needed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function isCompleteAndHasNoZeroValue is used inside AST_MATCHER(EnumDecl, isCompleteAndHasNoZeroValue) and as a freestanding function.

If I convert it to static, then there are build errors like:

clang-tools-extra/clang-tidy/bugprone/InvalidEnumDefaultInitializationCheck.cpp:37:10: error: no matching function for call to 'isCompleteAndHasNoZeroValue'
   37 |   return isCompleteAndHasNoZeroValue(&Node);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~
llvm2/llvm-project/clang-tools-extra/clang-tidy/bugprone/InvalidEnumDefaultInitializationCheck.cpp:36:23: note: candidate function not viable: requires 0 arguments, but 1 was provided
   36 | AST_MATCHER(EnumDecl, isCompleteAndHasNoZeroValue) {
      |                       ^
llvm2/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersMacros.h:108:57: note: expanded from macro 'AST_MATCHER'
  108 |   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() {      \
      |                                                         ^
llvm2/llvm-project/clang-tools-extra/clang-tidy/bugprone/InvalidEnumDefaultInitializationCheck.cpp:37:10: error: no viable conversion from returned value of type '::clang::ast_matchers::internal::Matcher<EnumDecl>' to function return type 'bool'
   37 |   return isCompleteAndHasNoZeroValue(&Node);

In the past I dodge it by renaming ether matcher of function, but here I think the name is so self-contained that we should leave it as-is..

bool isCompleteAndHasNoZeroValue(const EnumDecl *D) {
const EnumDecl *Definition = D->getDefinition();
return Definition && Definition->isComplete() &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@ using namespace clang::ast_matchers;

namespace clang::tidy::bugprone {

namespace {
static constexpr char ConstructExprN[] = "found_construct_expr";
static constexpr char NewExprN[] = "found_new_expr";
static constexpr char ConstructorN[] = "found_constructor";

constexpr char ConstructExprN[] = "found_construct_expr";
constexpr char NewExprN[] = "found_new_expr";
constexpr char ConstructorN[] = "found_constructor";

bool isInSingleDeclStmt(const DeclaratorDecl *D) {
static bool isInSingleDeclStmt(const DeclaratorDecl *D) {
const DynTypedNodeList Parents =
D->getASTContext().getParentMapContext().getParents(*D);
for (const DynTypedNode &PNode : Parents)
Expand All @@ -30,8 +28,8 @@ bool isInSingleDeclStmt(const DeclaratorDecl *D) {
return false;
}

const DeclaratorDecl *getConstructedVarOrField(const Expr *FoundConstructExpr,
ASTContext &Ctx) {
static const DeclaratorDecl *
getConstructedVarOrField(const Expr *FoundConstructExpr, ASTContext &Ctx) {
const DynTypedNodeList ConstructParents =
Ctx.getParentMapContext().getParents(*FoundConstructExpr);
if (ConstructParents.size() != 1)
Expand All @@ -43,8 +41,6 @@ const DeclaratorDecl *getConstructedVarOrField(const Expr *FoundConstructExpr,
return nullptr;
}

} // namespace

const char SmartPtrArrayMismatchCheck::PointerTypeN[] = "pointer_type";

SmartPtrArrayMismatchCheck::SmartPtrArrayMismatchCheck(
Expand Down
8 changes: 2 additions & 6 deletions clang-tools-extra/clang-tidy/google/FunctionNamingCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ using namespace clang::ast_matchers;

namespace clang::tidy::google::objc {

namespace {

std::string validFunctionNameRegex(bool RequirePrefix) {
static std::string validFunctionNameRegex(bool RequirePrefix) {
// Allow the following name patterns for all functions:
// • ABFoo (prefix + UpperCamelCase)
// • ABURL (prefix + capitalized acronym/initialism)
Expand All @@ -43,7 +41,7 @@ std::string validFunctionNameRegex(bool RequirePrefix) {
/// For now we will only fix functions of static storage class with names like
/// 'functionName' or 'function_name' and convert them to 'FunctionName'. For
/// other cases the user must determine an appropriate name on their own.
FixItHint generateFixItHint(const FunctionDecl *Decl) {
static FixItHint generateFixItHint(const FunctionDecl *Decl) {
// A fixit can be generated for functions of static storage class but
// otherwise the check cannot determine the appropriate function name prefix
// to use.
Expand Down Expand Up @@ -82,8 +80,6 @@ FixItHint generateFixItHint(const FunctionDecl *Decl) {
return {};
}

} // namespace

void FunctionNamingCheck::registerMatchers(MatchFinder *Finder) {
// Enforce Objective-C function naming conventions on all functions except:
// • Functions defined in system headers.
Expand Down
12 changes: 6 additions & 6 deletions clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@ struct OptionEnumMapping<misc::UseInternalLinkageCheck::FixModeKind> {

namespace clang::tidy::misc {

namespace {

AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); }

AST_MATCHER(FunctionDecl, hasBody) { return Node.hasBody(); }

static bool isInMainFile(SourceLocation L, SourceManager &SM,
const FileExtensionsSet &HeaderFileExtensions) {
for (;;) {
Expand All @@ -65,6 +59,12 @@ static bool isInMainFile(SourceLocation L, SourceManager &SM,
}
}

namespace {

AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); }

AST_MATCHER(FunctionDecl, hasBody) { return Node.hasBody(); }

AST_MATCHER_P(Decl, isAllRedeclsInMainFile, FileExtensionsSet,
HeaderFileExtensions) {
return llvm::all_of(Node.redecls(), [&](const Decl *D) {
Expand Down
16 changes: 8 additions & 8 deletions clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ using namespace clang::ast_matchers;

namespace clang::tidy::modernize {

template <typename TargetType, typename NodeType>
static const TargetType *getAs(const NodeType *Node) {
if constexpr (std::is_same_v<NodeType, clang::DynTypedNode>)
return Node->template get<TargetType>();
else
return llvm::dyn_cast<TargetType>(Node);
}

namespace {

AST_MATCHER(clang::TypeLoc, hasValidBeginLoc) {
Expand All @@ -39,14 +47,6 @@ AST_MATCHER(clang::ParmVarDecl, isArgvOfMain) {
return FD ? FD->isMain() : false;
}

template <typename TargetType, typename NodeType>
const TargetType *getAs(const NodeType *Node) {
if constexpr (std::is_same_v<NodeType, clang::DynTypedNode>)
return Node->template get<TargetType>();
else
return llvm::dyn_cast<TargetType>(Node);
}

AST_MATCHER(clang::TypeLoc, isWithinImplicitTemplateInstantiation) {
const auto IsImplicitTemplateInstantiation = [](const auto *Node) {
const auto IsImplicitInstantiation = [](const auto *Node) {
Expand Down
55 changes: 27 additions & 28 deletions clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,13 @@ using namespace clang::ast_matchers;
using namespace clang::ast_matchers::internal;

namespace clang::tidy::modernize {
namespace {

const char IteratorDeclStmtId[] = "iterator_decl";
const char DeclWithNewId[] = "decl_new";
const char DeclWithCastId[] = "decl_cast";
const char DeclWithTemplateCastId[] = "decl_template";
static const char IteratorDeclStmtId[] = "iterator_decl";
static const char DeclWithNewId[] = "decl_new";
static const char DeclWithCastId[] = "decl_cast";
static const char DeclWithTemplateCastId[] = "decl_template";

size_t getTypeNameLength(bool RemoveStars, StringRef Text) {
static size_t getTypeNameLength(bool RemoveStars, StringRef Text) {
enum CharType { Space, Alpha, Punctuation };
CharType LastChar = Space, BeforeSpace = Punctuation;
size_t NumChars = 0;
Expand All @@ -54,6 +53,7 @@ size_t getTypeNameLength(bool RemoveStars, StringRef Text) {
return NumChars;
}

namespace {
/// Matches variable declarations that have explicit initializers that
/// are not initializer lists.
///
Expand All @@ -65,7 +65,7 @@ size_t getTypeNameLength(bool RemoveStars, StringRef Text) {
/// MyType C;
/// \endcode
///
/// varDecl(hasWrittenNonListInitializer()) maches \c I and \c A but not \c B
/// varDecl(hasWrittenNonListInitializer()) matches \c I and \c A but not \c B
/// or \c C.
AST_MATCHER(VarDecl, hasWrittenNonListInitializer) {
const Expr *Init = Node.getAnyInitializer();
Expand Down Expand Up @@ -108,6 +108,15 @@ AST_MATCHER_P(QualType, isSugarFor, Matcher<QualType>, SugarMatcher) {
}
}

/// Matches declaration reference or member expressions with explicit template
/// arguments.
AST_POLYMORPHIC_MATCHER(hasExplicitTemplateArgs,
AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,
MemberExpr)) {
return Node.hasExplicitTemplateArgs();
}
} // namespace

/// Matches named declarations that have one of the standard iterator
/// names: iterator, reverse_iterator, const_iterator, const_reverse_iterator.
///
Expand All @@ -118,7 +127,7 @@ AST_MATCHER_P(QualType, isSugarFor, Matcher<QualType>, SugarMatcher) {
/// \endcode
///
/// namedDecl(hasStdIteratorName()) matches \c I and \c CI.
Matcher<NamedDecl> hasStdIteratorName() {
static Matcher<NamedDecl> hasStdIteratorName() {
static const StringRef IteratorNames[] = {"iterator", "reverse_iterator",
"const_iterator",
"const_reverse_iterator"};
Expand All @@ -137,7 +146,7 @@ Matcher<NamedDecl> hasStdIteratorName() {
///
/// recordDecl(hasStdContainerName()) matches \c vector and \c forward_list
/// but not \c my_vec.
Matcher<NamedDecl> hasStdContainerName() {
static Matcher<NamedDecl> hasStdContainerName() {
static StringRef ContainerNames[] = {"array", "deque",
"forward_list", "list",
"vector",
Expand All @@ -154,37 +163,29 @@ Matcher<NamedDecl> hasStdContainerName() {
return hasAnyName(ContainerNames);
}

/// Matches declaration reference or member expressions with explicit template
/// arguments.
AST_POLYMORPHIC_MATCHER(hasExplicitTemplateArgs,
AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,
MemberExpr)) {
return Node.hasExplicitTemplateArgs();
}

/// Returns a DeclarationMatcher that matches standard iterators nested
/// inside records with a standard container name.
DeclarationMatcher standardIterator() {
static DeclarationMatcher standardIterator() {
return decl(
namedDecl(hasStdIteratorName()),
hasDeclContext(recordDecl(hasStdContainerName(), isInStdNamespace())));
}

/// Returns a TypeMatcher that matches typedefs for standard iterators
/// inside records with a standard container name.
TypeMatcher typedefIterator() {
static TypeMatcher typedefIterator() {
return typedefType(hasDeclaration(standardIterator()));
}

/// Returns a TypeMatcher that matches records named for standard
/// iterators nested inside records named for standard containers.
TypeMatcher nestedIterator() {
static TypeMatcher nestedIterator() {
return recordType(hasDeclaration(standardIterator()));
}

/// Returns a TypeMatcher that matches types declared with using
/// declarations and which name standard iterators for standard containers.
TypeMatcher iteratorFromUsingDeclaration() {
static TypeMatcher iteratorFromUsingDeclaration() {
auto HasIteratorDecl = hasDeclaration(namedDecl(hasStdIteratorName()));
// Unwrap the nested name specifier to test for one of the standard
// containers.
Expand All @@ -198,7 +199,7 @@ TypeMatcher iteratorFromUsingDeclaration() {

/// This matcher returns declaration statements that contain variable
/// declarations with written non-list initializer for standard iterators.
StatementMatcher makeIteratorDeclMatcher() {
static StatementMatcher makeIteratorDeclMatcher() {
return declStmt(unless(has(
varDecl(anyOf(unless(hasWrittenNonListInitializer()),
unless(hasType(isSugarFor(anyOf(
Expand All @@ -207,7 +208,7 @@ StatementMatcher makeIteratorDeclMatcher() {
.bind(IteratorDeclStmtId);
}

StatementMatcher makeDeclWithNewMatcher() {
static StatementMatcher makeDeclWithNewMatcher() {
return declStmt(
unless(has(varDecl(anyOf(
unless(hasInitializer(ignoringParenImpCasts(cxxNewExpr()))),
Expand All @@ -225,13 +226,13 @@ StatementMatcher makeDeclWithNewMatcher() {
.bind(DeclWithNewId);
}

StatementMatcher makeDeclWithCastMatcher() {
static StatementMatcher makeDeclWithCastMatcher() {
return declStmt(
unless(has(varDecl(unless(hasInitializer(explicitCastExpr()))))))
.bind(DeclWithCastId);
}

StatementMatcher makeDeclWithTemplateCastMatcher() {
static StatementMatcher makeDeclWithTemplateCastMatcher() {
auto ST =
substTemplateTypeParmType(hasReplacementType(equalsBoundNode("arg")));

Expand All @@ -252,7 +253,7 @@ StatementMatcher makeDeclWithTemplateCastMatcher() {
.bind(DeclWithTemplateCastId);
}

StatementMatcher makeCombinedMatcher() {
static StatementMatcher makeCombinedMatcher() {
return declStmt(
// At least one varDecl should be a child of the declStmt to ensure
// it's a declaration list and avoid matching other declarations,
Expand All @@ -265,8 +266,6 @@ StatementMatcher makeCombinedMatcher() {
makeDeclWithCastMatcher(), makeDeclWithTemplateCastMatcher()));
}

} // namespace

UseAutoCheck::UseAutoCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
MinTypeNameLength(Options.get("MinTypeNameLength", 5)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ static constexpr char StrictCppStandardComplianceName[] =
"StrictCppStandardCompliance";
static constexpr bool StrictCppStandardComplianceDefault = true;

static unsigned getNumberOfDesignated(const InitListExpr *SyntacticInitList) {
return llvm::count_if(*SyntacticInitList, [](auto *InitExpr) {
return isa<DesignatedInitExpr>(InitExpr);
});
}

namespace {

struct Designators {
Expand Down Expand Up @@ -74,12 +80,6 @@ struct Designators {
}
};

unsigned getNumberOfDesignated(const InitListExpr *SyntacticInitList) {
return llvm::count_if(*SyntacticInitList, [](auto *InitExpr) {
return isa<DesignatedInitExpr>(InitExpr);
});
}

AST_MATCHER(CXXRecordDecl, isAggregate) {
return Node.hasDefinition() && Node.isAggregate();
}
Expand Down
26 changes: 14 additions & 12 deletions clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,41 +81,44 @@ AST_MATCHER(CXXMemberCallExpr, hasSameNumArgsAsDeclNumParams) {
AST_MATCHER(DeclRefExpr, hasExplicitTemplateArgs) {
return Node.hasExplicitTemplateArgs();
}
} // namespace

// Helper Matcher which applies the given QualType Matcher either directly or by
// resolving a pointer type to its pointee. Used to match v.push_back() as well
// as p->push_back().
auto hasTypeOrPointeeType(
static auto hasTypeOrPointeeType(
const ast_matchers::internal::Matcher<QualType> &TypeMatcher) {
return anyOf(hasType(TypeMatcher),
hasType(pointerType(pointee(TypeMatcher))));
}

// Matches if the node has canonical type matching any of the given names.
auto hasWantedType(llvm::ArrayRef<StringRef> TypeNames) {
static auto hasWantedType(llvm::ArrayRef<StringRef> TypeNames) {
return hasCanonicalType(hasDeclaration(cxxRecordDecl(hasAnyName(TypeNames))));
}

// Matches member call expressions of the named method on the listed container
// types.
auto cxxMemberCallExprOnContainer(StringRef MethodName,
llvm::ArrayRef<StringRef> ContainerNames) {
static auto
cxxMemberCallExprOnContainer(StringRef MethodName,
llvm::ArrayRef<StringRef> ContainerNames) {
return cxxMemberCallExpr(
hasDeclaration(functionDecl(hasName(MethodName))),
on(hasTypeOrPointeeType(hasWantedType(ContainerNames))));
}

const auto DefaultContainersWithPushBack =
static const auto DefaultContainersWithPushBack =
"::std::vector; ::std::list; ::std::deque";
const auto DefaultContainersWithPush =
static const auto DefaultContainersWithPush =
"::std::stack; ::std::queue; ::std::priority_queue";
const auto DefaultContainersWithPushFront =
static const auto DefaultContainersWithPushFront =
"::std::forward_list; ::std::list; ::std::deque";
const auto DefaultSmartPointers =
static const auto DefaultSmartPointers =
"::std::shared_ptr; ::std::unique_ptr; ::std::auto_ptr; ::std::weak_ptr";
const auto DefaultTupleTypes = "::std::pair; ::std::tuple";
const auto DefaultTupleMakeFunctions = "::std::make_pair; ::std::make_tuple";
const auto DefaultEmplacyFunctions =
static const auto DefaultTupleTypes = "::std::pair; ::std::tuple";
static const auto DefaultTupleMakeFunctions =
"::std::make_pair; ::std::make_tuple";
static const auto DefaultEmplacyFunctions =
"vector::emplace_back; vector::emplace;"
"deque::emplace; deque::emplace_front; deque::emplace_back;"
"forward_list::emplace_after; forward_list::emplace_front;"
Expand All @@ -129,7 +132,6 @@ const auto DefaultEmplacyFunctions =
"unordered_multiset::emplace; unordered_multiset::emplace_hint;"
"unordered_multimap::emplace; unordered_multimap::emplace_hint;"
"stack::emplace; queue::emplace; priority_queue::emplace";
} // namespace

UseEmplaceCheck::UseEmplaceCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context), IgnoreImplicitConstructors(Options.get(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ AST_MATCHER(Stmt, isMacroExpansion) {

AST_MATCHER(Stmt, isC23) { return Finder->getASTContext().getLangOpts().C23; }

// Preserve same name as AST_MATCHER(isNULLMacroExpansion)
// NOLINTNEXTLINE(llvm-prefer-static-over-anonymous-namespace)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

bool isNULLMacroExpansion(const Stmt *Statement, ASTContext &Context) {
SourceManager &SM = Context.getSourceManager();
const LangOptions &LO = Context.getLangOpts();
Expand Down
Loading