aboutsummaryrefslogtreecommitdiff
path: root/lib/TableGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/TableGen')
-rw-r--r--lib/TableGen/Main.cpp8
-rw-r--r--lib/TableGen/Record.cpp56
-rw-r--r--lib/TableGen/TGLexer.cpp11
-rw-r--r--lib/TableGen/TGLexer.h15
-rw-r--r--lib/TableGen/TGParser.cpp209
-rw-r--r--lib/TableGen/TGParser.h6
-rw-r--r--lib/TableGen/TableGenBackend.cpp31
7 files changed, 209 insertions, 127 deletions
diff --git a/lib/TableGen/Main.cpp b/lib/TableGen/Main.cpp
index d0ca756016..e1cd623783 100644
--- a/lib/TableGen/Main.cpp
+++ b/lib/TableGen/Main.cpp
@@ -64,11 +64,11 @@ static int createDependencyFile(const TGParser &Parser, const char *argv0) {
return 1;
}
DepOut.os() << OutputFilename << ":";
- const std::vector<std::string> &Dependencies = Parser.getDependencies();
- for (std::vector<std::string>::const_iterator I = Dependencies.begin(),
- E = Dependencies.end();
+ const TGLexer::DependenciesMapTy &Dependencies = Parser.getDependencies();
+ for (TGLexer::DependenciesMapTy::const_iterator I = Dependencies.begin(),
+ E = Dependencies.end();
I != E; ++I) {
- DepOut.os() << " " << (*I);
+ DepOut.os() << " " << I->first;
}
DepOut.os() << "\n";
DepOut.keep();
diff --git a/lib/TableGen/Record.cpp b/lib/TableGen/Record.cpp
index 9b65adcf85..9ad20532d7 100644
--- a/lib/TableGen/Record.cpp
+++ b/lib/TableGen/Record.cpp
@@ -95,15 +95,16 @@ ListRecTy *RecTy::getListTy() {
return ListTy;
}
+bool RecTy::baseClassOf(const RecTy *RHS) const{
+ assert (RHS && "NULL pointer");
+ return Kind == RHS->getRecTyKind();
+}
+
Init *BitRecTy::convertValue(BitsInit *BI) {
if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
return BI->getBit(0);
}
-bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const {
- return RHS->getNumBits() == 1;
-}
-
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!
@@ -118,6 +119,14 @@ Init *BitRecTy::convertValue(TypedInit *VI) {
return 0;
}
+bool BitRecTy::baseClassOf(const RecTy *RHS) const{
+ if(RecTy::baseClassOf(RHS) || getRecTyKind() == IntRecTyKind)
+ return true;
+ if(const BitsRecTy *BitsTy = dyn_cast<BitsRecTy>(RHS))
+ return BitsTy->getNumBits() == 1;
+ return false;
+}
+
BitsRecTy *BitsRecTy::get(unsigned Sz) {
static std::vector<BitsRecTy*> Shared;
if (Sz >= Shared.size())
@@ -193,6 +202,13 @@ Init *BitsRecTy::convertValue(TypedInit *VI) {
return 0;
}
+bool BitsRecTy::baseClassOf(const RecTy *RHS) const{
+ if (RecTy::baseClassOf(RHS)) //argument and the receiver are the same type
+ return cast<BitsRecTy>(RHS)->Size == Size;
+ RecTyKind kind = RHS->getRecTyKind();
+ return (kind == BitRecTyKind && Size == 1) || (kind == IntRecTyKind);
+}
+
Init *IntRecTy::convertValue(BitInit *BI) {
return IntInit::get(BI->getValue());
}
@@ -214,6 +230,11 @@ Init *IntRecTy::convertValue(TypedInit *TI) {
return 0;
}
+bool IntRecTy::baseClassOf(const RecTy *RHS) const{
+ RecTyKind kind = RHS->getRecTyKind();
+ return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind;
+}
+
Init *StringRecTy::convertValue(UnOpInit *BO) {
if (BO->getOpcode() == UnOpInit::CAST) {
Init *L = BO->getOperand()->convertInitializerTo(this);
@@ -275,6 +296,12 @@ Init *ListRecTy::convertValue(TypedInit *TI) {
return 0;
}
+bool ListRecTy::baseClassOf(const RecTy *RHS) const{
+ if(const ListRecTy* ListTy = dyn_cast<ListRecTy>(RHS))
+ return ListTy->getElementType()->typeIsConvertibleTo(Ty);
+ return false;
+}
+
Init *DagRecTy::convertValue(TypedInit *TI) {
if (TI->getType()->typeIsConvertibleTo(this))
return TI;
@@ -328,13 +355,17 @@ Init *RecordRecTy::convertValue(TypedInit *TI) {
return 0;
}
-bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
- if (Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec))
+bool RecordRecTy::baseClassOf(const RecTy *RHS) const{
+ const RecordRecTy *RTy = dyn_cast<RecordRecTy>(RHS);
+ if (!RTy)
+ return false;
+
+ if (Rec == RTy->getRecord() || RTy->getRecord()->isSubClassOf(Rec))
return true;
const std::vector<Record*> &SC = Rec->getSuperClasses();
for (unsigned i = 0, e = SC.size(); i != e; ++i)
- if (RHS->getRecord()->isSubClassOf(SC[i]))
+ if (RTy->getRecord()->isSubClassOf(SC[i]))
return true;
return false;
@@ -904,6 +935,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
break;
}
+ case ADD:
case SHL:
case SRA:
case SRL: {
@@ -914,6 +946,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
int64_t Result;
switch (getOpcode()) {
default: llvm_unreachable("Bad opcode!");
+ case ADD: Result = LHSv + RHSv; break;
case SHL: Result = LHSv << RHSv; break;
case SRA: Result = LHSv >> RHSv; break;
case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
@@ -939,6 +972,7 @@ std::string BinOpInit::getAsString() const {
std::string Result;
switch (Opc) {
case CONCAT: Result = "!con"; break;
+ case ADD: Result = "!add"; break;
case SHL: Result = "!shl"; break;
case SRA: Result = "!sra"; break;
case SRL: Result = "!srl"; break;
@@ -1491,11 +1525,9 @@ Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const {
return const_cast<FieldInit *>(this);
}
-void ProfileDagInit(FoldingSetNodeID &ID,
- Init *V,
- const std::string &VN,
- ArrayRef<Init *> ArgRange,
- ArrayRef<std::string> NameRange) {
+static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, const std::string &VN,
+ ArrayRef<Init *> ArgRange,
+ ArrayRef<std::string> NameRange) {
ID.AddPointer(V);
ID.AddString(VN);
diff --git a/lib/TableGen/TGLexer.cpp b/lib/TableGen/TGLexer.cpp
index d733f142aa..c6be4f8a11 100644
--- a/lib/TableGen/TGLexer.cpp
+++ b/lib/TableGen/TGLexer.cpp
@@ -309,7 +309,15 @@ bool TGLexer::LexInclude() {
return true;
}
- Dependencies.push_back(IncludedFile);
+ DependenciesMapTy::const_iterator Found = Dependencies.find(IncludedFile);
+ if (Found != Dependencies.end()) {
+ PrintError(getLoc(),
+ "File '" + IncludedFile + "' has already been included.");
+ SrcMgr.PrintMessage(Found->second, SourceMgr::DK_Note,
+ "previously included here");
+ return true;
+ }
+ Dependencies.insert(std::make_pair(IncludedFile, getLoc()));
// Save the line number and lex buffer of the includer.
CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
CurPtr = CurBuf->getBufferStart();
@@ -462,6 +470,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
.Case("head", tgtok::XHead)
.Case("tail", tgtok::XTail)
.Case("con", tgtok::XConcat)
+ .Case("add", tgtok::XADD)
.Case("shl", tgtok::XSHL)
.Case("sra", tgtok::XSRA)
.Case("srl", tgtok::XSRL)
diff --git a/lib/TableGen/TGLexer.h b/lib/TableGen/TGLexer.h
index e2e116bb82..d1bd70d2ec 100644
--- a/lib/TableGen/TGLexer.h
+++ b/lib/TableGen/TGLexer.h
@@ -15,9 +15,10 @@
#define TGLEXER_H
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/SMLoc.h"
#include <cassert>
+#include <map>
#include <string>
-#include <vector>
namespace llvm {
class MemoryBuffer;
@@ -46,7 +47,7 @@ namespace tgtok {
MultiClass, String,
// !keywords.
- XConcat, XSRA, XSRL, XSHL, XStrConcat, XCast, XSubst,
+ XConcat, XADD, XSRA, XSRL, XSHL, XStrConcat, XCast, XSubst,
XForEach, XHead, XTail, XEmpty, XIf, XEq,
// Integer value.
@@ -73,9 +74,13 @@ class TGLexer {
/// CurBuffer - This is the current buffer index we're lexing from as managed
/// by the SourceMgr object.
int CurBuffer;
+
+public:
+ typedef std::map<std::string, SMLoc> DependenciesMapTy;
+private:
/// Dependencies - This is the list of all included files.
- std::vector<std::string> Dependencies;
-
+ DependenciesMapTy Dependencies;
+
public:
TGLexer(SourceMgr &SrcMgr);
~TGLexer() {}
@@ -84,7 +89,7 @@ public:
return CurCode = LexToken();
}
- const std::vector<std::string> &getDependencies() const {
+ const DependenciesMapTy &getDependencies() const {
return Dependencies;
}
diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp
index 17f0abc974..c4b48fe5e8 100644
--- a/lib/TableGen/TGParser.cpp
+++ b/lib/TableGen/TGParser.cpp
@@ -26,7 +26,7 @@ using namespace llvm;
namespace llvm {
struct SubClassReference {
- SMLoc RefLoc;
+ SMRange RefRange;
Record *Rec;
std::vector<Init*> TemplateArgs;
SubClassReference() : Rec(0) {}
@@ -35,7 +35,7 @@ struct SubClassReference {
};
struct SubMultiClassReference {
- SMLoc RefLoc;
+ SMRange RefRange;
MultiClass *MC;
std::vector<Init*> TemplateArgs;
SubMultiClassReference() : MC(0) {}
@@ -150,22 +150,23 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
// Add all of the values in the subclass into the current class.
const std::vector<RecordVal> &Vals = SC->getValues();
for (unsigned i = 0, e = Vals.size(); i != e; ++i)
- if (AddValue(CurRec, SubClass.RefLoc, Vals[i]))
+ if (AddValue(CurRec, SubClass.RefRange.Start, Vals[i]))
return true;
const std::vector<Init *> &TArgs = SC->getTemplateArgs();
// Ensure that an appropriate number of template arguments are specified.
if (TArgs.size() < SubClass.TemplateArgs.size())
- return Error(SubClass.RefLoc, "More template args specified than expected");
+ return Error(SubClass.RefRange.Start,
+ "More template args specified than expected");
// Loop over all of the template arguments, setting them to the specified
// value or leaving them as the default if necessary.
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
if (i < SubClass.TemplateArgs.size()) {
// If a value is specified for this template arg, set it now.
- if (SetValue(CurRec, SubClass.RefLoc, TArgs[i], std::vector<unsigned>(),
- SubClass.TemplateArgs[i]))
+ if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i],
+ std::vector<unsigned>(), SubClass.TemplateArgs[i]))
return true;
// Resolve it next.
@@ -175,7 +176,8 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
CurRec->removeValue(TArgs[i]);
} else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
- return Error(SubClass.RefLoc,"Value not specified for template argument #"
+ return Error(SubClass.RefRange.Start,
+ "Value not specified for template argument #"
+ utostr(i) + " (" + TArgs[i]->getAsUnquotedString()
+ ") of subclass '" + SC->getNameInitAsString() + "'!");
}
@@ -184,17 +186,18 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
// Since everything went well, we can now set the "superclass" list for the
// current record.
const std::vector<Record*> &SCs = SC->getSuperClasses();
+ ArrayRef<SMRange> SCRanges = SC->getSuperClassRanges();
for (unsigned i = 0, e = SCs.size(); i != e; ++i) {
if (CurRec->isSubClassOf(SCs[i]))
- return Error(SubClass.RefLoc,
+ return Error(SubClass.RefRange.Start,
"Already subclass of '" + SCs[i]->getName() + "'!\n");
- CurRec->addSuperClass(SCs[i]);
+ CurRec->addSuperClass(SCs[i], SCRanges[i]);
}
if (CurRec->isSubClassOf(SC))
- return Error(SubClass.RefLoc,
+ return Error(SubClass.RefRange.Start,
"Already subclass of '" + SC->getName() + "'!\n");
- CurRec->addSuperClass(SC);
+ CurRec->addSuperClass(SC, SubClass.RefRange);
return false;
}
@@ -211,7 +214,7 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
// Add all of the values in the subclass into the current class.
const std::vector<RecordVal> &SMCVals = SMC->Rec.getValues();
for (unsigned i = 0, e = SMCVals.size(); i != e; ++i)
- if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
+ if (AddValue(CurRec, SubMultiClass.RefRange.Start, SMCVals[i]))
return true;
int newDefStart = CurMC->DefPrototypes.size();
@@ -226,7 +229,7 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
// Add all of the values in the superclass into the current def.
for (unsigned i = 0, e = MCVals.size(); i != e; ++i)
- if (AddValue(NewDef, SubMultiClass.RefLoc, MCVals[i]))
+ if (AddValue(NewDef, SubMultiClass.RefRange.Start, MCVals[i]))
return true;
CurMC->DefPrototypes.push_back(NewDef);
@@ -237,7 +240,7 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
// Ensure that an appropriate number of template arguments are
// specified.
if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
- return Error(SubMultiClass.RefLoc,
+ return Error(SubMultiClass.RefRange.Start,
"More template args specified than expected");
// Loop over all of the template arguments, setting them to the specified
@@ -246,7 +249,7 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
if (i < SubMultiClass.TemplateArgs.size()) {
// If a value is specified for this template arg, set it in the
// superclass now.
- if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i],
+ if (SetValue(CurRec, SubMultiClass.RefRange.Start, SMCTArgs[i],
std::vector<unsigned>(),
SubMultiClass.TemplateArgs[i]))
return true;
@@ -266,7 +269,7 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
++j) {
Record *Def = *j;
- if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i],
+ if (SetValue(Def, SubMultiClass.RefRange.Start, SMCTArgs[i],
std::vector<unsigned>(),
SubMultiClass.TemplateArgs[i]))
return true;
@@ -278,7 +281,7 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
Def->removeValue(SMCTArgs[i]);
}
} else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
- return Error(SubMultiClass.RefLoc,
+ return Error(SubMultiClass.RefRange.Start,
"Value not specified for template argument #"
+ utostr(i) + " (" + SMCTArgs[i]->getAsUnquotedString()
+ ") of subclass '" + SMC->Rec.getNameInitAsString() + "'!");
@@ -379,11 +382,12 @@ static bool isObjectStart(tgtok::TokKind K) {
static std::string GetNewAnonymousName() {
static unsigned AnonCounter = 0;
- return "anonymous."+utostr(AnonCounter++);
+ unsigned Tmp = AnonCounter++; // MSVC2012 ICEs without this.
+ return "anonymous." + utostr(Tmp);
}
/// ParseObjectName - If an object name is specified, return it. Otherwise,
-/// return an anonymous name.
+/// return 0.
/// ObjectName ::= Value [ '#' Value ]*
/// ObjectName ::= /*empty*/
///
@@ -395,7 +399,7 @@ 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 StringInit::get(GetNewAnonymousName());
+ return 0;
default:
break;
}
@@ -443,35 +447,18 @@ Record *TGParser::ParseClassID() {
///
MultiClass *TGParser::ParseMultiClassID() {
if (Lex.getCode() != tgtok::Id) {
- TokError("expected name for ClassID");
+ TokError("expected name for MultiClassID");
return 0;
}
MultiClass *Result = MultiClasses[Lex.getCurStrVal()];
if (Result == 0)
- TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
-
- Lex.Lex();
- return Result;
-}
-
-Record *TGParser::ParseDefmID() {
- if (Lex.getCode() != tgtok::Id) {
- TokError("expected multiclass name");
- return 0;
- }
-
- MultiClass *MC = MultiClasses[Lex.getCurStrVal()];
- if (MC == 0) {
TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'");
- return 0;
- }
Lex.Lex();
- return &MC->Rec;
+ return Result;
}
-
/// ParseSubClassReference - Parse a reference to a subclass or to a templated
/// subclass. This returns a SubClassRefTy with a null Record* on error.
///
@@ -481,17 +468,21 @@ Record *TGParser::ParseDefmID() {
SubClassReference TGParser::
ParseSubClassReference(Record *CurRec, bool isDefm) {
SubClassReference Result;
- Result.RefLoc = Lex.getLoc();
+ Result.RefRange.Start = Lex.getLoc();
- if (isDefm)
- Result.Rec = ParseDefmID();
- else
+ if (isDefm) {
+ if (MultiClass *MC = ParseMultiClassID())
+ Result.Rec = &MC->Rec;
+ } else {
Result.Rec = ParseClassID();
+ }
if (Result.Rec == 0) return Result;
// If there is no template arg list, we're done.
- if (Lex.getCode() != tgtok::less)
+ if (Lex.getCode() != tgtok::less) {
+ Result.RefRange.End = Lex.getLoc();
return Result;
+ }
Lex.Lex(); // Eat the '<'
if (Lex.getCode() == tgtok::greater) {
@@ -512,6 +503,7 @@ ParseSubClassReference(Record *CurRec, bool isDefm) {
return Result;
}
Lex.Lex();
+ Result.RefRange.End = Lex.getLoc();
return Result;
}
@@ -526,14 +518,16 @@ ParseSubClassReference(Record *CurRec, bool isDefm) {
SubMultiClassReference TGParser::
ParseSubMultiClassReference(MultiClass *CurMC) {
SubMultiClassReference Result;
- Result.RefLoc = Lex.getLoc();
+ Result.RefRange.Start = Lex.getLoc();
Result.MC = ParseMultiClassID();
if (Result.MC == 0) return Result;
// If there is no template arg list, we're done.
- if (Lex.getCode() != tgtok::less)
+ if (Lex.getCode() != tgtok::less) {
+ Result.RefRange.End = Lex.getLoc();
return Result;
+ }
Lex.Lex(); // Eat the '<'
if (Lex.getCode() == tgtok::greater) {
@@ -554,6 +548,7 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
return Result;
}
Lex.Lex();
+ Result.RefRange.End = Lex.getLoc();
return Result;
}
@@ -918,6 +913,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
}
case tgtok::XConcat:
+ case tgtok::XADD:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
@@ -933,6 +929,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
switch (OpTok) {
default: llvm_unreachable("Unhandled code!");
case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break;
+ case tgtok::XADD: Code = BinOpInit::ADD; Type = IntRecTy::get(); break;
case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break;
case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break;
case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break;
@@ -1148,6 +1145,7 @@ RecTy *TGParser::ParseOperatorType() {
/// SimpleValue ::= '[' ValueList ']'
/// SimpleValue ::= '(' IDValue DagArgList ')'
/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
+/// SimpleValue ::= ADDTOK '(' Value ',' Value ')'
/// SimpleValue ::= SHLTOK '(' Value ',' Value ')'
/// SimpleValue ::= SRATOK '(' Value ',' Value ')'
/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
@@ -1214,14 +1212,16 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
return 0;
}
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);
+ Records,
+ /*IsAnonymous=*/true);
SubClassReference SCRef;
- SCRef.RefLoc = NameLoc;
+ SCRef.RefRange = SMRange(NameLoc, EndLoc);
SCRef.Rec = Class;
SCRef.TemplateArgs = ValueList;
// Add info about the subclass to NewRec.
@@ -1401,6 +1401,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XEmpty:
case tgtok::XCast: // Value ::= !unop '(' Value ')'
case tgtok::XConcat:
+ case tgtok::XADD:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
@@ -1876,6 +1877,17 @@ bool TGParser::ParseBody(Record *CurRec) {
return false;
}
+/// \brief Apply the current let bindings to \a CurRec.
+/// \returns true on error, false otherwise.
+bool TGParser::ApplyLetStack(Record *CurRec) {
+ for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
+ for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
+ if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
+ LetStack[i][j].Bits, LetStack[i][j].Value))
+ return true;
+ return false;
+}
+
/// ParseObjectBody - Parse the body of a def or class. This consists of an
/// optional ClassList followed by a Body. CurRec is the current def or class
/// that is being parsed.
@@ -1906,12 +1918,8 @@ bool TGParser::ParseObjectBody(Record *CurRec) {
}
}
- // Process any variables on the let stack.
- for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
- for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
- if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
- LetStack[i][j].Bits, LetStack[i][j].Value))
- return true;
+ if (ApplyLetStack(CurRec))
+ return true;
return ParseBody(CurRec);
}
@@ -1927,7 +1935,13 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
Lex.Lex(); // Eat the 'def' token.
// Parse ObjectName and make a record for it.
- Record *CurRec = new Record(ParseObjectName(CurMultiClass), DefLoc, Records);
+ Record *CurRec;
+ Init *Name = ParseObjectName(CurMultiClass);
+ if (Name)
+ CurRec = new Record(Name, DefLoc, Records);
+ else
+ CurRec = new Record(GetNewAnonymousName(), DefLoc, Records,
+ /*IsAnonymous=*/true);
if (!CurMultiClass && Loops.empty()) {
// Top-level def definition.
@@ -2160,7 +2174,12 @@ bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
/// ParseMultiClass - Parse a multiclass definition.
///
/// MultiClassInst ::= MULTICLASS ID TemplateArgList?
-/// ':' BaseMultiClassList '{' MultiClassDef+ '}'
+/// ':' BaseMultiClassList '{' MultiClassObject+ '}'
+/// MultiClassObject ::= DefInst
+/// MultiClassObject ::= MultiClassInst
+/// MultiClassObject ::= DefMInst
+/// MultiClassObject ::= LETCommand '{' ObjectList '}'
+/// MultiClassObject ::= LETCommand Object
///
bool TGParser::ParseMultiClass() {
assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
@@ -2242,7 +2261,7 @@ Record *TGParser::
InstantiateMulticlassDef(MultiClass &MC,
Record *DefProto,
Init *DefmPrefix,
- SMLoc DefmPrefixLoc) {
+ SMRange DefmPrefixRange) {
// We need to preserve DefProto so it can be reused for later
// instantiations, so create a new Record to inherit from it.
@@ -2251,8 +2270,11 @@ InstantiateMulticlassDef(MultiClass &MC,
// name, substitute the prefix for #NAME#. Otherwise, use the defm name
// as a prefix.
- if (DefmPrefix == 0)
+ bool IsAnonymous = false;
+ if (DefmPrefix == 0) {
DefmPrefix = StringInit::get(GetNewAnonymousName());
+ IsAnonymous = true;
+ }
Init *DefName = DefProto->getNameInit();
@@ -2269,21 +2291,21 @@ InstantiateMulticlassDef(MultiClass &MC,
}
// Make a trail of SMLocs from the multiclass instantiations.
- SmallVector<SMLoc, 4> Locs(1, DefmPrefixLoc);
+ SmallVector<SMLoc, 4> Locs(1, DefmPrefixRange.Start);
Locs.append(DefProto->getLoc().begin(), DefProto->getLoc().end());
- Record *CurRec = new Record(DefName, Locs, Records);
+ Record *CurRec = new Record(DefName, Locs, Records, IsAnonymous);
SubClassReference Ref;
- Ref.RefLoc = DefmPrefixLoc;
+ Ref.RefRange = DefmPrefixRange;
Ref.Rec = DefProto;
AddSubClass(CurRec, Ref);
// Set the value for NAME. We don't resolve references to it 'til later,
// though, so that uses in nested multiclass names don't get
// confused.
- if (SetValue(CurRec, Ref.RefLoc, "NAME", std::vector<unsigned>(),
+ if (SetValue(CurRec, Ref.RefRange.Start, "NAME", std::vector<unsigned>(),
DefmPrefix)) {
- Error(DefmPrefixLoc, "Could not resolve "
+ Error(DefmPrefixRange.Start, "Could not resolve "
+ CurRec->getNameInitAsString() + ":NAME to '"
+ DefmPrefix->getAsUnquotedString() + "'");
return 0;
@@ -2314,7 +2336,7 @@ InstantiateMulticlassDef(MultiClass &MC,
// Ensure redefinition doesn't happen.
if (Records.getDef(CurRec->getNameInitAsString())) {
- Error(DefmPrefixLoc, "def '" + CurRec->getNameInitAsString() +
+ Error(DefmPrefixRange.Start, "def '" + CurRec->getNameInitAsString() +
"' already defined, instantiating defm with subdef '" +
DefProto->getNameInitAsString() + "'");
return 0;
@@ -2365,33 +2387,30 @@ bool TGParser::ResolveMulticlassDef(MultiClass &MC,
Record *DefProto,
SMLoc DefmPrefixLoc) {
// If the mdef is inside a 'let' expression, add to each def.
- for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
- for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
- if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
- LetStack[i][j].Bits, LetStack[i][j].Value))
- return Error(DefmPrefixLoc, "when instantiating this defm");
+ if (ApplyLetStack(CurRec))
+ return Error(DefmPrefixLoc, "when instantiating this defm");
// Don't create a top level definition for defm inside multiclasses,
// instead, only update the prototypes and bind the template args
// with the new created definition.
- if (CurMultiClass) {
- for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size();
- i != e; ++i)
- if (CurMultiClass->DefPrototypes[i]->getNameInit()
- == CurRec->getNameInit())
- return Error(DefmPrefixLoc, "defm '" + CurRec->getNameInitAsString() +
- "' already defined in this multiclass!");
- CurMultiClass->DefPrototypes.push_back(CurRec);
+ if (!CurMultiClass)
+ return false;
+ for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size();
+ i != e; ++i)
+ if (CurMultiClass->DefPrototypes[i]->getNameInit()
+ == CurRec->getNameInit())
+ return Error(DefmPrefixLoc, "defm '" + CurRec->getNameInitAsString() +
+ "' already defined in this multiclass!");
+ CurMultiClass->DefPrototypes.push_back(CurRec);
- // Copy the template arguments for the multiclass into the new def.
- const std::vector<Init *> &TA =
- CurMultiClass->Rec.getTemplateArgs();
+ // Copy the template arguments for the multiclass into the new def.
+ const std::vector<Init *> &TA =
+ CurMultiClass->Rec.getTemplateArgs();
- for (unsigned i = 0, e = TA.size(); i != e; ++i) {
- const RecordVal *RV = CurMultiClass->Rec.getValue(TA[i]);
- assert(RV && "Template arg doesn't exist?");
- CurRec->addValue(*RV);
- }
+ for (unsigned i = 0, e = TA.size(); i != e; ++i) {
+ const RecordVal *RV = CurMultiClass->Rec.getValue(TA[i]);
+ assert(RV && "Template arg doesn't exist?");
+ CurRec->addValue(*RV);
}
return false;
@@ -2403,14 +2422,14 @@ bool TGParser::ResolveMulticlassDef(MultiClass &MC,
///
bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
-
+ SMLoc DefmLoc = Lex.getLoc();
Init *DefmPrefix = 0;
if (Lex.Lex() == tgtok::Id) { // eat the defm.
DefmPrefix = ParseObjectName(CurMultiClass);
}
- SMLoc DefmPrefixLoc = Lex.getLoc();
+ SMLoc DefmPrefixEndLoc = Lex.getLoc();
if (Lex.getCode() != tgtok::colon)
return TokError("expected ':' after defm identifier");
@@ -2446,15 +2465,17 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
Record *DefProto = MC->DefPrototypes[i];
- Record *CurRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix, DefmPrefixLoc);
+ Record *CurRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix,
+ SMRange(DefmLoc,
+ DefmPrefixEndLoc));
if (!CurRec)
return true;
- if (ResolveMulticlassDefArgs(*MC, CurRec, DefmPrefixLoc, SubClassLoc,
+ if (ResolveMulticlassDefArgs(*MC, CurRec, DefmLoc, SubClassLoc,
TArgs, TemplateVals, true/*Delete args*/))
return Error(SubClassLoc, "could not instantiate def");
- if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmPrefixLoc))
+ if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmLoc))
return Error(SubClassLoc, "could not instantiate def");
NewRecDefs.push_back(CurRec);
@@ -2493,12 +2514,8 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
if (AddSubClass(CurRec, SubClass))
return true;
- // Process any variables on the let stack.
- for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
- for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
- if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
- LetStack[i][j].Bits, LetStack[i][j].Value))
- return true;
+ if (ApplyLetStack(CurRec))
+ return true;
}
if (Lex.getCode() != tgtok::comma) break;
diff --git a/lib/TableGen/TGParser.h b/lib/TableGen/TGParser.h
index 0ea962b995..044e3a02ba 100644
--- a/lib/TableGen/TGParser.h
+++ b/lib/TableGen/TGParser.h
@@ -96,7 +96,7 @@ public:
bool TokError(const Twine &Msg) const {
return Error(Lex.getLoc(), Msg);
}
- const std::vector<std::string> &getDependencies() const {
+ const TGLexer::DependenciesMapTy &getDependencies() const {
return Lex.getDependencies();
}
@@ -134,7 +134,7 @@ private: // Parser methods.
Record *InstantiateMulticlassDef(MultiClass &MC,
Record *DefProto,
Init *DefmPrefix,
- SMLoc DefmPrefixLoc);
+ SMRange DefmPrefixRange);
bool ResolveMulticlassDefArgs(MultiClass &MC,
Record *DefProto,
SMLoc DefmPrefixLoc,
@@ -183,7 +183,7 @@ private: // Parser methods.
Init *ParseObjectName(MultiClass *CurMultiClass);
Record *ParseClassID();
MultiClass *ParseMultiClassID();
- Record *ParseDefmID();
+ bool ApplyLetStack(Record *CurRec);
};
} // end namespace llvm
diff --git a/lib/TableGen/TableGenBackend.cpp b/lib/TableGen/TableGenBackend.cpp
index 7c8367ab9d..79d567753a 100644
--- a/lib/TableGen/TableGenBackend.cpp
+++ b/lib/TableGen/TableGenBackend.cpp
@@ -14,13 +14,20 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/TableGenBackend.h"
+#include <algorithm>
+
using namespace llvm;
+const size_t MAX_LINE_LEN = 80U;
+
static void printLine(raw_ostream &OS, const Twine &Prefix, char Fill,
StringRef Suffix) {
- uint64_t Pos = OS.tell();
+ size_t Pos = (size_t)OS.tell();
+ assert((MAX_LINE_LEN - Prefix.str().size() - Suffix.size() > 0) &&
+ "header line exceeds max limit");
OS << Prefix;
- for (unsigned i = OS.tell() - Pos, e = 80 - Suffix.size(); i != e; ++i)
+ const size_t e = MAX_LINE_LEN - Suffix.size();
+ for (size_t i = (size_t)OS.tell() - Pos; i < e; ++i)
OS << Fill;
OS << Suffix << '\n';
}
@@ -28,10 +35,22 @@ static void printLine(raw_ostream &OS, const Twine &Prefix, char Fill,
void llvm::emitSourceFileHeader(StringRef Desc, raw_ostream &OS) {
printLine(OS, "/*===- TableGen'erated file ", '-', "*- C++ -*-===*\\");
printLine(OS, "|*", ' ', "*|");
- printLine(OS, "|* " + Desc, ' ', "*|");
- printLine(OS, "|*", ' ', "*|");
- printLine(OS, "|* Automatically generated file, do not edit!", ' ', "*|");
- printLine(OS, "|*", ' ', "*|");
+ size_t Pos = 0U;
+ size_t PosE;
+ StringRef Prefix("|*");
+ StringRef Suffix(" *|");
+ do{
+ size_t PSLen = Suffix.size() + Prefix.size();
+ PosE = Pos + ((MAX_LINE_LEN > (Desc.size() - PSLen)) ?
+ Desc.size() :
+ MAX_LINE_LEN - PSLen);
+ printLine(OS, Prefix + Desc.slice(Pos, PosE), ' ', Suffix);
+ Pos = PosE;
+ } while(Pos < Desc.size());
+ printLine(OS, Prefix, ' ', Suffix);
+ printLine(OS, Prefix + " Automatically generated file, do not edit!", ' ',
+ Suffix);
+ printLine(OS, Prefix, ' ', Suffix);
printLine(OS, "\\*===", '-', "===*/");
OS << '\n';
}