aboutsummaryrefslogtreecommitdiff
path: root/lib/TableGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/TableGen')
-rw-r--r--lib/TableGen/Main.cpp44
-rw-r--r--lib/TableGen/Record.cpp443
-rw-r--r--lib/TableGen/TGLexer.cpp16
-rw-r--r--lib/TableGen/TGLexer.h4
-rw-r--r--lib/TableGen/TGParser.cpp240
-rw-r--r--lib/TableGen/TGParser.h38
6 files changed, 385 insertions, 400 deletions
diff --git a/lib/TableGen/Main.cpp b/lib/TableGen/Main.cpp
index bb590c7d87f2..278b567fb220 100644
--- a/lib/TableGen/Main.cpp
+++ b/lib/TableGen/Main.cpp
@@ -17,6 +17,7 @@
#include "llvm/TableGen/Main.h"
#include "TGParser.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -45,22 +46,25 @@ static cl::list<std::string>
IncludeDirs("I", cl::desc("Directory of include files"),
cl::value_desc("directory"), cl::Prefix);
+static int reportError(const char *ProgName, Twine Msg) {
+ errs() << ProgName << ": " << Msg;
+ errs().flush();
+ return 1;
+}
+
/// \brief Create a dependency file for `-d` option.
///
/// This functionality is really only for the benefit of the build system.
/// It is similar to GCC's `-M*` family of options.
static int createDependencyFile(const TGParser &Parser, const char *argv0) {
- if (OutputFilename == "-") {
- errs() << argv0 << ": the option -d must be used together with -o\n";
- return 1;
- }
+ if (OutputFilename == "-")
+ return reportError(argv0, "the option -d must be used together with -o\n");
+
std::error_code EC;
tool_output_file DepOut(DependFilename, EC, sys::fs::F_Text);
- if (EC) {
- errs() << argv0 << ": error opening " << DependFilename << ":"
- << EC.message() << "\n";
- return 1;
- }
+ if (EC)
+ return reportError(argv0, "error opening " + DependFilename + ":" +
+ EC.message() + "\n");
DepOut.os() << OutputFilename << ":";
for (const auto &Dep : Parser.getDependencies()) {
DepOut.os() << ' ' << Dep.first;
@@ -76,11 +80,9 @@ int llvm::TableGenMain(char *argv0, TableGenMainFn *MainFn) {
// Parse the input file.
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(InputFilename);
- if (std::error_code EC = FileOrErr.getError()) {
- errs() << "Could not open input file '" << InputFilename
- << "': " << EC.message() << "\n";
- return 1;
- }
+ if (std::error_code EC = FileOrErr.getError())
+ return reportError(argv0, "Could not open input file '" + InputFilename +
+ "': " + EC.message() + "\n");
// Tell SrcMgr about this buffer, which is what TGParser will pick up.
SrcMgr.AddNewSourceBuffer(std::move(*FileOrErr), SMLoc());
@@ -96,11 +98,9 @@ int llvm::TableGenMain(char *argv0, TableGenMainFn *MainFn) {
std::error_code EC;
tool_output_file Out(OutputFilename, EC, sys::fs::F_Text);
- if (EC) {
- errs() << argv0 << ": error opening " << OutputFilename << ":"
- << EC.message() << "\n";
- return 1;
- }
+ if (EC)
+ return reportError(argv0, "error opening " + OutputFilename + ":" +
+ EC.message() + "\n");
if (!DependFilename.empty()) {
if (int Ret = createDependencyFile(Parser, argv0))
return Ret;
@@ -109,10 +109,8 @@ int llvm::TableGenMain(char *argv0, TableGenMainFn *MainFn) {
if (MainFn(Out.os(), Records))
return 1;
- if (ErrorsPrinted > 0) {
- errs() << argv0 << ": " << ErrorsPrinted << " errors.\n";
- return 1;
- }
+ if (ErrorsPrinted > 0)
+ return reportError(argv0, utostr(ErrorsPrinted) + " errors.\n");
// Declare success.
Out.keep();
diff --git a/lib/TableGen/Record.cpp b/lib/TableGen/Record.cpp
index 66fbc9a8c96b..ea9c9a19904e 100644
--- a/lib/TableGen/Record.cpp
+++ b/lib/TableGen/Record.cpp
@@ -15,67 +15,20 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
#include "llvm/TableGen/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <new>
using namespace llvm;
-//===----------------------------------------------------------------------===//
-// std::string wrapper for DenseMap purposes
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-
-/// This is a wrapper for std::string suitable for using as a key to a DenseMap.
-/// Because there isn't a particularly
-/// good way to indicate tombstone or empty keys for strings, we want
-/// to wrap std::string to indicate that this is a "special" string
-/// not expected to take on certain values (those of the tombstone and
-/// empty keys). This makes things a little safer as it clarifies
-/// that DenseMap is really not appropriate for general strings.
-
-class TableGenStringKey {
-public:
- TableGenStringKey(const std::string &str) : data(str) {}
- TableGenStringKey(const char *str) : data(str) {}
-
- const std::string &str() const { return data; }
-
- friend hash_code hash_value(const TableGenStringKey &Value) {
- using llvm::hash_value;
- return hash_value(Value.str());
- }
-private:
- std::string data;
-};
-
-/// Specialize DenseMapInfo for TableGenStringKey.
-template<> struct DenseMapInfo<TableGenStringKey> {
- static inline TableGenStringKey getEmptyKey() {
- TableGenStringKey Empty("<<<EMPTY KEY>>>");
- return Empty;
- }
- static inline TableGenStringKey getTombstoneKey() {
- TableGenStringKey Tombstone("<<<TOMBSTONE KEY>>>");
- return Tombstone;
- }
- static unsigned getHashValue(const TableGenStringKey& Val) {
- using llvm::hash_value;
- return hash_value(Val);
- }
- static bool isEqual(const TableGenStringKey& LHS,
- const TableGenStringKey& RHS) {
- return LHS.str() == RHS.str();
- }
-};
-
-} // namespace llvm
+static BumpPtrAllocator Allocator;
//===----------------------------------------------------------------------===//
// Type implementations
@@ -91,8 +44,8 @@ LLVM_DUMP_METHOD void RecTy::dump() const { print(errs()); }
ListRecTy *RecTy::getListTy() {
if (!ListTy)
- ListTy.reset(new ListRecTy(this));
- return ListTy.get();
+ ListTy = new(Allocator) ListRecTy(this);
+ return ListTy;
}
bool RecTy::typeIsConvertibleTo(const RecTy *RHS) const {
@@ -109,13 +62,13 @@ bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{
}
BitsRecTy *BitsRecTy::get(unsigned Sz) {
- static std::vector<std::unique_ptr<BitsRecTy>> Shared;
+ static std::vector<BitsRecTy*> Shared;
if (Sz >= Shared.size())
Shared.resize(Sz + 1);
- std::unique_ptr<BitsRecTy> &Ty = Shared[Sz];
+ BitsRecTy *&Ty = Shared[Sz];
if (!Ty)
- Ty.reset(new BitsRecTy(Sz));
- return Ty.get();
+ Ty = new(Allocator) BitsRecTy(Sz);
+ return Ty;
}
std::string BitsRecTy::getAsString() const {
@@ -203,7 +156,6 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
return nullptr;
}
-
//===----------------------------------------------------------------------===//
// Initializer implementations
//===----------------------------------------------------------------------===//
@@ -263,7 +215,7 @@ ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) {
BitsInit *BitsInit::get(ArrayRef<Init *> Range) {
static FoldingSet<BitsInit> ThePool;
- static std::vector<std::unique_ptr<BitsInit>> TheActualPool;
+ static std::vector<BitsInit*> TheActualPool;
FoldingSetNodeID ID;
ProfileBitsInit(ID, Range);
@@ -272,12 +224,13 @@ BitsInit *BitsInit::get(ArrayRef<Init *> Range) {
if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
return I;
- void *Mem = ::operator new (totalSizeToAlloc<Init *>(Range.size()));
- BitsInit *I = new (Mem) BitsInit(Range.size());
+ void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
+ alignof(BitsInit));
+ BitsInit *I = new(Mem) BitsInit(Range.size());
std::uninitialized_copy(Range.begin(), Range.end(),
I->getTrailingObjects<Init *>());
ThePool.InsertNode(I, IP);
- TheActualPool.push_back(std::unique_ptr<BitsInit>(I));
+ TheActualPool.push_back(I);
return I;
}
@@ -312,7 +265,7 @@ Init *BitsInit::convertInitializerTo(RecTy *Ty) const {
}
Init *
-BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
+BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
SmallVector<Init *, 16> NewBits(Bits.size());
for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
@@ -393,11 +346,11 @@ Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) const {
}
IntInit *IntInit::get(int64_t V) {
- static DenseMap<int64_t, std::unique_ptr<IntInit>> ThePool;
+ static DenseMap<int64_t, IntInit*> ThePool;
- std::unique_ptr<IntInit> &I = ThePool[V];
- if (!I) I.reset(new IntInit(V));
- return I.get();
+ IntInit *&I = ThePool[V];
+ if (!I) I = new(Allocator) IntInit(V);
+ return I;
}
std::string IntInit::getAsString() const {
@@ -437,7 +390,7 @@ Init *IntInit::convertInitializerTo(RecTy *Ty) const {
}
Init *
-IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
+IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
SmallVector<Init *, 16> NewBits(Bits.size());
for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
@@ -450,19 +403,27 @@ IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
}
CodeInit *CodeInit::get(StringRef V) {
- static StringMap<std::unique_ptr<CodeInit>> ThePool;
+ static DenseMap<StringRef, CodeInit*> ThePool;
- std::unique_ptr<CodeInit> &I = ThePool[V];
- if (!I) I.reset(new CodeInit(V));
- return I.get();
+ auto I = ThePool.insert(std::make_pair(V, nullptr));
+ if (I.second) {
+ StringRef VCopy = V.copy(Allocator);
+ I.first->first = VCopy;
+ I.first->second = new(Allocator) CodeInit(VCopy);
+ }
+ return I.first->second;
}
StringInit *StringInit::get(StringRef V) {
- static StringMap<std::unique_ptr<StringInit>> ThePool;
+ static DenseMap<StringRef, StringInit*> ThePool;
- std::unique_ptr<StringInit> &I = ThePool[V];
- if (!I) I.reset(new StringInit(V));
- return I.get();
+ auto I = ThePool.insert(std::make_pair(V, nullptr));
+ if (I.second) {
+ StringRef VCopy = V.copy(Allocator);
+ I.first->first = VCopy;
+ I.first->second = new(Allocator) StringInit(VCopy);
+ }
+ return I.first->second;
}
Init *StringInit::convertInitializerTo(RecTy *Ty) const {
@@ -491,7 +452,7 @@ static void ProfileListInit(FoldingSetNodeID &ID,
ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) {
static FoldingSet<ListInit> ThePool;
- static std::vector<std::unique_ptr<ListInit>> TheActualPool;
+ static std::vector<ListInit*> TheActualPool;
FoldingSetNodeID ID;
ProfileListInit(ID, Range, EltTy);
@@ -500,12 +461,13 @@ ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) {
if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
return I;
- void *Mem = ::operator new (totalSizeToAlloc<Init *>(Range.size()));
- ListInit *I = new (Mem) ListInit(Range.size(), EltTy);
+ void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
+ alignof(ListInit));
+ ListInit *I = new(Mem) ListInit(Range.size(), EltTy);
std::uninitialized_copy(Range.begin(), Range.end(),
I->getTrailingObjects<Init *>());
ThePool.InsertNode(I, IP);
- TheActualPool.push_back(std::unique_ptr<ListInit>(I));
+ TheActualPool.push_back(I);
return I;
}
@@ -516,31 +478,40 @@ void ListInit::Profile(FoldingSetNodeID &ID) const {
}
Init *ListInit::convertInitializerTo(RecTy *Ty) const {
+ if (getType() == Ty)
+ return const_cast<ListInit*>(this);
+
if (auto *LRT = dyn_cast<ListRecTy>(Ty)) {
- std::vector<Init*> Elements;
+ SmallVector<Init*, 8> Elements;
+ Elements.reserve(getValues().size());
// Verify that all of the elements of the list are subclasses of the
// appropriate class!
+ bool Changed = false;
+ RecTy *ElementType = LRT->getElementType();
for (Init *I : getValues())
- if (Init *CI = I->convertInitializerTo(LRT->getElementType()))
+ if (Init *CI = I->convertInitializerTo(ElementType)) {
Elements.push_back(CI);
- else
+ if (CI != I)
+ Changed = true;
+ } else
return nullptr;
- if (isa<ListRecTy>(getType()))
- return ListInit::get(Elements, Ty);
+ if (!Changed)
+ return const_cast<ListInit*>(this);
+ return ListInit::get(Elements, Ty);
}
return nullptr;
}
-Init *
-ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) const {
- std::vector<Init*> Vals;
- for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
- if (Elements[i] >= size())
+Init *ListInit::convertInitListSlice(ArrayRef<unsigned> Elements) const {
+ SmallVector<Init*, 8> Vals;
+ Vals.reserve(Elements.size());
+ for (unsigned Element : Elements) {
+ if (Element >= size())
return nullptr;
- Vals.push_back(getElement(Elements[i]));
+ Vals.push_back(getElement(Element));
}
return ListInit::get(Vals, getType());
}
@@ -554,7 +525,7 @@ Record *ListInit::getElementAsRecord(unsigned i) const {
}
Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) const {
- std::vector<Init*> Resolved;
+ SmallVector<Init*, 8> Resolved;
Resolved.reserve(size());
bool Changed = false;
@@ -589,9 +560,11 @@ Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
std::string ListInit::getAsString() const {
std::string Result = "[";
- for (unsigned i = 0, e = NumValues; i != e; ++i) {
- if (i) Result += ", ";
- Result += getElement(i)->getAsString();
+ const char *sep = "";
+ for (Init *Element : *this) {
+ Result += sep;
+ sep = ", ";
+ Result += Element->getAsString();
}
return Result + "]";
}
@@ -629,7 +602,7 @@ ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *Op, RecTy *Type) {
UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, RecTy *Type) {
static FoldingSet<UnOpInit> ThePool;
- static std::vector<std::unique_ptr<UnOpInit>> TheActualPool;
+ static std::vector<UnOpInit*> TheActualPool;
FoldingSetNodeID ID;
ProfileUnOpInit(ID, Opc, LHS, Type);
@@ -638,9 +611,9 @@ UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, RecTy *Type) {
if (UnOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
return I;
- UnOpInit *I = new UnOpInit(Opc, LHS, Type);
+ UnOpInit *I = new(Allocator) UnOpInit(Opc, LHS, Type);
ThePool.InsertNode(I, IP);
- TheActualPool.push_back(std::unique_ptr<UnOpInit>(I));
+ TheActualPool.push_back(I);
return I;
}
@@ -661,9 +634,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
if (IntInit *LHSi = dyn_cast<IntInit>(LHS))
return StringInit::get(LHSi->getAsString());
} else {
- if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) {
- const std::string &Name = LHSs->getValue();
-
+ if (StringInit *Name = dyn_cast<StringInit>(LHS)) {
// From TGParser::ParseIDValue
if (CurRec) {
if (const RecordVal *RV = CurRec->getValue(Name)) {
@@ -701,11 +672,11 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
}
}
assert(CurRec && "NULL pointer");
- if (Record *D = (CurRec->getRecords()).getDef(Name))
+ if (Record *D = (CurRec->getRecords()).getDef(Name->getValue()))
return DefInit::get(D);
PrintFatalError(CurRec->getLoc(),
- "Undefined reference:'" + Name + "'\n");
+ "Undefined reference:'" + Name->getValue() + "'\n");
}
if (isa<IntRecTy>(getType())) {
@@ -777,7 +748,7 @@ ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *RHS,
BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS,
Init *RHS, RecTy *Type) {
static FoldingSet<BinOpInit> ThePool;
- static std::vector<std::unique_ptr<BinOpInit>> TheActualPool;
+ static std::vector<BinOpInit*> TheActualPool;
FoldingSetNodeID ID;
ProfileBinOpInit(ID, Opc, LHS, RHS, Type);
@@ -786,9 +757,9 @@ BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS,
if (BinOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
return I;
- BinOpInit *I = new BinOpInit(Opc, LHS, RHS, Type);
+ BinOpInit *I = new(Allocator) BinOpInit(Opc, LHS, RHS, Type);
ThePool.InsertNode(I, IP);
- TheActualPool.push_back(std::unique_ptr<BinOpInit>(I));
+ TheActualPool.push_back(I);
return I;
}
@@ -796,6 +767,13 @@ void BinOpInit::Profile(FoldingSetNodeID &ID) const {
ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType());
}
+static StringInit *ConcatStringInits(const StringInit *I0,
+ const StringInit *I1) {
+ SmallString<80> Concat(I0->getValue());
+ Concat.append(I1->getValue());
+ return StringInit::get(Concat);
+}
+
Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
switch (getOpcode()) {
case CONCAT: {
@@ -806,8 +784,8 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator());
if (!LOp || !ROp || LOp->getDef() != ROp->getDef())
PrintFatalError("Concated Dag operators do not match!");
- std::vector<Init*> Args;
- std::vector<std::string> ArgNames;
+ SmallVector<Init*, 8> Args;
+ SmallVector<StringInit*, 8> ArgNames;
for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
Args.push_back(LHSs->getArg(i));
ArgNames.push_back(LHSs->getArgName(i));
@@ -816,7 +794,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
Args.push_back(RHSs->getArg(i));
ArgNames.push_back(RHSs->getArgName(i));
}
- return DagInit::get(LHSs->getOperator(), "", Args, ArgNames);
+ return DagInit::get(LHSs->getOperator(), nullptr, Args, ArgNames);
}
break;
}
@@ -824,7 +802,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
ListInit *LHSs = dyn_cast<ListInit>(LHS);
ListInit *RHSs = dyn_cast<ListInit>(RHS);
if (LHSs && RHSs) {
- std::vector<Init *> Args;
+ SmallVector<Init *, 8> Args;
Args.insert(Args.end(), LHSs->begin(), LHSs->end());
Args.insert(Args.end(), RHSs->begin(), RHSs->end());
return ListInit::get(
@@ -836,7 +814,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
StringInit *LHSs = dyn_cast<StringInit>(LHS);
StringInit *RHSs = dyn_cast<StringInit>(RHS);
if (LHSs && RHSs)
- return StringInit::get(LHSs->getValue() + RHSs->getValue());
+ return ConcatStringInits(LHSs, RHSs);
break;
}
case EQ: {
@@ -861,6 +839,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
}
case ADD:
case AND:
+ case OR:
case SHL:
case SRA:
case SRL: {
@@ -875,6 +854,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
default: llvm_unreachable("Bad opcode!");
case ADD: Result = LHSv + RHSv; break;
case AND: Result = LHSv & RHSv; break;
+ case OR: Result = LHSv | RHSv; break;
case SHL: Result = LHSv << RHSv; break;
case SRA: Result = LHSv >> RHSv; break;
case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
@@ -902,6 +882,7 @@ std::string BinOpInit::getAsString() const {
case CONCAT: Result = "!con"; break;
case ADD: Result = "!add"; break;
case AND: Result = "!and"; break;
+ case OR: Result = "!or"; break;
case SHL: Result = "!shl"; break;
case SRA: Result = "!sra"; break;
case SRL: Result = "!srl"; break;
@@ -925,7 +906,7 @@ ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *MHS,
TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS,
RecTy *Type) {
static FoldingSet<TernOpInit> ThePool;
- static std::vector<std::unique_ptr<TernOpInit>> TheActualPool;
+ static std::vector<TernOpInit*> TheActualPool;
FoldingSetNodeID ID;
ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type);
@@ -934,9 +915,9 @@ TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS,
if (TernOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
return I;
- TernOpInit *I = new TernOpInit(Opc, LHS, MHS, RHS, Type);
+ TernOpInit *I = new(Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type);
ThePool.InsertNode(I, IP);
- TheActualPool.push_back(std::unique_ptr<TernOpInit>(I));
+ TheActualPool.push_back(I);
return I;
}
@@ -955,8 +936,9 @@ static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
if (isa<DagRecTy>(TArg->getType()))
return ForeachHelper(LHS, Arg, RHSo, Type, CurRec, CurMultiClass);
- std::vector<Init *> NewOperands;
- for (unsigned i = 0; i < RHSo->getNumOperands(); ++i) {
+ SmallVector<Init *, 8> NewOperands;
+ NewOperands.reserve(RHSo->getNumOperands());
+ for (unsigned i = 0, e = RHSo->getNumOperands(); i < e; ++i) {
if (auto *RHSoo = dyn_cast<OpInit>(RHSo->getOperand(i))) {
if (Init *Result = EvaluateOperation(RHSoo, LHS, Arg,
Type, CurRec, CurMultiClass))
@@ -996,10 +978,10 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
Type, CurRec, CurMultiClass))
Val = Result;
- std::vector<std::pair<Init *, std::string> > args;
+ SmallVector<std::pair<Init *, StringInit*>, 8> args;
for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
Init *Arg = MHSd->getArg(i);
- std::string ArgName = MHSd->getArgName(i);
+ StringInit *ArgName = MHSd->getArgName(i);
// Process args
if (Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type,
@@ -1010,13 +992,13 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
args.push_back(std::make_pair(Arg, ArgName));
}
- return DagInit::get(Val, "", args);
+ return DagInit::get(Val, nullptr, args);
}
ListInit *MHSl = dyn_cast<ListInit>(MHS);
if (MHSl && isa<ListRecTy>(Type)) {
- std::vector<Init *> NewOperands;
- std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
+ SmallVector<Init *, 8> NewOperands;
+ SmallVector<Init *, 8> NewList(MHSl->begin(), MHSl->end());
for (Init *&Item : NewList) {
NewOperands.clear();
@@ -1148,7 +1130,7 @@ std::string TernOpInit::getAsString() const {
RHS->getAsString() + ")";
}
-RecTy *TypedInit::getFieldType(const std::string &FieldName) const {
+RecTy *TypedInit::getFieldType(StringInit *FieldName) const {
if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType()))
if (RecordVal *Field = RecordType->getRecord()->getValue(FieldName))
return Field->getType();
@@ -1237,56 +1219,56 @@ TypedInit::convertInitializerTo(RecTy *Ty) const {
return nullptr;
}
-Init *
-TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
+Init *TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
BitsRecTy *T = dyn_cast<BitsRecTy>(getType());
if (!T) return nullptr; // Cannot subscript a non-bits variable.
unsigned NumBits = T->getNumBits();
- SmallVector<Init *, 16> NewBits(Bits.size());
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- if (Bits[i] >= NumBits)
+ SmallVector<Init *, 16> NewBits;
+ NewBits.reserve(Bits.size());
+ for (unsigned Bit : Bits) {
+ if (Bit >= NumBits)
return nullptr;
- NewBits[i] = VarBitInit::get(const_cast<TypedInit *>(this), Bits[i]);
+ NewBits.push_back(VarBitInit::get(const_cast<TypedInit *>(this), Bit));
}
return BitsInit::get(NewBits);
}
-Init *
-TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) const {
+Init *TypedInit::convertInitListSlice(ArrayRef<unsigned> Elements) const {
ListRecTy *T = dyn_cast<ListRecTy>(getType());
if (!T) return nullptr; // Cannot subscript a non-list variable.
if (Elements.size() == 1)
return VarListElementInit::get(const_cast<TypedInit *>(this), Elements[0]);
- std::vector<Init*> ListInits;
+ SmallVector<Init*, 8> ListInits;
ListInits.reserve(Elements.size());
- for (unsigned i = 0, e = Elements.size(); i != e; ++i)
+ for (unsigned Element : Elements)
ListInits.push_back(VarListElementInit::get(const_cast<TypedInit *>(this),
- Elements[i]));
+ Element));
return ListInit::get(ListInits, T);
}
-VarInit *VarInit::get(const std::string &VN, RecTy *T) {
+VarInit *VarInit::get(StringRef VN, RecTy *T) {
Init *Value = StringInit::get(VN);
return VarInit::get(Value, T);
}
VarInit *VarInit::get(Init *VN, RecTy *T) {
typedef std::pair<RecTy *, Init *> Key;
- static DenseMap<Key, std::unique_ptr<VarInit>> ThePool;
+ static DenseMap<Key, VarInit*> ThePool;
Key TheKey(std::make_pair(T, VN));
- std::unique_ptr<VarInit> &I = ThePool[TheKey];
- if (!I) I.reset(new VarInit(VN, T));
- return I.get();
+ VarInit *&I = ThePool[TheKey];
+ if (!I)
+ I = new(Allocator) VarInit(VN, T);
+ return I;
}
-const std::string &VarInit::getName() const {
+StringRef VarInit::getName() const {
StringInit *NameString = cast<StringInit>(getNameInit());
return NameString->getValue();
}
@@ -1320,8 +1302,7 @@ Init *VarInit::resolveListElementReference(Record &R,
return nullptr;
}
-
-RecTy *VarInit::getFieldType(const std::string &FieldName) const {
+RecTy *VarInit::getFieldType(StringInit *FieldName) const {
if (RecordRecTy *RTy = dyn_cast<RecordRecTy>(getType()))
if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
return RV->getType();
@@ -1329,7 +1310,7 @@ RecTy *VarInit::getFieldType(const std::string &FieldName) const {
}
Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
- const std::string &FieldName) const {
+ StringInit *FieldName) const {
if (isa<RecordRecTy>(getType()))
if (const RecordVal *Val = R.getValue(VarName)) {
if (RV != Val && (RV || isa<UnsetInit>(Val->getValue())))
@@ -1352,13 +1333,14 @@ Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) const {
VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) {
typedef std::pair<TypedInit *, unsigned> Key;
- static DenseMap<Key, std::unique_ptr<VarBitInit>> ThePool;
+ static DenseMap<Key, VarBitInit*> ThePool;
Key TheKey(std::make_pair(T, B));
- std::unique_ptr<VarBitInit> &I = ThePool[TheKey];
- if (!I) I.reset(new VarBitInit(T, B));
- return I.get();
+ VarBitInit *&I = ThePool[TheKey];
+ if (!I)
+ I = new(Allocator) VarBitInit(T, B);
+ return I;
}
Init *VarBitInit::convertInitializerTo(RecTy *Ty) const {
@@ -1383,13 +1365,13 @@ Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) const {
VarListElementInit *VarListElementInit::get(TypedInit *T,
unsigned E) {
typedef std::pair<TypedInit *, unsigned> Key;
- static DenseMap<Key, std::unique_ptr<VarListElementInit>> ThePool;
+ static DenseMap<Key, VarListElementInit*> ThePool;
Key TheKey(std::make_pair(T, E));
- std::unique_ptr<VarListElementInit> &I = ThePool[TheKey];
- if (!I) I.reset(new VarListElementInit(T, E));
- return I.get();
+ VarListElementInit *&I = ThePool[TheKey];
+ if (!I) I = new(Allocator) VarListElementInit(T, E);
+ return I;
}
std::string VarListElementInit::getAsString() const {
@@ -1436,31 +1418,30 @@ Init *DefInit::convertInitializerTo(RecTy *Ty) const {
return nullptr;
}
-RecTy *DefInit::getFieldType(const std::string &FieldName) const {
+RecTy *DefInit::getFieldType(StringInit *FieldName) const {
if (const RecordVal *RV = Def->getValue(FieldName))
return RV->getType();
return nullptr;
}
Init *DefInit::getFieldInit(Record &R, const RecordVal *RV,
- const std::string &FieldName) const {
+ StringInit *FieldName) const {
return Def->getValue(FieldName)->getValue();
}
-
std::string DefInit::getAsString() const {
return Def->getName();
}
-FieldInit *FieldInit::get(Init *R, const std::string &FN) {
- typedef std::pair<Init *, TableGenStringKey> Key;
- static DenseMap<Key, std::unique_ptr<FieldInit>> ThePool;
+FieldInit *FieldInit::get(Init *R, StringInit *FN) {
+ typedef std::pair<Init *, StringInit *> Key;
+ static DenseMap<Key, FieldInit*> ThePool;
Key TheKey(std::make_pair(R, FN));
- std::unique_ptr<FieldInit> &I = ThePool[TheKey];
- if (!I) I.reset(new FieldInit(R, FN));
- return I.get();
+ FieldInit *&I = ThePool[TheKey];
+ if (!I) I = new(Allocator) FieldInit(R, FN);
+ return I;
}
Init *FieldInit::getBit(unsigned Bit) const {
@@ -1498,28 +1479,27 @@ Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const {
return const_cast<FieldInit *>(this);
}
-static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, const std::string &VN,
+static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN,
ArrayRef<Init *> ArgRange,
- ArrayRef<std::string> NameRange) {
+ ArrayRef<StringInit *> NameRange) {
ID.AddPointer(V);
- ID.AddString(VN);
+ ID.AddPointer(VN);
- ArrayRef<Init *>::iterator Arg = ArgRange.begin();
- ArrayRef<std::string>::iterator Name = NameRange.begin();
+ ArrayRef<Init *>::iterator Arg = ArgRange.begin();
+ ArrayRef<StringInit *>::iterator Name = NameRange.begin();
while (Arg != ArgRange.end()) {
assert(Name != NameRange.end() && "Arg name underflow!");
ID.AddPointer(*Arg++);
- ID.AddString(*Name++);
+ ID.AddPointer(*Name++);
}
assert(Name == NameRange.end() && "Arg name overflow!");
}
DagInit *
-DagInit::get(Init *V, const std::string &VN,
- ArrayRef<Init *> ArgRange,
- ArrayRef<std::string> NameRange) {
+DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
+ ArrayRef<StringInit *> NameRange) {
static FoldingSet<DagInit> ThePool;
- static std::vector<std::unique_ptr<DagInit>> TheActualPool;
+ static std::vector<DagInit*> TheActualPool;
FoldingSetNodeID ID;
ProfileDagInit(ID, V, VN, ArgRange, NameRange);
@@ -1528,17 +1508,17 @@ DagInit::get(Init *V, const std::string &VN,
if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
return I;
- DagInit *I = new DagInit(V, VN, ArgRange, NameRange);
+ DagInit *I = new(Allocator) DagInit(V, VN, ArgRange, NameRange);
ThePool.InsertNode(I, IP);
- TheActualPool.push_back(std::unique_ptr<DagInit>(I));
+ TheActualPool.push_back(I);
return I;
}
DagInit *
-DagInit::get(Init *V, const std::string &VN,
- const std::vector<std::pair<Init*, std::string> > &args) {
- std::vector<Init *> Args;
- std::vector<std::string> Names;
+DagInit::get(Init *V, StringInit *VN,
+ ArrayRef<std::pair<Init*, StringInit*>> args) {
+ SmallVector<Init *, 8> Args;
+ SmallVector<StringInit *, 8> Names;
for (const auto &Arg : args) {
Args.push_back(Arg.first);
@@ -1560,52 +1540,54 @@ Init *DagInit::convertInitializerTo(RecTy *Ty) const {
}
Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) const {
- std::vector<Init*> NewArgs;
- for (unsigned i = 0, e = Args.size(); i != e; ++i)
- NewArgs.push_back(Args[i]->resolveReferences(R, RV));
+ SmallVector<Init*, 8> NewArgs;
+ NewArgs.reserve(Args.size());
+ bool ArgsChanged = false;
+ for (const Init *Arg : Args) {
+ Init *NewArg = Arg->resolveReferences(R, RV);
+ NewArgs.push_back(NewArg);
+ ArgsChanged |= NewArg != Arg;
+ }
Init *Op = Val->resolveReferences(R, RV);
-
- if (Args != NewArgs || Op != Val)
+ if (Op != Val || ArgsChanged)
return DagInit::get(Op, ValName, NewArgs, ArgNames);
return const_cast<DagInit *>(this);
}
-
std::string DagInit::getAsString() const {
std::string Result = "(" + Val->getAsString();
- if (!ValName.empty())
- Result += ":" + ValName;
+ if (ValName)
+ Result += ":" + ValName->getAsUnquotedString();
if (!Args.empty()) {
Result += " " + Args[0]->getAsString();
- if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0];
+ if (ArgNames[0]) Result += ":$" + ArgNames[0]->getAsUnquotedString();
for (unsigned i = 1, e = Args.size(); i != e; ++i) {
Result += ", " + Args[i]->getAsString();
- if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i];
+ if (ArgNames[i]) Result += ":$" + ArgNames[i]->getAsUnquotedString();
}
}
return Result + ")";
}
-
//===----------------------------------------------------------------------===//
// Other implementations
//===----------------------------------------------------------------------===//
RecordVal::RecordVal(Init *N, RecTy *T, bool P)
- : NameAndPrefix(N, P), Ty(T) {
- Value = UnsetInit::get()->convertInitializerTo(Ty);
+ : Name(N), TyAndPrefix(T, P) {
+ Value = UnsetInit::get()->convertInitializerTo(T);
assert(Value && "Cannot create unset value for current type!");
}
-RecordVal::RecordVal(const std::string &N, RecTy *T, bool P)
- : NameAndPrefix(StringInit::get(N), P), Ty(T) {
- Value = UnsetInit::get()->convertInitializerTo(Ty);
+RecordVal::RecordVal(StringRef N, RecTy *T, bool P)
+ : Name(StringInit::get(N)), TyAndPrefix(T, P) {
+ Value = UnsetInit::get()->convertInitializerTo(T);
assert(Value && "Cannot create unset value for current type!");
}
-const std::string &RecordVal::getName() const {
+StringRef RecordVal::getName() const {
return cast<StringInit>(getNameInit())->getValue();
}
@@ -1628,7 +1610,7 @@ void Record::init() {
// Every record potentially has a def at the top. This value is
// replaced with the top-level def name at instantiation time.
- RecordVal DN("NAME", StringRecTy::get(), 0);
+ RecordVal DN("NAME", StringRecTy::get(), false);
addValue(DN);
}
@@ -1641,11 +1623,11 @@ void Record::checkName() {
DefInit *Record::getDefInit() {
if (!TheInit)
- TheInit.reset(new DefInit(this, new RecordRecTy(this)));
- return TheInit.get();
+ TheInit = new(Allocator) DefInit(this, new(Allocator) RecordRecTy(this));
+ return TheInit;
}
-const std::string &Record::getName() const {
+StringRef Record::getName() const {
return cast<StringInit>(Name)->getValue();
}
@@ -1665,18 +1647,18 @@ void Record::setName(Init *NewName) {
// this. See TGParser::ParseDef and TGParser::ParseDefm.
}
-void Record::setName(const std::string &Name) {
+void Record::setName(StringRef Name) {
setName(StringInit::get(Name));
}
void Record::resolveReferencesTo(const RecordVal *RV) {
- for (unsigned i = 0, e = Values.size(); i != e; ++i) {
- if (RV == &Values[i]) // Skip resolve the same field as the given one
+ for (RecordVal &Value : Values) {
+ if (RV == &Value) // Skip resolve the same field as the given one
continue;
- if (Init *V = Values[i].getValue())
- if (Values[i].setValue(V->resolveReferences(*this, RV)))
+ if (Init *V = Value.getValue())
+ if (Value.setValue(V->resolveReferences(*this, RV)))
PrintFatalError(getLoc(), "Invalid value is found when setting '" +
- Values[i].getNameInitAsString() +
+ Value.getNameInitAsString() +
"' after resolving references" +
(RV ? " against '" + RV->getNameInitAsString() +
"' of (" + RV->getValue()->getAsUnquotedString() +
@@ -1720,10 +1702,10 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
OS << "\n";
for (const RecordVal &Val : R.getValues())
- if (Val.getPrefix() && !R.isTemplateArg(Val.getName()))
+ if (Val.getPrefix() && !R.isTemplateArg(Val.getNameInit()))
OS << Val;
for (const RecordVal &Val : R.getValues())
- if (!Val.getPrefix() && !R.isTemplateArg(Val.getName()))
+ if (!Val.getPrefix() && !R.isTemplateArg(Val.getNameInit()))
OS << Val;
return OS << "}\n";
@@ -1737,7 +1719,6 @@ Init *Record::getValueInit(StringRef FieldName) const {
return R->getValue();
}
-
std::string Record::getValueAsString(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
if (!R || !R->getValue())
@@ -1884,7 +1865,6 @@ DagInit *Record::getValueAsDag(StringRef FieldName) const {
FieldName + "' does not have a dag initializer!");
}
-
LLVM_DUMP_METHOD void MultiClass::dump() const {
errs() << "Record:\n";
Rec.dump();
@@ -1894,7 +1874,6 @@ LLVM_DUMP_METHOD void MultiClass::dump() const {
Proto->dump();
}
-
LLVM_DUMP_METHOD void RecordKeeper::dump() const { errs() << *this; }
raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
@@ -1909,7 +1888,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
}
std::vector<Record *>
-RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const {
+RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const {
Record *Class = getClass(ClassName);
if (!Class)
PrintFatalError("ERROR: Couldn't find the `" + ClassName + "' class!\n");
@@ -1922,35 +1901,25 @@ RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const {
return Defs;
}
-Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass,
- Init *Name, const std::string &Scoper) {
- RecTy *Type = cast<TypedInit>(Name)->getType();
-
- BinOpInit *NewName =
- BinOpInit::get(BinOpInit::STRCONCAT,
- BinOpInit::get(BinOpInit::STRCONCAT,
- CurRec.getNameInit(),
- StringInit::get(Scoper),
- Type)->Fold(&CurRec, CurMultiClass),
- Name,
- Type);
+static Init *GetStrConcat(Init *I0, Init *I1) {
+ // Shortcut for the common case of concatenating two strings.
+ if (const StringInit *I0s = dyn_cast<StringInit>(I0))
+ if (const StringInit *I1s = dyn_cast<StringInit>(I1))
+ return ConcatStringInits(I0s, I1s);
+ return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, StringRecTy::get());
+}
+Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass,
+ Init *Name, StringRef Scoper) {
+ Init *NewName = GetStrConcat(CurRec.getNameInit(), StringInit::get(Scoper));
+ NewName = GetStrConcat(NewName, Name);
if (CurMultiClass && Scoper != "::") {
- NewName =
- BinOpInit::get(BinOpInit::STRCONCAT,
- BinOpInit::get(BinOpInit::STRCONCAT,
- CurMultiClass->Rec.getNameInit(),
- StringInit::get("::"),
- Type)->Fold(&CurRec, CurMultiClass),
- NewName->Fold(&CurRec, CurMultiClass),
- Type);
+ Init *Prefix = GetStrConcat(CurMultiClass->Rec.getNameInit(),
+ StringInit::get("::"));
+ NewName = GetStrConcat(Prefix, NewName);
}
- return NewName->Fold(&CurRec, CurMultiClass);
-}
-
-Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass,
- const std::string &Name,
- const std::string &Scoper) {
- return QualifyName(CurRec, CurMultiClass, StringInit::get(Name), Scoper);
+ if (BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName))
+ NewName = BinOp->Fold(&CurRec, CurMultiClass);
+ return NewName;
}
diff --git a/lib/TableGen/TGLexer.cpp b/lib/TableGen/TGLexer.cpp
index 63b85842d6a9..5d6f7c23e0b6 100644
--- a/lib/TableGen/TGLexer.cpp
+++ b/lib/TableGen/TGLexer.cpp
@@ -15,11 +15,13 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h" // for strtoull()/strtoll() define
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/TableGen/Error.h"
#include <cctype>
#include <cerrno>
+#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
@@ -155,7 +157,7 @@ tgtok::TokKind TGLexer::LexToken() {
case '0': case '1':
if (NextChar == 'b')
return LexNumber();
- // Fallthrough
+ LLVM_FALLTHROUGH;
case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
@@ -222,7 +224,7 @@ tgtok::TokKind TGLexer::LexString() {
case '\0':
if (CurPtr == CurBuf.end())
return ReturnError(StrStart, "End of file in string literal");
- // FALL THROUGH
+ LLVM_FALLTHROUGH;
default:
return ReturnError(CurPtr, "invalid escape in string literal");
}
@@ -246,7 +248,6 @@ tgtok::TokKind TGLexer::LexVarName() {
return tgtok::VarName;
}
-
tgtok::TokKind TGLexer::LexIdentifier() {
// The first letter is [a-zA-Z_#].
const char *IdentStart = TokStart;
@@ -301,7 +302,6 @@ bool TGLexer::LexInclude() {
std::string Filename = CurStrVal;
std::string IncludedFile;
-
CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr),
IncludedFile);
if (!CurBuffer) {
@@ -326,7 +326,7 @@ bool TGLexer::LexInclude() {
void TGLexer::SkipBCPLComment() {
++CurPtr; // skip the second slash.
- while (1) {
+ while (true) {
switch (*CurPtr) {
case '\n':
case '\r':
@@ -348,7 +348,7 @@ bool TGLexer::SkipCComment() {
++CurPtr; // skip the star.
unsigned CommentDepth = 1;
- while (1) {
+ while (true) {
int CurChar = getNextChar();
switch (CurChar) {
case EOF:
@@ -436,7 +436,7 @@ tgtok::TokKind TGLexer::LexBracket() {
return tgtok::l_square;
++CurPtr;
const char *CodeStart = CurPtr;
- while (1) {
+ while (true) {
int Char = getNextChar();
if (Char == EOF) break;
@@ -472,6 +472,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
.Case("con", tgtok::XConcat)
.Case("add", tgtok::XADD)
.Case("and", tgtok::XAND)
+ .Case("or", tgtok::XOR)
.Case("shl", tgtok::XSHL)
.Case("sra", tgtok::XSRA)
.Case("srl", tgtok::XSRL)
@@ -485,4 +486,3 @@ tgtok::TokKind TGLexer::LexExclaim() {
return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator");
}
-
diff --git a/lib/TableGen/TGLexer.h b/lib/TableGen/TGLexer.h
index cbc30be8a572..b5b58161878b 100644
--- a/lib/TableGen/TGLexer.h
+++ b/lib/TableGen/TGLexer.h
@@ -45,9 +45,9 @@ namespace tgtok {
// Keywords.
Bit, Bits, Class, Code, Dag, Def, Foreach, Defm, Field, In, Int, Let, List,
MultiClass, String,
-
+
// !keywords.
- XConcat, XADD, XAND, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast,
+ XConcat, XADD, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast,
XSubst, XForEach, XHead, XTail, XEmpty, XIf, XEq,
// Integer value.
diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp
index 34e90925e929..1a91b37b742b 100644
--- a/lib/TableGen/TGParser.cpp
+++ b/lib/TableGen/TGParser.cpp
@@ -12,11 +12,19 @@
//===----------------------------------------------------------------------===//
#include "TGParser.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Record.h"
#include <algorithm>
+#include <cassert>
+#include <cstdint>
+
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -24,10 +32,12 @@ using namespace llvm;
//===----------------------------------------------------------------------===//
namespace llvm {
+
struct SubClassReference {
SMRange RefRange;
Record *Rec;
- std::vector<Init*> TemplateArgs;
+ SmallVector<Init*, 4> TemplateArgs;
+
SubClassReference() : Rec(nullptr) {}
bool isInvalid() const { return Rec == nullptr; }
@@ -36,7 +46,8 @@ struct SubClassReference {
struct SubMultiClassReference {
SMRange RefRange;
MultiClass *MC;
- std::vector<Init*> TemplateArgs;
+ SmallVector<Init*, 4> TemplateArgs;
+
SubMultiClassReference() : MC(nullptr) {}
bool isInvalid() const { return MC == nullptr; }
@@ -130,7 +141,7 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
}
if (RV->setValue(V)) {
- std::string InitType = "";
+ std::string InitType;
if (BitsInit *BI = dyn_cast<BitsInit>(V))
InitType = (Twine("' of type bit initializer with length ") +
Twine(BI->getNumBits())).str();
@@ -328,14 +339,14 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
IterRec->addValue(RecordVal(IterVar->getName(), IVal->getType(), false));
- if (SetValue(IterRec.get(), Loc, IterVar->getName(), None, IVal))
+ if (SetValue(IterRec.get(), Loc, IterVar->getNameInit(), None, IVal))
return Error(Loc, "when instantiating this def");
// Resolve it next.
- IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getName()));
+ IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getNameInit()));
// Remove it.
- IterRec->removeValue(IterVar->getName());
+ IterRec->removeValue(IterVar->getNameInit());
}
if (Records.getDef(IterRec->getNameInitAsString())) {
@@ -474,7 +485,7 @@ ParseSubClassReference(Record *CurRec, bool isDefm) {
return Result;
}
- Result.TemplateArgs = ParseValueList(CurRec, Result.Rec);
+ ParseValueList(Result.TemplateArgs, CurRec, Result.Rec);
if (Result.TemplateArgs.empty()) {
Result.Rec = nullptr; // Error parsing value list.
return Result;
@@ -519,7 +530,7 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
return Result;
}
- Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec);
+ ParseValueList(Result.TemplateArgs, &CurMC->Rec, &Result.MC->Rec);
if (Result.TemplateArgs.empty()) {
Result.MC = nullptr; // Error parsing value list.
return Result;
@@ -540,7 +551,7 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
/// RangePiece ::= INTVAL
/// RangePiece ::= INTVAL '-' INTVAL
/// RangePiece ::= INTVAL INTVAL
-bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) {
+bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges) {
if (Lex.getCode() != tgtok::IntVal) {
TokError("expected integer or bitrange");
return true;
@@ -584,26 +595,27 @@ bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) {
///
/// RangeList ::= RangePiece (',' RangePiece)*
///
-std::vector<unsigned> TGParser::ParseRangeList() {
- std::vector<unsigned> Result;
-
+void TGParser::ParseRangeList(SmallVectorImpl<unsigned> &Result) {
// Parse the first piece.
- if (ParseRangePiece(Result))
- return std::vector<unsigned>();
+ if (ParseRangePiece(Result)) {
+ Result.clear();
+ return;
+ }
while (Lex.getCode() == tgtok::comma) {
Lex.Lex(); // Eat the comma.
// Parse the next range piece.
- if (ParseRangePiece(Result))
- return std::vector<unsigned>();
+ if (ParseRangePiece(Result)) {
+ Result.clear();
+ return;
+ }
}
- return Result;
}
/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing.
/// OptionalRangeList ::= '<' RangeList '>'
/// OptionalRangeList ::= /*empty*/
-bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) {
+bool TGParser::ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges) {
if (Lex.getCode() != tgtok::less)
return false;
@@ -611,7 +623,7 @@ bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) {
Lex.Lex(); // eat the '<'
// Parse the range list.
- Ranges = ParseRangeList();
+ ParseRangeList(Ranges);
if (Ranges.empty()) return true;
if (Lex.getCode() != tgtok::greater) {
@@ -625,7 +637,7 @@ bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) {
/// ParseOptionalBitList - Parse either a bit list in {}'s or nothing.
/// OptionalBitList ::= '{' RangeList '}'
/// OptionalBitList ::= /*empty*/
-bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) {
+bool TGParser::ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges) {
if (Lex.getCode() != tgtok::l_brace)
return false;
@@ -633,7 +645,7 @@ bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) {
Lex.Lex(); // eat the '{'
// Parse the range list.
- Ranges = ParseRangeList();
+ ParseRangeList(Ranges);
if (Ranges.empty()) return true;
if (Lex.getCode() != tgtok::r_brace) {
@@ -644,7 +656,6 @@ bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) {
return false;
}
-
/// ParseType - Parse and return a tblgen type. This returns null on error.
///
/// Type ::= STRING // string type
@@ -705,8 +716,7 @@ RecTy *TGParser::ParseType() {
/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID
/// has already been read.
-Init *TGParser::ParseIDValue(Record *CurRec,
- const std::string &Name, SMLoc NameLoc,
+Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
IDParseMode Mode) {
if (CurRec) {
if (const RecordVal *RV = CurRec->getValue(Name))
@@ -726,8 +736,7 @@ Init *TGParser::ParseIDValue(Record *CurRec,
}
if (CurMultiClass) {
- Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name,
- "::");
+ Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::");
if (CurMultiClass->Rec.isTemplateArg(MCName)) {
const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
@@ -739,22 +748,22 @@ Init *TGParser::ParseIDValue(Record *CurRec,
// If this is in a foreach loop, make sure it's not a loop iterator
for (const auto &L : Loops) {
VarInit *IterVar = dyn_cast<VarInit>(L.IterVar);
- if (IterVar && IterVar->getName() == Name)
+ if (IterVar && IterVar->getNameInit() == Name)
return IterVar;
}
if (Mode == ParseNameMode)
- return StringInit::get(Name);
+ return Name;
- if (Record *D = Records.getDef(Name))
+ if (Record *D = Records.getDef(Name->getValue()))
return DefInit::get(D);
if (Mode == ParseValueMode) {
- Error(NameLoc, "Variable not defined: '" + Name + "'");
+ Error(NameLoc, "Variable not defined: '" + Name->getValue() + "'");
return nullptr;
}
- return StringInit::get(Name);
+ return Name;
}
/// ParseOperation - Parse an operator. This returns null on error.
@@ -871,6 +880,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XConcat:
case tgtok::XADD:
case tgtok::XAND:
+ case tgtok::XOR:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
@@ -889,6 +899,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break;
case tgtok::XADD: Code = BinOpInit::ADD; Type = IntRecTy::get(); break;
case tgtok::XAND: Code = BinOpInit::AND; Type = IntRecTy::get(); break;
+ case tgtok::XOR: Code = BinOpInit::OR; Type = IntRecTy::get(); break;
case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break;
case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break;
case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break;
@@ -1110,7 +1121,6 @@ RecTy *TGParser::ParseOperatorType() {
return Type;
}
-
/// ParseSimpleValue - Parse a tblgen value. This returns null on error.
///
/// SimpleValue ::= IDValue
@@ -1173,7 +1183,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
break;
case tgtok::Id: {
SMLoc NameLoc = Lex.getLoc();
- std::string Name = Lex.getCurStrVal();
+ StringInit *Name = StringInit::get(Lex.getCurStrVal());
if (Lex.Lex() != tgtok::less) // consume the Id.
return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue
@@ -1186,14 +1196,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
// This is a CLASS<initvalslist> expression. This is supposed to synthesize
// a new anonymous definition, deriving from CLASS<initvalslist> with no
// body.
- Record *Class = Records.getClass(Name);
+ Record *Class = Records.getClass(Name->getValue());
if (!Class) {
- Error(NameLoc, "Expected a class name, got '" + Name + "'");
+ Error(NameLoc, "Expected a class name, got '" + Name->getValue() + "'");
return nullptr;
}
- std::vector<Init*> ValueList = ParseValueList(CurRec, Class);
- if (ValueList.empty()) return nullptr;
+ SubClassReference SCRef;
+ ParseValueList(SCRef.TemplateArgs, CurRec, Class);
+ if (SCRef.TemplateArgs.empty()) return nullptr;
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' at end of value list");
@@ -1206,10 +1217,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
auto NewRecOwner = llvm::make_unique<Record>(GetNewAnonymousName(), NameLoc,
Records, /*IsAnonymous=*/true);
Record *NewRec = NewRecOwner.get(); // Keep a copy since we may release.
- SubClassReference SCRef;
SCRef.RefRange = SMRange(NameLoc, EndLoc);
SCRef.Rec = Class;
- SCRef.TemplateArgs = ValueList;
// Add info about the subclass to NewRec.
if (AddSubClass(NewRec, SCRef))
return nullptr;
@@ -1251,10 +1260,10 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::l_brace: { // Value ::= '{' ValueList '}'
SMLoc BraceLoc = Lex.getLoc();
Lex.Lex(); // eat the '{'
- std::vector<Init*> Vals;
+ SmallVector<Init*, 16> Vals;
if (Lex.getCode() != tgtok::r_brace) {
- Vals = ParseValueList(CurRec);
+ ParseValueList(Vals, CurRec);
if (Vals.empty()) return nullptr;
}
if (Lex.getCode() != tgtok::r_brace) {
@@ -1301,7 +1310,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
}
case tgtok::l_square: { // Value ::= '[' ValueList ']'
Lex.Lex(); // eat the '['
- std::vector<Init*> Vals;
+ SmallVector<Init*, 16> Vals;
RecTy *DeducedEltTy = nullptr;
ListRecTy *GivenListTy = nullptr;
@@ -1317,8 +1326,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
}
if (Lex.getCode() != tgtok::r_square) {
- Vals = ParseValueList(CurRec, nullptr,
- GivenListTy ? GivenListTy->getElementType() : nullptr);
+ ParseValueList(Vals, CurRec, nullptr,
+ GivenListTy ? GivenListTy->getElementType() : nullptr);
if (Vals.empty()) return nullptr;
}
if (Lex.getCode() != tgtok::r_square) {
@@ -1405,19 +1414,19 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
if (!Operator) return nullptr;
// If the operator name is present, parse it.
- std::string OperatorName;
+ StringInit *OperatorName = nullptr;
if (Lex.getCode() == tgtok::colon) {
if (Lex.Lex() != tgtok::VarName) { // eat the ':'
TokError("expected variable name in dag operator");
return nullptr;
}
- OperatorName = Lex.getCurStrVal();
+ OperatorName = StringInit::get(Lex.getCurStrVal());
Lex.Lex(); // eat the VarName.
}
- std::vector<std::pair<llvm::Init*, std::string> > DagArgs;
+ SmallVector<std::pair<llvm::Init*, StringInit*>, 8> DagArgs;
if (Lex.getCode() != tgtok::r_paren) {
- DagArgs = ParseDagArgList(CurRec);
+ ParseDagArgList(DagArgs, CurRec);
if (DagArgs.empty()) return nullptr;
}
@@ -1437,6 +1446,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XConcat:
case tgtok::XADD:
case tgtok::XAND:
+ case tgtok::XOR:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
@@ -1465,7 +1475,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
if (!Result) return nullptr;
// Parse the suffixes now if present.
- while (1) {
+ while (true) {
switch (Lex.getCode()) {
default: return Result;
case tgtok::l_brace: {
@@ -1475,7 +1485,8 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
SMLoc CurlyLoc = Lex.getLoc();
Lex.Lex(); // eat the '{'
- std::vector<unsigned> Ranges = ParseRangeList();
+ SmallVector<unsigned, 16> Ranges;
+ ParseRangeList(Ranges);
if (Ranges.empty()) return nullptr;
// Reverse the bitlist.
@@ -1497,7 +1508,8 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
case tgtok::l_square: {
SMLoc SquareLoc = Lex.getLoc();
Lex.Lex(); // eat the '['
- std::vector<unsigned> Ranges = ParseRangeList();
+ SmallVector<unsigned, 16> Ranges;
+ ParseRangeList(Ranges);
if (Ranges.empty()) return nullptr;
Result = Result->convertInitListSlice(Ranges);
@@ -1514,19 +1526,21 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
Lex.Lex();
break;
}
- case tgtok::period:
+ case tgtok::period: {
if (Lex.Lex() != tgtok::Id) { // eat the .
TokError("expected field identifier after '.'");
return nullptr;
}
- if (!Result->getFieldType(Lex.getCurStrVal())) {
+ StringInit *FieldName = StringInit::get(Lex.getCurStrVal());
+ if (!Result->getFieldType(FieldName)) {
TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
Result->getAsString() + "'");
return nullptr;
}
- Result = FieldInit::get(Result, Lex.getCurStrVal());
+ Result = FieldInit::get(Result, FieldName);
Lex.Lex(); // eat field name
break;
+ }
case tgtok::paste:
SMLoc PasteLoc = Lex.getLoc();
@@ -1587,30 +1601,34 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
/// DagArg ::= VARNAME
/// DagArgList ::= DagArg
/// DagArgList ::= DagArgList ',' DagArg
-std::vector<std::pair<llvm::Init*, std::string> >
-TGParser::ParseDagArgList(Record *CurRec) {
- std::vector<std::pair<llvm::Init*, std::string> > Result;
+void TGParser::ParseDagArgList(
+ SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result,
+ Record *CurRec) {
- while (1) {
+ while (true) {
// DagArg ::= VARNAME
if (Lex.getCode() == tgtok::VarName) {
// A missing value is treated like '?'.
- Result.emplace_back(UnsetInit::get(), Lex.getCurStrVal());
+ StringInit *VarName = StringInit::get(Lex.getCurStrVal());
+ Result.emplace_back(UnsetInit::get(), VarName);
Lex.Lex();
} else {
// DagArg ::= Value (':' VARNAME)?
Init *Val = ParseValue(CurRec);
- if (!Val)
- return std::vector<std::pair<llvm::Init*, std::string> >();
+ if (!Val) {
+ Result.clear();
+ return;
+ }
// If the variable name is present, add it.
- std::string VarName;
+ StringInit *VarName = nullptr;
if (Lex.getCode() == tgtok::colon) {
if (Lex.Lex() != tgtok::VarName) { // eat the ':'
TokError("expected variable name in dag literal");
- return std::vector<std::pair<llvm::Init*, std::string> >();
+ Result.clear();
+ return;
}
- VarName = Lex.getCurStrVal();
+ VarName = StringInit::get(Lex.getCurStrVal());
Lex.Lex(); // eat the VarName.
}
@@ -1619,27 +1637,24 @@ TGParser::ParseDagArgList(Record *CurRec) {
if (Lex.getCode() != tgtok::comma) break;
Lex.Lex(); // eat the ','
}
-
- return Result;
}
-
/// ParseValueList - Parse a comma separated list of values, returning them as a
/// vector. Note that this always expects to be able to parse at least one
/// value. It returns an empty list if this is not possible.
///
/// ValueList ::= Value (',' Value)
///
-std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
- RecTy *EltTy) {
- std::vector<Init*> Result;
+void TGParser::ParseValueList(SmallVectorImpl<Init*> &Result, Record *CurRec,
+ Record *ArgsRec, RecTy *EltTy) {
RecTy *ItemType = EltTy;
unsigned int ArgN = 0;
if (ArgsRec && !EltTy) {
ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();
if (TArgs.empty()) {
TokError("template argument provided to non-template class");
- return std::vector<Init*>();
+ Result.clear();
+ return;
}
const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
if (!RV) {
@@ -1651,7 +1666,10 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
++ArgN;
}
Result.push_back(ParseValue(CurRec, ItemType));
- if (!Result.back()) return std::vector<Init*>();
+ if (!Result.back()) {
+ Result.clear();
+ return;
+ }
while (Lex.getCode() == tgtok::comma) {
Lex.Lex(); // Eat the comma
@@ -1660,7 +1678,8 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();
if (ArgN >= TArgs.size()) {
TokError("too many template arguments");
- return std::vector<Init*>();
+ Result.clear();
+ return;
}
const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
assert(RV && "Template argument record not found??");
@@ -1668,13 +1687,13 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
++ArgN;
}
Result.push_back(ParseValue(CurRec, ItemType));
- if (!Result.back()) return std::vector<Init*>();
+ if (!Result.back()) {
+ Result.clear();
+ return;
+ }
}
-
- return Result;
}
-
/// ParseDeclaration - Read a declaration, returning the name of field ID, or an
/// empty string on error. This can happen in a number of different context's,
/// including within a def or in the template args for a def (which which case
@@ -1758,7 +1777,7 @@ VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
Lex.Lex(); // Eat the '='
RecTy *IterType = nullptr;
- std::vector<unsigned> Ranges;
+ SmallVector<unsigned, 16> Ranges;
switch (Lex.getCode()) {
default: TokError("Unknown token when expecting a range list"); return nullptr;
@@ -1787,7 +1806,7 @@ VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
case tgtok::l_brace: { // '{' RangeList '}'
Lex.Lex(); // eat the '{'
- Ranges = ParseRangeList();
+ ParseRangeList(Ranges);
if (Lex.getCode() != tgtok::r_brace) {
TokError("expected '}' at end of bit range list");
return nullptr;
@@ -1848,7 +1867,6 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
return false;
}
-
/// ParseBodyItem - Parse a single item at within the body of a def or class.
///
/// BodyItem ::= Declaration ';'
@@ -1869,10 +1887,10 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
return TokError("expected field identifier after let");
SMLoc IdLoc = Lex.getLoc();
- std::string FieldName = Lex.getCurStrVal();
+ StringInit *FieldName = StringInit::get(Lex.getCurStrVal());
Lex.Lex(); // eat the field name.
- std::vector<unsigned> BitList;
+ SmallVector<unsigned, 16> BitList;
if (ParseOptionalBitList(BitList))
return true;
std::reverse(BitList.begin(), BitList.end());
@@ -1883,7 +1901,7 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
RecordVal *Field = CurRec->getValue(FieldName);
if (!Field)
- return TokError("Value '" + FieldName + "' unknown!");
+ return TokError("Value '" + FieldName->getValue() + "' unknown!");
RecTy *Type = Field->getType();
@@ -1928,7 +1946,7 @@ bool TGParser::ParseBody(Record *CurRec) {
/// \brief Apply the current let bindings to \a CurRec.
/// \returns true on error, false otherwise.
bool TGParser::ApplyLetStack(Record *CurRec) {
- for (std::vector<LetRecord> &LetInfo : LetStack)
+ for (SmallVectorImpl<LetRecord> &LetInfo : LetStack)
for (LetRecord &LR : LetInfo)
if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))
return true;
@@ -1951,7 +1969,7 @@ bool TGParser::ParseObjectBody(Record *CurRec) {
// Read all of the subclasses.
SubClassReference SubClass = ParseSubClassReference(CurRec, false);
- while (1) {
+ while (true) {
// Check for error.
if (!SubClass.Rec) return true;
@@ -2139,38 +2157,44 @@ bool TGParser::ParseClass() {
/// LetList ::= LetItem (',' LetItem)*
/// LetItem ::= ID OptionalRangeList '=' Value
///
-std::vector<LetRecord> TGParser::ParseLetList() {
- std::vector<LetRecord> Result;
-
- while (1) {
+void TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) {
+ while (true) {
if (Lex.getCode() != tgtok::Id) {
TokError("expected identifier in let definition");
- return std::vector<LetRecord>();
+ Result.clear();
+ return;
}
- std::string Name = Lex.getCurStrVal();
+
+ StringInit *Name = StringInit::get(Lex.getCurStrVal());
SMLoc NameLoc = Lex.getLoc();
Lex.Lex(); // Eat the identifier.
// Check for an optional RangeList.
- std::vector<unsigned> Bits;
- if (ParseOptionalRangeList(Bits))
- return std::vector<LetRecord>();
+ SmallVector<unsigned, 16> Bits;
+ if (ParseOptionalRangeList(Bits)) {
+ Result.clear();
+ return;
+ }
std::reverse(Bits.begin(), Bits.end());
if (Lex.getCode() != tgtok::equal) {
TokError("expected '=' in let expression");
- return std::vector<LetRecord>();
+ Result.clear();
+ return;
}
Lex.Lex(); // eat the '='.
Init *Val = ParseValue(nullptr);
- if (!Val) return std::vector<LetRecord>();
+ if (!Val) {
+ Result.clear();
+ return;
+ }
// Now that we have everything, add the record.
- Result.emplace_back(std::move(Name), std::move(Bits), Val, NameLoc);
+ Result.emplace_back(Name, Bits, Val, NameLoc);
if (Lex.getCode() != tgtok::comma)
- return Result;
+ return;
Lex.Lex(); // eat the comma.
}
}
@@ -2186,7 +2210,8 @@ bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
Lex.Lex();
// Add this entry to the let stack.
- std::vector<LetRecord> LetInfo = ParseLetList();
+ SmallVector<LetRecord, 8> LetInfo;
+ ParseLetList(LetInfo);
if (LetInfo.empty()) return true;
LetStack.push_back(std::move(LetInfo));
@@ -2264,7 +2289,7 @@ bool TGParser::ParseMultiClass() {
// Read all of the submulticlasses.
SubMultiClassReference SubMultiClass =
ParseSubMultiClassReference(CurMultiClass);
- while (1) {
+ while (true) {
// Check for error.
if (!SubMultiClass.MC) return true;
@@ -2312,7 +2337,7 @@ Record *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto,
Init *&DefmPrefix,
SMRange DefmPrefixRange,
ArrayRef<Init *> TArgs,
- std::vector<Init *> &TemplateVals) {
+ ArrayRef<Init *> TemplateVals) {
// We need to preserve DefProto so it can be reused for later
// instantiations, so create a new Record to inherit from it.
@@ -2353,8 +2378,8 @@ Record *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto,
// Set the value for NAME. We don't resolve references to it 'til later,
// though, so that uses in nested multiclass names don't get
// confused.
- if (SetValue(CurRec.get(), Ref.RefRange.Start, "NAME", None, DefmPrefix,
- /*AllowSelfAssignment*/true)) {
+ if (SetValue(CurRec.get(), Ref.RefRange.Start, StringInit::get("NAME"), None,
+ DefmPrefix, /*AllowSelfAssignment*/true)) {
Error(DefmPrefixRange.Start, "Could not resolve " +
CurRec->getNameInitAsString() + ":NAME to '" +
DefmPrefix->getAsUnquotedString() + "'");
@@ -2433,7 +2458,7 @@ Record *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto,
bool TGParser::ResolveMulticlassDefArgs(MultiClass &MC, Record *CurRec,
SMLoc DefmPrefixLoc, SMLoc SubClassLoc,
ArrayRef<Init *> TArgs,
- std::vector<Init *> &TemplateVals,
+ ArrayRef<Init *> TemplateVals,
bool DeleteArgs) {
// Loop over all of the template arguments, setting them to the specified
// value or leaving them as the default if necessary.
@@ -2519,7 +2544,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
SMLoc SubClassLoc = Lex.getLoc();
SubClassReference Ref = ParseSubClassReference(nullptr, true);
- while (1) {
+ while (true) {
if (!Ref.Rec) return true;
// To instantiate a multiclass, we need to first get the multiclass, then
@@ -2527,7 +2552,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
// template parameters.
MultiClass *MC = MultiClasses[Ref.Rec->getName()].get();
assert(MC && "Didn't lookup multiclass correctly?");
- std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
+ ArrayRef<Init*> TemplateVals = Ref.TemplateArgs;
// Verify that the correct number of template arguments were specified.
ArrayRef<Init *> TArgs = MC->Rec.getTemplateArgs();
@@ -2589,7 +2614,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
// Process all the classes to inherit as if they were part of a
// regular 'def' and inherit all record values.
SubClassReference SubClass = ParseSubClassReference(nullptr, false);
- while (1) {
+ while (true) {
// Check for error.
if (!SubClass.Rec) return true;
@@ -2664,4 +2689,3 @@ bool TGParser::ParseFile() {
return TokError("Unexpected input at top level");
}
-
diff --git a/lib/TableGen/TGParser.h b/lib/TableGen/TGParser.h
index 739d9a9c5f37..76f7d8fe5026 100644
--- a/lib/TableGen/TGParser.h
+++ b/lib/TableGen/TGParser.h
@@ -32,12 +32,11 @@ namespace llvm {
struct SubMultiClassReference;
struct LetRecord {
- std::string Name;
+ StringInit *Name;
std::vector<unsigned> Bits;
Init *Value;
SMLoc Loc;
- LetRecord(const std::string &N, const std::vector<unsigned> &B, Init *V,
- SMLoc L)
+ LetRecord(StringInit *N, ArrayRef<unsigned> B, Init *V, SMLoc L)
: Name(N), Bits(B), Value(V), Loc(L) {
}
};
@@ -54,7 +53,7 @@ namespace llvm {
class TGParser {
TGLexer Lex;
- std::vector<std::vector<LetRecord> > LetStack;
+ std::vector<SmallVector<LetRecord, 4>> LetStack;
std::map<std::string, std::unique_ptr<MultiClass>> MultiClasses;
/// Loops - Keep track of any foreach loops we are within.
@@ -107,12 +106,6 @@ private: // Semantic analysis methods.
bool SetValue(Record *TheRec, SMLoc Loc, Init *ValName,
ArrayRef<unsigned> BitList, Init *V,
bool AllowSelfAssignment = false);
- bool SetValue(Record *TheRec, SMLoc Loc, const std::string &ValName,
- ArrayRef<unsigned> BitList, Init *V,
- bool AllowSelfAssignment = false) {
- return SetValue(TheRec, Loc, StringInit::get(ValName), BitList, V,
- AllowSelfAssignment);
- }
bool AddSubClass(Record *Rec, SubClassReference &SubClass);
bool AddSubMultiClass(MultiClass *CurMC,
SubMultiClassReference &SubMultiClass);
@@ -141,12 +134,11 @@ private: // Parser methods.
Record *InstantiateMulticlassDef(MultiClass &MC, Record *DefProto,
Init *&DefmPrefix, SMRange DefmPrefixRange,
ArrayRef<Init *> TArgs,
- std::vector<Init *> &TemplateVals);
+ ArrayRef<Init *> TemplateVals);
bool ResolveMulticlassDefArgs(MultiClass &MC, Record *DefProto,
SMLoc DefmPrefixLoc, SMLoc SubClassLoc,
ArrayRef<Init *> TArgs,
- std::vector<Init *> &TemplateVals,
- bool DeleteArgs);
+ ArrayRef<Init *> TemplateVals, bool DeleteArgs);
bool ResolveMulticlassDef(MultiClass &MC,
Record *CurRec,
Record *DefProto,
@@ -155,7 +147,7 @@ private: // Parser methods.
bool ParseDef(MultiClass *CurMultiClass);
bool ParseForeach(MultiClass *CurMultiClass);
bool ParseTopLevelLet(MultiClass *CurMultiClass);
- std::vector<LetRecord> ParseLetList();
+ void ParseLetList(SmallVectorImpl<LetRecord> &Result);
bool ParseObjectBody(Record *CurRec);
bool ParseBody(Record *CurRec);
@@ -168,19 +160,21 @@ private: // Parser methods.
SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
- Init *ParseIDValue(Record *CurRec, const std::string &Name, SMLoc NameLoc,
+ Init *ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
IDParseMode Mode = ParseValueMode);
Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = nullptr,
IDParseMode Mode = ParseValueMode);
Init *ParseValue(Record *CurRec, RecTy *ItemType = nullptr,
IDParseMode Mode = ParseValueMode);
- std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = nullptr,
- RecTy *EltTy = nullptr);
- std::vector<std::pair<llvm::Init*, std::string> > ParseDagArgList(Record *);
- bool ParseOptionalRangeList(std::vector<unsigned> &Ranges);
- bool ParseOptionalBitList(std::vector<unsigned> &Ranges);
- std::vector<unsigned> ParseRangeList();
- bool ParseRangePiece(std::vector<unsigned> &Ranges);
+ void ParseValueList(SmallVectorImpl<llvm::Init*> &Result, Record *CurRec,
+ Record *ArgsRec = nullptr, RecTy *EltTy = nullptr);
+ void ParseDagArgList(
+ SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result,
+ Record *CurRec);
+ bool ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges);
+ bool ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges);
+ void ParseRangeList(SmallVectorImpl<unsigned> &Result);
+ bool ParseRangePiece(SmallVectorImpl<unsigned> &Ranges);
RecTy *ParseType();
Init *ParseOperation(Record *CurRec, RecTy *ItemType);
RecTy *ParseOperatorType();