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