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