39
39
#include < vector>
40
40
#include < list>
41
41
#include < new>
42
+ #include < cstring>
42
43
43
44
using namespace swift ;
44
45
using namespace Demangle ;
@@ -472,6 +473,16 @@ static bool sameObjCTypeManglings(Demangle::NodePointer node1,
472
473
}
473
474
#endif
474
475
476
+ // / Optimization for the case where we need to compare a StringRef and a null terminated C string
477
+ // / Not converting s2 to a StringRef avoids the need to call both strlen and memcmp when non-matching
478
+ // / but equal length
479
+ static bool stringRefEqualsCString (StringRef s1, const char *s2) {
480
+ size_t length = s1.size ();
481
+ // It may be possible for s1 to contain embedded NULL characters
482
+ // so additionally validate that the lengths match
483
+ return strncmp (s1.data (), s2, length) == 0 && strlen (s2) == length;
484
+ }
485
+
475
486
bool
476
487
swift::_contextDescriptorMatchesMangling (const ContextDescriptor *context,
477
488
Demangle::NodePointer node) {
@@ -496,7 +507,7 @@ swift::_contextDescriptorMatchesMangling(const ContextDescriptor *context,
496
507
// Match to a mangled module name.
497
508
if (node->getKind () != Demangle::Node::Kind::Module)
498
509
return false ;
499
- if (!node->getText (). equals ( module ->Name .get ()))
510
+ if (!stringRefEqualsCString ( node->getText (), module ->Name .get ()))
500
511
return false ;
501
512
502
513
node = nullptr ;
@@ -568,7 +579,7 @@ swift::_contextDescriptorMatchesMangling(const ContextDescriptor *context,
568
579
auto nameNode = node->getChild (1 );
569
580
if (nameNode->getKind () != Demangle::Node::Kind::Identifier)
570
581
return false ;
571
- if (nameNode->getText () == proto->Name .get ()) {
582
+ if (stringRefEqualsCString ( nameNode->getText (), proto->Name .get () )) {
572
583
node = node->getChild (0 );
573
584
break ;
574
585
}
0 commit comments