@@ -39,12 +39,6 @@ static constexpr const char ArgName[] = "ArgName";
39
39
40
40
namespace clang ::tidy::utils {
41
41
42
- static bool operator ==(const UseRangesCheck::Indexes &L,
43
- const UseRangesCheck::Indexes &R) {
44
- return std::tie (L.BeginArg , L.EndArg , L.ReplaceArg ) ==
45
- std::tie (R.BeginArg , R.EndArg , R.ReplaceArg );
46
- }
47
-
48
42
static std::string getFullPrefix (ArrayRef<UseRangesCheck::Indexes> Signature) {
49
43
std::string Output;
50
44
llvm::raw_string_ostream OS (Output);
@@ -54,15 +48,6 @@ static std::string getFullPrefix(ArrayRef<UseRangesCheck::Indexes> Signature) {
54
48
return Output;
55
49
}
56
50
57
- static llvm::hash_code hash_value (const UseRangesCheck::Indexes &Indexes) {
58
- return llvm::hash_combine (Indexes.BeginArg , Indexes.EndArg ,
59
- Indexes.ReplaceArg );
60
- }
61
-
62
- static llvm::hash_code hash_value (const UseRangesCheck::Signature &Sig) {
63
- return llvm::hash_combine_range (Sig.begin (), Sig.end ());
64
- }
65
-
66
51
namespace {
67
52
68
53
AST_MATCHER (Expr, hasSideEffects) {
@@ -123,32 +108,34 @@ makeMatcherPair(StringRef State, const UseRangesCheck::Indexes &Indexes,
123
108
}
124
109
125
110
void UseRangesCheck::registerMatchers (MatchFinder *Finder) {
126
- Replaces = getReplacerMap ();
111
+ auto Replaces = getReplacerMap ();
127
112
ReverseDescriptor = getReverseDescriptor ();
128
113
auto BeginEndNames = getFreeBeginEndMethods ();
129
114
llvm::SmallVector<StringRef, 4 > BeginNames{
130
115
llvm::make_first_range (BeginEndNames)};
131
116
llvm::SmallVector<StringRef, 4 > EndNames{
132
117
llvm::make_second_range (BeginEndNames)};
133
- llvm::DenseSet<ArrayRef<Signature>> Seen;
118
+ Replacers.clear ();
119
+ llvm::DenseSet<Replacer *> SeenRepl;
134
120
for (auto I = Replaces.begin (), E = Replaces.end (); I != E; ++I) {
135
- const ArrayRef<Signature> &Signatures =
136
- I->getValue ()->getReplacementSignatures ();
137
- if (!Seen.insert (Signatures).second )
121
+ auto Replacer = I->getValue ();
122
+ if (!SeenRepl.insert (Replacer.get ()).second )
138
123
continue ;
139
- assert (!Signatures.empty () &&
140
- llvm::all_of (Signatures, [](auto Index) { return !Index.empty (); }));
124
+ Replacers.push_back (Replacer);
125
+ assert (!Replacer->getReplacementSignatures ().empty () &&
126
+ llvm::all_of (Replacer->getReplacementSignatures (),
127
+ [](auto Index) { return !Index.empty (); }));
141
128
std::vector<StringRef> Names (1 , I->getKey ());
142
129
for (auto J = std::next (I); J != E; ++J)
143
- if (J->getValue ()-> getReplacementSignatures () == Signatures )
130
+ if (J->getValue () == Replacer )
144
131
Names.push_back (J->getKey ());
145
132
146
133
std::vector<ast_matchers::internal::DynTypedMatcher> TotalMatchers;
147
134
// As we match on the first matched signature, we need to sort the
148
135
// signatures in order of length(longest to shortest). This way any
149
136
// signature that is a subset of another signature will be matched after the
150
137
// other.
151
- SmallVector<Signature> SigVec (Signatures );
138
+ SmallVector<Signature> SigVec (Replacer-> getReplacementSignatures () );
152
139
llvm::sort (SigVec, [](auto &L, auto &R) { return R.size () < L.size (); });
153
140
for (const auto &Signature : SigVec) {
154
141
std::vector<ast_matchers::internal::DynTypedMatcher> Matchers;
@@ -163,7 +150,8 @@ void UseRangesCheck::registerMatchers(MatchFinder *Finder) {
163
150
}
164
151
Finder->addMatcher (
165
152
callExpr (
166
- callee (functionDecl (hasAnyName (std::move (Names))).bind (FuncDecl)),
153
+ callee (functionDecl (hasAnyName (std::move (Names)))
154
+ .bind ((FuncDecl + Twine (Replacers.size () - 1 ).str ()))),
167
155
ast_matchers::internal::DynTypedMatcher::constructVariadic (
168
156
ast_matchers::internal::DynTypedMatcher::VO_AnyOf,
169
157
ASTNodeKind::getFromNodeKind<CallExpr>(),
@@ -205,21 +193,33 @@ static void removeFunctionArgs(DiagnosticBuilder &Diag, const CallExpr &Call,
205
193
}
206
194
207
195
void UseRangesCheck::check (const MatchFinder::MatchResult &Result) {
208
- const auto *Function = Result.Nodes .getNodeAs <FunctionDecl>(FuncDecl);
209
- std::string Qualified = " ::" + Function->getQualifiedNameAsString ();
210
- auto Iter = Replaces.find (Qualified);
211
- assert (Iter != Replaces.end ());
196
+ Replacer *Replacer = nullptr ;
197
+ const FunctionDecl *Function = nullptr ;
198
+ for (auto [Node, Value] : Result.Nodes .getMap ()) {
199
+ StringRef NodeStr (Node);
200
+ if (!NodeStr.consume_front (FuncDecl))
201
+ continue ;
202
+ Function = Value.get <FunctionDecl>();
203
+ size_t Index;
204
+ if (NodeStr.getAsInteger (10 , Index)) {
205
+ llvm_unreachable (" Unable to extract replacer index" );
206
+ }
207
+ assert (Index < Replacers.size ());
208
+ Replacer = Replacers[Index].get ();
209
+ break ;
210
+ }
211
+ assert (Replacer && Function);
212
212
SmallString<64 > Buffer;
213
- for (const Signature &Sig : Iter-> getValue () ->getReplacementSignatures ()) {
213
+ for (const Signature &Sig : Replacer ->getReplacementSignatures ()) {
214
214
Buffer.assign ({BoundCall, getFullPrefix (Sig)});
215
215
const auto *Call = Result.Nodes .getNodeAs <CallExpr>(Buffer);
216
216
if (!Call)
217
217
continue ;
218
218
auto Diag = createDiag (*Call);
219
- if (auto ReplaceName = Iter-> getValue () ->getReplaceName (*Function))
219
+ if (auto ReplaceName = Replacer ->getReplaceName (*Function))
220
220
Diag << FixItHint::CreateReplacement (Call->getCallee ()->getSourceRange (),
221
221
*ReplaceName);
222
- if (auto Include = Iter-> getValue () ->getHeaderInclusion (*Function))
222
+ if (auto Include = Replacer ->getHeaderInclusion (*Function))
223
223
Diag << Inserter.createIncludeInsertion (
224
224
Result.SourceManager ->getFileID (Call->getBeginLoc ()), *Include);
225
225
llvm::SmallVector<unsigned , 3 > ToRemove;
0 commit comments