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/StringMap.h" 15 #include "llvm/ADT/StringExtras.h" 16 #include "llvm/Support/raw_ostream.h" 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 public: 28 GetOrAddStringOffset(StringRef Str)29 unsigned GetOrAddStringOffset(StringRef Str) { 30 unsigned &Entry = StringOffset[Str]; 31 if (Entry == 0) { 32 // Add the string to the aggregate if this is the first time found. 33 Entry = AggregateString.size(); 34 AggregateString.append(Str.begin(), Str.end()); 35 AggregateString += '\0'; 36 } 37 38 return Entry; 39 } 40 EmitString(raw_ostream & O)41 void EmitString(raw_ostream &O) { 42 // Escape the string. 43 SmallString<256> Str; 44 raw_svector_ostream(Str).write_escaped(AggregateString); 45 AggregateString = Str.str(); 46 47 O << " \""; 48 unsigned CharsPrinted = 0; 49 for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) { 50 if (CharsPrinted > 70) { 51 O << "\"\n \""; 52 CharsPrinted = 0; 53 } 54 O << AggregateString[i]; 55 ++CharsPrinted; 56 57 // Print escape sequences all together. 58 if (AggregateString[i] != '\\') 59 continue; 60 61 assert(i+1 < AggregateString.size() && "Incomplete escape sequence!"); 62 if (isdigit(AggregateString[i+1])) { 63 assert(isdigit(AggregateString[i+2]) && 64 isdigit(AggregateString[i+3]) && 65 "Expected 3 digit octal escape!"); 66 O << AggregateString[++i]; 67 O << AggregateString[++i]; 68 O << AggregateString[++i]; 69 CharsPrinted += 3; 70 } else { 71 O << AggregateString[++i]; 72 ++CharsPrinted; 73 } 74 } 75 O << "\""; 76 } 77 }; 78 79 } // end namespace llvm 80 81 #endif 82