@@ -354,40 +354,6 @@ using namespace Demangle;
354354// Node member functions //
355355// ////////////////////////////////
356356
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-
391357void Node::addChild (NodePointer Child, NodeFactory &Factory) {
392358 DEMANGLER_ALWAYS_ASSERT (Child, this );
393359 switch (NodePayloadKind) {
@@ -635,6 +601,58 @@ NodePointer NodeFactory::createNode(Node::Kind K, const char *Text) {
635601int NodeFactory::nestingLevel = 0 ;
636602#endif
637603
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+
638656// ////////////////////////////////
639657// CharVector member functions //
640658// ////////////////////////////////
@@ -651,7 +669,7 @@ void CharVector::append(int Number, NodeFactory &Factory) {
651669 const int MaxIntPrintSize = 11 ;
652670 if (NumElems + MaxIntPrintSize > Capacity)
653671 Factory.Reallocate (Elems, Capacity, /* Growth*/ MaxIntPrintSize);
654- int Length = snprintf ( Elems + NumElems, MaxIntPrintSize, " %d " , Number );
672+ int Length = int2str (Number, Elems + NumElems);
655673 assert (Length > 0 && Length < MaxIntPrintSize);
656674 NumElems += Length;
657675}
@@ -660,7 +678,7 @@ void CharVector::append(unsigned long long Number, NodeFactory &Factory) {
660678 const int MaxPrintSize = 21 ;
661679 if (NumElems + MaxPrintSize > Capacity)
662680 Factory.Reallocate (Elems, Capacity, /* Growth*/ MaxPrintSize);
663- int Length = snprintf ( Elems + NumElems, MaxPrintSize, " %llu " , Number );
681+ int Length = int2str (Number, Elems + NumElems);
664682 assert (Length > 0 && Length < MaxPrintSize);
665683 NumElems += Length;
666684}
0 commit comments