StringToOffsetTable.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //===- StringToOffsetTable.h - Emit a big concatenated string ---*- 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. #ifndef LLVM_TABLEGEN_STRINGTOOFFSETTABLE_H
  10. #define LLVM_TABLEGEN_STRINGTOOFFSETTABLE_H
  11. #include "llvm/ADT/SmallString.h"
  12. #include "llvm/ADT/StringExtras.h"
  13. #include "llvm/ADT/StringMap.h"
  14. #include "llvm/Support/raw_ostream.h"
  15. #include <cctype>
  16. namespace llvm {
  17. /// StringToOffsetTable - This class uniques a bunch of nul-terminated strings
  18. /// and keeps track of their offset in a massive contiguous string allocation.
  19. /// It can then output this string blob and use indexes into the string to
  20. /// reference each piece.
  21. class StringToOffsetTable {
  22. StringMap<unsigned> StringOffset;
  23. std::string AggregateString;
  24. public:
  25. unsigned GetOrAddStringOffset(StringRef Str, bool appendZero = true) {
  26. auto IterBool =
  27. StringOffset.insert(std::make_pair(Str, AggregateString.size()));
  28. if (IterBool.second) {
  29. // Add the string to the aggregate if this is the first time found.
  30. AggregateString.append(Str.begin(), Str.end());
  31. if (appendZero)
  32. AggregateString += '\0';
  33. }
  34. return IterBool.first->second;
  35. }
  36. void EmitString(raw_ostream &O) {
  37. // Escape the string.
  38. SmallString<256> Str;
  39. raw_svector_ostream(Str).write_escaped(AggregateString);
  40. AggregateString = Str.str();
  41. O << " \"";
  42. unsigned CharsPrinted = 0;
  43. for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) {
  44. if (CharsPrinted > 70) {
  45. O << "\"\n \"";
  46. CharsPrinted = 0;
  47. }
  48. O << AggregateString[i];
  49. ++CharsPrinted;
  50. // Print escape sequences all together.
  51. if (AggregateString[i] != '\\')
  52. continue;
  53. assert(i+1 < AggregateString.size() && "Incomplete escape sequence!");
  54. if (isdigit(AggregateString[i+1])) {
  55. assert(isdigit(AggregateString[i+2]) &&
  56. isdigit(AggregateString[i+3]) &&
  57. "Expected 3 digit octal escape!");
  58. O << AggregateString[++i];
  59. O << AggregateString[++i];
  60. O << AggregateString[++i];
  61. CharsPrinted += 3;
  62. } else {
  63. O << AggregateString[++i];
  64. ++CharsPrinted;
  65. }
  66. }
  67. O << "\"";
  68. }
  69. };
  70. } // end namespace llvm
  71. #endif