144da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner//===- StringToOffsetTable.h - Emit a big concatenated string ---*- C++ -*-===//
244da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner//
344da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner//                     The LLVM Compiler Infrastructure
444da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner//
544da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner// This file is distributed under the University of Illinois Open Source
644da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner// License. See LICENSE.TXT for details.
744da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner//
844da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner//===----------------------------------------------------------------------===//
944da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner
1044da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner#ifndef TBLGEN_STRING_TO_OFFSET_TABLE_H
1144da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner#define TBLGEN_STRING_TO_OFFSET_TABLE_H
1244da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner
133446cf142eb3113679cbc11c3f63b133423d4c8bDaniel Dunbar#include "llvm/ADT/SmallString.h"
1444da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner#include "llvm/ADT/StringExtras.h"
154ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/ADT/StringMap.h"
163446cf142eb3113679cbc11c3f63b133423d4c8bDaniel Dunbar#include "llvm/Support/raw_ostream.h"
1778cab947cf8f81fc3cadbedd90c20fbe6e5eb1eeJoerg Sonnenberger#include <cctype>
1844da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner
1944da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattnernamespace llvm {
2044da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner
2144da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner/// StringToOffsetTable - This class uniques a bunch of nul-terminated strings
2244da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner/// and keeps track of their offset in a massive contiguous string allocation.
2344da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner/// It can then output this string blob and use indexes into the string to
2444da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner/// reference each piece.
2544da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattnerclass StringToOffsetTable {
2644da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner  StringMap<unsigned> StringOffset;
2744da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner  std::string AggregateString;
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2944da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattnerpublic:
3002ee75393fc38a35e900e078b58f069735da153aBenjamin Kramer  unsigned GetOrAddStringOffset(StringRef Str, bool appendZero = true) {
3102ee75393fc38a35e900e078b58f069735da153aBenjamin Kramer    StringMapEntry<unsigned> &Entry = StringOffset.GetOrCreateValue(Str, -1U);
3202ee75393fc38a35e900e078b58f069735da153aBenjamin Kramer    if (Entry.getValue() == -1U) {
3344da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      // Add the string to the aggregate if this is the first time found.
3402ee75393fc38a35e900e078b58f069735da153aBenjamin Kramer      Entry.setValue(AggregateString.size());
3544da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      AggregateString.append(Str.begin(), Str.end());
3602ee75393fc38a35e900e078b58f069735da153aBenjamin Kramer      if (appendZero)
3702ee75393fc38a35e900e078b58f069735da153aBenjamin Kramer        AggregateString += '\0';
3844da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner    }
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4002ee75393fc38a35e900e078b58f069735da153aBenjamin Kramer    return Entry.getValue();
4144da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner  }
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4344da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner  void EmitString(raw_ostream &O) {
443446cf142eb3113679cbc11c3f63b133423d4c8bDaniel Dunbar    // Escape the string.
453446cf142eb3113679cbc11c3f63b133423d4c8bDaniel Dunbar    SmallString<256> Str;
463446cf142eb3113679cbc11c3f63b133423d4c8bDaniel Dunbar    raw_svector_ostream(Str).write_escaped(AggregateString);
473446cf142eb3113679cbc11c3f63b133423d4c8bDaniel Dunbar    AggregateString = Str.str();
483446cf142eb3113679cbc11c3f63b133423d4c8bDaniel Dunbar
4944da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner    O << "    \"";
5044da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner    unsigned CharsPrinted = 0;
5144da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner    for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) {
5244da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      if (CharsPrinted > 70) {
5344da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        O << "\"\n    \"";
5444da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        CharsPrinted = 0;
5544da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      }
5644da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      O << AggregateString[i];
5744da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      ++CharsPrinted;
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
5944da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      // Print escape sequences all together.
6044da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      if (AggregateString[i] != '\\')
6144da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        continue;
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
6344da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      assert(i+1 < AggregateString.size() && "Incomplete escape sequence!");
6444da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      if (isdigit(AggregateString[i+1])) {
6544da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        assert(isdigit(AggregateString[i+2]) &&
6644da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner               isdigit(AggregateString[i+3]) &&
6744da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner               "Expected 3 digit octal escape!");
6844da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        O << AggregateString[++i];
6944da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        O << AggregateString[++i];
7044da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        O << AggregateString[++i];
7144da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        CharsPrinted += 3;
7244da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      } else {
7344da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        O << AggregateString[++i];
7444da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner        ++CharsPrinted;
7544da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner      }
7644da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner    }
7744da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner    O << "\"";
7844da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner  }
7944da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner};
8044da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner
8144da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner} // end namespace llvm
8244da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner
8344da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner#endif
84