/// SetValue -
/// Return true on error, false on success.
-bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName,
+bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
const std::vector<unsigned> &BitList, Init *V) {
if (!V) return false;
RecordVal *RV = CurRec->getValue(ValName);
if (RV == 0)
- return Error(Loc, "Value '" + ValName + "' unknown!");
+ return Error(Loc, "Value '" + ValName->getAsUnquotedString()
+ + "' unknown!");
// Do not allow assignments like 'X = X'. This will just cause infinite loops
// in the resolution machinery.
if (BitList.empty())
if (VarInit *VI = dynamic_cast<VarInit*>(V))
- if (VI->getName() == ValName)
+ if (VI->getNameInit() == ValName)
return false;
// If we are assigning to a subset of the bits in the value... then we must be
if (!BitList.empty()) {
BitsInit *CurVal = dynamic_cast<BitsInit*>(RV->getValue());
if (CurVal == 0)
- return Error(Loc, "Value '" + ValName + "' is not a bits type");
+ 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()));
unsigned Bit = BitList[i];
if (NewBits[Bit])
return Error(Loc, "Cannot set bit #" + utostr(Bit) + " of value '" +
- ValName + "' more than once");
+ ValName->getAsUnquotedString() + "' more than once");
NewBits[Bit] = BInit->getBit(i);
}
}
if (RV->setValue(V))
- return Error(Loc, "Value '" + ValName + "' of type '" +
- RV->getType()->getAsString() +
- "' is incompatible with initializer '" + V->getAsString() +"'");
+ return Error(Loc, "Value '" + ValName->getAsUnquotedString() + "' of type '"
+ + RV->getType()->getAsString() +
+ "' is incompatible with initializer '" + V->getAsString()
+ + "'");
return false;
}
if (AddValue(CurRec, SubClass.RefLoc, Vals[i]))
return true;
- const std::vector<std::string> &TArgs = SC->getTemplateArgs();
+ const std::vector<Init *> &TArgs = SC->getTemplateArgs();
// Ensure that an appropriate number of template arguments are specified.
if (TArgs.size() < SubClass.TemplateArgs.size())
} else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
return Error(SubClass.RefLoc,"Value not specified for template argument #"
- + utostr(i) + " (" + TArgs[i] + ") of subclass '" +
- SC->getName() + "'!");
+ + utostr(i) + " (" + TArgs[i]->getAsUnquotedString()
+ + ") of subclass '" + SC->getNameInitAsString() + "'!");
}
}
CurMC->DefPrototypes.push_back(NewDef);
}
- const std::vector<std::string> &SMCTArgs = SMC->Rec.getTemplateArgs();
+ const std::vector<Init *> &SMCTArgs = SMC->Rec.getTemplateArgs();
// Ensure that an appropriate number of template arguments are
// specified.
} else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
return Error(SubMultiClass.RefLoc,
"Value not specified for template argument #"
- + utostr(i) + " (" + SMCTArgs[i] + ") of subclass '" +
- SMC->Rec.getName() + "'!");
+ + utostr(i) + " (" + SMCTArgs[i]->getAsUnquotedString()
+ + ") of subclass '" + SMC->Rec.getNameInitAsString() + "'!");
}
}
/// IDValue ::= ID [multiclass template argument]
/// IDValue ::= ID [def name]
///
-Init *TGParser::ParseIDValue(Record *CurRec) {
+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();
/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID
/// has already been read.
Init *TGParser::ParseIDValue(Record *CurRec,
- const std::string &Name, SMLoc NameLoc) {
+ const std::string &Name, SMLoc NameLoc,
+ IDParseMode Mode) {
if (CurRec) {
if (const RecordVal *RV = CurRec->getValue(Name))
return VarInit::get(Name, RV->getType());
- std::string TemplateArgName = CurRec->getName()+":"+Name;
+ Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":");
+
+ if (CurMultiClass)
+ TemplateArgName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name,
+ "::");
+
if (CurRec->isTemplateArg(TemplateArgName)) {
const RecordVal *RV = CurRec->getValue(TemplateArgName);
assert(RV && "Template arg doesn't exist??");
}
if (CurMultiClass) {
- std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
+ Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name,
+ "::");
+
if (CurMultiClass->Rec.isTemplateArg(MCName)) {
const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
assert(RV && "Template arg doesn't exist??");
}
}
+ if (Mode == ParseNameMode)
+ return StringInit::get(Name);
+
if (Record *D = Records.getDef(Name))
return DefInit::get(D);
- Error(NameLoc, "Variable not defined: '" + Name + "'");
- return 0;
+ if (Mode == ParseValueMode) {
+ Error(NameLoc, "Variable not defined: '" + Name + "'");
+ return 0;
+ }
+
+ return StringInit::get(Name);
}
/// ParseOperation - Parse an operator. This returns null on error.
/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
///
-Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
+Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
+ IDParseMode Mode) {
Init *R = 0;
switch (Lex.getCode()) {
default: TokError("Unknown token when parsing a value"); break;
SMLoc NameLoc = Lex.getLoc();
std::string Name = Lex.getCurStrVal();
if (Lex.Lex() != tgtok::less) // consume the Id.
- return ParseIDValue(CurRec, Name, NameLoc); // Value ::= IDValue
+ return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue
// Value ::= ID '<' ValueListNE '>'
if (Lex.Lex() == tgtok::greater) {
/// ValueSuffix ::= '[' BitList ']'
/// ValueSuffix ::= '.' ID
///
-Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
- Init *Result = ParseSimpleValue(CurRec, ItemType);
+Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
+ Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
if (Result == 0) return 0;
// Parse the suffixes now if present.
RecTy *ItemType = EltTy;
unsigned int ArgN = 0;
if (ArgsRec != 0 && EltTy == 0) {
- const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
+ const std::vector<Init *> &TArgs = ArgsRec->getTemplateArgs();
const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
if (!RV) {
errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN]
Lex.Lex(); // Eat the comma
if (ArgsRec != 0 && EltTy == 0) {
- const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
+ const std::vector<Init *> &TArgs = ArgsRec->getTemplateArgs();
if (ArgN >= TArgs.size()) {
TokError("too many template arguments");
return std::vector<Init*>();
///
/// Declaration ::= FIELD? Type ID ('=' Value)?
///
-std::string TGParser::ParseDeclaration(Record *CurRec,
+Init *TGParser::ParseDeclaration(Record *CurRec,
bool ParsingTemplateArgs) {
// Read the field prefix if present.
bool HasField = Lex.getCode() == tgtok::Field;
if (HasField) Lex.Lex();
RecTy *Type = ParseType();
- if (Type == 0) return "";
+ if (Type == 0) return 0;
if (Lex.getCode() != tgtok::Id) {
TokError("Expected identifier in declaration");
- return "";
+ return 0;
}
SMLoc IdLoc = Lex.getLoc();
- std::string DeclName = Lex.getCurStrVal();
+ Init *DeclName = StringInit::get(Lex.getCurStrVal());
Lex.Lex();
if (ParsingTemplateArgs) {
if (CurRec) {
- DeclName = CurRec->getName() + ":" + DeclName;
+ DeclName = QualifyName(*CurRec, CurMultiClass, DeclName, ":");
} else {
assert(CurMultiClass);
}
if (CurMultiClass)
- DeclName = CurMultiClass->Rec.getName() + "::" + DeclName;
+ DeclName = QualifyName(CurMultiClass->Rec, CurMultiClass, DeclName,
+ "::");
}
// Add the value.
if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField)))
- return "";
+ return 0;
// If a value is present, parse it.
if (Lex.getCode() == tgtok::equal) {
Init *Val = ParseValue(CurRec, Type);
if (Val == 0 ||
SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
- return "";
+ return 0;
}
return DeclName;
Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
// Read the first declaration.
- std::string TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
- if (TemplArg.empty())
+ Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
+ if (TemplArg == 0)
return true;
TheRecToAddTo->addTemplateArg(TemplArg);
// Read the following declarations.
TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
- if (TemplArg.empty())
+ if (TemplArg == 0)
return true;
TheRecToAddTo->addTemplateArg(TemplArg);
}
/// BodyItem ::= LET ID OptionalBitList '=' Value ';'
bool TGParser::ParseBodyItem(Record *CurRec) {
if (Lex.getCode() != tgtok::Let) {
- if (ParseDeclaration(CurRec, false).empty())
+ if (ParseDeclaration(CurRec, false) == 0)
return true;
if (Lex.getCode() != tgtok::semi)
// Ensure redefinition doesn't happen.
if (Records.getDef(CurRec->getName())) {
- Error(DefLoc, "def '" + CurRec->getName() + "' already defined");
+ Error(DefLoc, "def '" + CurRec->getNameInitAsString()
+ + "' already defined");
return true;
}
Records.addDef(CurRec);
} else {
// 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]->getName() == CurRec->getName()) {
- Error(DefLoc, "def '" + CurRec->getName() +
+ if (CurMultiClass->DefPrototypes[i]->getNameInit()
+ == CurRec->getNameInit()) {
+ Error(DefLoc, "def '" + CurRec->getNameInitAsString() +
"' already defined in this multiclass!");
return true;
}
if (CurMultiClass) {
// Copy the template arguments for the multiclass into the def.
- const std::vector<std::string> &TArgs =
+ const std::vector<Init *> &TArgs =
CurMultiClass->Rec.getTemplateArgs();
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
return false;
}
-
-/// ParseMultiDef - Parse and return a multiclass multidef, return the record
-/// corresponding to it. This returns null on error.
-///
-/// MultiDefInst ::= MULTIDEF ObjectName '<' Value ',' Declaration ','
-/// Value '>' ObjectBody
-///
-bool TGParser::ParseMultiDef(MultiClass *CurMultiClass) {
- assert(CurMultiClass && "No multiclass for multidef!");
-
- SMLoc DefLoc = Lex.getLoc();
- assert(Lex.getCode() == tgtok::MultiDef && "Unknown tok");
- Lex.Lex(); // Eat the 'multidef' token.
-
- // Parse ObjectName and make a record for it.
- Record *CurRec = new Record(ParseObjectName(), DefLoc, Records);
-
- if (Lex.getCode() != tgtok::less)
- return TokError("multidef init requires a non-empty list of values");
- Lex.Lex(); // Eat the '<'
-
- Init *ListI = ParseValue(CurRec, 0);
- if (ListI == 0)
- return TokError("First multidef init must be of list type");
-
- if (Lex.getCode() != tgtok::comma)
- return TokError("expected comma in multidef");
- Lex.Lex(); // Eat the comma
-
- std::string ItemName = ParseDeclaration(CurRec, false/*Not a template arg*/);
- if (ItemName.empty())
- return TokError("expected declaration in multidef");
-
- if (Lex.getCode() != tgtok::comma)
- return TokError("expected comma in multidef");
- Lex.Lex(); // Eat the comma
-
- Init *IntI = ParseValue(CurRec, 0);
- if (IntI == 0)
- return TokError("expected integer value in multidef");
-
- if (Lex.getCode() != tgtok::greater)
- return TokError("multidef init requires a non-empty list of values");
- Lex.Lex(); // Eat the '>'
-
- TypedInit *List = dynamic_cast<TypedInit *>(ListI);
- if (dynamic_cast<ListRecTy *>(List->getType()) == 0)
- return TokError("First multidef init must be of list type");
-
- IntInit *Int = dynamic_cast<IntInit *>(IntI);
- if (Int == 0)
- return TokError("Second multidef init must be a constant integer");
-
- // Add it to the multiclass.
- for (unsigned i = 0, e = CurMultiClass->MultiDefPrototypes.size();
- i != e; ++i)
- if (CurMultiClass->MultiDefPrototypes[i].Rec->getName()
- == CurRec->getName())
- return Error(DefLoc, "multidef '" + CurRec->getName() +
- "' already defined in this multiclass!");
-
- CurMultiClass->MultiDefPrototypes.push_back(
- MultiClass::MultiDef(CurRec, List, Int, ItemName));
-
- if (ParseObjectBody(CurRec))
- return true;
-
- // If ObjectBody has template arguments, it's an error.
- assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
-
- // Copy the template arguments for the multiclass into the
- // multidef.
- const std::vector<std::string> &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?");
- CurRec->addValue(*RV);
- }
-
- return false;
-}
-
-
/// ParseClass - Parse a tblgen class definition.
///
/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody
Record *CurRec = Records.getClass(Lex.getCurStrVal());
if (CurRec) {
// If the body was previously defined, this is an error.
- if (!CurRec->getValues().empty() ||
+ if (CurRec->getValues().size() > 1 || // Account for NAME.
!CurRec->getSuperClasses().empty() ||
!CurRec->getTemplateArgs().empty())
- return TokError("Class '" + CurRec->getName() + "' already defined");
+ return TokError("Class '" + CurRec->getNameInitAsString()
+ + "' already defined");
} else {
// If this is the first reference to this class, create and add it.
CurRec = new Record(Lex.getCurStrVal(), Lex.getLoc(), Records);
while (Lex.getCode() != tgtok::r_brace) {
switch (Lex.getCode()) {
default:
- return TokError("expected 'let', 'def', 'defm' or 'multidef'"
- "in multiclass body");
+ return TokError("expected 'let', 'def' or 'defm' in multiclass body");
case tgtok::Let:
case tgtok::Def:
case tgtok::Defm:
- case tgtok::MultiDef:
if (ParseObject(CurMultiClass))
return true;
break;
Record *CurRec,
SMLoc DefmPrefixLoc,
SMLoc SubClassLoc,
- const std::vector<std::string> &TArgs,
+ const std::vector<Init *> &TArgs,
std::vector<Init *> &TemplateVals,
bool DeleteArgs) {
// Loop over all of the template arguments, setting them to the specified
} else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
return Error(SubClassLoc, "value not specified for template argument #"+
- utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
- MC.Rec.getName() + "'");
+ utostr(i) + " (" + TArgs[i]->getAsUnquotedString()
+ + ") of multiclassclass '" + MC.Rec.getNameInitAsString()
+ + "'");
}
}
return false;
if (CurMultiClass) {
for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size();
i != e; ++i)
- if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName())
- return Error(DefmPrefixLoc, "defm '" + CurRec->getName() +
+ 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<std::string> &TA =
+ const std::vector<Init *> &TA =
CurMultiClass->Rec.getTemplateArgs();
for (unsigned i = 0, e = TA.size(); i != e; ++i) {
std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
// Verify that the correct number of template arguments were specified.
- const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
+ const std::vector<Init *> &TArgs = MC->Rec.getTemplateArgs();
if (TArgs.size() < TemplateVals.size())
return Error(SubClassLoc,
"more template args specified than multiclass expects");
/// ParseObject
/// Object ::= ClassInst
/// Object ::= DefInst
-/// Object ::= MultiDefInst
/// Object ::= MultiClassInst
/// Object ::= DefMInst
/// Object ::= LETCommand '{' ObjectList '}'
return TokError("Expected class, def, defm, multiclass or let definition");
case tgtok::Let: return ParseTopLevelLet(MC);
case tgtok::Def: return ParseDef(MC);
- case tgtok::MultiDef: return ParseMultiDef(MC);
case tgtok::Defm: return ParseDefm(MC);
case tgtok::Class: return ParseClass();
case tgtok::MultiClass: return ParseMultiClass();