Line data Source code
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 LLVM_TABLEGEN_STRINGTOOFFSETTABLE_H
11 : #define LLVM_TABLEGEN_STRINGTOOFFSETTABLE_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 :
29 : public:
30 6 : bool Empty() const { return StringOffset.empty(); }
31 :
32 176090 : unsigned GetOrAddStringOffset(StringRef Str, bool appendZero = true) {
33 : auto IterBool =
34 176090 : StringOffset.insert(std::make_pair(Str, AggregateString.size()));
35 176090 : if (IterBool.second) {
36 : // Add the string to the aggregate if this is the first time found.
37 17375 : AggregateString.append(Str.begin(), Str.end());
38 17375 : if (appendZero)
39 : AggregateString += '\0';
40 : }
41 :
42 176090 : return IterBool.first->second;
43 : }
44 :
45 18 : void EmitString(raw_ostream &O) {
46 : // Escape the string.
47 : SmallString<256> Str;
48 18 : raw_svector_ostream(Str).write_escaped(AggregateString);
49 18 : AggregateString = Str.str();
50 :
51 18 : O << " \"";
52 : unsigned CharsPrinted = 0;
53 113132 : for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) {
54 113114 : if (CharsPrinted > 70) {
55 2072 : O << "\"\n \"";
56 : CharsPrinted = 0;
57 : }
58 226228 : O << AggregateString[i];
59 113114 : ++CharsPrinted;
60 :
61 : // Print escape sequences all together.
62 113114 : if (AggregateString[i] != '\\')
63 : continue;
64 :
65 : assert(i + 1 < AggregateString.size() && "Incomplete escape sequence!");
66 25050 : if (isdigit(AggregateString[i + 1])) {
67 : assert(isdigit(AggregateString[i + 2]) &&
68 : isdigit(AggregateString[i + 3]) &&
69 : "Expected 3 digit octal escape!");
70 : O << AggregateString[++i];
71 23054 : O << AggregateString[++i];
72 23054 : O << AggregateString[++i];
73 11527 : CharsPrinted += 3;
74 : } else {
75 : O << AggregateString[++i];
76 998 : ++CharsPrinted;
77 : }
78 : }
79 18 : O << "\"";
80 18 : }
81 :
82 : /// Emit the string using character literals. MSVC has a limitation that
83 : /// string literals cannot be longer than 64K.
84 2 : void EmitCharArray(raw_ostream &O) {
85 : assert(AggregateString.find(')') == std::string::npos &&
86 : "can't emit raw string with closing parens");
87 : int Count = 0;
88 : O << ' ';
89 131391 : for (char C : AggregateString) {
90 131389 : O << " \'";
91 131389 : O.write_escaped(StringRef(&C, 1));
92 131389 : O << "\',";
93 131389 : Count++;
94 131389 : if (Count > 14) {
95 8759 : O << "\n ";
96 : Count = 0;
97 : }
98 : }
99 : O << '\n';
100 2 : }
101 : };
102 :
103 : } // end namespace llvm
104 :
105 : #endif
|