Make Template Arg Names Inits

Allow template arg names to be Inits.  This is further work to
implement paste as it allows template names to participate in paste
operations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142500 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Greene 2011-10-19 13:02:42 +00:00
parent 917924d991
commit e22b321d22
4 changed files with 53 additions and 38 deletions

View File

@ -1385,7 +1385,7 @@ class Record {
unsigned ID; unsigned ID;
Init *Name; Init *Name;
SMLoc Loc; SMLoc Loc;
std::vector<std::string> TemplateArgs; std::vector<Init *> TemplateArgs;
std::vector<RecordVal> Values; std::vector<RecordVal> Values;
std::vector<Record*> SuperClasses; std::vector<Record*> SuperClasses;
@ -1425,17 +1425,20 @@ public:
/// get the corresponding DefInit. /// get the corresponding DefInit.
DefInit *getDefInit(); DefInit *getDefInit();
const std::vector<std::string> &getTemplateArgs() const { const std::vector<Init *> &getTemplateArgs() const {
return TemplateArgs; return TemplateArgs;
} }
const std::vector<RecordVal> &getValues() const { return Values; } const std::vector<RecordVal> &getValues() const { return Values; }
const std::vector<Record*> &getSuperClasses() const { return SuperClasses; } const std::vector<Record*> &getSuperClasses() const { return SuperClasses; }
bool isTemplateArg(StringRef Name) const { bool isTemplateArg(Init *Name) const {
for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i) for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
if (TemplateArgs[i] == Name) return true; if (TemplateArgs[i] == Name) return true;
return false; return false;
} }
bool isTemplateArg(StringRef Name) const {
return isTemplateArg(StringInit::get(Name.str()));
}
const RecordVal *getValue(StringRef Name) const { const RecordVal *getValue(StringRef Name) const {
for (unsigned i = 0, e = Values.size(); i != e; ++i) for (unsigned i = 0, e = Values.size(); i != e; ++i)
@ -1451,10 +1454,13 @@ public:
const RecordVal *getValue(Init *Name) const; const RecordVal *getValue(Init *Name) const;
RecordVal *getValue(Init *Name); RecordVal *getValue(Init *Name);
void addTemplateArg(StringRef Name) { void addTemplateArg(Init *Name) {
assert(!isTemplateArg(Name) && "Template arg already defined!"); assert(!isTemplateArg(Name) && "Template arg already defined!");
TemplateArgs.push_back(Name); TemplateArgs.push_back(Name);
} }
void addTemplateArg(StringRef Name) {
addTemplateArg(StringInit::get(Name.str()));
}
void addValue(const RecordVal &RV) { void addValue(const RecordVal &RV) {
assert(getValue(RV.getName()) == 0 && "Value already added!"); assert(getValue(RV.getName()) == 0 && "Value already added!");

View File

@ -760,7 +760,9 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
return VarInit::get(Name, RV->getType()); return VarInit::get(Name, RV->getType());
} }
std::string TemplateArgName = CurRec->getName()+":"+Name; Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name,
":");
if (CurRec->isTemplateArg(TemplateArgName)) { if (CurRec->isTemplateArg(TemplateArgName)) {
const RecordVal *RV = CurRec->getValue(TemplateArgName); const RecordVal *RV = CurRec->getValue(TemplateArgName);
assert(RV && "Template arg doesn't exist??"); assert(RV && "Template arg doesn't exist??");
@ -773,7 +775,8 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
} }
if (CurMultiClass) { if (CurMultiClass) {
std::string MCName = CurMultiClass->Rec.getName()+"::"+Name; Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::");
if (CurMultiClass->Rec.isTemplateArg(MCName)) { if (CurMultiClass->Rec.isTemplateArg(MCName)) {
const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
assert(RV && "Template arg doesn't exist??"); assert(RV && "Template arg doesn't exist??");
@ -1765,7 +1768,7 @@ void Record::dump() const { errs() << *this; }
raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) { raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
OS << R.getName(); OS << R.getName();
const std::vector<std::string> &TArgs = R.getTemplateArgs(); const std::vector<Init *> &TArgs = R.getTemplateArgs();
if (!TArgs.empty()) { if (!TArgs.empty()) {
OS << "<"; OS << "<";
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {

View File

@ -154,7 +154,7 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
if (AddValue(CurRec, SubClass.RefLoc, Vals[i])) if (AddValue(CurRec, SubClass.RefLoc, Vals[i]))
return true; 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. // Ensure that an appropriate number of template arguments are specified.
if (TArgs.size() < SubClass.TemplateArgs.size()) if (TArgs.size() < SubClass.TemplateArgs.size())
@ -177,8 +177,8 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
} else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
return Error(SubClass.RefLoc,"Value not specified for template argument #" return Error(SubClass.RefLoc,"Value not specified for template argument #"
+ utostr(i) + " (" + TArgs[i] + ") of subclass '" + + utostr(i) + " (" + TArgs[i]->getAsUnquotedString()
SC->getName() + "'!"); + ") of subclass '" + SC->getNameInitAsString() + "'!");
} }
} }
@ -233,7 +233,7 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
CurMC->DefPrototypes.push_back(NewDef); 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 // Ensure that an appropriate number of template arguments are
// specified. // specified.
@ -281,8 +281,8 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
} else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) { } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
return Error(SubMultiClass.RefLoc, return Error(SubMultiClass.RefLoc,
"Value not specified for template argument #" "Value not specified for template argument #"
+ utostr(i) + " (" + SMCTArgs[i] + ") of subclass '" + + utostr(i) + " (" + SMCTArgs[i]->getAsUnquotedString()
SMC->Rec.getName() + "'!"); + ") of subclass '" + SMC->Rec.getNameInitAsString() + "'!");
} }
} }
@ -652,9 +652,11 @@ Init *TGParser::ParseIDValue(Record *CurRec,
if (const RecordVal *RV = CurRec->getValue(Name)) if (const RecordVal *RV = CurRec->getValue(Name))
return VarInit::get(Name, RV->getType()); return VarInit::get(Name, RV->getType());
std::string TemplateArgName = CurRec->getName()+":"+Name; Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":");
if (CurMultiClass) if (CurMultiClass)
TemplateArgName = CurMultiClass->Rec.getName()+"::"+TemplateArgName; TemplateArgName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name,
"::");
if (CurRec->isTemplateArg(TemplateArgName)) { if (CurRec->isTemplateArg(TemplateArgName)) {
const RecordVal *RV = CurRec->getValue(TemplateArgName); const RecordVal *RV = CurRec->getValue(TemplateArgName);
@ -664,7 +666,9 @@ Init *TGParser::ParseIDValue(Record *CurRec,
} }
if (CurMultiClass) { if (CurMultiClass) {
std::string MCName = CurMultiClass->Rec.getName()+"::"+Name; Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name,
"::");
if (CurMultiClass->Rec.isTemplateArg(MCName)) { if (CurMultiClass->Rec.isTemplateArg(MCName)) {
const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
assert(RV && "Template arg doesn't exist??"); assert(RV && "Template arg doesn't exist??");
@ -1420,7 +1424,7 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
RecTy *ItemType = EltTy; RecTy *ItemType = EltTy;
unsigned int ArgN = 0; unsigned int ArgN = 0;
if (ArgsRec != 0 && EltTy == 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]); const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
if (!RV) { if (!RV) {
errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN] errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN]
@ -1437,7 +1441,7 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
Lex.Lex(); // Eat the comma Lex.Lex(); // Eat the comma
if (ArgsRec != 0 && EltTy == 0) { if (ArgsRec != 0 && EltTy == 0) {
const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs(); const std::vector<Init *> &TArgs = ArgsRec->getTemplateArgs();
if (ArgN >= TArgs.size()) { if (ArgN >= TArgs.size()) {
TokError("too many template arguments"); TokError("too many template arguments");
return std::vector<Init*>(); return std::vector<Init*>();
@ -1465,37 +1469,38 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
/// ///
/// Declaration ::= FIELD? Type ID ('=' Value)? /// Declaration ::= FIELD? Type ID ('=' Value)?
/// ///
std::string TGParser::ParseDeclaration(Record *CurRec, Init *TGParser::ParseDeclaration(Record *CurRec,
bool ParsingTemplateArgs) { bool ParsingTemplateArgs) {
// Read the field prefix if present. // Read the field prefix if present.
bool HasField = Lex.getCode() == tgtok::Field; bool HasField = Lex.getCode() == tgtok::Field;
if (HasField) Lex.Lex(); if (HasField) Lex.Lex();
RecTy *Type = ParseType(); RecTy *Type = ParseType();
if (Type == 0) return ""; if (Type == 0) return 0;
if (Lex.getCode() != tgtok::Id) { if (Lex.getCode() != tgtok::Id) {
TokError("Expected identifier in declaration"); TokError("Expected identifier in declaration");
return ""; return 0;
} }
SMLoc IdLoc = Lex.getLoc(); SMLoc IdLoc = Lex.getLoc();
std::string DeclName = Lex.getCurStrVal(); Init *DeclName = StringInit::get(Lex.getCurStrVal());
Lex.Lex(); Lex.Lex();
if (ParsingTemplateArgs) { if (ParsingTemplateArgs) {
if (CurRec) { if (CurRec) {
DeclName = CurRec->getName() + ":" + DeclName; DeclName = QualifyName(*CurRec, CurMultiClass, DeclName, ":");
} else { } else {
assert(CurMultiClass); assert(CurMultiClass);
} }
if (CurMultiClass) if (CurMultiClass)
DeclName = CurMultiClass->Rec.getName() + "::" + DeclName; DeclName = QualifyName(CurMultiClass->Rec, CurMultiClass, DeclName,
"::");
} }
// Add the value. // Add the value.
if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField))) if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField)))
return ""; return 0;
// If a value is present, parse it. // If a value is present, parse it.
if (Lex.getCode() == tgtok::equal) { if (Lex.getCode() == tgtok::equal) {
@ -1504,7 +1509,7 @@ std::string TGParser::ParseDeclaration(Record *CurRec,
Init *Val = ParseValue(CurRec, Type); Init *Val = ParseValue(CurRec, Type);
if (Val == 0 || if (Val == 0 ||
SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val)) SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
return ""; return 0;
} }
return DeclName; return DeclName;
@ -1524,8 +1529,8 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec; Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
// Read the first declaration. // Read the first declaration.
std::string TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
if (TemplArg.empty()) if (TemplArg == 0)
return true; return true;
TheRecToAddTo->addTemplateArg(TemplArg); TheRecToAddTo->addTemplateArg(TemplArg);
@ -1535,7 +1540,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
// Read the following declarations. // Read the following declarations.
TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
if (TemplArg.empty()) if (TemplArg == 0)
return true; return true;
TheRecToAddTo->addTemplateArg(TemplArg); TheRecToAddTo->addTemplateArg(TemplArg);
} }
@ -1553,7 +1558,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
/// BodyItem ::= LET ID OptionalBitList '=' Value ';' /// BodyItem ::= LET ID OptionalBitList '=' Value ';'
bool TGParser::ParseBodyItem(Record *CurRec) { bool TGParser::ParseBodyItem(Record *CurRec) {
if (Lex.getCode() != tgtok::Let) { if (Lex.getCode() != tgtok::Let) {
if (ParseDeclaration(CurRec, false).empty()) if (ParseDeclaration(CurRec, false) == 0)
return true; return true;
if (Lex.getCode() != tgtok::semi) if (Lex.getCode() != tgtok::semi)
@ -1710,7 +1715,7 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
if (CurMultiClass) { if (CurMultiClass) {
// Copy the template arguments for the multiclass into the def. // Copy the template arguments for the multiclass into the def.
const std::vector<std::string> &TArgs = const std::vector<Init *> &TArgs =
CurMultiClass->Rec.getTemplateArgs(); CurMultiClass->Rec.getTemplateArgs();
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
@ -1960,7 +1965,7 @@ bool TGParser::ResolveMulticlassDefArgs(MultiClass &MC,
Record *CurRec, Record *CurRec,
SMLoc DefmPrefixLoc, SMLoc DefmPrefixLoc,
SMLoc SubClassLoc, SMLoc SubClassLoc,
const std::vector<std::string> &TArgs, const std::vector<Init *> &TArgs,
std::vector<Init *> &TemplateVals, std::vector<Init *> &TemplateVals,
bool DeleteArgs) { bool DeleteArgs) {
// Loop over all of the template arguments, setting them to the specified // Loop over all of the template arguments, setting them to the specified
@ -1982,8 +1987,9 @@ bool TGParser::ResolveMulticlassDefArgs(MultiClass &MC,
} else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
return Error(SubClassLoc, "value not specified for template argument #"+ return Error(SubClassLoc, "value not specified for template argument #"+
utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" + utostr(i) + " (" + TArgs[i]->getAsUnquotedString()
MC.Rec.getName() + "'"); + ") of multiclassclass '" + MC.Rec.getNameInitAsString()
+ "'");
} }
} }
return false; return false;
@ -2018,7 +2024,7 @@ bool TGParser::ResolveMulticlassDef(MultiClass &MC,
CurMultiClass->DefPrototypes.push_back(CurRec); CurMultiClass->DefPrototypes.push_back(CurRec);
// Copy the template arguments for the multiclass into the new def. // 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(); CurMultiClass->Rec.getTemplateArgs();
for (unsigned i = 0, e = TA.size(); i != e; ++i) { for (unsigned i = 0, e = TA.size(); i != e; ++i) {
@ -2073,7 +2079,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
std::vector<Init*> &TemplateVals = Ref.TemplateArgs; std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
// Verify that the correct number of template arguments were specified. // 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()) if (TArgs.size() < TemplateVals.size())
return Error(SubClassLoc, return Error(SubClassLoc,
"more template args specified than multiclass expects"); "more template args specified than multiclass expects");

View File

@ -96,7 +96,7 @@ private: // Parser methods.
Record *DefProto, Record *DefProto,
SMLoc DefmPrefixLoc, SMLoc DefmPrefixLoc,
SMLoc SubClassLoc, SMLoc SubClassLoc,
const std::vector<std::string> &TArgs, const std::vector<Init *> &TArgs,
std::vector<Init *> &TemplateVals, std::vector<Init *> &TemplateVals,
bool DeleteArgs); bool DeleteArgs);
bool ResolveMulticlassDef(MultiClass &MC, bool ResolveMulticlassDef(MultiClass &MC,
@ -113,7 +113,7 @@ private: // Parser methods.
bool ParseBodyItem(Record *CurRec); bool ParseBodyItem(Record *CurRec);
bool ParseTemplateArgList(Record *CurRec); bool ParseTemplateArgList(Record *CurRec);
std::string ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs); Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm); SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC); SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);