Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- StringToOffsetTable.h - Emit a big concatenated string ---*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef LLVM_TABLEGEN_STRINGTOOFFSETTABLE_H
  10. #define LLVM_TABLEGEN_STRINGTOOFFSETTABLE_H
  11.  
  12. #include "llvm/ADT/SmallString.h"
  13. #include "llvm/ADT/StringExtras.h"
  14. #include "llvm/ADT/StringMap.h"
  15. #include "llvm/Support/raw_ostream.h"
  16. #include <cctype>
  17.  
  18. namespace llvm {
  19.  
  20. /// StringToOffsetTable - This class uniques a bunch of nul-terminated strings
  21. /// and keeps track of their offset in a massive contiguous string allocation.
  22. /// It can then output this string blob and use indexes into the string to
  23. /// reference each piece.
  24. class StringToOffsetTable {
  25.   StringMap<unsigned> StringOffset;
  26.   std::string AggregateString;
  27.  
  28. public:
  29.   bool Empty() const { return StringOffset.empty(); }
  30.  
  31.   unsigned GetOrAddStringOffset(StringRef Str, bool appendZero = true) {
  32.     auto IterBool =
  33.         StringOffset.insert(std::make_pair(Str, AggregateString.size()));
  34.     if (IterBool.second) {
  35.       // Add the string to the aggregate if this is the first time found.
  36.       AggregateString.append(Str.begin(), Str.end());
  37.       if (appendZero)
  38.         AggregateString += '\0';
  39.     }
  40.  
  41.     return IterBool.first->second;
  42.   }
  43.  
  44.   void EmitString(raw_ostream &O) {
  45.     // Escape the string.
  46.     SmallString<256> Str;
  47.     raw_svector_ostream(Str).write_escaped(AggregateString);
  48.     AggregateString = std::string(Str.str());
  49.  
  50.     O << "    \"";
  51.     unsigned CharsPrinted = 0;
  52.     for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) {
  53.       if (CharsPrinted > 70) {
  54.         O << "\"\n    \"";
  55.         CharsPrinted = 0;
  56.       }
  57.       O << AggregateString[i];
  58.       ++CharsPrinted;
  59.  
  60.       // Print escape sequences all together.
  61.       if (AggregateString[i] != '\\')
  62.         continue;
  63.  
  64.       assert(i + 1 < AggregateString.size() && "Incomplete escape sequence!");
  65.       if (isdigit(AggregateString[i + 1])) {
  66.         assert(isdigit(AggregateString[i + 2]) &&
  67.                isdigit(AggregateString[i + 3]) &&
  68.                "Expected 3 digit octal escape!");
  69.         O << AggregateString[++i];
  70.         O << AggregateString[++i];
  71.         O << AggregateString[++i];
  72.         CharsPrinted += 3;
  73.       } else {
  74.         O << AggregateString[++i];
  75.         ++CharsPrinted;
  76.       }
  77.     }
  78.     O << "\"";
  79.   }
  80.  
  81.   /// Emit the string using character literals. MSVC has a limitation that
  82.   /// string literals cannot be longer than 64K.
  83.   void EmitCharArray(raw_ostream &O) {
  84.     assert(AggregateString.find(')') == std::string::npos &&
  85.            "can't emit raw string with closing parens");
  86.     int Count = 0;
  87.     O << ' ';
  88.     for (char C : AggregateString) {
  89.       O << " \'";
  90.       O.write_escaped(StringRef(&C, 1));
  91.       O << "\',";
  92.       Count++;
  93.       if (Count > 14) {
  94.         O << "\n ";
  95.         Count = 0;
  96.       }
  97.     }
  98.     O << '\n';
  99.   }
  100. };
  101.  
  102. } // end namespace llvm
  103.  
  104. #endif
  105.