summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/TableGen
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-11-24 17:02:24 +0000
committerdim <dim@FreeBSD.org>2014-11-24 17:02:24 +0000
commit2c8643c6396b0a3db33430cf9380e70bbb9efce0 (patch)
tree4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/lib/TableGen
parent678318cd20f7db4e6c6b85d83fe00fa327b04fca (diff)
parente27feadae0885aa074df58ebfda2e7a7f7a7d590 (diff)
downloadFreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.zip
FreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.tar.gz
Merge llvm 3.5.0 release from ^/vendor/llvm/dist, resolve conflicts, and
preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/lib/TableGen')
-rw-r--r--contrib/llvm/lib/TableGen/Error.cpp6
-rw-r--r--contrib/llvm/lib/TableGen/Main.cpp20
-rw-r--r--contrib/llvm/lib/TableGen/Record.cpp242
-rw-r--r--contrib/llvm/lib/TableGen/SetTheory.cpp323
-rw-r--r--contrib/llvm/lib/TableGen/TGLexer.cpp33
-rw-r--r--contrib/llvm/lib/TableGen/TGLexer.h8
-rw-r--r--contrib/llvm/lib/TableGen/TGParser.cpp500
-rw-r--r--contrib/llvm/lib/TableGen/TGParser.h23
-rw-r--r--contrib/llvm/lib/TableGen/module.modulemap1
9 files changed, 766 insertions, 390 deletions
diff --git a/contrib/llvm/lib/TableGen/Error.cpp b/contrib/llvm/lib/TableGen/Error.cpp
index 928b120..8d9ae20 100644
--- a/contrib/llvm/lib/TableGen/Error.cpp
+++ b/contrib/llvm/lib/TableGen/Error.cpp
@@ -62,12 +62,12 @@ void PrintError(const Twine &Msg) {
errs() << "error:" << Msg << "\n";
}
-void PrintFatalError(const std::string &Msg) {
- PrintError(Twine(Msg));
+void PrintFatalError(const Twine &Msg) {
+ PrintError(Msg);
std::exit(1);
}
-void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const std::string &Msg) {
+void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
PrintError(ErrorLoc, Msg);
std::exit(1);
}
diff --git a/contrib/llvm/lib/TableGen/Main.cpp b/contrib/llvm/lib/TableGen/Main.cpp
index 7fe47bc..e317fbf 100644
--- a/contrib/llvm/lib/TableGen/Main.cpp
+++ b/contrib/llvm/lib/TableGen/Main.cpp
@@ -16,16 +16,16 @@
//===----------------------------------------------------------------------===//
#include "TGParser.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/system_error.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Main.h"
#include "llvm/TableGen/Record.h"
#include <algorithm>
#include <cstdio>
+#include <system_error>
using namespace llvm;
namespace {
@@ -57,7 +57,7 @@ static int createDependencyFile(const TGParser &Parser, const char *argv0) {
return 1;
}
std::string Error;
- tool_output_file DepOut(DependFilename.c_str(), Error);
+ tool_output_file DepOut(DependFilename.c_str(), Error, sys::fs::F_Text);
if (!Error.empty()) {
errs() << argv0 << ": error opening " << DependFilename
<< ":" << Error << "\n";
@@ -81,14 +81,14 @@ int TableGenMain(char *argv0, TableGenMainFn *MainFn) {
RecordKeeper Records;
// Parse the input file.
- OwningPtr<MemoryBuffer> File;
- if (error_code ec =
- MemoryBuffer::getFileOrSTDIN(InputFilename, File)) {
- errs() << "Could not open input file '" << InputFilename << "': "
- << ec.message() <<"\n";
+ 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;
}
- MemoryBuffer *F = File.take();
+ MemoryBuffer *F = FileOrErr.get().release();
// Tell SrcMgr about this buffer, which is what TGParser will pick up.
SrcMgr.AddNewSourceBuffer(F, SMLoc());
@@ -103,7 +103,7 @@ int TableGenMain(char *argv0, TableGenMainFn *MainFn) {
return 1;
std::string Error;
- tool_output_file Out(OutputFilename.c_str(), Error);
+ tool_output_file Out(OutputFilename.c_str(), Error, sys::fs::F_Text);
if (!Error.empty()) {
errs() << argv0 << ": error opening " << OutputFilename
<< ":" << Error << "\n";
diff --git a/contrib/llvm/lib/TableGen/Record.cpp b/contrib/llvm/lib/TableGen/Record.cpp
index 431f4aa..0f40904 100644
--- a/contrib/llvm/lib/TableGen/Record.cpp
+++ b/contrib/llvm/lib/TableGen/Record.cpp
@@ -101,13 +101,13 @@ bool RecTy::baseClassOf(const RecTy *RHS) const{
}
Init *BitRecTy::convertValue(BitsInit *BI) {
- if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
+ if (BI->getNumBits() != 1) return nullptr; // Only accept if just one bit!
return BI->getBit(0);
}
Init *BitRecTy::convertValue(IntInit *II) {
int64_t Val = II->getValue();
- if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit!
+ if (Val != 0 && Val != 1) return nullptr; // Only accept 0 or 1 for a bit!
return BitInit::get(Val != 0);
}
@@ -116,7 +116,7 @@ Init *BitRecTy::convertValue(TypedInit *VI) {
RecTy *Ty = VI->getType();
if (isa<BitRecTy>(Ty) || isa<BitsRecTy>(Ty) || isa<IntRecTy>(Ty))
return VI; // Accept variable if it is already of bit type!
- return 0;
+ return nullptr;
}
bool BitRecTy::baseClassOf(const RecTy *RHS) const{
@@ -151,8 +151,8 @@ Init *BitsRecTy::convertValue(UnsetInit *UI) {
}
Init *BitsRecTy::convertValue(BitInit *UI) {
- if (Size != 1) return 0; // Can only convert single bit.
- return BitsInit::get(UI);
+ if (Size != 1) return nullptr; // Can only convert single bit.
+ return BitsInit::get(UI);
}
/// canFitInBitfield - Return true if the number of bits is large enough to hold
@@ -170,7 +170,7 @@ Init *BitsRecTy::convertValue(IntInit *II) {
int64_t Value = II->getValue();
// Make sure this bitfield is large enough to hold the integer value.
if (!canFitInBitfield(Value, Size))
- return 0;
+ return nullptr;
SmallVector<Init *, 16> NewBits(Size);
@@ -184,7 +184,7 @@ Init *BitsRecTy::convertValue(BitsInit *BI) {
// If the number of bits is right, return it. Otherwise we need to expand or
// truncate.
if (BI->getNumBits() == Size) return BI;
- return 0;
+ return nullptr;
}
Init *BitsRecTy::convertValue(TypedInit *VI) {
@@ -199,7 +199,7 @@ Init *BitsRecTy::convertValue(TypedInit *VI) {
return BitsInit::get(NewBits);
}
- return 0;
+ return nullptr;
}
bool BitsRecTy::baseClassOf(const RecTy *RHS) const{
@@ -219,7 +219,7 @@ Init *IntRecTy::convertValue(BitsInit *BI) {
if (BitInit *Bit = dyn_cast<BitInit>(BI->getBit(i))) {
Result |= Bit->getValue() << i;
} else {
- return 0;
+ return nullptr;
}
return IntInit::get(Result);
}
@@ -227,7 +227,7 @@ Init *IntRecTy::convertValue(BitsInit *BI) {
Init *IntRecTy::convertValue(TypedInit *TI) {
if (TI->getType()->typeIsConvertibleTo(this))
return TI; // Accept variable if already of the right type!
- return 0;
+ return nullptr;
}
bool IntRecTy::baseClassOf(const RecTy *RHS) const{
@@ -238,7 +238,7 @@ bool IntRecTy::baseClassOf(const RecTy *RHS) const{
Init *StringRecTy::convertValue(UnOpInit *BO) {
if (BO->getOpcode() == UnOpInit::CAST) {
Init *L = BO->getOperand()->convertInitializerTo(this);
- if (L == 0) return 0;
+ if (!L) return nullptr;
if (L != BO->getOperand())
return UnOpInit::get(UnOpInit::CAST, L, new StringRecTy);
return BO;
@@ -251,7 +251,7 @@ Init *StringRecTy::convertValue(BinOpInit *BO) {
if (BO->getOpcode() == BinOpInit::STRCONCAT) {
Init *L = BO->getLHS()->convertInitializerTo(this);
Init *R = BO->getRHS()->convertInitializerTo(this);
- if (L == 0 || R == 0) return 0;
+ if (!L || !R) return nullptr;
if (L != BO->getLHS() || R != BO->getRHS())
return BinOpInit::get(BinOpInit::STRCONCAT, L, R, new StringRecTy);
return BO;
@@ -264,7 +264,7 @@ Init *StringRecTy::convertValue(BinOpInit *BO) {
Init *StringRecTy::convertValue(TypedInit *TI) {
if (isa<StringRecTy>(TI->getType()))
return TI; // Accept variable if already of the right type!
- return 0;
+ return nullptr;
}
std::string ListRecTy::getAsString() const {
@@ -280,10 +280,10 @@ Init *ListRecTy::convertValue(ListInit *LI) {
if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
Elements.push_back(CI);
else
- return 0;
+ return nullptr;
if (!isa<ListRecTy>(LI->getType()))
- return 0;
+ return nullptr;
return ListInit::get(Elements, this);
}
@@ -293,7 +293,7 @@ Init *ListRecTy::convertValue(TypedInit *TI) {
if (ListRecTy *LRT = dyn_cast<ListRecTy>(TI->getType()))
if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
return TI;
- return 0;
+ return nullptr;
}
bool ListRecTy::baseClassOf(const RecTy *RHS) const{
@@ -305,30 +305,30 @@ bool ListRecTy::baseClassOf(const RecTy *RHS) const{
Init *DagRecTy::convertValue(TypedInit *TI) {
if (TI->getType()->typeIsConvertibleTo(this))
return TI;
- return 0;
+ return nullptr;
}
Init *DagRecTy::convertValue(UnOpInit *BO) {
if (BO->getOpcode() == UnOpInit::CAST) {
Init *L = BO->getOperand()->convertInitializerTo(this);
- if (L == 0) return 0;
+ if (!L) return nullptr;
if (L != BO->getOperand())
return UnOpInit::get(UnOpInit::CAST, L, new DagRecTy);
return BO;
}
- return 0;
+ return nullptr;
}
Init *DagRecTy::convertValue(BinOpInit *BO) {
if (BO->getOpcode() == BinOpInit::CONCAT) {
Init *L = BO->getLHS()->convertInitializerTo(this);
Init *R = BO->getRHS()->convertInitializerTo(this);
- if (L == 0 || R == 0) return 0;
+ if (!L || !R) return nullptr;
if (L != BO->getLHS() || R != BO->getRHS())
return BinOpInit::get(BinOpInit::CONCAT, L, R, new DagRecTy);
return BO;
}
- return 0;
+ return nullptr;
}
RecordRecTy *RecordRecTy::get(Record *R) {
@@ -342,7 +342,7 @@ std::string RecordRecTy::getAsString() const {
Init *RecordRecTy::convertValue(DefInit *DI) {
// Ensure that DI is a subclass of Rec.
if (!DI->getDef()->isSubClassOf(Rec))
- return 0;
+ return nullptr;
return DI;
}
@@ -352,7 +352,7 @@ Init *RecordRecTy::convertValue(TypedInit *TI) {
if (RRT->getRecord()->isSubClassOf(getRecord()) ||
RRT->getRecord() == getRecord())
return TI;
- return 0;
+ return nullptr;
}
bool RecordRecTy::baseClassOf(const RecTy *RHS) const{
@@ -391,7 +391,7 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
++i) {
RecordRecTy *SuperRecTy1 = RecordRecTy::get(*i);
RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
- if (NewType1 != 0) {
+ if (NewType1) {
if (NewType1 != SuperRecTy1) {
delete SuperRecTy1;
}
@@ -409,7 +409,7 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
++i) {
RecordRecTy *SuperRecTy2 = RecordRecTy::get(*i);
RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
- if (NewType2 != 0) {
+ if (NewType2) {
if (NewType2 != SuperRecTy2) {
delete SuperRecTy2;
}
@@ -417,7 +417,7 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
}
}
}
- return 0;
+ return nullptr;
}
@@ -462,7 +462,7 @@ BitsInit *BitsInit::get(ArrayRef<Init *> Range) {
FoldingSetNodeID ID;
ProfileBitsInit(ID, Range);
- void *IP = 0;
+ void *IP = nullptr;
if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
return I;
@@ -482,7 +482,7 @@ BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
if (Bits[i] >= getNumBits())
- return 0;
+ return nullptr;
NewBits[i] = getBit(Bits[i]);
}
return BitsInit::get(NewBits);
@@ -516,8 +516,8 @@ Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) const {
bool Changed = false;
SmallVector<Init *, 16> NewBits(getNumBits());
- Init *CachedInit = 0;
- Init *CachedBitVar = 0;
+ Init *CachedInit = nullptr;
+ Init *CachedBitVar = nullptr;
bool CachedBitVarChanged = false;
for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
@@ -590,7 +590,7 @@ IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
if (Bits[i] >= 64)
- return 0;
+ return nullptr;
NewBits[i] = BitInit::get(Value & (INT64_C(1) << Bits[i]));
}
@@ -623,18 +623,18 @@ static void ProfileListInit(FoldingSetNodeID &ID,
ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) {
typedef FoldingSet<ListInit> Pool;
static Pool ThePool;
+ static std::vector<std::unique_ptr<ListInit>> TheActualPool;
- // Just use the FoldingSetNodeID to compute a hash. Use a DenseMap
- // for actual storage.
FoldingSetNodeID ID;
ProfileListInit(ID, Range, EltTy);
- void *IP = 0;
+ void *IP = nullptr;
if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
return I;
ListInit *I = new ListInit(Range, EltTy);
ThePool.InsertNode(I, IP);
+ TheActualPool.push_back(std::unique_ptr<ListInit>(I));
return I;
}
@@ -651,7 +651,7 @@ 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] >= getSize())
- return 0;
+ return nullptr;
Vals.push_back(getElement(Elements[i]));
}
return ListInit::get(Vals, getType());
@@ -660,7 +660,7 @@ ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) const {
Record *ListInit::getElementAsRecord(unsigned i) const {
assert(i < Values.size() && "List element index out of range!");
DefInit *DI = dyn_cast<DefInit>(Values[i]);
- if (DI == 0)
+ if (!DI)
PrintFatalError("Expected record in list!");
return DI->getDef();
}
@@ -690,14 +690,14 @@ Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) const {
Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
unsigned Elt) const {
if (Elt >= getSize())
- return 0; // Out of range reference.
+ return nullptr; // Out of range reference.
Init *E = getElement(Elt);
// If the element is set to some value, or if we are resolving a reference
// to a specific variable and that variable is explicitly unset, then
// replace the VarListElementInit with it.
if (IRV || !isa<UnsetInit>(E))
return E;
- return 0;
+ return nullptr;
}
std::string ListInit::getAsString() const {
@@ -714,7 +714,7 @@ Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
Init *Resolved = resolveReferences(R, IRV);
OpInit *OResolved = dyn_cast<OpInit>(Resolved);
if (OResolved) {
- Resolved = OResolved->Fold(&R, 0);
+ Resolved = OResolved->Fold(&R, nullptr);
}
if (Resolved != this) {
@@ -728,7 +728,7 @@ Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
}
}
- return 0;
+ return nullptr;
}
Init *OpInit::getBit(unsigned Bit) const {
@@ -811,20 +811,14 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
}
case HEAD: {
if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
- if (LHSl->getSize() == 0) {
- assert(0 && "Empty list in car");
- return 0;
- }
+ assert(LHSl->getSize() != 0 && "Empty list in car");
return LHSl->getElement(0);
}
break;
}
case TAIL: {
if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
- if (LHSl->getSize() == 0) {
- assert(0 && "Empty list in cdr");
- return 0;
- }
+ assert(LHSl->getSize() != 0 && "Empty list in cdr");
// Note the +1. We can't just pass the result of getValues()
// directly.
ArrayRef<Init *>::iterator begin = LHSl->getValues().begin()+1;
@@ -862,8 +856,8 @@ Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) const {
Init *lhs = LHS->resolveReferences(R, RV);
if (LHS != lhs)
- return (UnOpInit::get(getOpcode(), lhs, getType()))->Fold(&R, 0);
- return Fold(&R, 0);
+ return (UnOpInit::get(getOpcode(), lhs, getType()))->Fold(&R, nullptr);
+ return Fold(&R, nullptr);
}
std::string UnOpInit::getAsString() const {
@@ -902,7 +896,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
if (LHSs && RHSs) {
DefInit *LOp = dyn_cast<DefInit>(LHSs->getOperator());
DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator());
- if (LOp == 0 || ROp == 0 || LOp->getDef() != ROp->getDef())
+ if (!LOp || !ROp || LOp->getDef() != ROp->getDef())
PrintFatalError("Concated Dag operators do not match!");
std::vector<Init*> Args;
std::vector<std::string> ArgNames;
@@ -918,6 +912,18 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
}
break;
}
+ case LISTCONCAT: {
+ ListInit *LHSs = dyn_cast<ListInit>(LHS);
+ ListInit *RHSs = dyn_cast<ListInit>(RHS);
+ if (LHSs && RHSs) {
+ std::vector<Init *> Args;
+ Args.insert(Args.end(), LHSs->begin(), LHSs->end());
+ Args.insert(Args.end(), RHSs->begin(), RHSs->end());
+ return ListInit::get(
+ Args, static_cast<ListRecTy *>(LHSs->getType())->getElementType());
+ }
+ break;
+ }
case STRCONCAT: {
StringInit *LHSs = dyn_cast<StringInit>(LHS);
StringInit *RHSs = dyn_cast<StringInit>(RHS);
@@ -949,8 +955,10 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
case SHL:
case SRA:
case SRL: {
- IntInit *LHSi = dyn_cast<IntInit>(LHS);
- IntInit *RHSi = dyn_cast<IntInit>(RHS);
+ IntInit *LHSi =
+ dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get()));
+ IntInit *RHSi =
+ dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get()));
if (LHSi && RHSi) {
int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
int64_t Result;
@@ -974,8 +982,8 @@ Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) const {
Init *rhs = RHS->resolveReferences(R, RV);
if (LHS != lhs || RHS != rhs)
- return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
- return Fold(&R, 0);
+ return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))->Fold(&R,nullptr);
+ return Fold(&R, nullptr);
}
std::string BinOpInit::getAsString() const {
@@ -987,6 +995,7 @@ std::string BinOpInit::getAsString() const {
case SRA: Result = "!sra"; break;
case SRL: Result = "!srl"; break;
case EQ: Result = "!eq"; break;
+ case LISTCONCAT: Result = "!listconcat"; break;
case STRCONCAT: Result = "!strconcat"; break;
}
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
@@ -1031,11 +1040,7 @@ static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
if (TArg && TArg->getType()->getAsString() == "dag") {
Init *Result = ForeachHelper(LHS, Arg, RHSo, Type,
CurRec, CurMultiClass);
- if (Result != 0) {
- return Result;
- } else {
- return 0;
- }
+ return Result;
}
for (int i = 0; i < RHSo->getNumOperands(); ++i) {
@@ -1044,7 +1049,7 @@ static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
if (RHSoo) {
Init *Result = EvaluateOperation(RHSoo, LHS, Arg,
Type, CurRec, CurMultiClass);
- if (Result != 0) {
+ if (Result) {
NewOperands.push_back(Result);
} else {
NewOperands.push_back(Arg);
@@ -1059,10 +1064,7 @@ static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
// Now run the operator and use its result as the new leaf
const OpInit *NewOp = RHSo->clone(NewOperands);
Init *NewVal = NewOp->Fold(CurRec, CurMultiClass);
- if (NewVal != NewOp)
- return NewVal;
-
- return 0;
+ return (NewVal != NewOp) ? NewVal : nullptr;
}
static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
@@ -1086,7 +1088,7 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
Init *Val = MHSd->getOperator();
Init *Result = EvaluateOperation(RHSo, LHS, Val,
Type, CurRec, CurMultiClass);
- if (Result != 0) {
+ if (Result) {
Val = Result;
}
@@ -1100,7 +1102,7 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
// Process args
Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type,
CurRec, CurMultiClass);
- if (Result != 0) {
+ if (Result) {
Arg = Result;
}
@@ -1138,7 +1140,7 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
return ListInit::get(NewList, MHSl->getType());
}
}
- return 0;
+ return nullptr;
}
Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
@@ -1195,7 +1197,7 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
case FOREACH: {
Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
CurRec, CurMultiClass);
- if (Result != 0) {
+ if (Result) {
return Result;
}
break;
@@ -1227,16 +1229,16 @@ Init *TernOpInit::resolveReferences(Record &R,
IntInit *Value = dyn_cast<IntInit>(lhs);
if (Init *I = lhs->convertInitializerTo(IntRecTy::get()))
Value = dyn_cast<IntInit>(I);
- if (Value != 0) {
+ if (Value) {
// Short-circuit
if (Value->getValue()) {
Init *mhs = MHS->resolveReferences(R, RV);
return (TernOpInit::get(getOpcode(), lhs, mhs,
- RHS, getType()))->Fold(&R, 0);
+ RHS, getType()))->Fold(&R, nullptr);
} else {
Init *rhs = RHS->resolveReferences(R, RV);
return (TernOpInit::get(getOpcode(), lhs, MHS,
- rhs, getType()))->Fold(&R, 0);
+ rhs, getType()))->Fold(&R, nullptr);
}
}
}
@@ -1246,8 +1248,8 @@ Init *TernOpInit::resolveReferences(Record &R,
if (LHS != lhs || MHS != mhs || RHS != rhs)
return (TernOpInit::get(getOpcode(), lhs, mhs, rhs,
- getType()))->Fold(&R, 0);
- return Fold(&R, 0);
+ getType()))->Fold(&R, nullptr);
+ return Fold(&R, nullptr);
}
std::string TernOpInit::getAsString() const {
@@ -1265,19 +1267,19 @@ RecTy *TypedInit::getFieldType(const std::string &FieldName) const {
if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType()))
if (RecordVal *Field = RecordType->getRecord()->getValue(FieldName))
return Field->getType();
- return 0;
+ return nullptr;
}
Init *
TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
BitsRecTy *T = dyn_cast<BitsRecTy>(getType());
- if (T == 0) return 0; // Cannot subscript a non-bits variable.
+ 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)
- return 0;
+ return nullptr;
NewBits[i] = VarBitInit::get(const_cast<TypedInit *>(this), Bits[i]);
}
@@ -1287,7 +1289,7 @@ TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
Init *
TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) const {
ListRecTy *T = dyn_cast<ListRecTy>(getType());
- if (T == 0) return 0; // Cannot subscript a non-list variable.
+ if (!T) return nullptr; // Cannot subscript a non-list variable.
if (Elements.size() == 1)
return VarListElementInit::get(const_cast<TypedInit *>(this), Elements[0]);
@@ -1332,8 +1334,8 @@ Init *VarInit::getBit(unsigned Bit) const {
Init *VarInit::resolveListElementReference(Record &R,
const RecordVal *IRV,
unsigned Elt) const {
- if (R.isTemplateArg(getNameInit())) return 0;
- if (IRV && IRV->getNameInit() != getNameInit()) return 0;
+ if (R.isTemplateArg(getNameInit())) return nullptr;
+ if (IRV && IRV->getNameInit() != getNameInit()) return nullptr;
RecordVal *RV = R.getValue(getNameInit());
assert(RV && "Reference to a non-existent variable?");
@@ -1345,14 +1347,14 @@ Init *VarInit::resolveListElementReference(Record &R,
}
if (Elt >= LI->getSize())
- return 0; // Out of range reference.
+ return nullptr; // Out of range reference.
Init *E = LI->getElement(Elt);
// If the element is set to some value, or if we are resolving a reference
// to a specific variable and that variable is explicitly unset, then
// replace the VarListElementInit with it.
if (IRV || !isa<UnsetInit>(E))
return E;
- return 0;
+ return nullptr;
}
@@ -1360,7 +1362,7 @@ RecTy *VarInit::getFieldType(const std::string &FieldName) const {
if (RecordRecTy *RTy = dyn_cast<RecordRecTy>(getType()))
if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
return RV->getType();
- return 0;
+ return nullptr;
}
Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
@@ -1368,15 +1370,15 @@ Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
if (isa<RecordRecTy>(getType()))
if (const RecordVal *Val = R.getValue(VarName)) {
if (RV != Val && (RV || isa<UnsetInit>(Val->getValue())))
- return 0;
+ return nullptr;
Init *TheInit = Val->getValue();
assert(TheInit != this && "Infinite loop detected!");
if (Init *I = TheInit->getFieldInit(R, RV, FieldName))
return I;
else
- return 0;
+ return nullptr;
}
- return 0;
+ return nullptr;
}
/// resolveReferences - This method is used by classes that refer to other
@@ -1386,7 +1388,7 @@ Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
///
Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) const {
if (RecordVal *Val = R.getValue(VarName))
- if (RV == Val || (RV == 0 && !isa<UnsetInit>(Val->getValue())))
+ if (RV == Val || (!RV && !isa<UnsetInit>(Val->getValue())))
return Val->getValue();
return const_cast<VarInit *>(this);
}
@@ -1462,7 +1464,7 @@ Init *VarListElementInit:: resolveListElementReference(Record &R,
return Result;
}
- return 0;
+ return nullptr;
}
DefInit *DefInit::get(Record *R) {
@@ -1472,7 +1474,7 @@ DefInit *DefInit::get(Record *R) {
RecTy *DefInit::getFieldType(const std::string &FieldName) const {
if (const RecordVal *RV = Def->getValue(FieldName))
return RV->getType();
- return 0;
+ return nullptr;
}
Init *DefInit::getFieldInit(Record &R, const RecordVal *RV,
@@ -1507,7 +1509,7 @@ Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
unsigned Elt) const {
if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName))
if (ListInit *LI = dyn_cast<ListInit>(ListVal)) {
- if (Elt >= LI->getSize()) return 0;
+ if (Elt >= LI->getSize()) return nullptr;
Init *E = LI->getElement(Elt);
// If the element is set to some value, or if we are resolving a
@@ -1516,7 +1518,7 @@ Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
if (RV || !isa<UnsetInit>(E))
return E;
}
- return 0;
+ return nullptr;
}
Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const {
@@ -1560,7 +1562,7 @@ DagInit::get(Init *V, const std::string &VN,
FoldingSetNodeID ID;
ProfileDagInit(ID, V, VN, ArgRange, NameRange);
- void *IP = 0;
+ void *IP = nullptr;
if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
return I;
@@ -1784,9 +1786,9 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
///
Init *Record::getValueInit(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
+ if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
- "' does not have a field named `" + FieldName.str() + "'!\n");
+ "' does not have a field named `" + FieldName + "'!\n");
return R->getValue();
}
@@ -1797,14 +1799,14 @@ Init *Record::getValueInit(StringRef FieldName) const {
///
std::string Record::getValueAsString(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
+ if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
- "' does not have a field named `" + FieldName.str() + "'!\n");
+ "' does not have a field named `" + FieldName + "'!\n");
if (StringInit *SI = dyn_cast<StringInit>(R->getValue()))
return SI->getValue();
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have a string initializer!");
+ FieldName + "' does not have a string initializer!");
}
/// getValueAsBitsInit - This method looks up the specified field and returns
@@ -1813,14 +1815,14 @@ std::string Record::getValueAsString(StringRef FieldName) const {
///
BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
+ if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
- "' does not have a field named `" + FieldName.str() + "'!\n");
+ "' does not have a field named `" + FieldName + "'!\n");
if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
return BI;
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have a BitsInit initializer!");
+ FieldName + "' does not have a BitsInit initializer!");
}
/// getValueAsListInit - This method looks up the specified field and returns
@@ -1829,14 +1831,14 @@ BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
///
ListInit *Record::getValueAsListInit(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
+ if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
- "' does not have a field named `" + FieldName.str() + "'!\n");
+ "' does not have a field named `" + FieldName + "'!\n");
if (ListInit *LI = dyn_cast<ListInit>(R->getValue()))
return LI;
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have a list initializer!");
+ FieldName + "' does not have a list initializer!");
}
/// getValueAsListOfDefs - This method looks up the specified field and returns
@@ -1852,7 +1854,7 @@ Record::getValueAsListOfDefs(StringRef FieldName) const {
Defs.push_back(DI->getDef());
} else {
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' list is not entirely DefInit!");
+ FieldName + "' list is not entirely DefInit!");
}
}
return Defs;
@@ -1864,14 +1866,14 @@ Record::getValueAsListOfDefs(StringRef FieldName) const {
///
int64_t Record::getValueAsInt(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
+ if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
- "' does not have a field named `" + FieldName.str() + "'!\n");
+ "' does not have a field named `" + FieldName + "'!\n");
if (IntInit *II = dyn_cast<IntInit>(R->getValue()))
return II->getValue();
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have an int initializer!");
+ FieldName + "' does not have an int initializer!");
}
/// getValueAsListOfInts - This method looks up the specified field and returns
@@ -1887,7 +1889,7 @@ Record::getValueAsListOfInts(StringRef FieldName) const {
Ints.push_back(II->getValue());
} else {
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have a list of ints initializer!");
+ FieldName + "' does not have a list of ints initializer!");
}
}
return Ints;
@@ -1906,7 +1908,7 @@ Record::getValueAsListOfStrings(StringRef FieldName) const {
Strings.push_back(II->getValue());
} else {
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have a list of strings initializer!");
+ FieldName + "' does not have a list of strings initializer!");
}
}
return Strings;
@@ -1918,14 +1920,14 @@ Record::getValueAsListOfStrings(StringRef FieldName) const {
///
Record *Record::getValueAsDef(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
+ if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
- "' does not have a field named `" + FieldName.str() + "'!\n");
+ "' does not have a field named `" + FieldName + "'!\n");
if (DefInit *DI = dyn_cast<DefInit>(R->getValue()))
return DI->getDef();
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have a def initializer!");
+ FieldName + "' does not have a def initializer!");
}
/// getValueAsBit - This method looks up the specified field and returns its
@@ -1934,19 +1936,19 @@ Record *Record::getValueAsDef(StringRef FieldName) const {
///
bool Record::getValueAsBit(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
+ if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
- "' does not have a field named `" + FieldName.str() + "'!\n");
+ "' does not have a field named `" + FieldName + "'!\n");
if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
return BI->getValue();
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have a bit initializer!");
+ FieldName + "' does not have a bit initializer!");
}
bool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const {
const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
+ if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
"' does not have a field named `" + FieldName.str() + "'!\n");
@@ -1958,7 +1960,7 @@ bool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const {
if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
return BI->getValue();
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have a bit initializer!");
+ FieldName + "' does not have a bit initializer!");
}
/// getValueAsDag - This method looks up the specified field and returns its
@@ -1967,14 +1969,14 @@ bool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const {
///
DagInit *Record::getValueAsDag(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
+ if (!R || !R->getValue())
PrintFatalError(getLoc(), "Record `" + getName() +
- "' does not have a field named `" + FieldName.str() + "'!\n");
+ "' does not have a field named `" + FieldName + "'!\n");
if (DagInit *DI = dyn_cast<DagInit>(R->getValue()))
return DI;
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
- FieldName.str() + "' does not have a dag initializer!");
+ FieldName + "' does not have a dag initializer!");
}
diff --git a/contrib/llvm/lib/TableGen/SetTheory.cpp b/contrib/llvm/lib/TableGen/SetTheory.cpp
new file mode 100644
index 0000000..c99c2ba
--- /dev/null
+++ b/contrib/llvm/lib/TableGen/SetTheory.cpp
@@ -0,0 +1,323 @@
+//===- SetTheory.cpp - Generate ordered sets from DAG expressions ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SetTheory class that computes ordered sets of
+// Records from DAG expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Format.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/SetTheory.h"
+
+using namespace llvm;
+
+// Define the standard operators.
+namespace {
+
+typedef SetTheory::RecSet RecSet;
+typedef SetTheory::RecVec RecVec;
+
+// (add a, b, ...) Evaluate and union all arguments.
+struct AddOp : public SetTheory::Operator {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
+ ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts, Loc);
+ }
+};
+
+// (sub Add, Sub, ...) Set difference.
+struct SubOp : public SetTheory::Operator {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
+ if (Expr->arg_size() < 2)
+ PrintFatalError(Loc, "Set difference needs at least two arguments: " +
+ Expr->getAsString());
+ RecSet Add, Sub;
+ ST.evaluate(*Expr->arg_begin(), Add, Loc);
+ ST.evaluate(Expr->arg_begin() + 1, Expr->arg_end(), Sub, Loc);
+ for (RecSet::iterator I = Add.begin(), E = Add.end(); I != E; ++I)
+ if (!Sub.count(*I))
+ Elts.insert(*I);
+ }
+};
+
+// (and S1, S2) Set intersection.
+struct AndOp : public SetTheory::Operator {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
+ if (Expr->arg_size() != 2)
+ PrintFatalError(Loc, "Set intersection requires two arguments: " +
+ Expr->getAsString());
+ RecSet S1, S2;
+ ST.evaluate(Expr->arg_begin()[0], S1, Loc);
+ ST.evaluate(Expr->arg_begin()[1], S2, Loc);
+ for (RecSet::iterator I = S1.begin(), E = S1.end(); I != E; ++I)
+ if (S2.count(*I))
+ Elts.insert(*I);
+ }
+};
+
+// SetIntBinOp - Abstract base class for (Op S, N) operators.
+struct SetIntBinOp : public SetTheory::Operator {
+ virtual void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) = 0;
+
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
+ if (Expr->arg_size() != 2)
+ PrintFatalError(Loc, "Operator requires (Op Set, Int) arguments: " +
+ Expr->getAsString());
+ RecSet Set;
+ ST.evaluate(Expr->arg_begin()[0], Set, Loc);
+ IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[1]);
+ if (!II)
+ PrintFatalError(Loc, "Second argument must be an integer: " +
+ Expr->getAsString());
+ apply2(ST, Expr, Set, II->getValue(), Elts, Loc);
+ }
+};
+
+// (shl S, N) Shift left, remove the first N elements.
+struct ShlOp : public SetIntBinOp {
+ void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) override {
+ if (N < 0)
+ PrintFatalError(Loc, "Positive shift required: " +
+ Expr->getAsString());
+ if (unsigned(N) < Set.size())
+ Elts.insert(Set.begin() + N, Set.end());
+ }
+};
+
+// (trunc S, N) Truncate after the first N elements.
+struct TruncOp : public SetIntBinOp {
+ void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) override {
+ if (N < 0)
+ PrintFatalError(Loc, "Positive length required: " +
+ Expr->getAsString());
+ if (unsigned(N) > Set.size())
+ N = Set.size();
+ Elts.insert(Set.begin(), Set.begin() + N);
+ }
+};
+
+// Left/right rotation.
+struct RotOp : public SetIntBinOp {
+ const bool Reverse;
+
+ RotOp(bool Rev) : Reverse(Rev) {}
+
+ void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) override {
+ if (Reverse)
+ N = -N;
+ // N > 0 -> rotate left, N < 0 -> rotate right.
+ if (Set.empty())
+ return;
+ if (N < 0)
+ N = Set.size() - (-N % Set.size());
+ else
+ N %= Set.size();
+ Elts.insert(Set.begin() + N, Set.end());
+ Elts.insert(Set.begin(), Set.begin() + N);
+ }
+};
+
+// (decimate S, N) Pick every N'th element of S.
+struct DecimateOp : public SetIntBinOp {
+ void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) override {
+ if (N <= 0)
+ PrintFatalError(Loc, "Positive stride required: " +
+ Expr->getAsString());
+ for (unsigned I = 0; I < Set.size(); I += N)
+ Elts.insert(Set[I]);
+ }
+};
+
+// (interleave S1, S2, ...) Interleave elements of the arguments.
+struct InterleaveOp : public SetTheory::Operator {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
+ // Evaluate the arguments individually.
+ SmallVector<RecSet, 4> Args(Expr->getNumArgs());
+ unsigned MaxSize = 0;
+ for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i) {
+ ST.evaluate(Expr->getArg(i), Args[i], Loc);
+ MaxSize = std::max(MaxSize, unsigned(Args[i].size()));
+ }
+ // Interleave arguments into Elts.
+ for (unsigned n = 0; n != MaxSize; ++n)
+ for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i)
+ if (n < Args[i].size())
+ Elts.insert(Args[i][n]);
+ }
+};
+
+// (sequence "Format", From, To) Generate a sequence of records by name.
+struct SequenceOp : public SetTheory::Operator {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
+ int Step = 1;
+ if (Expr->arg_size() > 4)
+ PrintFatalError(Loc, "Bad args to (sequence \"Format\", From, To): " +
+ Expr->getAsString());
+ else if (Expr->arg_size() == 4) {
+ if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[3])) {
+ Step = II->getValue();
+ } else
+ PrintFatalError(Loc, "Stride must be an integer: " +
+ Expr->getAsString());
+ }
+
+ std::string Format;
+ if (StringInit *SI = dyn_cast<StringInit>(Expr->arg_begin()[0]))
+ Format = SI->getValue();
+ else
+ PrintFatalError(Loc, "Format must be a string: " + Expr->getAsString());
+
+ int64_t From, To;
+ if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[1]))
+ From = II->getValue();
+ else
+ PrintFatalError(Loc, "From must be an integer: " + Expr->getAsString());
+ if (From < 0 || From >= (1 << 30))
+ PrintFatalError(Loc, "From out of range");
+
+ if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[2]))
+ To = II->getValue();
+ else
+ PrintFatalError(Loc, "From must be an integer: " + Expr->getAsString());
+ if (To < 0 || To >= (1 << 30))
+ PrintFatalError(Loc, "To out of range");
+
+ RecordKeeper &Records =
+ cast<DefInit>(Expr->getOperator())->getDef()->getRecords();
+
+ Step *= From <= To ? 1 : -1;
+ while (true) {
+ if (Step > 0 && From > To)
+ break;
+ else if (Step < 0 && From < To)
+ break;
+ std::string Name;
+ raw_string_ostream OS(Name);
+ OS << format(Format.c_str(), unsigned(From));
+ Record *Rec = Records.getDef(OS.str());
+ if (!Rec)
+ PrintFatalError(Loc, "No def named '" + Name + "': " +
+ Expr->getAsString());
+ // Try to reevaluate Rec in case it is a set.
+ if (const RecVec *Result = ST.expand(Rec))
+ Elts.insert(Result->begin(), Result->end());
+ else
+ Elts.insert(Rec);
+
+ From += Step;
+ }
+ }
+};
+
+// Expand a Def into a set by evaluating one of its fields.
+struct FieldExpander : public SetTheory::Expander {
+ StringRef FieldName;
+
+ FieldExpander(StringRef fn) : FieldName(fn) {}
+
+ void expand(SetTheory &ST, Record *Def, RecSet &Elts) override {
+ ST.evaluate(Def->getValueInit(FieldName), Elts, Def->getLoc());
+ }
+};
+} // end anonymous namespace
+
+// Pin the vtables to this file.
+void SetTheory::Operator::anchor() {}
+void SetTheory::Expander::anchor() {}
+
+
+SetTheory::SetTheory() {
+ addOperator("add", new AddOp);
+ addOperator("sub", new SubOp);
+ addOperator("and", new AndOp);
+ addOperator("shl", new ShlOp);
+ addOperator("trunc", new TruncOp);
+ addOperator("rotl", new RotOp(false));
+ addOperator("rotr", new RotOp(true));
+ addOperator("decimate", new DecimateOp);
+ addOperator("interleave", new InterleaveOp);
+ addOperator("sequence", new SequenceOp);
+}
+
+void SetTheory::addOperator(StringRef Name, Operator *Op) {
+ Operators[Name] = Op;
+}
+
+void SetTheory::addExpander(StringRef ClassName, Expander *E) {
+ Expanders[ClassName] = E;
+}
+
+void SetTheory::addFieldExpander(StringRef ClassName, StringRef FieldName) {
+ addExpander(ClassName, new FieldExpander(FieldName));
+}
+
+void SetTheory::evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc) {
+ // A def in a list can be a just an element, or it may expand.
+ if (DefInit *Def = dyn_cast<DefInit>(Expr)) {
+ if (const RecVec *Result = expand(Def->getDef()))
+ return Elts.insert(Result->begin(), Result->end());
+ Elts.insert(Def->getDef());
+ return;
+ }
+
+ // Lists simply expand.
+ if (ListInit *LI = dyn_cast<ListInit>(Expr))
+ return evaluate(LI->begin(), LI->end(), Elts, Loc);
+
+ // Anything else must be a DAG.
+ DagInit *DagExpr = dyn_cast<DagInit>(Expr);
+ if (!DagExpr)
+ PrintFatalError(Loc, "Invalid set element: " + Expr->getAsString());
+ DefInit *OpInit = dyn_cast<DefInit>(DagExpr->getOperator());
+ if (!OpInit)
+ PrintFatalError(Loc, "Bad set expression: " + Expr->getAsString());
+ Operator *Op = Operators.lookup(OpInit->getDef()->getName());
+ if (!Op)
+ PrintFatalError(Loc, "Unknown set operator: " + Expr->getAsString());
+ Op->apply(*this, DagExpr, Elts, Loc);
+}
+
+const RecVec *SetTheory::expand(Record *Set) {
+ // Check existing entries for Set and return early.
+ ExpandMap::iterator I = Expansions.find(Set);
+ if (I != Expansions.end())
+ return &I->second;
+
+ // This is the first time we see Set. Find a suitable expander.
+ const std::vector<Record*> &SC = Set->getSuperClasses();
+ for (unsigned i = 0, e = SC.size(); i != e; ++i) {
+ // Skip unnamed superclasses.
+ if (!dyn_cast<StringInit>(SC[i]->getNameInit()))
+ continue;
+ if (Expander *Exp = Expanders.lookup(SC[i]->getName())) {
+ // This breaks recursive definitions.
+ RecVec &EltVec = Expansions[Set];
+ RecSet Elts;
+ Exp->expand(*this, Set, Elts);
+ EltVec.assign(Elts.begin(), Elts.end());
+ return &EltVec;
+ }
+ }
+
+ // Set is not expandable.
+ return nullptr;
+}
+
diff --git a/contrib/llvm/lib/TableGen/TGLexer.cpp b/contrib/llvm/lib/TableGen/TGLexer.cpp
index c6be4f8..fc1d3ca 100644
--- a/contrib/llvm/lib/TableGen/TGLexer.cpp
+++ b/contrib/llvm/lib/TableGen/TGLexer.cpp
@@ -27,10 +27,10 @@
using namespace llvm;
TGLexer::TGLexer(SourceMgr &SM) : SrcMgr(SM) {
- CurBuffer = 0;
- CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
- CurPtr = CurBuf->getBufferStart();
- TokStart = 0;
+ CurBuffer = SrcMgr.getMainFileID();
+ CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer();
+ CurPtr = CurBuf.begin();
+ TokStart = nullptr;
}
SMLoc TGLexer::getLoc() const {
@@ -52,7 +52,7 @@ int TGLexer::getNextChar() {
case 0: {
// A nul character in the stream is either the end of the current buffer or
// a random nul in the file. Disambiguate that here.
- if (CurPtr-1 != CurBuf->getBufferEnd())
+ if (CurPtr-1 != CurBuf.end())
return 0; // Just whitespace.
// If this is the end of an included file, pop the parent file off the
@@ -60,7 +60,7 @@ int TGLexer::getNextChar() {
SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
if (ParentIncludeLoc != SMLoc()) {
CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
- CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
+ CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer();
CurPtr = ParentIncludeLoc.getPointer();
return getNextChar();
}
@@ -187,7 +187,7 @@ tgtok::TokKind TGLexer::LexString() {
while (*CurPtr != '"') {
// If we hit the end of the buffer, report an error.
- if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd())
+ if (*CurPtr == 0 && CurPtr == CurBuf.end())
return ReturnError(StrStart, "End of file in string literal");
if (*CurPtr == '\n' || *CurPtr == '\r')
@@ -220,7 +220,7 @@ tgtok::TokKind TGLexer::LexString() {
// If we hit the end of the buffer, report an error.
case '\0':
- if (CurPtr == CurBuf->getBufferEnd())
+ if (CurPtr == CurBuf.end())
return ReturnError(StrStart, "End of file in string literal");
// FALL THROUGH
default:
@@ -304,7 +304,7 @@ bool TGLexer::LexInclude() {
CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr),
IncludedFile);
- if (CurBuffer == -1) {
+ if (!CurBuffer) {
PrintError(getLoc(), "Could not find include file '" + Filename + "'");
return true;
}
@@ -319,8 +319,8 @@ bool TGLexer::LexInclude() {
}
Dependencies.insert(std::make_pair(IncludedFile, getLoc()));
// Save the line number and lex buffer of the includer.
- CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
- CurPtr = CurBuf->getBufferStart();
+ CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer();
+ CurPtr = CurBuf.begin();
return false;
}
@@ -333,7 +333,7 @@ void TGLexer::SkipBCPLComment() {
return; // Newline is end of comment.
case 0:
// If this is the end of the buffer, end the comment.
- if (CurPtr == CurBuf->getBufferEnd())
+ if (CurPtr == CurBuf.end())
return;
break;
}
@@ -389,12 +389,12 @@ tgtok::TokKind TGLexer::LexNumber() {
return ReturnError(TokStart, "Invalid hexadecimal number");
errno = 0;
- CurIntVal = strtoll(NumStart, 0, 16);
+ CurIntVal = strtoll(NumStart, nullptr, 16);
if (errno == EINVAL)
return ReturnError(TokStart, "Invalid hexadecimal number");
if (errno == ERANGE) {
errno = 0;
- CurIntVal = (int64_t)strtoull(NumStart, 0, 16);
+ CurIntVal = (int64_t)strtoull(NumStart, nullptr, 16);
if (errno == EINVAL)
return ReturnError(TokStart, "Invalid hexadecimal number");
if (errno == ERANGE)
@@ -410,7 +410,7 @@ tgtok::TokKind TGLexer::LexNumber() {
// Requires at least one binary digit.
if (CurPtr == NumStart)
return ReturnError(CurPtr-2, "Invalid binary number");
- CurIntVal = strtoll(NumStart, 0, 2);
+ CurIntVal = strtoll(NumStart, nullptr, 2);
return tgtok::IntVal;
}
}
@@ -425,7 +425,7 @@ tgtok::TokKind TGLexer::LexNumber() {
while (isdigit(CurPtr[0]))
++CurPtr;
- CurIntVal = strtoll(TokStart, 0, 10);
+ CurIntVal = strtoll(TokStart, nullptr, 10);
return tgtok::IntVal;
}
@@ -478,6 +478,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
.Case("empty", tgtok::XEmpty)
.Case("subst", tgtok::XSubst)
.Case("foreach", tgtok::XForEach)
+ .Case("listconcat", tgtok::XListConcat)
.Case("strconcat", tgtok::XStrConcat)
.Default(tgtok::Error);
diff --git a/contrib/llvm/lib/TableGen/TGLexer.h b/contrib/llvm/lib/TableGen/TGLexer.h
index d1bd70d..a2c95ca 100644
--- a/contrib/llvm/lib/TableGen/TGLexer.h
+++ b/contrib/llvm/lib/TableGen/TGLexer.h
@@ -14,6 +14,7 @@
#ifndef TGLEXER_H
#define TGLEXER_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
#include <cassert>
@@ -21,7 +22,6 @@
#include <string>
namespace llvm {
-class MemoryBuffer;
class SourceMgr;
class SMLoc;
class Twine;
@@ -47,7 +47,7 @@ namespace tgtok {
MultiClass, String,
// !keywords.
- XConcat, XADD, XSRA, XSRL, XSHL, XStrConcat, XCast, XSubst,
+ XConcat, XADD, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast, XSubst,
XForEach, XHead, XTail, XEmpty, XIf, XEq,
// Integer value.
@@ -63,7 +63,7 @@ class TGLexer {
SourceMgr &SrcMgr;
const char *CurPtr;
- const MemoryBuffer *CurBuf;
+ StringRef CurBuf;
// Information about the current token.
const char *TokStart;
@@ -73,7 +73,7 @@ class TGLexer {
/// CurBuffer - This is the current buffer index we're lexing from as managed
/// by the SourceMgr object.
- int CurBuffer;
+ unsigned CurBuffer;
public:
typedef std::map<std::string, SMLoc> DependenciesMapTy;
diff --git a/contrib/llvm/lib/TableGen/TGParser.cpp b/contrib/llvm/lib/TableGen/TGParser.cpp
index daac574..0550692 100644
--- a/contrib/llvm/lib/TableGen/TGParser.cpp
+++ b/contrib/llvm/lib/TableGen/TGParser.cpp
@@ -29,18 +29,18 @@ struct SubClassReference {
SMRange RefRange;
Record *Rec;
std::vector<Init*> TemplateArgs;
- SubClassReference() : Rec(0) {}
+ SubClassReference() : Rec(nullptr) {}
- bool isInvalid() const { return Rec == 0; }
+ bool isInvalid() const { return Rec == nullptr; }
};
struct SubMultiClassReference {
SMRange RefRange;
MultiClass *MC;
std::vector<Init*> TemplateArgs;
- SubMultiClassReference() : MC(0) {}
+ SubMultiClassReference() : MC(nullptr) {}
- bool isInvalid() const { return MC == 0; }
+ bool isInvalid() const { return MC == nullptr; }
void dump() const;
};
@@ -61,7 +61,7 @@ void SubMultiClassReference::dump() const {
} // end namespace llvm
bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
- if (CurRec == 0)
+ if (!CurRec)
CurRec = &CurMultiClass->Rec;
if (RecordVal *ERV = CurRec->getValue(RV.getNameInit())) {
@@ -83,10 +83,10 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
const std::vector<unsigned> &BitList, Init *V) {
if (!V) return false;
- if (CurRec == 0) CurRec = &CurMultiClass->Rec;
+ if (!CurRec) CurRec = &CurMultiClass->Rec;
RecordVal *RV = CurRec->getValue(ValName);
- if (RV == 0)
+ if (!RV)
return Error(Loc, "Value '" + ValName->getAsUnquotedString()
+ "' unknown!");
@@ -103,19 +103,19 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
//
if (!BitList.empty()) {
BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue());
- if (CurVal == 0)
+ if (!CurVal)
return Error(Loc, "Value '" + ValName->getAsUnquotedString()
+ "' is not a bits type");
// Convert the incoming value to a bits type of the appropriate size...
Init *BI = V->convertInitializerTo(BitsRecTy::get(BitList.size()));
- if (BI == 0) {
+ if (!BI) {
return Error(Loc, "Initializer is not compatible with bit range");
}
// We should have a BitsInit type now.
BitsInit *BInit = dyn_cast<BitsInit>(BI);
- assert(BInit != 0);
+ assert(BInit != nullptr);
SmallVector<Init *, 16> NewBits(CurVal->getNumBits());
@@ -129,7 +129,7 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
}
for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
- if (NewBits[i] == 0)
+ if (!NewBits[i])
NewBits[i] = CurVal->getBit(i);
V = BitsInit::get(NewBits);
@@ -314,14 +314,14 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
assert(IterVals.size() < Loops.size());
ForeachLoop &CurLoop = Loops[IterVals.size()];
ListInit *List = dyn_cast<ListInit>(CurLoop.ListValue);
- if (List == 0) {
+ if (!List) {
Error(Loc, "Loop list is not a list");
return true;
}
// Process each value.
for (int64_t i = 0; i < List->getSize(); ++i) {
- Init *ItemVal = List->resolveListElementReference(*CurRec, 0, i);
+ Init *ItemVal = List->resolveListElementReference(*CurRec, nullptr, i);
IterVals.push_back(IterRecord(CurLoop.IterVar, ItemVal));
if (ProcessForeachDefs(CurRec, Loc, IterVals))
return true;
@@ -339,7 +339,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
for (unsigned i = 0, e = IterVals.size(); i != e; ++i) {
VarInit *IterVar = IterVals[i].IterVar;
TypedInit *IVal = dyn_cast<TypedInit>(IterVals[i].IterValue);
- if (IVal == 0) {
+ if (!IVal) {
Error(Loc, "foreach iterator value is untyped");
return true;
}
@@ -360,8 +360,13 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
}
if (Records.getDef(IterRec->getNameInitAsString())) {
- Error(Loc, "def already exists: " + IterRec->getNameInitAsString());
- return true;
+ // If this record is anonymous, it's no problem, just generate a new name
+ if (IterRec->isAnonymous())
+ IterRec->setName(GetNewAnonymousName());
+ else {
+ Error(Loc, "def already exists: " + IterRec->getNameInitAsString());
+ return true;
+ }
}
Records.addDef(IterRec);
@@ -380,10 +385,11 @@ static bool isObjectStart(tgtok::TokKind K) {
K == tgtok::MultiClass || K == tgtok::Foreach;
}
-static std::string GetNewAnonymousName() {
- static unsigned AnonCounter = 0;
+/// GetNewAnonymousName - Generate a unique anonymous name that can be used as
+/// an identifier.
+std::string TGParser::GetNewAnonymousName() {
unsigned Tmp = AnonCounter++; // MSVC2012 ICEs without this.
- return "anonymous." + utostr(Tmp);
+ return "anonymous_" + utostr(Tmp);
}
/// ParseObjectName - If an object name is specified, return it. Otherwise,
@@ -399,21 +405,21 @@ Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
// These are all of the tokens that can begin an object body.
// Some of these can also begin values but we disallow those cases
// because they are unlikely to be useful.
- return 0;
+ return nullptr;
default:
break;
}
- Record *CurRec = 0;
+ Record *CurRec = nullptr;
if (CurMultiClass)
CurRec = &CurMultiClass->Rec;
- RecTy *Type = 0;
+ RecTy *Type = nullptr;
if (CurRec) {
const TypedInit *CurRecName = dyn_cast<TypedInit>(CurRec->getNameInit());
if (!CurRecName) {
TokError("Record name is not typed!");
- return 0;
+ return nullptr;
}
Type = CurRecName->getType();
}
@@ -429,11 +435,11 @@ Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
Record *TGParser::ParseClassID() {
if (Lex.getCode() != tgtok::Id) {
TokError("expected name for ClassID");
- return 0;
+ return nullptr;
}
Record *Result = Records.getClass(Lex.getCurStrVal());
- if (Result == 0)
+ if (!Result)
TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
Lex.Lex();
@@ -448,11 +454,11 @@ Record *TGParser::ParseClassID() {
MultiClass *TGParser::ParseMultiClassID() {
if (Lex.getCode() != tgtok::Id) {
TokError("expected name for MultiClassID");
- return 0;
+ return nullptr;
}
MultiClass *Result = MultiClasses[Lex.getCurStrVal()];
- if (Result == 0)
+ if (!Result)
TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'");
Lex.Lex();
@@ -476,7 +482,7 @@ ParseSubClassReference(Record *CurRec, bool isDefm) {
} else {
Result.Rec = ParseClassID();
}
- if (Result.Rec == 0) return Result;
+ if (!Result.Rec) return Result;
// If there is no template arg list, we're done.
if (Lex.getCode() != tgtok::less) {
@@ -487,19 +493,19 @@ ParseSubClassReference(Record *CurRec, bool isDefm) {
if (Lex.getCode() == tgtok::greater) {
TokError("subclass reference requires a non-empty list of template values");
- Result.Rec = 0;
+ Result.Rec = nullptr;
return Result;
}
Result.TemplateArgs = ParseValueList(CurRec, Result.Rec);
if (Result.TemplateArgs.empty()) {
- Result.Rec = 0; // Error parsing value list.
+ Result.Rec = nullptr; // Error parsing value list.
return Result;
}
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' in template value list");
- Result.Rec = 0;
+ Result.Rec = nullptr;
return Result;
}
Lex.Lex();
@@ -521,7 +527,7 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
Result.RefRange.Start = Lex.getLoc();
Result.MC = ParseMultiClassID();
- if (Result.MC == 0) return Result;
+ if (!Result.MC) return Result;
// If there is no template arg list, we're done.
if (Lex.getCode() != tgtok::less) {
@@ -532,19 +538,19 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
if (Lex.getCode() == tgtok::greater) {
TokError("subclass reference requires a non-empty list of template values");
- Result.MC = 0;
+ Result.MC = nullptr;
return Result;
}
Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec);
if (Result.TemplateArgs.empty()) {
- Result.MC = 0; // Error parsing value list.
+ Result.MC = nullptr; // Error parsing value list.
return Result;
}
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' in template value list");
- Result.MC = 0;
+ Result.MC = nullptr;
return Result;
}
Lex.Lex();
@@ -676,7 +682,7 @@ bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) {
///
RecTy *TGParser::ParseType() {
switch (Lex.getCode()) {
- default: TokError("Unknown token when expecting a type"); return 0;
+ default: TokError("Unknown token when expecting a type"); return nullptr;
case tgtok::String: Lex.Lex(); return StringRecTy::get();
case tgtok::Code: Lex.Lex(); return StringRecTy::get();
case tgtok::Bit: Lex.Lex(); return BitRecTy::get();
@@ -684,20 +690,20 @@ RecTy *TGParser::ParseType() {
case tgtok::Dag: Lex.Lex(); return DagRecTy::get();
case tgtok::Id:
if (Record *R = ParseClassID()) return RecordRecTy::get(R);
- return 0;
+ return nullptr;
case tgtok::Bits: {
if (Lex.Lex() != tgtok::less) { // Eat 'bits'
TokError("expected '<' after bits type");
- return 0;
+ return nullptr;
}
if (Lex.Lex() != tgtok::IntVal) { // Eat '<'
TokError("expected integer in bits<n> type");
- return 0;
+ return nullptr;
}
uint64_t Val = Lex.getCurIntVal();
if (Lex.Lex() != tgtok::greater) { // Eat count.
TokError("expected '>' at end of bits<n> type");
- return 0;
+ return nullptr;
}
Lex.Lex(); // Eat '>'
return BitsRecTy::get(Val);
@@ -705,15 +711,15 @@ RecTy *TGParser::ParseType() {
case tgtok::List: {
if (Lex.Lex() != tgtok::less) { // Eat 'bits'
TokError("expected '<' after list type");
- return 0;
+ return nullptr;
}
Lex.Lex(); // Eat '<'
RecTy *SubType = ParseType();
- if (SubType == 0) return 0;
+ if (!SubType) return nullptr;
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' at end of list<ty> type");
- return 0;
+ return nullptr;
}
Lex.Lex(); // Eat '>'
return ListRecTy::get(SubType);
@@ -721,22 +727,6 @@ RecTy *TGParser::ParseType() {
}
}
-/// ParseIDValue - Parse an ID as a value and decode what it means.
-///
-/// IDValue ::= ID [def local value]
-/// IDValue ::= ID [def template arg]
-/// IDValue ::= ID [multiclass local value]
-/// IDValue ::= ID [multiclass template argument]
-/// IDValue ::= ID [def name]
-///
-Init *TGParser::ParseIDValue(Record *CurRec, IDParseMode Mode) {
- assert(Lex.getCode() == tgtok::Id && "Expected ID in ParseIDValue");
- std::string Name = Lex.getCurStrVal();
- SMLoc Loc = Lex.getLoc();
- Lex.Lex();
- return ParseIDValue(CurRec, Name, Loc);
-}
-
/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID
/// has already been read.
Init *TGParser::ParseIDValue(Record *CurRec,
@@ -787,7 +777,7 @@ Init *TGParser::ParseIDValue(Record *CurRec,
if (Mode == ParseValueMode) {
Error(NameLoc, "Variable not defined: '" + Name + "'");
- return 0;
+ return nullptr;
}
return StringInit::get(Name);
@@ -797,17 +787,17 @@ Init *TGParser::ParseIDValue(Record *CurRec,
///
/// Operation ::= XOperator ['<' Type '>'] '(' Args ')'
///
-Init *TGParser::ParseOperation(Record *CurRec) {
+Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
switch (Lex.getCode()) {
default:
TokError("unknown operation");
- return 0;
+ return nullptr;
case tgtok::XHead:
case tgtok::XTail:
case tgtok::XEmpty:
case tgtok::XCast: { // Value ::= !unop '(' Value ')'
UnOpInit::UnaryOp Code;
- RecTy *Type = 0;
+ RecTy *Type = nullptr;
switch (Lex.getCode()) {
default: llvm_unreachable("Unhandled code!");
@@ -817,9 +807,9 @@ Init *TGParser::ParseOperation(Record *CurRec) {
Type = ParseOperatorType();
- if (Type == 0) {
+ if (!Type) {
TokError("did not get type for unary operator");
- return 0;
+ return nullptr;
}
break;
@@ -839,12 +829,12 @@ Init *TGParser::ParseOperation(Record *CurRec) {
}
if (Lex.getCode() != tgtok::l_paren) {
TokError("expected '(' after unary operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the '('
Init *LHS = ParseValue(CurRec);
- if (LHS == 0) return 0;
+ if (!LHS) return nullptr;
if (Code == UnOpInit::HEAD
|| Code == UnOpInit::TAIL
@@ -852,36 +842,36 @@ Init *TGParser::ParseOperation(Record *CurRec) {
ListInit *LHSl = dyn_cast<ListInit>(LHS);
StringInit *LHSs = dyn_cast<StringInit>(LHS);
TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
- if (LHSl == 0 && LHSs == 0 && LHSt == 0) {
+ if (!LHSl && !LHSs && !LHSt) {
TokError("expected list or string type argument in unary operator");
- return 0;
+ return nullptr;
}
if (LHSt) {
ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType());
- if (LType == 0 && SType == 0) {
- TokError("expected list or string type argumnet in unary operator");
- return 0;
+ if (!LType && !SType) {
+ TokError("expected list or string type argument in unary operator");
+ return nullptr;
}
}
if (Code == UnOpInit::HEAD
|| Code == UnOpInit::TAIL) {
- if (LHSl == 0 && LHSt == 0) {
- TokError("expected list type argumnet in unary operator");
- return 0;
+ if (!LHSl && !LHSt) {
+ TokError("expected list type argument in unary operator");
+ return nullptr;
}
if (LHSl && LHSl->getSize() == 0) {
TokError("empty list argument in unary operator");
- return 0;
+ return nullptr;
}
if (LHSl) {
Init *Item = LHSl->getElement(0);
TypedInit *Itemt = dyn_cast<TypedInit>(Item);
- if (Itemt == 0) {
+ if (!Itemt) {
TokError("untyped list element in unary operator");
- return 0;
+ return nullptr;
}
if (Code == UnOpInit::HEAD) {
Type = Itemt->getType();
@@ -891,9 +881,9 @@ Init *TGParser::ParseOperation(Record *CurRec) {
} else {
assert(LHSt && "expected list type argument in unary operator");
ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
- if (LType == 0) {
- TokError("expected list type argumnet in unary operator");
- return 0;
+ if (!LType) {
+ TokError("expected list type argument in unary operator");
+ return nullptr;
}
if (Code == UnOpInit::HEAD) {
Type = LType->getElementType();
@@ -906,7 +896,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
if (Lex.getCode() != tgtok::r_paren) {
TokError("expected ')' in unary operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the ')'
return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec, CurMultiClass);
@@ -918,13 +908,14 @@ Init *TGParser::ParseOperation(Record *CurRec) {
case tgtok::XSRL:
case tgtok::XSHL:
case tgtok::XEq:
+ case tgtok::XListConcat:
case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')'
tgtok::TokKind OpTok = Lex.getCode();
SMLoc OpLoc = Lex.getLoc();
Lex.Lex(); // eat the operation
BinOpInit::BinaryOp Code;
- RecTy *Type = 0;
+ RecTy *Type = nullptr;
switch (OpTok) {
default: llvm_unreachable("Unhandled code!");
@@ -934,6 +925,10 @@ Init *TGParser::ParseOperation(Record *CurRec) {
case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break;
case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break;
case tgtok::XEq: Code = BinOpInit::EQ; Type = BitRecTy::get(); break;
+ case tgtok::XListConcat:
+ Code = BinOpInit::LISTCONCAT;
+ // We don't know the list type until we parse the first argument
+ break;
case tgtok::XStrConcat:
Code = BinOpInit::STRCONCAT;
Type = StringRecTy::get();
@@ -942,31 +937,44 @@ Init *TGParser::ParseOperation(Record *CurRec) {
if (Lex.getCode() != tgtok::l_paren) {
TokError("expected '(' after binary operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the '('
SmallVector<Init*, 2> InitList;
InitList.push_back(ParseValue(CurRec));
- if (InitList.back() == 0) return 0;
+ if (!InitList.back()) return nullptr;
while (Lex.getCode() == tgtok::comma) {
Lex.Lex(); // eat the ','
InitList.push_back(ParseValue(CurRec));
- if (InitList.back() == 0) return 0;
+ if (!InitList.back()) return nullptr;
}
if (Lex.getCode() != tgtok::r_paren) {
TokError("expected ')' in operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the ')'
+ // If we are doing !listconcat, we should know the type by now
+ if (OpTok == tgtok::XListConcat) {
+ if (VarInit *Arg0 = dyn_cast<VarInit>(InitList[0]))
+ Type = Arg0->getType();
+ else if (ListInit *Arg0 = dyn_cast<ListInit>(InitList[0]))
+ Type = Arg0->getType();
+ else {
+ InitList[0]->dump();
+ Error(OpLoc, "expected a list");
+ return nullptr;
+ }
+ }
+
// We allow multiple operands to associative operators like !strconcat as
// shorthand for nesting them.
- if (Code == BinOpInit::STRCONCAT) {
+ if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT) {
while (InitList.size() > 2) {
Init *RHS = InitList.pop_back_val();
RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))
@@ -980,14 +988,14 @@ Init *TGParser::ParseOperation(Record *CurRec) {
->Fold(CurRec, CurMultiClass);
Error(OpLoc, "expected two operands to operator");
- return 0;
+ return nullptr;
}
case tgtok::XIf:
case tgtok::XForEach:
case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
TernOpInit::TernaryOp Code;
- RecTy *Type = 0;
+ RecTy *Type = nullptr;
tgtok::TokKind LexCode = Lex.getCode();
Lex.Lex(); // eat the operation
@@ -1005,42 +1013,44 @@ Init *TGParser::ParseOperation(Record *CurRec) {
}
if (Lex.getCode() != tgtok::l_paren) {
TokError("expected '(' after ternary operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the '('
Init *LHS = ParseValue(CurRec);
- if (LHS == 0) return 0;
+ if (!LHS) return nullptr;
if (Lex.getCode() != tgtok::comma) {
TokError("expected ',' in ternary operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the ','
- Init *MHS = ParseValue(CurRec);
- if (MHS == 0) return 0;
+ Init *MHS = ParseValue(CurRec, ItemType);
+ if (!MHS)
+ return nullptr;
if (Lex.getCode() != tgtok::comma) {
TokError("expected ',' in ternary operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the ','
- Init *RHS = ParseValue(CurRec);
- if (RHS == 0) return 0;
+ Init *RHS = ParseValue(CurRec, ItemType);
+ if (!RHS)
+ return nullptr;
if (Lex.getCode() != tgtok::r_paren) {
TokError("expected ')' in binary operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the ')'
switch (LexCode) {
default: llvm_unreachable("Unhandled code!");
case tgtok::XIf: {
- RecTy *MHSTy = 0;
- RecTy *RHSTy = 0;
+ RecTy *MHSTy = nullptr;
+ RecTy *RHSTy = nullptr;
if (TypedInit *MHSt = dyn_cast<TypedInit>(MHS))
MHSTy = MHSt->getType();
@@ -1064,7 +1074,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
if (!MHSTy || !RHSTy) {
TokError("could not get type for !if");
- return 0;
+ return nullptr;
}
if (MHSTy->typeIsConvertibleTo(RHSTy)) {
@@ -1073,24 +1083,24 @@ Init *TGParser::ParseOperation(Record *CurRec) {
Type = MHSTy;
} else {
TokError("inconsistent types for !if");
- return 0;
+ return nullptr;
}
break;
}
case tgtok::XForEach: {
TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
- if (MHSt == 0) {
+ if (!MHSt) {
TokError("could not get type for !foreach");
- return 0;
+ return nullptr;
}
Type = MHSt->getType();
break;
}
case tgtok::XSubst: {
TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
- if (RHSt == 0) {
+ if (!RHSt) {
TokError("could not get type for !subst");
- return 0;
+ return nullptr;
}
Type = RHSt->getType();
break;
@@ -1108,24 +1118,24 @@ Init *TGParser::ParseOperation(Record *CurRec) {
/// OperatorType ::= '<' Type '>'
///
RecTy *TGParser::ParseOperatorType() {
- RecTy *Type = 0;
+ RecTy *Type = nullptr;
if (Lex.getCode() != tgtok::less) {
TokError("expected type name for operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the <
Type = ParseType();
- if (Type == 0) {
+ if (!Type) {
TokError("expected type name for operator");
- return 0;
+ return nullptr;
}
if (Lex.getCode() != tgtok::greater) {
TokError("expected type name for operator");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the >
@@ -1149,11 +1159,12 @@ RecTy *TGParser::ParseOperatorType() {
/// SimpleValue ::= SHLTOK '(' Value ',' Value ')'
/// SimpleValue ::= SRATOK '(' Value ',' Value ')'
/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
+/// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'
/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
///
Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
IDParseMode Mode) {
- Init *R = 0;
+ Init *R = nullptr;
switch (Lex.getCode()) {
default: TokError("Unknown token when parsing a value"); break;
case tgtok::paste:
@@ -1192,7 +1203,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
// Value ::= ID '<' ValueListNE '>'
if (Lex.Lex() == tgtok::greater) {
TokError("expected non-empty value list");
- return 0;
+ return nullptr;
}
// This is a CLASS<initvalslist> expression. This is supposed to synthesize
@@ -1201,24 +1212,21 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
Record *Class = Records.getClass(Name);
if (!Class) {
Error(NameLoc, "Expected a class name, got '" + Name + "'");
- return 0;
+ return nullptr;
}
std::vector<Init*> ValueList = ParseValueList(CurRec, Class);
- if (ValueList.empty()) return 0;
+ if (ValueList.empty()) return nullptr;
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' at end of value list");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the '>'
SMLoc EndLoc = Lex.getLoc();
// Create the new record, set it as CurRec temporarily.
- static unsigned AnonCounter = 0;
- Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++),
- NameLoc,
- Records,
+ Record *NewRec = new Record(GetNewAnonymousName(), NameLoc, Records,
/*IsAnonymous=*/true);
SubClassReference SCRef;
SCRef.RefRange = SMRange(NameLoc, EndLoc);
@@ -1226,9 +1234,37 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
SCRef.TemplateArgs = ValueList;
// Add info about the subclass to NewRec.
if (AddSubClass(NewRec, SCRef))
- return 0;
- NewRec->resolveReferences();
- Records.addDef(NewRec);
+ return nullptr;
+ if (!CurMultiClass) {
+ NewRec->resolveReferences();
+ Records.addDef(NewRec);
+ } else {
+ // Otherwise, we're inside a multiclass, add it to the multiclass.
+ CurMultiClass->DefPrototypes.push_back(NewRec);
+
+ // Copy the template arguments for the multiclass into the def.
+ const std::vector<Init *> &TArgs =
+ CurMultiClass->Rec.getTemplateArgs();
+
+ for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+ const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]);
+ assert(RV && "Template arg doesn't exist?");
+ NewRec->addValue(*RV);
+ }
+
+ // We can't return the prototype def here, instead return:
+ // !cast<ItemType>(!strconcat(NAME, AnonName)).
+ const RecordVal *MCNameRV = CurMultiClass->Rec.getValue("NAME");
+ assert(MCNameRV && "multiclass record must have a NAME");
+
+ return UnOpInit::get(UnOpInit::CAST,
+ BinOpInit::get(BinOpInit::STRCONCAT,
+ VarInit::get(MCNameRV->getName(),
+ MCNameRV->getType()),
+ NewRec->getNameInit(),
+ StringRecTy::get()),
+ Class->getDefInit()->getType());
+ }
// The result of the expression is a reference to the new record.
return DefInit::get(NewRec);
@@ -1240,11 +1276,11 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
if (Lex.getCode() != tgtok::r_brace) {
Vals = ParseValueList(CurRec);
- if (Vals.empty()) return 0;
+ if (Vals.empty()) return nullptr;
}
if (Lex.getCode() != tgtok::r_brace) {
TokError("expected '}' at end of bit list value");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the '}'
@@ -1252,10 +1288,10 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
Init *Bit = Vals[i]->convertInitializerTo(BitRecTy::get());
- if (Bit == 0) {
+ if (!Bit) {
Error(BraceLoc, "Element #" + utostr(i) + " (" + Vals[i]->getAsString()+
") is not convertable to a bit");
- return 0;
+ return nullptr;
}
NewBits[Vals.size()-i-1] = Bit;
}
@@ -1265,87 +1301,87 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
Lex.Lex(); // eat the '['
std::vector<Init*> Vals;
- RecTy *DeducedEltTy = 0;
- ListRecTy *GivenListTy = 0;
+ RecTy *DeducedEltTy = nullptr;
+ ListRecTy *GivenListTy = nullptr;
- if (ItemType != 0) {
+ if (ItemType) {
ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType);
- if (ListType == 0) {
+ if (!ListType) {
std::string s;
raw_string_ostream ss(s);
ss << "Type mismatch for list, expected list type, got "
<< ItemType->getAsString();
TokError(ss.str());
- return 0;
+ return nullptr;
}
GivenListTy = ListType;
}
if (Lex.getCode() != tgtok::r_square) {
- Vals = ParseValueList(CurRec, 0,
- GivenListTy ? GivenListTy->getElementType() : 0);
- if (Vals.empty()) return 0;
+ Vals = ParseValueList(CurRec, nullptr,
+ GivenListTy ? GivenListTy->getElementType() : nullptr);
+ if (Vals.empty()) return nullptr;
}
if (Lex.getCode() != tgtok::r_square) {
TokError("expected ']' at end of list value");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the ']'
- RecTy *GivenEltTy = 0;
+ RecTy *GivenEltTy = nullptr;
if (Lex.getCode() == tgtok::less) {
// Optional list element type
Lex.Lex(); // eat the '<'
GivenEltTy = ParseType();
- if (GivenEltTy == 0) {
+ if (!GivenEltTy) {
// Couldn't parse element type
- return 0;
+ return nullptr;
}
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' at end of list element type");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the '>'
}
// Check elements
- RecTy *EltTy = 0;
+ RecTy *EltTy = nullptr;
for (std::vector<Init *>::iterator i = Vals.begin(), ie = Vals.end();
i != ie;
++i) {
TypedInit *TArg = dyn_cast<TypedInit>(*i);
- if (TArg == 0) {
+ if (!TArg) {
TokError("Untyped list element");
- return 0;
+ return nullptr;
}
- if (EltTy != 0) {
+ if (EltTy) {
EltTy = resolveTypes(EltTy, TArg->getType());
- if (EltTy == 0) {
+ if (!EltTy) {
TokError("Incompatible types in list elements");
- return 0;
+ return nullptr;
}
} else {
EltTy = TArg->getType();
}
}
- if (GivenEltTy != 0) {
- if (EltTy != 0) {
+ if (GivenEltTy) {
+ if (EltTy) {
// Verify consistency
if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
TokError("Incompatible types in list elements");
- return 0;
+ return nullptr;
}
}
EltTy = GivenEltTy;
}
- if (EltTy == 0) {
- if (ItemType == 0) {
+ if (!EltTy) {
+ if (!ItemType) {
TokError("No type for list");
- return 0;
+ return nullptr;
}
DeducedEltTy = GivenListTy->getElementType();
} else {
@@ -1353,7 +1389,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
if (GivenListTy) {
if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
TokError("Element type mismatch for list");
- return 0;
+ return nullptr;
}
}
DeducedEltTy = EltTy;
@@ -1365,18 +1401,18 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
Lex.Lex(); // eat the '('
if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast) {
TokError("expected identifier in dag init");
- return 0;
+ return nullptr;
}
Init *Operator = ParseValue(CurRec);
- if (Operator == 0) return 0;
+ if (!Operator) return nullptr;
// If the operator name is present, parse it.
std::string OperatorName;
if (Lex.getCode() == tgtok::colon) {
if (Lex.Lex() != tgtok::VarName) { // eat the ':'
TokError("expected variable name in dag operator");
- return 0;
+ return nullptr;
}
OperatorName = Lex.getCurStrVal();
Lex.Lex(); // eat the VarName.
@@ -1385,12 +1421,12 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
std::vector<std::pair<llvm::Init*, std::string> > DagArgs;
if (Lex.getCode() != tgtok::r_paren) {
DagArgs = ParseDagArgList(CurRec);
- if (DagArgs.empty()) return 0;
+ if (DagArgs.empty()) return nullptr;
}
if (Lex.getCode() != tgtok::r_paren) {
TokError("expected ')' in dag init");
- return 0;
+ return nullptr;
}
Lex.Lex(); // eat the ')'
@@ -1407,11 +1443,12 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XSRL:
case tgtok::XSHL:
case tgtok::XEq:
+ case tgtok::XListConcat:
case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')'
case tgtok::XIf:
case tgtok::XForEach:
case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
- return ParseOperation(CurRec);
+ return ParseOperation(CurRec, ItemType);
}
}
@@ -1427,7 +1464,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
///
Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
- if (Result == 0) return 0;
+ if (!Result) return nullptr;
// Parse the suffixes now if present.
while (1) {
@@ -1441,20 +1478,20 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
SMLoc CurlyLoc = Lex.getLoc();
Lex.Lex(); // eat the '{'
std::vector<unsigned> Ranges = ParseRangeList();
- if (Ranges.empty()) return 0;
+ if (Ranges.empty()) return nullptr;
// Reverse the bitlist.
std::reverse(Ranges.begin(), Ranges.end());
Result = Result->convertInitializerBitRange(Ranges);
- if (Result == 0) {
+ if (!Result) {
Error(CurlyLoc, "Invalid bit range for value");
- return 0;
+ return nullptr;
}
// Eat the '}'.
if (Lex.getCode() != tgtok::r_brace) {
TokError("expected '}' at end of bit range list");
- return 0;
+ return nullptr;
}
Lex.Lex();
break;
@@ -1463,18 +1500,18 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
SMLoc SquareLoc = Lex.getLoc();
Lex.Lex(); // eat the '['
std::vector<unsigned> Ranges = ParseRangeList();
- if (Ranges.empty()) return 0;
+ if (Ranges.empty()) return nullptr;
Result = Result->convertInitListSlice(Ranges);
- if (Result == 0) {
+ if (!Result) {
Error(SquareLoc, "Invalid range for list slice");
- return 0;
+ return nullptr;
}
// Eat the ']'.
if (Lex.getCode() != tgtok::r_square) {
TokError("expected ']' at end of list slice");
- return 0;
+ return nullptr;
}
Lex.Lex();
break;
@@ -1482,12 +1519,12 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
case tgtok::period:
if (Lex.Lex() != tgtok::Id) { // eat the .
TokError("expected field identifier after '.'");
- return 0;
+ return nullptr;
}
if (!Result->getFieldType(Lex.getCurStrVal())) {
TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
Result->getAsString() + "'");
- return 0;
+ return nullptr;
}
Result = FieldInit::get(Result, Lex.getCurStrVal());
Lex.Lex(); // eat field name
@@ -1502,14 +1539,14 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
TypedInit *LHS = dyn_cast<TypedInit>(Result);
if (!LHS) {
Error(PasteLoc, "LHS of paste is not typed!");
- return 0;
+ return nullptr;
}
if (LHS->getType() != StringRecTy::get()) {
LHS = UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get());
}
- TypedInit *RHS = 0;
+ TypedInit *RHS = nullptr;
Lex.Lex(); // Eat the '#'.
switch (Lex.getCode()) {
@@ -1529,7 +1566,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
RHS = dyn_cast<TypedInit>(RHSResult);
if (!RHS) {
Error(PasteLoc, "RHS of paste is not typed!");
- return 0;
+ return nullptr;
}
if (RHS->getType() != StringRecTy::get()) {
@@ -1565,7 +1602,7 @@ TGParser::ParseDagArgList(Record *CurRec) {
} else {
// DagArg ::= Value (':' VARNAME)?
Init *Val = ParseValue(CurRec);
- if (Val == 0)
+ if (!Val)
return std::vector<std::pair<llvm::Init*, std::string> >();
// If the variable name is present, add it.
@@ -1600,7 +1637,7 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
std::vector<Init*> Result;
RecTy *ItemType = EltTy;
unsigned int ArgN = 0;
- if (ArgsRec != 0 && EltTy == 0) {
+ if (ArgsRec && !EltTy) {
const std::vector<Init *> &TArgs = ArgsRec->getTemplateArgs();
if (!TArgs.size()) {
TokError("template argument provided to non-template class");
@@ -1616,12 +1653,12 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
++ArgN;
}
Result.push_back(ParseValue(CurRec, ItemType));
- if (Result.back() == 0) return std::vector<Init*>();
+ if (!Result.back()) return std::vector<Init*>();
while (Lex.getCode() == tgtok::comma) {
Lex.Lex(); // Eat the comma
- if (ArgsRec != 0 && EltTy == 0) {
+ if (ArgsRec && !EltTy) {
const std::vector<Init *> &TArgs = ArgsRec->getTemplateArgs();
if (ArgN >= TArgs.size()) {
TokError("too many template arguments");
@@ -1633,7 +1670,7 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
++ArgN;
}
Result.push_back(ParseValue(CurRec, ItemType));
- if (Result.back() == 0) return std::vector<Init*>();
+ if (!Result.back()) return std::vector<Init*>();
}
return Result;
@@ -1657,11 +1694,11 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
if (HasField) Lex.Lex();
RecTy *Type = ParseType();
- if (Type == 0) return 0;
+ if (!Type) return nullptr;
if (Lex.getCode() != tgtok::Id) {
TokError("Expected identifier in declaration");
- return 0;
+ return nullptr;
}
SMLoc IdLoc = Lex.getLoc();
@@ -1681,16 +1718,16 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
// Add the value.
if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField)))
- return 0;
+ return nullptr;
// If a value is present, parse it.
if (Lex.getCode() == tgtok::equal) {
Lex.Lex();
SMLoc ValLoc = Lex.getLoc();
Init *Val = ParseValue(CurRec, Type);
- if (Val == 0 ||
+ if (!Val ||
SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
- return 0;
+ return nullptr;
}
return DeclName;
@@ -1707,7 +1744,7 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
if (Lex.getCode() != tgtok::Id) {
TokError("Expected identifier in foreach declaration");
- return 0;
+ return nullptr;
}
Init *DeclName = StringInit::get(Lex.getCurStrVal());
@@ -1716,27 +1753,27 @@ VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
// If a value is present, parse it.
if (Lex.getCode() != tgtok::equal) {
TokError("Expected '=' in foreach declaration");
- return 0;
+ return nullptr;
}
Lex.Lex(); // Eat the '='
- RecTy *IterType = 0;
+ RecTy *IterType = nullptr;
std::vector<unsigned> Ranges;
switch (Lex.getCode()) {
- default: TokError("Unknown token when expecting a range list"); return 0;
+ default: TokError("Unknown token when expecting a range list"); return nullptr;
case tgtok::l_square: { // '[' ValueList ']'
- Init *List = ParseSimpleValue(0, 0, ParseForeachMode);
+ Init *List = ParseSimpleValue(nullptr, nullptr, ParseForeachMode);
ForeachListValue = dyn_cast<ListInit>(List);
- if (ForeachListValue == 0) {
+ if (!ForeachListValue) {
TokError("Expected a Value list");
- return 0;
+ return nullptr;
}
RecTy *ValueType = ForeachListValue->getType();
ListRecTy *ListType = dyn_cast<ListRecTy>(ValueType);
- if (ListType == 0) {
+ if (!ListType) {
TokError("Value list is not of list type");
- return 0;
+ return nullptr;
}
IterType = ListType->getElementType();
break;
@@ -1744,7 +1781,7 @@ VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
case tgtok::IntVal: { // RangePiece.
if (ParseRangePiece(Ranges))
- return 0;
+ return nullptr;
break;
}
@@ -1753,7 +1790,7 @@ VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
Ranges = ParseRangeList();
if (Lex.getCode() != tgtok::r_brace) {
TokError("expected '}' at end of bit range list");
- return 0;
+ return nullptr;
}
Lex.Lex();
break;
@@ -1770,7 +1807,7 @@ VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
}
if (!IterType)
- return 0;
+ return nullptr;
return VarInit::get(DeclName, IterType);
}
@@ -1790,7 +1827,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
// Read the first declaration.
Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
- if (TemplArg == 0)
+ if (!TemplArg)
return true;
TheRecToAddTo->addTemplateArg(TemplArg);
@@ -1800,7 +1837,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
// Read the following declarations.
TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
- if (TemplArg == 0)
+ if (!TemplArg)
return true;
TheRecToAddTo->addTemplateArg(TemplArg);
}
@@ -1818,7 +1855,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
/// BodyItem ::= LET ID OptionalBitList '=' Value ';'
bool TGParser::ParseBodyItem(Record *CurRec) {
if (Lex.getCode() != tgtok::Let) {
- if (ParseDeclaration(CurRec, false) == 0)
+ if (!ParseDeclaration(CurRec, false))
return true;
if (Lex.getCode() != tgtok::semi)
@@ -1845,13 +1882,13 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
Lex.Lex(); // eat the '='.
RecordVal *Field = CurRec->getValue(FieldName);
- if (Field == 0)
+ if (!Field)
return TokError("Value '" + FieldName + "' unknown!");
RecTy *Type = Field->getType();
Init *Val = ParseValue(CurRec, Type);
- if (Val == 0) return true;
+ if (!Val) return true;
if (Lex.getCode() != tgtok::semi)
return TokError("expected ';' after let expression");
@@ -1917,7 +1954,7 @@ bool TGParser::ParseObjectBody(Record *CurRec) {
SubClassReference SubClass = ParseSubClassReference(CurRec, false);
while (1) {
// Check for error.
- if (SubClass.Rec == 0) return true;
+ if (!SubClass.Rec) return true;
// Add it.
if (AddSubClass(CurRec, SubClass))
@@ -1964,7 +2001,18 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
return true;
}
Records.addDef(CurRec);
+
+ if (ParseObjectBody(CurRec))
+ return true;
} else if (CurMultiClass) {
+ // Parse the body before adding this prototype to the DefPrototypes vector.
+ // That way implicit definitions will be added to the DefPrototypes vector
+ // before this object, instantiated prior to defs derived from this object,
+ // and this available for indirect name resolution when defs derived from
+ // this object are instantiated.
+ if (ParseObjectBody(CurRec))
+ return true;
+
// Otherwise, a def inside a multiclass, add it to the multiclass.
for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i)
if (CurMultiClass->DefPrototypes[i]->getNameInit()
@@ -1974,12 +2022,10 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
return true;
}
CurMultiClass->DefPrototypes.push_back(CurRec);
- }
-
- if (ParseObjectBody(CurRec))
+ } else if (ParseObjectBody(CurRec))
return true;
- if (CurMultiClass == 0) // Def's in multiclasses aren't really defs.
+ if (!CurMultiClass) // Def's in multiclasses aren't really defs.
// See Record::setName(). This resolve step will see any new name
// for the def that might have been created when resolving
// inheritance, values and arguments above.
@@ -2021,9 +2067,9 @@ bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
// Make a temporary object to record items associated with the for
// loop.
- ListInit *ListValue = 0;
+ ListInit *ListValue = nullptr;
VarInit *IterName = ParseForeachDeclaration(ListValue);
- if (IterName == 0)
+ if (!IterName)
return TokError("expected declaration in for");
if (Lex.getCode() != tgtok::In)
@@ -2125,8 +2171,8 @@ std::vector<LetRecord> TGParser::ParseLetList() {
}
Lex.Lex(); // eat the '='.
- Init *Val = ParseValue(0);
- if (Val == 0) return std::vector<LetRecord>();
+ Init *Val = ParseValue(nullptr);
+ if (!Val) return std::vector<LetRecord>();
// Now that we have everything, add the record.
Result.push_back(LetRecord(Name, Bits, Val, NameLoc));
@@ -2209,7 +2255,7 @@ bool TGParser::ParseMultiClass() {
// If there are template args, parse them.
if (Lex.getCode() == tgtok::less)
- if (ParseTemplateArgList(0))
+ if (ParseTemplateArgList(nullptr))
return true;
bool inherits = false;
@@ -2225,7 +2271,7 @@ bool TGParser::ParseMultiClass() {
ParseSubMultiClassReference(CurMultiClass);
while (1) {
// Check for error.
- if (SubMultiClass.MC == 0) return true;
+ if (!SubMultiClass.MC) return true;
// Add it.
if (AddSubMultiClass(CurMultiClass, SubMultiClass))
@@ -2264,14 +2310,14 @@ bool TGParser::ParseMultiClass() {
Lex.Lex(); // eat the '}'.
}
- CurMultiClass = 0;
+ CurMultiClass = nullptr;
return false;
}
Record *TGParser::
InstantiateMulticlassDef(MultiClass &MC,
Record *DefProto,
- Init *DefmPrefix,
+ Init *&DefmPrefix,
SMRange DefmPrefixRange) {
// We need to preserve DefProto so it can be reused for later
// instantiations, so create a new Record to inherit from it.
@@ -2282,7 +2328,7 @@ InstantiateMulticlassDef(MultiClass &MC,
// as a prefix.
bool IsAnonymous = false;
- if (DefmPrefix == 0) {
+ if (!DefmPrefix) {
DefmPrefix = StringInit::get(GetNewAnonymousName());
IsAnonymous = true;
}
@@ -2291,7 +2337,7 @@ InstantiateMulticlassDef(MultiClass &MC,
StringInit *DefNameString = dyn_cast<StringInit>(DefName);
- if (DefNameString != 0) {
+ if (DefNameString) {
// We have a fully expanded string so there are no operators to
// resolve. We should concatenate the given prefix and name.
DefName =
@@ -2319,13 +2365,13 @@ InstantiateMulticlassDef(MultiClass &MC,
Error(DefmPrefixRange.Start, "Could not resolve "
+ CurRec->getNameInitAsString() + ":NAME to '"
+ DefmPrefix->getAsUnquotedString() + "'");
- return 0;
+ return nullptr;
}
// If the DefNameString didn't resolve, we probably have a reference to
// NAME and need to replace it. We need to do at least this much greedily,
// otherwise nested multiclasses will end up with incorrect NAME expansions.
- if (DefNameString == 0) {
+ if (!DefNameString) {
RecordVal *DefNameRV = CurRec->getValue("NAME");
CurRec->resolveReferencesTo(DefNameRV);
}
@@ -2350,7 +2396,7 @@ InstantiateMulticlassDef(MultiClass &MC,
Error(DefmPrefixRange.Start, "def '" + CurRec->getNameInitAsString() +
"' already defined, instantiating defm with subdef '" +
DefProto->getNameInitAsString() + "'");
- return 0;
+ return nullptr;
}
Records.addDef(CurRec);
@@ -2434,7 +2480,7 @@ bool TGParser::ResolveMulticlassDef(MultiClass &MC,
bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
SMLoc DefmLoc = Lex.getLoc();
- Init *DefmPrefix = 0;
+ Init *DefmPrefix = nullptr;
if (Lex.Lex() == tgtok::Id) { // eat the defm.
DefmPrefix = ParseObjectName(CurMultiClass);
@@ -2454,10 +2500,10 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
Lex.Lex();
SMLoc SubClassLoc = Lex.getLoc();
- SubClassReference Ref = ParseSubClassReference(0, true);
+ SubClassReference Ref = ParseSubClassReference(nullptr, true);
while (1) {
- if (Ref.Rec == 0) return true;
+ if (!Ref.Rec) return true;
// To instantiate a multiclass, we need to first get the multiclass, then
// instantiate each def contained in the multiclass with the SubClassRef
@@ -2503,21 +2549,21 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
// A defm can inherit from regular classes (non-multiclass) as
// long as they come in the end of the inheritance list.
- InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != 0);
+ InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr);
if (InheritFromClass)
break;
- Ref = ParseSubClassReference(0, true);
+ Ref = ParseSubClassReference(nullptr, true);
}
if (InheritFromClass) {
// Process all the classes to inherit as if they were part of a
// regular 'def' and inherit all record values.
- SubClassReference SubClass = ParseSubClassReference(0, false);
+ SubClassReference SubClass = ParseSubClassReference(nullptr, false);
while (1) {
// Check for error.
- if (SubClass.Rec == 0) return true;
+ if (!SubClass.Rec) return true;
// Get the expanded definition prototypes and teach them about
// the record values the current class to inherit has
@@ -2534,7 +2580,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
if (Lex.getCode() != tgtok::comma) break;
Lex.Lex(); // eat ','.
- SubClass = ParseSubClassReference(0, false);
+ SubClass = ParseSubClassReference(nullptr, false);
}
}
diff --git a/contrib/llvm/lib/TableGen/TGParser.h b/contrib/llvm/lib/TableGen/TGParser.h
index 044e3a0..9f4b7e9 100644
--- a/contrib/llvm/lib/TableGen/TGParser.h
+++ b/contrib/llvm/lib/TableGen/TGParser.h
@@ -69,6 +69,8 @@ class TGParser {
// Record tracker
RecordKeeper &Records;
+ unsigned AnonCounter;
+
// A "named boolean" indicating how to parse identifiers. Usually
// identifiers map to some existing object but in special cases
// (e.g. parsing def names) no such object exists yet because we are
@@ -82,8 +84,8 @@ class TGParser {
};
public:
- TGParser(SourceMgr &SrcMgr, RecordKeeper &records) :
- Lex(SrcMgr), CurMultiClass(0), Records(records) {}
+ TGParser(SourceMgr &SrcMgr, RecordKeeper &records)
+ : Lex(SrcMgr), CurMultiClass(nullptr), Records(records), AnonCounter(0) {}
/// ParseFile - Main entrypoint for parsing a tblgen file. These parser
/// routines return true on error, or false on success.
@@ -112,6 +114,8 @@ private: // Semantic analysis methods.
bool AddSubMultiClass(MultiClass *CurMC,
SubMultiClassReference &SubMultiClass);
+ std::string GetNewAnonymousName();
+
// IterRecord: Map an iterator name to a value.
struct IterRecord {
VarInit *IterVar;
@@ -127,13 +131,13 @@ private: // Semantic analysis methods.
bool ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals);
private: // Parser methods.
- bool ParseObjectList(MultiClass *MC = 0);
+ bool ParseObjectList(MultiClass *MC = nullptr);
bool ParseObject(MultiClass *MC);
bool ParseClass();
bool ParseMultiClass();
Record *InstantiateMulticlassDef(MultiClass &MC,
Record *DefProto,
- Init *DefmPrefix,
+ Init *&DefmPrefix,
SMRange DefmPrefixRange);
bool ResolveMulticlassDefArgs(MultiClass &MC,
Record *DefProto,
@@ -163,22 +167,21 @@ private: // Parser methods.
SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
- Init *ParseIDValue(Record *CurRec, IDParseMode Mode = ParseValueMode);
Init *ParseIDValue(Record *CurRec, const std::string &Name, SMLoc NameLoc,
IDParseMode Mode = ParseValueMode);
- Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = 0,
+ Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = nullptr,
IDParseMode Mode = ParseValueMode);
- Init *ParseValue(Record *CurRec, RecTy *ItemType = 0,
+ Init *ParseValue(Record *CurRec, RecTy *ItemType = nullptr,
IDParseMode Mode = ParseValueMode);
- std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = 0,
- RecTy *EltTy = 0);
+ 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);
RecTy *ParseType();
- Init *ParseOperation(Record *CurRec);
+ Init *ParseOperation(Record *CurRec, RecTy *ItemType);
RecTy *ParseOperatorType();
Init *ParseObjectName(MultiClass *CurMultiClass);
Record *ParseClassID();
diff --git a/contrib/llvm/lib/TableGen/module.modulemap b/contrib/llvm/lib/TableGen/module.modulemap
new file mode 100644
index 0000000..8dac0a2
--- /dev/null
+++ b/contrib/llvm/lib/TableGen/module.modulemap
@@ -0,0 +1 @@
+module TableGen { requires cplusplus umbrella "." module * { export * } }
OpenPOWER on IntegriCloud