- //===- StringToOffsetTable.h - Emit a big concatenated string ---*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_TABLEGEN_STRINGTOOFFSETTABLE_H 
- #define LLVM_TABLEGEN_STRINGTOOFFSETTABLE_H 
-   
- #include "llvm/ADT/SmallString.h" 
- #include "llvm/ADT/StringExtras.h" 
- #include "llvm/ADT/StringMap.h" 
- #include "llvm/Support/raw_ostream.h" 
- #include <cctype> 
-   
- namespace llvm { 
-   
- /// StringToOffsetTable - This class uniques a bunch of nul-terminated strings 
- /// and keeps track of their offset in a massive contiguous string allocation. 
- /// It can then output this string blob and use indexes into the string to 
- /// reference each piece. 
- class StringToOffsetTable { 
-   StringMap<unsigned> StringOffset; 
-   std::string AggregateString; 
-   
- public: 
-   bool Empty() const { return StringOffset.empty(); } 
-   
-   unsigned GetOrAddStringOffset(StringRef Str, bool appendZero = true) { 
-     auto IterBool = 
-         StringOffset.insert(std::make_pair(Str, AggregateString.size())); 
-     if (IterBool.second) { 
-       // Add the string to the aggregate if this is the first time found. 
-       AggregateString.append(Str.begin(), Str.end()); 
-       if (appendZero) 
-         AggregateString += '\0'; 
-     } 
-   
-     return IterBool.first->second; 
-   } 
-   
-   void EmitString(raw_ostream &O) { 
-     // Escape the string. 
-     SmallString<256> Str; 
-     raw_svector_ostream(Str).write_escaped(AggregateString); 
-     AggregateString = std::string(Str.str()); 
-   
-     O << "    \""; 
-     unsigned CharsPrinted = 0; 
-     for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) { 
-       if (CharsPrinted > 70) { 
-         O << "\"\n    \""; 
-         CharsPrinted = 0; 
-       } 
-       O << AggregateString[i]; 
-       ++CharsPrinted; 
-   
-       // Print escape sequences all together. 
-       if (AggregateString[i] != '\\') 
-         continue; 
-   
-       assert(i + 1 < AggregateString.size() && "Incomplete escape sequence!"); 
-       if (isdigit(AggregateString[i + 1])) { 
-         assert(isdigit(AggregateString[i + 2]) && 
-                isdigit(AggregateString[i + 3]) && 
-                "Expected 3 digit octal escape!"); 
-         O << AggregateString[++i]; 
-         O << AggregateString[++i]; 
-         O << AggregateString[++i]; 
-         CharsPrinted += 3; 
-       } else { 
-         O << AggregateString[++i]; 
-         ++CharsPrinted; 
-       } 
-     } 
-     O << "\""; 
-   } 
-   
-   /// Emit the string using character literals. MSVC has a limitation that 
-   /// string literals cannot be longer than 64K. 
-   void EmitCharArray(raw_ostream &O) { 
-     assert(AggregateString.find(')') == std::string::npos && 
-            "can't emit raw string with closing parens"); 
-     int Count = 0; 
-     O << ' '; 
-     for (char C : AggregateString) { 
-       O << " \'"; 
-       O.write_escaped(StringRef(&C, 1)); 
-       O << "\',"; 
-       Count++; 
-       if (Count > 14) { 
-         O << "\n "; 
-         Count = 0; 
-       } 
-     } 
-     O << '\n'; 
-   } 
- }; 
-   
- } // end namespace llvm 
-   
- #endif 
-