LCOV - code coverage report
Current view: top level - include/llvm/Demangle - Utility.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 48 55 87.3 %
Date: 2018-10-20 13:21:21 Functions: 4 9 44.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- Utility.h ----------------------------------------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //
       9             : // This file contains several utility classes used by the demangle library.
      10             : //===----------------------------------------------------------------------===//
      11             : 
      12             : #ifndef LLVM_DEMANGLE_UTILITY_H
      13             : #define LLVM_DEMANGLE_UTILITY_H
      14             : 
      15             : #include "StringView.h"
      16             : 
      17             : #include <cstdint>
      18             : #include <cstdlib>
      19             : #include <cstring>
      20             : #include <iterator>
      21             : #include <limits>
      22             : 
      23             : // Stream that AST nodes write their string representation into after the AST
      24             : // has been parsed.
      25             : class OutputStream {
      26             :   char *Buffer;
      27             :   size_t CurrentPosition;
      28             :   size_t BufferCapacity;
      29             : 
      30             :   // Ensure there is at least n more positions in buffer.
      31       24624 :   void grow(size_t N) {
      32       24624 :     if (N + CurrentPosition >= BufferCapacity) {
      33          93 :       BufferCapacity *= 2;
      34          93 :       if (BufferCapacity < N + CurrentPosition)
      35           6 :         BufferCapacity = N + CurrentPosition;
      36          93 :       Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
      37          93 :       if (Buffer == nullptr)
      38           0 :         std::terminate();
      39             :     }
      40       24624 :   }
      41             : 
      42         345 :   void writeUnsigned(uint64_t N, bool isNeg = false) {
      43             :     // Handle special case...
      44         345 :     if (N == 0) {
      45             :       *this << '0';
      46          86 :       return;
      47             :     }
      48             : 
      49             :     char Temp[21];
      50             :     char *TempPtr = std::end(Temp);
      51             : 
      52         906 :     while (N) {
      53         647 :       *--TempPtr = '0' + char(N % 10);
      54         647 :       N /= 10;
      55             :     }
      56             : 
      57             :     // Add negative sign...
      58         259 :     if (isNeg)
      59          10 :       *--TempPtr = '-';
      60         259 :     this->operator<<(StringView(TempPtr, std::end(Temp)));
      61             :   }
      62             : 
      63             : public:
      64             :   OutputStream(char *StartBuf, size_t Size)
      65             :       : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
      66        2002 :   OutputStream() = default;
      67             :   void reset(char *Buffer_, size_t BufferCapacity_) {
      68        2367 :     CurrentPosition = 0;
      69        2367 :     Buffer = Buffer_;
      70        2290 :     BufferCapacity = BufferCapacity_;
      71             :   }
      72             : 
      73             :   /// If a ParameterPackExpansion (or similar type) is encountered, the offset
      74             :   /// into the pack that we're currently printing.
      75             :   unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
      76             :   unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
      77             : 
      78       21553 :   OutputStream &operator+=(StringView R) {
      79       21553 :     size_t Size = R.size();
      80       21553 :     if (Size == 0)
      81             :       return *this;
      82       21547 :     grow(Size);
      83       21547 :     std::memmove(Buffer + CurrentPosition, R.begin(), Size);
      84       21547 :     CurrentPosition += Size;
      85       21547 :     return *this;
      86             :   }
      87             : 
      88             :   OutputStream &operator+=(char C) {
      89        3057 :     grow(1);
      90        3000 :     Buffer[CurrentPosition++] = C;
      91             :     return *this;
      92             :   }
      93             : 
      94       15598 :   OutputStream &operator<<(StringView R) { return (*this += R); }
      95             : 
      96             :   OutputStream &operator<<(char C) { return (*this += C); }
      97             : 
      98          64 :   OutputStream &operator<<(long long N) {
      99          64 :     if (N < 0)
     100          10 :       writeUnsigned(static_cast<unsigned long long>(-N), true);
     101             :     else
     102          54 :       writeUnsigned(static_cast<unsigned long long>(N));
     103          64 :     return *this;
     104             :   }
     105             : 
     106             :   OutputStream &operator<<(unsigned long long N) {
     107         273 :     writeUnsigned(N, false);
     108             :     return *this;
     109             :   }
     110             : 
     111             :   OutputStream &operator<<(long N) {
     112          59 :     return this->operator<<(static_cast<long long>(N));
     113             :   }
     114             : 
     115             :   OutputStream &operator<<(unsigned long N) {
     116             :     return this->operator<<(static_cast<unsigned long long>(N));
     117             :   }
     118             : 
     119             :   OutputStream &operator<<(int N) {
     120           5 :     return this->operator<<(static_cast<long long>(N));
     121             :   }
     122             : 
     123             :   OutputStream &operator<<(unsigned int N) {
     124           8 :     return this->operator<<(static_cast<unsigned long long>(N));
     125             :   }
     126             : 
     127           0 :   size_t getCurrentPosition() const { return CurrentPosition; }
     128           0 :   void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
     129             : 
     130           0 :   char back() const {
     131        2231 :     return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
     132             :   }
     133             : 
     134           0 :   bool empty() const { return CurrentPosition == 0; }
     135             : 
     136           0 :   char *getBuffer() { return Buffer; }
     137             :   char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
     138             :   size_t getBufferCapacity() { return BufferCapacity; }
     139             : };
     140             : 
     141             : template <class T> class SwapAndRestore {
     142             :   T &Restore;
     143             :   T OriginalValue;
     144             :   bool ShouldRestore = true;
     145             : 
     146             : public:
     147             :   SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
     148             : 
     149           0 :   SwapAndRestore(T &Restore_, T NewVal)
     150          13 :       : Restore(Restore_), OriginalValue(Restore) {
     151         248 :     Restore = std::move(NewVal);
     152             :   }
     153             :   ~SwapAndRestore() {
     154             :     if (ShouldRestore)
     155         237 :       Restore = std::move(OriginalValue);
     156             :   }
     157             : 
     158             :   void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
     159             : 
     160             :   void restoreNow(bool Force) {
     161             :     if (!Force && !ShouldRestore)
     162             :       return;
     163             : 
     164             :     Restore = std::move(OriginalValue);
     165             :     ShouldRestore = false;
     166             :   }
     167             : 
     168             :   SwapAndRestore(const SwapAndRestore &) = delete;
     169             :   SwapAndRestore &operator=(const SwapAndRestore &) = delete;
     170             : };
     171             : 
     172             : inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
     173             :                                    size_t InitSize) {
     174             :   size_t BufferSize;
     175        1698 :   if (Buf == nullptr) {
     176        2285 :     Buf = static_cast<char *>(std::malloc(InitSize));
     177        2285 :     if (Buf == nullptr)
     178             :       return true;
     179             :     BufferSize = InitSize;
     180             :   } else
     181          82 :     BufferSize = *N;
     182             : 
     183             :   S.reset(Buf, BufferSize);
     184             :   return false;
     185             : }
     186             : 
     187             : #endif

Generated by: LCOV version 1.13