aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/TableGen/TGParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/TableGen/TGParser.cpp')
-rw-r--r--llvm/lib/TableGen/TGParser.cpp117
1 files changed, 93 insertions, 24 deletions
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index aab1802c5348..7fc46a8b4a87 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -12,7 +12,6 @@
#include "TGParser.h"
#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
@@ -161,7 +160,7 @@ bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
/// Return true on error, false on success.
bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
ArrayRef<unsigned> BitList, Init *V,
- bool AllowSelfAssignment) {
+ bool AllowSelfAssignment, bool OverrideDefLoc) {
if (!V) return false;
if (!CurRec) CurRec = &CurMultiClass->Rec;
@@ -211,7 +210,7 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
V = BitsInit::get(Records, NewBits);
}
- if (RV->setValue(V, Loc)) {
+ if (OverrideDefLoc ? RV->setValue(V, Loc) : RV->setValue(V)) {
std::string InitType;
if (BitsInit *BI = dyn_cast<BitsInit>(V))
InitType = (Twine("' of type bit initializer with length ") +
@@ -404,7 +403,7 @@ bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs,
}
bool Error = false;
- for (auto Elt : *LI) {
+ for (auto *Elt : *LI) {
if (Loop.IterVar)
Substs.emplace_back(Loop.IterVar->getNameInit(), Elt);
Error = resolve(Loop.Entries, Substs, Final, Dest);
@@ -586,6 +585,8 @@ Record *TGParser::ParseClassID() {
Lex.getCurStrVal() + "'");
else
TokError(Msg);
+ } else if (TrackReferenceLocs) {
+ Result->appendReferenceLoc(Lex.getLocRange());
}
Lex.Lex();
@@ -867,11 +868,14 @@ RecTy *TGParser::ParseType() {
}
/// ParseIDValue
-Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
+Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMRange NameLoc,
IDParseMode Mode) {
if (CurRec) {
- if (const RecordVal *RV = CurRec->getValue(Name))
+ if (RecordVal *RV = CurRec->getValue(Name)) {
+ if (TrackReferenceLocs)
+ RV->addReferenceLoc(NameLoc);
return VarInit::get(Name, RV->getType());
+ }
}
if ((CurRec && CurRec->isClass()) || CurMultiClass) {
@@ -887,6 +891,8 @@ Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
RecordVal *RV = TemplateRec->getValue(TemplateArgName);
assert(RV && "Template arg doesn't exist??");
RV->setUsed(true);
+ if (TrackReferenceLocs)
+ RV->addReferenceLoc(NameLoc);
return VarInit::get(TemplateArgName, RV->getType());
} else if (Name->getValue() == "NAME") {
return VarInit::get(TemplateArgName, StringRecTy::get(Records));
@@ -909,8 +915,14 @@ Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
if (Mode == ParseNameMode)
return Name;
- if (Init *I = Records.getGlobal(Name->getValue()))
+ if (Init *I = Records.getGlobal(Name->getValue())) {
+ // Add a reference to the global if it's a record.
+ if (TrackReferenceLocs) {
+ if (auto *Def = dyn_cast<DefInit>(I))
+ Def->getDef()->appendReferenceLoc(NameLoc);
+ }
return I;
+ }
// Allow self-references of concrete defs, but delay the lookup so that we
// get the correct type.
@@ -918,7 +930,7 @@ Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
CurRec->getNameInit() == Name)
return UnOpInit::get(UnOpInit::CAST, Name, CurRec->getType());
- Error(NameLoc, "Variable not defined: '" + Name->getValue() + "'");
+ Error(NameLoc.Start, "Variable not defined: '" + Name->getValue() + "'");
return nullptr;
}
@@ -932,6 +944,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
TokError("unknown bang operator");
return nullptr;
case tgtok::XNOT:
+ case tgtok::XLOG2:
case tgtok::XHead:
case tgtok::XTail:
case tgtok::XSize:
@@ -960,6 +973,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
Code = UnOpInit::NOT;
Type = IntRecTy::get(Records);
break;
+ case tgtok::XLOG2:
+ Lex.Lex(); // eat the operation
+ Code = UnOpInit::LOG2;
+ Type = IntRecTy::get(Records);
+ break;
case tgtok::XHead:
Lex.Lex(); // eat the operation
Code = UnOpInit::HEAD;
@@ -1146,6 +1164,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XADD:
case tgtok::XSUB:
case tgtok::XMUL:
+ case tgtok::XDIV:
case tgtok::XAND:
case tgtok::XOR:
case tgtok::XXOR:
@@ -1160,6 +1179,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XGt:
case tgtok::XListConcat:
case tgtok::XListSplat:
+ case tgtok::XListRemove:
case tgtok::XStrConcat:
case tgtok::XInterleave:
case tgtok::XSetDagOp: { // Value ::= !binop '(' Value ',' Value ')'
@@ -1174,6 +1194,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XADD: Code = BinOpInit::ADD; break;
case tgtok::XSUB: Code = BinOpInit::SUB; break;
case tgtok::XMUL: Code = BinOpInit::MUL; break;
+ case tgtok::XDIV: Code = BinOpInit::DIV; break;
case tgtok::XAND: Code = BinOpInit::AND; break;
case tgtok::XOR: Code = BinOpInit::OR; break;
case tgtok::XXOR: Code = BinOpInit::XOR; break;
@@ -1188,6 +1209,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XGt: Code = BinOpInit::GT; break;
case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break;
case tgtok::XListSplat: Code = BinOpInit::LISTSPLAT; break;
+ case tgtok::XListRemove: Code = BinOpInit::LISTREMOVE; break;
case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
case tgtok::XInterleave: Code = BinOpInit::INTERLEAVE; break;
case tgtok::XSetDagOp: Code = BinOpInit::SETDAGOP; break;
@@ -1212,6 +1234,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XADD:
case tgtok::XSUB:
case tgtok::XMUL:
+ case tgtok::XDIV:
Type = IntRecTy::get(Records);
ArgType = IntRecTy::get(Records);
break;
@@ -1225,12 +1248,16 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
// ArgType for the comparison operators is not yet known.
break;
case tgtok::XListConcat:
- // We don't know the list type until we parse the first argument
+ // We don't know the list type until we parse the first argument.
ArgType = ItemType;
break;
case tgtok::XListSplat:
// Can't do any typechecking until we parse the first argument.
break;
+ case tgtok::XListRemove:
+ // We don't know the list type until we parse the first argument.
+ ArgType = ItemType;
+ break;
case tgtok::XStrConcat:
Type = StringRecTy::get(Records);
ArgType = StringRecTy::get(Records);
@@ -1308,6 +1335,13 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
}
ArgType = nullptr; // Broken invariant: types not identical.
break;
+ case BinOpInit::LISTREMOVE:
+ if (!isa<ListRecTy>(ArgType)) {
+ Error(InitLoc, Twine("expected a list, got value of type '") +
+ ArgType->getAsString() + "'");
+ return nullptr;
+ }
+ break;
case BinOpInit::EQ:
case BinOpInit::NE:
if (!ArgType->typeIsConvertibleTo(IntRecTy::get(Records)) &&
@@ -1371,7 +1405,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
Code != BinOpInit::AND && Code != BinOpInit::OR &&
Code != BinOpInit::XOR && Code != BinOpInit::SRA &&
Code != BinOpInit::SRL && Code != BinOpInit::SHL &&
- Code != BinOpInit::MUL)
+ Code != BinOpInit::MUL && Code != BinOpInit::DIV)
ArgType = Resolved;
}
@@ -1402,6 +1436,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
// listsplat returns a list of type of the *first* argument.
if (Code == BinOpInit::LISTSPLAT)
Type = cast<TypedInit>(InitList.front())->getType()->getListTy();
+ // listremove returns a list with type of the argument.
+ if (Code == BinOpInit::LISTREMOVE)
+ Type = ArgType;
// We allow multiple operands to associative operators like !strconcat as
// shorthand for nesting them.
@@ -2126,12 +2163,14 @@ Init *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) {
/// SimpleValue ::= '(' IDValue DagArgList ')'
/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
/// SimpleValue ::= ADDTOK '(' Value ',' Value ')'
+/// SimpleValue ::= DIVTOK '(' Value ',' Value ')'
/// SimpleValue ::= SUBTOK '(' Value ',' Value ')'
/// SimpleValue ::= SHLTOK '(' Value ',' Value ')'
/// SimpleValue ::= SRATOK '(' Value ',' Value ')'
/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
/// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'
/// SimpleValue ::= LISTSPLATTOK '(' Value ',' Value ')'
+/// SimpleValue ::= LISTREMOVETOK '(' Value ',' Value ')'
/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
/// SimpleValue ::= COND '(' [Value ':' Value,]+ ')'
///
@@ -2184,7 +2223,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
Lex.Lex();
break;
case tgtok::Id: {
- SMLoc NameLoc = Lex.getLoc();
+ SMRange NameLoc = Lex.getLocRange();
StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());
if (Lex.Lex() != tgtok::less) // consume the Id.
return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue
@@ -2194,7 +2233,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
// from the class with the template arguments, but no body.
Record *Class = Records.getClass(Name->getValue());
if (!Class) {
- Error(NameLoc, "Expected a class name, got '" + Name->getValue() + "'");
+ Error(NameLoc.Start,
+ "Expected a class name, got '" + Name->getValue() + "'");
return nullptr;
}
@@ -2203,7 +2243,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
if (ParseTemplateArgValueList(Args, CurRec, Class))
return nullptr; // Error parsing value list.
- if (CheckTemplateArgValues(Args, NameLoc, Class))
+ if (CheckTemplateArgValues(Args, NameLoc.Start, Class))
return nullptr; // Error checking template argument values.
// Loop through the arguments that were not specified and make sure
@@ -2211,14 +2251,16 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
ArrayRef<Init *> TArgs = Class->getTemplateArgs();
for (unsigned I = Args.size(), E = TArgs.size(); I < E; ++I) {
RecordVal *Arg = Class->getValue(TArgs[I]);
- if (!Arg->getValue()->isComplete())
- Error(NameLoc, "Value not specified for template argument '" +
- TArgs[I]->getAsUnquotedString() + "' (#" + Twine(I) +
- ") of parent class '" +
- Class->getNameInitAsString() + "'");
-
+ if (!Arg->getValue()->isComplete()) {
+ Error(NameLoc.Start, "Value not specified for template argument '" +
+ TArgs[I]->getAsUnquotedString() + "' (#" +
+ Twine(I) + ") of parent class '" +
+ Class->getNameInitAsString() + "'");
+ }
}
+ if (TrackReferenceLocs)
+ Class->appendReferenceLoc(NameLoc);
return VarDefInit::get(Class, Args)->Fold();
}
case tgtok::l_brace: { // Value ::= '{' ValueList '}'
@@ -2411,7 +2453,9 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XADD:
case tgtok::XSUB:
case tgtok::XMUL:
+ case tgtok::XDIV:
case tgtok::XNOT:
+ case tgtok::XLOG2:
case tgtok::XAND:
case tgtok::XOR:
case tgtok::XXOR:
@@ -2426,6 +2470,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XGt:
case tgtok::XListConcat:
case tgtok::XListSplat:
+ case tgtok::XListRemove:
case tgtok::XStrConcat:
case tgtok::XInterleave:
case tgtok::XSetDagOp: // Value ::= !binop '(' Value ',' Value ')'
@@ -2510,12 +2555,27 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
TokError("expected field identifier after '.'");
return nullptr;
}
+ SMRange FieldNameLoc = Lex.getLocRange();
StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal());
if (!Result->getFieldType(FieldName)) {
TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
Result->getAsString() + "'");
return nullptr;
}
+
+ // Add a reference to this field if we know the record class.
+ if (TrackReferenceLocs) {
+ if (auto *DI = dyn_cast<DefInit>(Result)) {
+ DI->getDef()->getValue(FieldName)->addReferenceLoc(FieldNameLoc);
+ } else if (auto *TI = dyn_cast<TypedInit>(Result)) {
+ if (auto *RecTy = dyn_cast<RecordRecTy>(TI->getType())) {
+ for (Record *R : RecTy->getClasses())
+ if (auto *RV = R->getValue(FieldName))
+ RV->addReferenceLoc(FieldNameLoc);
+ }
+ }
+ }
+
Result = FieldInit::get(Result, FieldName)->Fold(CurRec);
Lex.Lex(); // eat field name
break;
@@ -2780,11 +2840,13 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
SMLoc ValLoc = Lex.getLoc();
Init *Val = ParseValue(CurRec, Type);
if (!Val ||
- SetValue(CurRec, ValLoc, DeclName, None, Val))
+ SetValue(CurRec, ValLoc, DeclName, std::nullopt, Val,
+ /*AllowSelfAssignment=*/false, /*OverrideDefLoc=*/false)) {
// Return the name, even if an error is thrown. This is so that we can
// continue to make some progress, even without the value having been
// initialized.
return DeclName;
+ }
}
return DeclName;
@@ -3078,17 +3140,24 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
assert(Lex.getCode() == tgtok::Def && "Unknown tok");
Lex.Lex(); // Eat the 'def' token.
+ // If the name of the def is an Id token, use that for the location.
+ // Otherwise, the name is more complex and we use the location of the 'def'
+ // token.
+ SMLoc NameLoc = Lex.getCode() == tgtok::Id ? Lex.getLoc() : DefLoc;
+
// Parse ObjectName and make a record for it.
std::unique_ptr<Record> CurRec;
Init *Name = ParseObjectName(CurMultiClass);
if (!Name)
return true;
- if (isa<UnsetInit>(Name))
- CurRec = std::make_unique<Record>(Records.getNewAnonymousName(), DefLoc, Records,
+ if (isa<UnsetInit>(Name)) {
+ CurRec =
+ std::make_unique<Record>(Records.getNewAnonymousName(), DefLoc, Records,
/*Anonymous=*/true);
- else
- CurRec = std::make_unique<Record>(Name, DefLoc, Records);
+ } else {
+ CurRec = std::make_unique<Record>(Name, NameLoc, Records);
+ }
if (ParseObjectBody(CurRec.get()))
return true;