LLVM API Documentation
00001 //===- StringToOffsetTable.h - Emit a big concatenated string ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_TABLEGEN_STRINGTOOFFSETTABLE_H 00011 #define LLVM_TABLEGEN_STRINGTOOFFSETTABLE_H 00012 00013 #include "llvm/ADT/SmallString.h" 00014 #include "llvm/ADT/StringExtras.h" 00015 #include "llvm/ADT/StringMap.h" 00016 #include "llvm/Support/raw_ostream.h" 00017 #include <cctype> 00018 00019 namespace llvm { 00020 00021 /// StringToOffsetTable - This class uniques a bunch of nul-terminated strings 00022 /// and keeps track of their offset in a massive contiguous string allocation. 00023 /// It can then output this string blob and use indexes into the string to 00024 /// reference each piece. 00025 class StringToOffsetTable { 00026 StringMap<unsigned> StringOffset; 00027 std::string AggregateString; 00028 00029 public: 00030 unsigned GetOrAddStringOffset(StringRef Str, bool appendZero = true) { 00031 StringMapEntry<unsigned> &Entry = StringOffset.GetOrCreateValue(Str, -1U); 00032 if (Entry.getValue() == -1U) { 00033 // Add the string to the aggregate if this is the first time found. 00034 Entry.setValue(AggregateString.size()); 00035 AggregateString.append(Str.begin(), Str.end()); 00036 if (appendZero) 00037 AggregateString += '\0'; 00038 } 00039 00040 return Entry.getValue(); 00041 } 00042 00043 void EmitString(raw_ostream &O) { 00044 // Escape the string. 00045 SmallString<256> Str; 00046 raw_svector_ostream(Str).write_escaped(AggregateString); 00047 AggregateString = Str.str(); 00048 00049 O << " \""; 00050 unsigned CharsPrinted = 0; 00051 for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) { 00052 if (CharsPrinted > 70) { 00053 O << "\"\n \""; 00054 CharsPrinted = 0; 00055 } 00056 O << AggregateString[i]; 00057 ++CharsPrinted; 00058 00059 // Print escape sequences all together. 00060 if (AggregateString[i] != '\\') 00061 continue; 00062 00063 assert(i+1 < AggregateString.size() && "Incomplete escape sequence!"); 00064 if (isdigit(AggregateString[i+1])) { 00065 assert(isdigit(AggregateString[i+2]) && 00066 isdigit(AggregateString[i+3]) && 00067 "Expected 3 digit octal escape!"); 00068 O << AggregateString[++i]; 00069 O << AggregateString[++i]; 00070 O << AggregateString[++i]; 00071 CharsPrinted += 3; 00072 } else { 00073 O << AggregateString[++i]; 00074 ++CharsPrinted; 00075 } 00076 } 00077 O << "\""; 00078 } 00079 }; 00080 00081 } // end namespace llvm 00082 00083 #endif