@@ -354,40 +354,6 @@ using namespace Demangle;
354
354
// Node member functions //
355
355
// ////////////////////////////////
356
356
357
- size_t Node::getNumChildren () const {
358
- switch (NodePayloadKind) {
359
- case PayloadKind::OneChild: return 1 ;
360
- case PayloadKind::TwoChildren: return 2 ;
361
- case PayloadKind::ManyChildren: return Children.Number ;
362
- default : return 0 ;
363
- }
364
- }
365
-
366
- Node::iterator Node::begin () const {
367
- switch (NodePayloadKind) {
368
- case PayloadKind::OneChild:
369
- case PayloadKind::TwoChildren:
370
- return &InlineChildren[0 ];
371
- case PayloadKind::ManyChildren:
372
- return Children.Nodes ;
373
- default :
374
- return nullptr ;
375
- }
376
- }
377
-
378
- Node::iterator Node::end () const {
379
- switch (NodePayloadKind) {
380
- case PayloadKind::OneChild:
381
- return &InlineChildren[1 ];
382
- case PayloadKind::TwoChildren:
383
- return &InlineChildren[2 ];
384
- case PayloadKind::ManyChildren:
385
- return Children.Nodes + Children.Number ;
386
- default :
387
- return nullptr ;
388
- }
389
- }
390
-
391
357
void Node::addChild (NodePointer Child, NodeFactory &Factory) {
392
358
DEMANGLER_ALWAYS_ASSERT (Child, this );
393
359
switch (NodePayloadKind) {
@@ -635,6 +601,58 @@ NodePointer NodeFactory::createNode(Node::Kind K, const char *Text) {
635
601
int NodeFactory::nestingLevel = 0 ;
636
602
#endif
637
603
604
+ // Fast integer formatting
605
+ namespace {
606
+
607
+ // Format an unsigned integer into a buffer
608
+ template <typename U,
609
+ typename std::enable_if<std::is_unsigned<U>::value, bool >::type = true >
610
+ size_t int2str (U n, char *buf) {
611
+ // The easy case is zero
612
+ if (n == 0 ) {
613
+ *buf++ = ' 0' ;
614
+ *buf++ = ' \0 ' ;
615
+ return 1 ;
616
+ }
617
+
618
+ // Do the digits one a time (for really high speed we could do these in
619
+ // chunks, but that's probably not necessary here.)
620
+ char *ptr = buf;
621
+ while (n) {
622
+ char digit = ' 0' + (n % 10 );
623
+ n /= 10 ;
624
+ *ptr++ = digit;
625
+ }
626
+ size_t len = ptr - buf;
627
+
628
+ // Terminate the string
629
+ *ptr = ' \0 ' ;
630
+
631
+ // Now reverse the digits
632
+ while (buf < ptr) {
633
+ char tmp = *--ptr;
634
+ *ptr = *buf;
635
+ *buf++ = tmp;
636
+ }
637
+
638
+ return len;
639
+ }
640
+
641
+ // Deal with negative numbers
642
+ template <typename S,
643
+ typename std::enable_if<std::is_signed<S>::value, bool >::type = true >
644
+ size_t int2str (S n, char *buf) {
645
+ using U = typename std::make_unsigned<S>::type;
646
+
647
+ if (n < 0 ) {
648
+ *buf++ = ' -' ;
649
+ return int2str (static_cast <U>(-n), buf);
650
+ }
651
+ return int2str (static_cast <U>(n), buf);
652
+ }
653
+
654
+ } // namespace
655
+
638
656
// ////////////////////////////////
639
657
// CharVector member functions //
640
658
// ////////////////////////////////
@@ -651,7 +669,7 @@ void CharVector::append(int Number, NodeFactory &Factory) {
651
669
const int MaxIntPrintSize = 11 ;
652
670
if (NumElems + MaxIntPrintSize > Capacity)
653
671
Factory.Reallocate (Elems, Capacity, /* Growth*/ MaxIntPrintSize);
654
- int Length = snprintf ( Elems + NumElems, MaxIntPrintSize, " %d " , Number );
672
+ int Length = int2str (Number, Elems + NumElems);
655
673
assert (Length > 0 && Length < MaxIntPrintSize);
656
674
NumElems += Length;
657
675
}
@@ -660,7 +678,7 @@ void CharVector::append(unsigned long long Number, NodeFactory &Factory) {
660
678
const int MaxPrintSize = 21 ;
661
679
if (NumElems + MaxPrintSize > Capacity)
662
680
Factory.Reallocate (Elems, Capacity, /* Growth*/ MaxPrintSize);
663
- int Length = snprintf ( Elems + NumElems, MaxPrintSize, " %llu " , Number );
681
+ int Length = int2str (Number, Elems + NumElems);
664
682
assert (Length > 0 && Length < MaxPrintSize);
665
683
NumElems += Length;
666
684
}
0 commit comments