Changeset View
Changeset View
Standalone View
Standalone View
llvm/utils/TableGen/SequenceToOffsetTable.h
Show All 9 Lines | |||||
// sequences as one big array. Use the same memory when a sequence is a suffix | // sequences as one big array. Use the same memory when a sequence is a suffix | ||||
// of another. | // of another. | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#ifndef LLVM_UTILS_TABLEGEN_SEQUENCETOOFFSETTABLE_H | #ifndef LLVM_UTILS_TABLEGEN_SEQUENCETOOFFSETTABLE_H | ||||
#define LLVM_UTILS_TABLEGEN_SEQUENCETOOFFSETTABLE_H | #define LLVM_UTILS_TABLEGEN_SEQUENCETOOFFSETTABLE_H | ||||
#include "PrinterTypes.h" | |||||
#include "llvm/Support/CommandLine.h" | #include "llvm/Support/CommandLine.h" | ||||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <cassert> | #include <cassert> | ||||
#include <cctype> | #include <cctype> | ||||
#include <functional> | #include <functional> | ||||
#include <map> | #include <map> | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | class SequenceToOffsetTable { | ||||
typedef std::map<SeqT, unsigned, SeqLess> SeqMap; | typedef std::map<SeqT, unsigned, SeqLess> SeqMap; | ||||
// Sequences added so far, with suffixes removed. | // Sequences added so far, with suffixes removed. | ||||
SeqMap Seqs; | SeqMap Seqs; | ||||
// Entries in the final table, or 0 before layout was called. | // Entries in the final table, or 0 before layout was called. | ||||
unsigned Entries; | unsigned Entries; | ||||
// The output language of the table. | |||||
PrinterLanguage PL; | |||||
rovka: I'd rather extract the printing code for this into a printer too. | |||||
nhaehnleUnsubmitted Not Done ReplyInline ActionsI disagree. That's additional complexity that simply isn't needed at this stage. nhaehnle: I disagree. That's additional complexity that simply isn't needed at this stage. | |||||
// isSuffix - Returns true if A is a suffix of B. | // isSuffix - Returns true if A is a suffix of B. | ||||
static bool isSuffix(const SeqT &A, const SeqT &B) { | static bool isSuffix(const SeqT &A, const SeqT &B) { | ||||
return A.size() <= B.size() && std::equal(A.rbegin(), A.rend(), B.rbegin()); | return A.size() <= B.size() && std::equal(A.rbegin(), A.rend(), B.rbegin()); | ||||
} | } | ||||
public: | public: | ||||
SequenceToOffsetTable() : Entries(0) {} | SequenceToOffsetTable() : Entries(0), PL(PRINTER_LANG_CPP) {} | ||||
SequenceToOffsetTable(PrinterLanguage PL) : Entries(0), PL(PL) {} | |||||
/// add - Add a sequence to the table. | /// add - Add a sequence to the table. | ||||
/// This must be called before layout(). | /// This must be called before layout(). | ||||
void add(const SeqT &Seq) { | void add(const SeqT &Seq) { | ||||
assert(Entries == 0 && "Cannot call add() after layout()"); | assert(Entries == 0 && "Cannot call add() after layout()"); | ||||
typename SeqMap::iterator I = Seqs.lower_bound(Seq); | typename SeqMap::iterator I = Seqs.lower_bound(Seq); | ||||
// If SeqMap contains a sequence that has Seq as a suffix, I will be | // If SeqMap contains a sequence that has Seq as a suffix, I will be | ||||
Show All 31 Lines | public: | ||||
unsigned get(const SeqT &Seq) const { | unsigned get(const SeqT &Seq) const { | ||||
assert(Entries && "Call layout() before get()"); | assert(Entries && "Call layout() before get()"); | ||||
typename SeqMap::const_iterator I = Seqs.lower_bound(Seq); | typename SeqMap::const_iterator I = Seqs.lower_bound(Seq); | ||||
assert(I != Seqs.end() && isSuffix(Seq, I->first) && | assert(I != Seqs.end() && isSuffix(Seq, I->first) && | ||||
"get() called with sequence that wasn't added first"); | "get() called with sequence that wasn't added first"); | ||||
return I->second + (I->first.size() - Seq.size()); | return I->second + (I->first.size() - Seq.size()); | ||||
} | } | ||||
void emitStringLiteralDef(raw_ostream &OS, const llvm::Twine &Decl) const { | |||||
switch (PL) { | |||||
default: | |||||
llvm_unreachable("Language not specified to print table in."); | |||||
case PRINTER_LANG_CPP: | |||||
emitStringLiteralDefCPP(OS, Decl); | |||||
} | |||||
} | |||||
void emit(raw_ostream &OS, | |||||
void (*Print)(raw_ostream&, ElemT), | |||||
const char *Term = "0") const { | |||||
switch (PL) { | |||||
default: | |||||
llvm_unreachable("Language not specified to print table in."); | |||||
case PRINTER_LANG_CPP: | |||||
emitCPP(OS, Print, Term); | |||||
} | |||||
} | |||||
/// `emitStringLiteralDef` - Print out the table as the body of an array | /// `emitStringLiteralDef` - Print out the table as the body of an array | ||||
/// initializer, where each element is a C string literal terminated by | /// initializer, where each element is a C string literal terminated by | ||||
/// `\0`. Falls back to emitting a comma-separated integer list if | /// `\0`. Falls back to emitting a comma-separated integer list if | ||||
/// `EmitLongStrLiterals` is false | /// `EmitLongStrLiterals` is false | ||||
void emitStringLiteralDef(raw_ostream &OS, const llvm::Twine &Decl) const { | void emitStringLiteralDefCPP(raw_ostream &OS, const llvm::Twine &Decl) const { | ||||
assert(Entries && "Call layout() before emitStringLiteralDef()"); | assert(Entries && "Call layout() before emitStringLiteralDef()"); | ||||
if (!EmitLongStrLiterals) { | if (!EmitLongStrLiterals) { | ||||
OS << Decl << " = {\n"; | OS << Decl << " = {\n"; | ||||
emit(OS, printChar, "0"); | emit(OS, printChar, "0"); | ||||
OS << " 0\n};\n\n"; | OS << " 0\n};\n\n"; | ||||
return; | return; | ||||
} | } | ||||
Show All 12 Lines | void emitStringLiteralDefCPP(raw_ostream &OS, const llvm::Twine &Decl) const { | ||||
OS << "};\n" | OS << "};\n" | ||||
<< "#ifdef __GNUC__\n" | << "#ifdef __GNUC__\n" | ||||
<< "#pragma GCC diagnostic pop\n" | << "#pragma GCC diagnostic pop\n" | ||||
<< "#endif\n\n"; | << "#endif\n\n"; | ||||
} | } | ||||
/// emit - Print out the table as the body of an array initializer. | /// emit - Print out the table as the body of an array initializer. | ||||
/// Use the Print function to print elements. | /// Use the Print function to print elements. | ||||
void emit(raw_ostream &OS, | void emitCPP(raw_ostream &OS, | ||||
void (*Print)(raw_ostream&, ElemT), | void (*Print)(raw_ostream&, ElemT), | ||||
const char *Term = "0") const { | const char *Term) const { | ||||
assert((empty() || Entries) && "Call layout() before emit()"); | assert((empty() || Entries) && "Call layout() before emit()"); | ||||
for (typename SeqMap::const_iterator I = Seqs.begin(), E = Seqs.end(); | for (typename SeqMap::const_iterator I = Seqs.begin(), E = Seqs.end(); | ||||
I != E; ++I) { | I != E; ++I) { | ||||
OS << " /* " << I->second << " */ "; | OS << " /* " << I->second << " */ "; | ||||
for (typename SeqT::const_iterator SI = I->first.begin(), | for (typename SeqT::const_iterator SI = I->first.begin(), | ||||
SE = I->first.end(); SI != SE; ++SI) { | SE = I->first.end(); SI != SE; ++SI) { | ||||
Print(OS, *SI); | Print(OS, *SI); | ||||
OS << ", "; | OS << ", "; | ||||
Show All 9 Lines |
I'd rather extract the printing code for this into a printer too.