123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|