@@ -307,10 +307,7 @@ bool CallEvent::isCalled(const CallDescription &CD) const {
307
307
if (getKind () == CE_ObjCMessage)
308
308
return false ;
309
309
310
- const IdentifierInfo *II = getCalleeIdentifier ();
311
- if (!II)
312
- return false ;
313
- const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(getDecl ());
310
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(getDecl ());
314
311
if (!FD)
315
312
return false ;
316
313
@@ -320,44 +317,69 @@ bool CallEvent::isCalled(const CallDescription &CD) const {
320
317
(!CD.RequiredParams || CD.RequiredParams <= parameters ().size ());
321
318
}
322
319
323
- if (!CD.IsLookupDone ) {
324
- CD.IsLookupDone = true ;
320
+ if (!CD.II .hasValue ()) {
325
321
CD.II = &getState ()->getStateManager ().getContext ().Idents .get (
326
322
CD.getFunctionName ());
327
323
}
328
324
329
- if (II != CD.II )
330
- return false ;
325
+ const auto MatchNameOnly = [](const CallDescription &CD,
326
+ const NamedDecl *ND) -> bool {
327
+ DeclarationName Name = ND->getDeclName ();
328
+ if (const auto *II = Name.getAsIdentifierInfo ())
329
+ return II == CD.II .getValue (); // Fast case.
331
330
332
- // If CallDescription provides prefix names, use them to improve matching
333
- // accuracy.
334
- if (CD.QualifiedName .size () > 1 && FD) {
335
- const DeclContext *Ctx = FD->getDeclContext ();
336
- // See if we'll be able to match them all.
337
- size_t NumUnmatched = CD.QualifiedName .size () - 1 ;
338
- for (; Ctx && isa<NamedDecl>(Ctx); Ctx = Ctx->getParent ()) {
339
- if (NumUnmatched == 0 )
340
- break ;
331
+ // Simply report mismatch for:
332
+ // C++ overloaded operators, constructors, destructors, etc.
333
+ return false ;
334
+ };
341
335
342
- if (const auto *ND = dyn_cast<NamespaceDecl>(Ctx)) {
343
- if (ND->getName () == CD.QualifiedName [NumUnmatched - 1 ])
344
- --NumUnmatched;
345
- continue ;
346
- }
336
+ const auto ExactMatchArgAndParamCounts =
337
+ [](const CallEvent &Call, const CallDescription &CD) -> bool {
338
+ const bool ArgsMatch =
339
+ !CD.RequiredArgs || CD.RequiredArgs == Call.getNumArgs ();
340
+ const bool ParamsMatch =
341
+ !CD.RequiredParams || CD.RequiredParams == Call.parameters ().size ();
342
+ return ArgsMatch && ParamsMatch;
343
+ };
347
344
348
- if (const auto *RD = dyn_cast<RecordDecl>(Ctx)) {
349
- if (RD->getName () == CD.QualifiedName [NumUnmatched - 1 ])
350
- --NumUnmatched;
345
+ const auto MatchQualifiedNameParts = [](const CallDescription &CD,
346
+ const Decl *D) -> bool {
347
+ const auto FindNextNamespaceOrRecord =
348
+ [](const DeclContext *Ctx) -> const DeclContext * {
349
+ while (Ctx && !isa<NamespaceDecl, RecordDecl>(Ctx))
350
+ Ctx = Ctx->getParent ();
351
+ return Ctx;
352
+ };
353
+
354
+ auto QualifierPartsIt = CD.begin_qualified_name_parts ();
355
+ const auto QualifierPartsEndIt = CD.end_qualified_name_parts ();
356
+
357
+ // Match namespace and record names. Skip unrelated names if they don't
358
+ // match.
359
+ const DeclContext *Ctx = FindNextNamespaceOrRecord (D->getDeclContext ());
360
+ for (; Ctx && QualifierPartsIt != QualifierPartsEndIt;
361
+ Ctx = FindNextNamespaceOrRecord (Ctx->getParent ())) {
362
+ // If not matched just continue and try matching for the next one.
363
+ if (cast<NamedDecl>(Ctx)->getName () != *QualifierPartsIt)
351
364
continue ;
352
- }
365
+ ++QualifierPartsIt;
353
366
}
354
367
355
- if (NumUnmatched > 0 )
356
- return false ;
357
- }
368
+ // We matched if we consumed all expected qualifier segments.
369
+ return QualifierPartsIt == QualifierPartsEndIt;
370
+ };
371
+
372
+ // Let's start matching...
373
+ if (!ExactMatchArgAndParamCounts (*this , CD))
374
+ return false ;
375
+
376
+ if (!MatchNameOnly (CD, FD))
377
+ return false ;
378
+
379
+ if (!CD.hasQualifiedNameParts ())
380
+ return true ;
358
381
359
- return (!CD.RequiredArgs || CD.RequiredArgs == getNumArgs ()) &&
360
- (!CD.RequiredParams || CD.RequiredParams == parameters ().size ());
382
+ return MatchQualifiedNameParts (CD, FD);
361
383
}
362
384
363
385
SVal CallEvent::getArgSVal (unsigned Index) const {
0 commit comments