1 //===--- UseRangesCheck.h - clang-tidy --------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_USERANGESCHECK_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_USERANGESCHECK_H
12 #include "../ClangTidyCheck.h"
13 #include "IncludeInserter.h"
14 #include "clang/AST/Decl.h"
15 #include "clang/AST/Expr.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "llvm/ADT/IntrusiveRefCntPtr.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/ADT/StringRef.h"
22 namespace clang::tidy::utils
{
24 /// Base class for handling converting std iterator algorithms to a range
26 class UseRangesCheck
: public ClangTidyCheck
{
29 enum Replace
{ First
, Second
};
31 unsigned EndArg
= BeginArg
+ 1;
32 Replace ReplaceArg
= First
;
35 using Signature
= SmallVector
<Indexes
, 2>;
37 struct ReverseIteratorDescriptor
{
38 StringRef ReverseAdaptorName
;
39 std::optional
<StringRef
> ReverseHeader
;
40 ArrayRef
<std::pair
<StringRef
, StringRef
>> FreeReverseNames
;
41 bool IsPipeSyntax
= false;
44 class Replacer
: public llvm::RefCountedBase
<Replacer
> {
46 /// Gets the name to replace a function with, return std::nullopt for a
47 /// replacement where we just call a different overload.
48 virtual std::optional
<std::string
>
49 getReplaceName(const NamedDecl
&OriginalName
) const = 0;
51 /// Gets the header needed to access the replaced function
52 /// Return std::nullopt if no new header is needed.
53 virtual std::optional
<std::string
>
54 getHeaderInclusion(const NamedDecl
&OriginalName
) const;
56 /// Gets an array of all the possible overloads for a function with indexes
57 /// where begin and end arguments are.
58 virtual ArrayRef
<Signature
> getReplacementSignatures() const = 0;
59 virtual ~Replacer() = default;
62 using ReplacerMap
= llvm::StringMap
<llvm::IntrusiveRefCntPtr
<Replacer
>>;
64 UseRangesCheck(StringRef Name
, ClangTidyContext
*Context
);
65 /// Gets a map of function to replace and methods to create the replacements
66 virtual ReplacerMap
getReplacerMap() const = 0;
67 /// Create a diagnostic for the CallExpr
68 /// Override this to support custom diagnostic messages
69 virtual DiagnosticBuilder
createDiag(const CallExpr
&Call
);
71 virtual std::optional
<ReverseIteratorDescriptor
> getReverseDescriptor() const;
73 /// Gets the fully qualified names of begin and end functions.
74 /// The functions must take the container as their one and only argument
75 /// `::std::begin` and `::std::end` are a common example
76 virtual ArrayRef
<std::pair
<StringRef
, StringRef
>>
77 getFreeBeginEndMethods() const;
79 void registerPPCallbacks(const SourceManager
&SM
, Preprocessor
*PP
,
80 Preprocessor
*ModuleExpanderPP
) final
;
81 void registerMatchers(ast_matchers::MatchFinder
*Finder
) final
;
82 void check(const ast_matchers::MatchFinder::MatchResult
&Result
) final
;
83 bool isLanguageVersionSupported(const LangOptions
&LangOpts
) const override
;
84 void storeOptions(ClangTidyOptions::OptionMap
&Options
) override
;
85 std::optional
<TraversalKind
> getCheckTraversalKind() const override
;
88 std::vector
<llvm::IntrusiveRefCntPtr
<Replacer
>> Replacers
;
89 std::optional
<ReverseIteratorDescriptor
> ReverseDescriptor
;
90 IncludeInserter Inserter
;
93 } // namespace clang::tidy::utils
95 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_USERANGESCHECK_H