}
-/// resolveTypes - Find a common type that T1 and T2 convert to.
+/// resolveTypes - Find a common type that T1 and T2 convert to.
/// Return 0 if no such type exists.
///
RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1);
if (RecTy1) {
// See if T2 inherits from a type T1 also inherits from
- const std::vector<Record *> &T1SuperClasses = RecTy1->getRecord()->getSuperClasses();
+ const std::vector<Record *> &T1SuperClasses =
+ RecTy1->getRecord()->getSuperClasses();
for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
iend = T1SuperClasses.end();
i != iend;
RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2);
if (RecTy2) {
// See if T1 inherits from a type T2 also inherits from
- const std::vector<Record *> &T2SuperClasses = RecTy2->getRecord()->getSuperClasses();
- for(std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
+ const std::vector<Record *> &T2SuperClasses =
+ RecTy2->getRecord()->getSuperClasses();
+ for (std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
iend = T2SuperClasses.end();
i != iend;
++i) {
}
Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
- unsigned Elt) {
+ unsigned Elt) {
if (Elt >= getSize())
return 0; // Out of range reference.
Init *E = getElement(Elt);
}
Init *OpInit::resolveBitReference(Record &R, const RecordVal *IRV,
- unsigned Bit) {
+ unsigned Bit) {
Init *Folded = Fold(&R, 0);
if (Folded != this) {
TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
if (Typed) {
return Typed->resolveBitReference(R, IRV, Bit);
- }
+ }
}
-
+
return 0;
}
Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
- unsigned Elt) {
+ unsigned Elt) {
Init *Folded = Fold(&R, 0);
if (Folded != this) {
TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
if (Typed) {
return Typed->resolveListElementReference(R, IRV, Elt);
- }
+ }
}
-
+
return 0;
}
if (LHSd) {
return new StringInit(LHSd->getDef()->getName());
}
- }
- else {
+ } else {
StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
if (LHSs) {
std::string Name = LHSs->getValue();
if (CurMultiClass->Rec.isTemplateArg(MCName)) {
const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
assert(RV && "Template arg doesn't exist??");
-
+
if (RV->getType() != getType()) {
throw "type mismatch in nameconcat";
}
-
+
return new VarInit(MCName, RV->getType());
}
}
-
+
if (Record *D = Records.getDef(Name))
return new DefInit(D);
assert(0 && "Empty list in cdr");
return 0;
}
- ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(), LHSl->getType());
+ ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(),
+ LHSl->getType());
return Result;
}
break;
if (LHSl) {
if (LHSl->getSize() == 0) {
return new IntInit(1);
- }
- else {
+ } else {
return new IntInit(0);
}
}
if (LHSs) {
if (LHSs->getValue().empty()) {
return new IntInit(1);
- }
- else {
+ } else {
return new IntInit(0);
}
}
-
+
break;
}
}
Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) {
Init *lhs = LHS->resolveReferences(R, RV);
-
+
if (LHS != lhs)
return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0);
return Fold(&R, 0);
}
return new VarInit(Name, RV->getType());
}
-
+
std::string TemplateArgName = CurRec->getName()+":"+Name;
if (CurRec->isTemplateArg(TemplateArgName)) {
const RecordVal *RV = CurRec->getValue(TemplateArgName);
if (RV->getType() != getType()) {
throw "type mismatch in nameconcat";
}
-
+
return new VarInit(MCName, RV->getType());
}
}
Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
Init *lhs = LHS->resolveReferences(R, RV);
Init *rhs = RHS->resolveReferences(R, RV);
-
+
if (LHS != lhs || RHS != rhs)
return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
return Fold(&R, 0);
case SRA: Result = "!sra"; break;
case SRL: Result = "!srl"; break;
case STRCONCAT: Result = "!strconcat"; break;
- case NAMECONCAT:
+ case NAMECONCAT:
Result = "!nameconcat<" + getType()->getAsString() + ">"; break;
}
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
CurRec, CurMultiClass);
if (Result != 0) {
return Result;
- }
- else {
+ } else {
return 0;
}
}
Type, CurRec, CurMultiClass);
if (Result != 0) {
NewOperands.push_back(Result);
- }
- else {
+ } else {
NewOperands.push_back(Arg);
}
- }
- else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+ } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
NewOperands.push_back(Arg);
- }
- else {
+ } else {
NewOperands.push_back(RHSo->getOperand(i));
}
}
// First, replace the foreach variable with the list item
if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
NewOperands.push_back(Item);
- }
- else {
+ } else {
NewOperands.push_back(RHSo->getOperand(i));
}
}
}
}
break;
- }
+ }
case FOREACH: {
Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
if (LHSi) {
if (LHSi->getValue()) {
return MHS;
- }
- else {
+ } else {
return RHS;
}
}
// Short-circuit
if (Value->getValue()) {
Init *mhs = MHS->resolveReferences(R, RV);
- return (new TernOpInit(getOpcode(), lhs, mhs, RHS, getType()))->Fold(&R, 0);
- }
- else {
+ return (new TernOpInit(getOpcode(), lhs, mhs,
+ RHS, getType()))->Fold(&R, 0);
+ } else {
Init *rhs = RHS->resolveReferences(R, RV);
- return (new TernOpInit(getOpcode(), lhs, MHS, rhs, getType()))->Fold(&R, 0);
+ return (new TernOpInit(getOpcode(), lhs, MHS,
+ rhs, getType()))->Fold(&R, 0);
}
}
}
-
+
Init *mhs = MHS->resolveReferences(R, RV);
Init *rhs = RHS->resolveReferences(R, RV);
std::string Result;
switch (Opc) {
case SUBST: Result = "!subst"; break;
- case FOREACH: Result = "!foreach"; break;
- case IF: Result = "!if"; break;
+ case FOREACH: Result = "!foreach"; break;
+ case IF: Result = "!if"; break;
}
- return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
+ return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
+ RHS->getAsString() + ")";
}
assert(VI && "Invalid list element!");
return new VarListElementInit(VI, Elt);
}
-
+
if (Elt >= LI->getSize())
return 0; // Out of range reference.
Init *E = LI->getElement(Elt);
std::vector<Init*> NewArgs;
for (unsigned i = 0, e = Args.size(); i != e; ++i)
NewArgs.push_back(Args[i]->resolveReferences(R, RV));
-
+
Init *Op = Val->resolveReferences(R, RV);
-
+
if (Args != NewArgs || Op != Val)
return new DagInit(Op, "", NewArgs, ArgNames);
-
+
return this;
}
/// its value as a vector of records, throwing an exception if the field does
/// not exist or if the value is not the right type.
///
-std::vector<Record*>
+std::vector<Record*>
Record::getValueAsListOfDefs(StringRef FieldName) const {
ListInit *List = getValueAsListInit(FieldName);
std::vector<Record*> Defs;
/// its value as a vector of integers, throwing an exception if the field does
/// not exist or if the value is not the right type.
///
-std::vector<int64_t>
+std::vector<int64_t>
Record::getValueAsListOfInts(StringRef FieldName) const {
ListInit *List = getValueAsListInit(FieldName);
std::vector<int64_t> Ints;
if (R == 0 || R->getValue() == 0)
throw "Record `" + getName() + "' does not have a field named `" +
FieldName.str() + "'!\n";
-
+
if (const CodeInit *CI = dynamic_cast<const CodeInit*>(R->getValue()))
return CI->getValue();
throw "Record `" + getName() + "', field `" + FieldName.str() +
void MultiClass::dump() const {
errs() << "Record:\n";
Rec.dump();
-
+
errs() << "Defs:\n";
for (RecordVector::const_iterator r = DefPrototypes.begin(),
rend = DefPrototypes.end();
namespace llvm {
class raw_ostream;
-
+
// RecTy subclasses.
class BitRecTy;
class BitsRecTy;
virtual bool baseClassOf(const RecordRecTy *RHS) const;
};
-/// resolveTypes - Find a common type that T1 and T2 convert to.
+/// resolveTypes - Find a common type that T1 and T2 convert to.
/// Return 0 if no such type exists.
///
RecTy *resolveTypes(RecTy *T1, RecTy *T2);
}
Record *getElementAsRecord(unsigned i) const;
-
+
Init *convertInitListSlice(const std::vector<unsigned> &Elements);
virtual Init *convertInitializerTo(RecTy *Ty) {
virtual Init *convertInitializerTo(RecTy *Ty) {
return Ty->convertValue(this);
}
-
+
virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
unsigned Bit);
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
assert(i == 0 && "Invalid operand id for unary operator");
return getOperand();
}
-
+
UnaryOp getOpcode() const { return Opc; }
Init *getOperand() const { return LHS; }
Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
+
/// getFieldType - This method is used to implement the FieldInit class.
/// Implementors of this method should return the type of the named field if
/// they are of record type.
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {
}
-
+
// Clone - Clone this operator, replacing arguments with the new list
virtual OpInit *clone(std::vector<Init *> &Operands) {
assert(Operands.size() == 2 &&
assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
if (i == 0) {
return getLHS();
- }
- else {
+ } else {
return getRHS();
}
}
Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
+
virtual std::string getAsString() const;
};
TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) :
OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {
}
-
+
// Clone - Clone this operator, replacing arguments with the new list
virtual OpInit *clone(std::vector<Init *> &Operands) {
assert(Operands.size() == 3 &&
"Invalid operand id for ternary operator");
if (i == 0) {
return getLHS();
- }
- else if (i == 1) {
+ } else if (i == 1) {
return getMHS();
- }
- else {
+ } else {
return getRHS();
}
}
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
-
+
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
+
virtual std::string getAsString() const;
};
std::vector<Init*> Args;
std::vector<std::string> ArgNames;
public:
- DagInit(Init *V, std::string VN,
+ DagInit(Init *V, std::string VN,
const std::vector<std::pair<Init*, std::string> > &args)
: TypedInit(new DagRecTy), Val(V), ValName(VN) {
Args.reserve(args.size());
ArgNames.push_back(args[i].second);
}
}
- DagInit(Init *V, std::string VN, const std::vector<Init*> &args,
+ DagInit(Init *V, std::string VN, const std::vector<Init*> &args,
const std::vector<std::string> &argNames)
- : TypedInit(new DagRecTy), Val(V), ValName(VN), Args(args), ArgNames(argNames) {
- }
-
+ : TypedInit(new DagRecTy), Val(V), ValName(VN), Args(args),
+ ArgNames(argNames) { }
+
virtual Init *convertInitializerTo(RecTy *Ty) {
return Ty->convertValue(this);
}
assert(Num < Args.size() && "Arg number out of range!");
Args[Num] = I;
}
-
+
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
virtual std::string getAsString() const;
assert(0 && "Illegal bit reference off dag");
return 0;
}
-
+
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
unsigned Elt) {
assert(0 && "Illegal element reference off dag");
return 0;
}
-
};
//===----------------------------------------------------------------------===//
std::vector<Record*> SuperClasses;
public:
- explicit Record(const std::string &N, SMLoc loc) :
+ explicit Record(const std::string &N, SMLoc loc) :
ID(LastID++), Name(N), Loc(loc) {}
~Record() {}
-
+
unsigned getID() const { return ID; }
const std::string &getName() const { return Name; }
void setName(const std::string &Name); // Also updates RecordKeeper.
-
+
SMLoc getLoc() const { return Loc; }
-
+
const std::vector<std::string> &getTemplateArgs() const {
return TemplateArgs;
}
/// not exist or if the value is not the right type.
///
std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
-
+
/// getValueAsDef - This method looks up the specified field and returns its
/// value as a Record, throwing an exception if the field does not exist or if
/// the value is not the right type.
/// the value is not the right type.
///
DagInit *getValueAsDag(StringRef FieldName) const;
-
+
/// getValueAsCode - This method looks up the specified field and returns
/// its value as the string data in a CodeInit, throwing an exception if the
/// field does not exist or if the value is not a code object.
assert(Defs.count(Name) && "Def does not exist!");
Defs.erase(Name);
}
-
+
//===--------------------------------------------------------------------===//
// High-level helper methods, useful for tablegen backends...
}
};
-/// LessRecordFieldName - Sorting predicate to sort record pointers by their
+/// LessRecordFieldName - Sorting predicate to sort record pointers by their
/// name field.
///
struct LessRecordFieldName {
std::string Message;
public:
TGError(SMLoc loc, const std::string &message) : Loc(loc), Message(message) {}
-
+
SMLoc getLoc() const { return Loc; }
const std::string &getMessage() const { return Message; }
};
-
-
+
+
raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
extern RecordKeeper Records;
void PrintError(SMLoc ErrorLoc, const std::string &Msg);
-
} // End llvm namespace
#endif
void SubMultiClassReference::dump() const {
errs() << "Multiclass:\n";
-
+
MC->dump();
-
+
errs() << "Template args:\n";
for (std::vector<Init *>::const_iterator i = TemplateArgs.begin(),
iend = TemplateArgs.end();
bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
if (CurRec == 0)
CurRec = &CurMultiClass->Rec;
-
+
if (RecordVal *ERV = CurRec->getValue(RV.getName())) {
// The value already exists in the class, treat this as a set.
if (ERV->setValue(RV.getValue()))
return Error(Loc, "New definition of '" + RV.getName() + "' of type '" +
RV.getType()->getAsString() + "' is incompatible with " +
- "previous definition of type '" +
+ "previous definition of type '" +
ERV->getType()->getAsString() + "'");
} else {
CurRec->addValue(RV);
/// 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, const std::string &ValName,
const std::vector<unsigned> &BitList, Init *V) {
if (!V) return false;
if (VarInit *VI = dynamic_cast<VarInit*>(V))
if (VI->getName() == ValName)
return false;
-
+
// If we are assigning to a subset of the bits in the value... then we must be
// assigning to a field of BitsRecTy, which must have a BitsInit
// initializer.
V->convertInitializerTo(new BitsRecTy(BitList.size()));
return Error(Loc, "Initializer is not compatible with bit range");
}
-
+
// We should have a BitsInit type now.
BitsInit *BInit = dynamic_cast<BitsInit*>(BI);
assert(BInit != 0);
}
if (RV->setValue(V))
- return Error(Loc, "Value '" + ValName + "' of type '" +
- RV->getType()->getAsString() +
+ return Error(Loc, "Value '" + ValName + "' of type '" +
+ RV->getType()->getAsString() +
"' is incompatible with initializer '" + V->getAsString() +"'");
return false;
}
// 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");
-
+
// 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>(),
+ if (SetValue(CurRec, SubClass.RefLoc, TArgs[i], std::vector<unsigned>(),
SubClass.TemplateArgs[i]))
return true;
-
+
// Resolve it next.
CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
-
+
// Now remove it.
CurRec->removeValue(TArgs[i]);
} else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
return Error(SubClass.RefLoc,"Value not specified for template argument #"
- + utostr(i) + " (" + TArgs[i] + ") of subclass '" +
+ + utostr(i) + " (" + TArgs[i] + ") of subclass '" +
SC->getName() + "'!");
}
}
"Already subclass of '" + SCs[i]->getName() + "'!\n");
CurRec->addSuperClass(SCs[i]);
}
-
+
if (CurRec->isSubClassOf(SC))
return Error(SubClass.RefLoc,
"Already subclass of '" + SC->getName() + "'!\n");
/// isObjectStart - Return true if this is a valid first token for an Object.
static bool isObjectStart(tgtok::TokKind K) {
return K == tgtok::Class || K == tgtok::Def ||
- K == tgtok::Defm || K == tgtok::Let || K == tgtok::MultiClass;
+ K == tgtok::Defm || K == tgtok::Let || K == tgtok::MultiClass;
}
/// ParseObjectName - If an object name is specified, return it. Otherwise,
Lex.Lex();
return Ret;
}
-
+
static unsigned AnonCounter = 0;
return "anonymous."+utostr(AnonCounter++);
}
TokError("expected name for ClassID");
return 0;
}
-
+
Record *Result = Records.getClass(Lex.getCurStrVal());
if (Result == 0)
TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
-
+
Lex.Lex();
return Result;
}
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;
-}
-
+}
/// ParseSubClassReference - Parse a reference to a subclass or to a templated
ParseSubClassReference(Record *CurRec, bool isDefm) {
SubClassReference Result;
Result.RefLoc = Lex.getLoc();
-
+
if (isDefm)
Result.Rec = ParseDefmID();
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)
return Result;
Lex.Lex(); // Eat the '<'
-
+
if (Lex.getCode() == tgtok::greater) {
TokError("subclass reference requires a non-empty list of template values");
Result.Rec = 0;
return Result;
}
-
+
Result.TemplateArgs = ParseValueList(CurRec, Result.Rec);
if (Result.TemplateArgs.empty()) {
Result.Rec = 0; // Error parsing value list.
return Result;
}
-
+
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' in template value list");
Result.Rec = 0;
return Result;
}
Lex.Lex();
-
+
return Result;
}
}
int64_t Start = Lex.getCurIntVal();
int64_t End;
-
+
if (Start < 0)
return TokError("invalid range, cannot be negative");
-
+
switch (Lex.Lex()) { // eat first character.
- default:
+ default:
Ranges.push_back(Start);
return false;
case tgtok::minus:
End = -Lex.getCurIntVal();
break;
}
- if (End < 0)
+ if (End < 0)
return TokError("invalid range, cannot be negative");
Lex.Lex();
-
+
// Add to the range.
if (Start < End) {
for (; Start <= End; ++Start)
///
std::vector<unsigned> TGParser::ParseRangeList() {
std::vector<unsigned> Result;
-
+
// Parse the first piece.
if (ParseRangePiece(Result))
return std::vector<unsigned>();
bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) {
if (Lex.getCode() != tgtok::less)
return false;
-
+
SMLoc StartLoc = Lex.getLoc();
Lex.Lex(); // eat the '<'
-
+
// Parse the range list.
Ranges = ParseRangeList();
if (Ranges.empty()) return true;
-
+
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' at end of range list");
return Error(StartLoc, "to match this '<'");
bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) {
if (Lex.getCode() != tgtok::l_brace)
return false;
-
+
SMLoc StartLoc = Lex.getLoc();
Lex.Lex(); // eat the '{'
-
+
// Parse the range list.
Ranges = ParseRangeList();
if (Ranges.empty()) return true;
-
+
if (Lex.getCode() != tgtok::r_brace) {
TokError("expected '}' at end of bit list");
return Error(StartLoc, "to match this '{'");
Lex.Lex(); // Eat '<'
RecTy *SubType = ParseType();
if (SubType == 0) return 0;
-
+
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' at end of list<ty> type");
return 0;
Lex.Lex(); // Eat '>'
return new ListRecTy(SubType);
}
- }
+ }
}
/// ParseIDValue - Parse an ID as a value and decode what it means.
/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID
/// has already been read.
-Init *TGParser::ParseIDValue(Record *CurRec,
+Init *TGParser::ParseIDValue(Record *CurRec,
const std::string &Name, SMLoc NameLoc) {
if (CurRec) {
if (const RecordVal *RV = CurRec->getValue(Name))
return new VarInit(Name, RV->getType());
-
+
std::string TemplateArgName = CurRec->getName()+":"+Name;
if (CurRec->isTemplateArg(TemplateArgName)) {
const RecordVal *RV = CurRec->getValue(TemplateArgName);
return new VarInit(TemplateArgName, RV->getType());
}
}
-
+
if (CurMultiClass) {
std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
if (CurMultiClass->Rec.isTemplateArg(MCName)) {
return new VarInit(MCName, RV->getType());
}
}
-
+
if (Record *D = Records.getDef(Name))
return new DefInit(D);
TokError("expected list type argumnet in unary operator");
return 0;
}
-
+
if (LHSl && LHSl->getSize() == 0) {
TokError("empty list argument in unary operator");
return 0;
}
if (Code == UnOpInit::CAR) {
Type = Itemt->getType();
- }
- else {
+ } else {
Type = new ListRecTy(Itemt->getType());
}
- }
- else {
+ } else {
assert(LHSt && "expected list type argument in unary operator");
ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
if (LType == 0) {
}
if (Code == UnOpInit::CAR) {
Type = LType->getElementType();
- }
- else {
+ } else {
Type = LType;
}
}
}
case tgtok::XConcat:
- case tgtok::XSRA:
+ case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
case tgtok::XStrConcat:
switch (Lex.getCode()) {
default: assert(0 && "Unhandled code!");
- case tgtok::XConcat:
+ case tgtok::XConcat:
Lex.Lex(); // eat the operation
Code = BinOpInit::CONCAT;
Type = new DagRecTy();
break;
- case tgtok::XSRA:
+ case tgtok::XSRA:
Lex.Lex(); // eat the operation
Code = BinOpInit::SRA;
Type = new IntRecTy();
break;
- case tgtok::XSRL:
+ case tgtok::XSRL:
Lex.Lex(); // eat the operation
Code = BinOpInit::SRL;
Type = new IntRecTy();
break;
- case tgtok::XSHL:
+ case tgtok::XSHL:
Lex.Lex(); // eat the operation
Code = BinOpInit::SHL;
Type = new IntRecTy();
break;
- case tgtok::XStrConcat:
+ case tgtok::XStrConcat:
Lex.Lex(); // eat the operation
Code = BinOpInit::STRCONCAT;
Type = new StringRecTy();
break;
- case tgtok::XNameConcat:
+ case tgtok::XNameConcat:
Lex.Lex(); // eat the operation
Code = BinOpInit::NAMECONCAT;
return 0;
}
Lex.Lex(); // eat the ','
-
+
Init *RHS = ParseValue(CurRec);
if (RHS == 0) return 0;
return 0;
}
Lex.Lex(); // eat the ','
-
+
Init *MHS = ParseValue(CurRec);
if (MHS == 0) return 0;
return 0;
}
Lex.Lex(); // eat the ','
-
+
Init *RHS = ParseValue(CurRec);
if (RHS == 0) return 0;
}
if (MHSt->getType()->typeIsConvertibleTo(RHSt->getType())) {
Type = RHSt->getType();
- }
- else if (RHSt->getType()->typeIsConvertibleTo(MHSt->getType())) {
+ } else if (RHSt->getType()->typeIsConvertibleTo(MHSt->getType())) {
Type = MHSt->getType();
- }
- else {
+ } else {
TokError("inconsistent types for !if");
return 0;
}
break;
}
}
- return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+ return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec,
+ CurMultiClass);
}
}
TokError("could not parse operation");
case tgtok::StrVal: {
std::string Val = Lex.getCurStrVal();
Lex.Lex();
-
+
// Handle multiple consecutive concatenated strings.
while (Lex.getCode() == tgtok::StrVal) {
Val += Lex.getCurStrVal();
Lex.Lex();
}
-
+
R = new StringInit(Val);
break;
}
case tgtok::CodeFragment:
- R = new CodeInit(Lex.getCurStrVal()); Lex.Lex(); break;
+ R = new CodeInit(Lex.getCurStrVal()); Lex.Lex(); break;
case tgtok::question: R = new UnsetInit(); Lex.Lex(); break;
case tgtok::Id: {
SMLoc NameLoc = Lex.getLoc();
std::string Name = Lex.getCurStrVal();
if (Lex.Lex() != tgtok::less) // consume the Id.
return ParseIDValue(CurRec, Name, NameLoc); // Value ::= IDValue
-
+
// Value ::= ID '<' ValueListNE '>'
if (Lex.Lex() == tgtok::greater) {
TokError("expected non-empty value list");
std::vector<Init*> ValueList = ParseValueList(CurRec, Class);
if (ValueList.empty()) return 0;
-
+
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' at end of value list");
return 0;
}
Lex.Lex(); // eat the '>'
-
+
// Create the new record, set it as CurRec temporarily.
static unsigned AnonCounter = 0;
Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++),NameLoc);
return 0;
NewRec->resolveReferences();
Records.addDef(NewRec);
-
+
// The result of the expression is a reference to the new record.
return new DefInit(NewRec);
- }
+ }
case tgtok::l_brace: { // Value ::= '{' ValueList '}'
SMLoc BraceLoc = Lex.getLoc();
Lex.Lex(); // eat the '{'
std::vector<Init*> Vals;
-
+
if (Lex.getCode() != tgtok::r_brace) {
Vals = ParseValueList(CurRec);
if (Vals.empty()) return 0;
return 0;
}
Lex.Lex(); // eat the '}'
-
+
BitsInit *Result = new BitsInit(Vals.size());
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
Init *Bit = Vals[i]->convertInitializerTo(new BitRecTy());
case tgtok::l_square: { // Value ::= '[' ValueList ']'
Lex.Lex(); // eat the '['
std::vector<Init*> Vals;
-
+
RecTy *DeducedEltTy = 0;
ListRecTy *GivenListTy = 0;
-
+
if (ItemType != 0) {
ListRecTy *ListType = dynamic_cast<ListRecTy*>(ItemType);
if (ListType == 0) {
std::stringstream s;
- s << "Type mismatch for list, expected list type, got "
+ s << "Type mismatch for list, expected list type, got "
<< ItemType->getAsString();
TokError(s.str());
}
GivenListTy = ListType;
- }
+ }
if (Lex.getCode() != tgtok::r_square) {
- Vals = ParseValueList(CurRec, 0, GivenListTy ? GivenListTy->getElementType() : 0);
+ Vals = ParseValueList(CurRec, 0,
+ GivenListTy ? GivenListTy->getElementType() : 0);
if (Vals.empty()) return 0;
}
if (Lex.getCode() != tgtok::r_square) {
TokError("Incompatible types in list elements");
return 0;
}
- }
- else {
+ } else {
EltTy = TArg->getType();
}
}
return 0;
}
DeducedEltTy = GivenListTy->getElementType();
- }
- else {
+ } else {
// Make sure the deduced type is compatible with the given type
if (GivenListTy) {
if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
}
DeducedEltTy = EltTy;
}
-
+
return new ListInit(Vals, DeducedEltTy);
}
case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
TokError("expected identifier in dag init");
return 0;
}
-
+
Init *Operator = 0;
if (Lex.getCode() == tgtok::Id) {
Operator = ParseIDValue(CurRec);
if (Operator == 0) return 0;
- }
- else {
+ } else {
Operator = ParseOperation(CurRec);
if (Operator == 0) return 0;
}
OperatorName = Lex.getCurStrVal();
Lex.Lex(); // eat the VarName.
}
-
+
std::vector<std::pair<llvm::Init*, std::string> > DagArgs;
if (Lex.getCode() != tgtok::r_paren) {
DagArgs = ParseDagArgList(CurRec);
if (DagArgs.empty()) return 0;
}
-
+
if (Lex.getCode() != tgtok::r_paren) {
TokError("expected ')' in dag init");
return 0;
}
Lex.Lex(); // eat the ')'
-
+
return new DagInit(Operator, OperatorName, DagArgs);
break;
}
-
+
case tgtok::XCar:
case tgtok::XCdr:
case tgtok::XNull:
case tgtok::XCast: // Value ::= !unop '(' Value ')'
case tgtok::XConcat:
- case tgtok::XSRA:
+ case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
case tgtok::XStrConcat:
break;
}
}
-
+
return R;
}
Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
Init *Result = ParseSimpleValue(CurRec, ItemType);
if (Result == 0) return 0;
-
+
// Parse the suffixes now if present.
while (1) {
switch (Lex.getCode()) {
Lex.Lex(); // eat the '{'
std::vector<unsigned> Ranges = ParseRangeList();
if (Ranges.empty()) return 0;
-
+
// Reverse the bitlist.
std::reverse(Ranges.begin(), Ranges.end());
Result = Result->convertInitializerBitRange(Ranges);
Error(CurlyLoc, "Invalid bit range for value");
return 0;
}
-
+
// Eat the '}'.
if (Lex.getCode() != tgtok::r_brace) {
TokError("expected '}' at end of bit range list");
Lex.Lex(); // eat the '['
std::vector<unsigned> Ranges = ParseRangeList();
if (Ranges.empty()) return 0;
-
+
Result = Result->convertInitListSlice(Ranges);
if (Result == 0) {
Error(SquareLoc, "Invalid range for list slice");
return 0;
}
-
+
// Eat the ']'.
if (Lex.getCode() != tgtok::r_square) {
TokError("expected ']' at end of list slice");
///
/// ParseDagArgList ::= Value (':' VARNAME)?
/// ParseDagArgList ::= ParseDagArgList ',' Value (':' VARNAME)?
-std::vector<std::pair<llvm::Init*, std::string> >
+std::vector<std::pair<llvm::Init*, std::string> >
TGParser::ParseDagArgList(Record *CurRec) {
std::vector<std::pair<llvm::Init*, std::string> > Result;
-
+
while (1) {
Init *Val = ParseValue(CurRec);
if (Val == 0) return std::vector<std::pair<llvm::Init*, std::string> >();
-
+
// If the variable name is present, add it.
std::string VarName;
if (Lex.getCode() == tgtok::colon) {
VarName = Lex.getCurStrVal();
Lex.Lex(); // eat the VarName.
}
-
+
Result.push_back(std::make_pair(Val, VarName));
-
+
if (Lex.getCode() != tgtok::comma) break;
- Lex.Lex(); // eat the ','
+ Lex.Lex(); // eat the ','
}
-
+
return Result;
}
///
/// ValueList ::= Value (',' Value)
///
-std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, RecTy *EltTy) {
+std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
+ RecTy *EltTy) {
std::vector<Init*> Result;
RecTy *ItemType = EltTy;
unsigned int ArgN = 0;
}
Result.push_back(ParseValue(CurRec, ItemType));
if (Result.back() == 0) return std::vector<Init*>();
-
+
while (Lex.getCode() == tgtok::comma) {
Lex.Lex(); // Eat the comma
-
+
if (ArgsRec != 0 && EltTy == 0) {
const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
if (ArgN >= TArgs.size()) {
TokError("too many template arguments");
return std::vector<Init*>();
- }
+ }
const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
assert(RV && "Template argument record not found??");
ItemType = RV->getType();
Result.push_back(ParseValue(CurRec, ItemType));
if (Result.back() == 0) return std::vector<Init*>();
}
-
+
return Result;
}
-
/// ParseDeclaration - Read a declaration, returning the name of field ID, or an
/// empty string on error. This can happen in a number of different context's,
/// including within a def or in the template args for a def (which which case
///
/// Declaration ::= FIELD? Type ID ('=' Value)?
///
-std::string TGParser::ParseDeclaration(Record *CurRec,
+std::string 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 (Lex.getCode() != tgtok::Id) {
TokError("Expected identifier in declaration");
return "";
}
-
+
SMLoc IdLoc = Lex.getLoc();
std::string DeclName = Lex.getCurStrVal();
Lex.Lex();
-
+
if (ParsingTemplateArgs) {
if (CurRec) {
DeclName = CurRec->getName() + ":" + DeclName;
if (CurMultiClass)
DeclName = CurMultiClass->Rec.getName() + "::" + DeclName;
}
-
+
// Add the value.
if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField)))
return "";
-
+
// If a value is present, parse it.
if (Lex.getCode() == tgtok::equal) {
Lex.Lex();
SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
return "";
}
-
+
return DeclName;
}
/// these are the template args for a multiclass.
///
/// TemplateArgList ::= '<' Declaration (',' Declaration)* '>'
-///
+///
bool TGParser::ParseTemplateArgList(Record *CurRec) {
assert(Lex.getCode() == tgtok::less && "Not a template arg list!");
Lex.Lex(); // eat the '<'
-
+
Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
-
+
// Read the first declaration.
std::string TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
if (TemplArg.empty())
return true;
-
+
TheRecToAddTo->addTemplateArg(TemplArg);
-
+
while (Lex.getCode() == tgtok::comma) {
Lex.Lex(); // eat the ','
-
+
// Read the following declarations.
TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
if (TemplArg.empty())
return true;
TheRecToAddTo->addTemplateArg(TemplArg);
}
-
+
if (Lex.getCode() != tgtok::greater)
return TokError("expected '>' at end of template argument list");
Lex.Lex(); // eat the '>'.
/// BodyItem ::= LET ID OptionalBitList '=' Value ';'
bool TGParser::ParseBodyItem(Record *CurRec) {
if (Lex.getCode() != tgtok::Let) {
- if (ParseDeclaration(CurRec, false).empty())
+ if (ParseDeclaration(CurRec, false).empty())
return true;
-
+
if (Lex.getCode() != tgtok::semi)
return TokError("expected ';' after declaration");
Lex.Lex();
// LET ID OptionalRangeList '=' Value ';'
if (Lex.Lex() != tgtok::Id)
return TokError("expected field identifier after let");
-
+
SMLoc IdLoc = Lex.getLoc();
std::string FieldName = Lex.getCurStrVal();
Lex.Lex(); // eat the field name.
-
+
std::vector<unsigned> BitList;
- if (ParseOptionalBitList(BitList))
+ if (ParseOptionalBitList(BitList))
return true;
std::reverse(BitList.begin(), BitList.end());
-
+
if (Lex.getCode() != tgtok::equal)
return TokError("expected '=' in let expression");
Lex.Lex(); // eat the '='.
-
+
RecordVal *Field = CurRec->getValue(FieldName);
if (Field == 0)
return TokError("Value '" + FieldName + "' unknown!");
RecTy *Type = Field->getType();
-
+
Init *Val = ParseValue(CurRec, Type);
if (Val == 0) return true;
-
+
if (Lex.getCode() != tgtok::semi)
return TokError("expected ';' after let expression");
Lex.Lex();
-
+
return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
}
Lex.Lex();
return false;
}
-
+
if (Lex.getCode() != tgtok::l_brace)
return TokError("Expected ';' or '{' to start body");
// Eat the '{'.
Lex.Lex();
-
+
while (Lex.getCode() != tgtok::r_brace)
if (ParseBodyItem(CurRec))
return true;
// If there is a baseclass list, read it.
if (Lex.getCode() == tgtok::colon) {
Lex.Lex();
-
+
// Read all of the subclasses.
SubClassReference SubClass = ParseSubClassReference(CurRec, false);
while (1) {
// Check for error.
if (SubClass.Rec == 0) return true;
-
+
// Add it.
if (AddSubClass(CurRec, SubClass))
return true;
-
+
if (Lex.getCode() != tgtok::comma) break;
Lex.Lex(); // eat ','.
SubClass = ParseSubClassReference(CurRec, false);
if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
LetStack[i][j].Bits, LetStack[i][j].Value))
return true;
-
+
return ParseBody(CurRec);
}
llvm::Record *TGParser::ParseDef(MultiClass *CurMultiClass) {
SMLoc DefLoc = Lex.getLoc();
assert(Lex.getCode() == tgtok::Def && "Unknown tok");
- Lex.Lex(); // Eat the 'def' token.
+ Lex.Lex(); // Eat the 'def' token.
// Parse ObjectName and make a record for it.
Record *CurRec = new Record(ParseObjectName(), DefLoc);
-
+
if (!CurMultiClass) {
// Top-level def definition.
-
+
// Ensure redefinition doesn't happen.
if (Records.getDef(CurRec->getName())) {
Error(DefLoc, "def '" + CurRec->getName() + "' already defined");
}
CurMultiClass->DefPrototypes.push_back(CurRec);
}
-
+
if (ParseObjectBody(CurRec))
return 0;
-
+
if (CurMultiClass == 0) // Def's in multiclasses aren't really defs.
CurRec->resolveReferences();
-
+
// If ObjectBody has template arguments, it's an error.
assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
return CurRec;
bool TGParser::ParseClass() {
assert(Lex.getCode() == tgtok::Class && "Unexpected token!");
Lex.Lex();
-
+
if (Lex.getCode() != tgtok::Id)
return TokError("expected class name after 'class' keyword");
-
+
Record *CurRec = Records.getClass(Lex.getCurStrVal());
if (CurRec) {
// If the body was previously defined, this is an error.
Records.addClass(CurRec);
}
Lex.Lex(); // eat the name.
-
+
// If there are template args, parse them.
if (Lex.getCode() == tgtok::less)
if (ParseTemplateArgList(CurRec))
///
std::vector<LetRecord> TGParser::ParseLetList() {
std::vector<LetRecord> Result;
-
+
while (1) {
if (Lex.getCode() != tgtok::Id) {
TokError("expected identifier in let definition");
}
std::string Name = Lex.getCurStrVal();
SMLoc NameLoc = Lex.getLoc();
- Lex.Lex(); // Eat the identifier.
+ Lex.Lex(); // Eat the identifier.
// Check for an optional RangeList.
std::vector<unsigned> Bits;
- if (ParseOptionalRangeList(Bits))
+ if (ParseOptionalRangeList(Bits))
return std::vector<LetRecord>();
std::reverse(Bits.begin(), Bits.end());
-
+
if (Lex.getCode() != tgtok::equal) {
TokError("expected '=' in let expression");
return std::vector<LetRecord>();
}
Lex.Lex(); // eat the '='.
-
+
Init *Val = ParseValue(0);
if (Val == 0) return std::vector<LetRecord>();
-
+
// Now that we have everything, add the record.
Result.push_back(LetRecord(Name, Bits, Val, NameLoc));
-
+
if (Lex.getCode() != tgtok::comma)
return Result;
- Lex.Lex(); // eat the comma.
+ Lex.Lex(); // eat the comma.
}
}
bool TGParser::ParseTopLevelLet() {
assert(Lex.getCode() == tgtok::Let && "Unexpected token");
Lex.Lex();
-
+
// Add this entry to the let stack.
std::vector<LetRecord> LetInfo = ParseLetList();
if (LetInfo.empty()) return true;
if (Lex.getCode() != tgtok::In)
return TokError("expected 'in' at end of top-level 'let'");
Lex.Lex();
-
+
// If this is a scalar let, just handle it now
if (Lex.getCode() != tgtok::l_brace) {
// LET LetList IN Object
SMLoc BraceLoc = Lex.getLoc();
// Otherwise, this is a group let.
Lex.Lex(); // eat the '{'.
-
+
// Parse the object list.
if (ParseObjectList())
return true;
-
+
if (Lex.getCode() != tgtok::r_brace) {
TokError("expected '}' at end of top level let command");
return Error(BraceLoc, "to match this '{'");
}
Lex.Lex();
}
-
+
// Outside this let scope, this let block is not active.
LetStack.pop_back();
return false;
/// MultiClassDef ::= DefInst
///
bool TGParser::ParseMultiClassDef(MultiClass *CurMC) {
- if (Lex.getCode() != tgtok::Def)
+ if (Lex.getCode() != tgtok::Def)
return TokError("expected 'def' in multiclass body");
Record *D = ParseDef(CurMC);
if (D == 0) return true;
-
+
// Copy the template arguments for the multiclass into the def.
const std::vector<std::string> &TArgs = CurMC->Rec.getTemplateArgs();
-
+
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
const RecordVal *RV = CurMC->Rec.getValue(TArgs[i]);
assert(RV && "Template arg doesn't exist?");
if (Lex.getCode() != tgtok::Id)
return TokError("expected identifier after multiclass for name");
std::string Name = Lex.getCurStrVal();
-
+
if (MultiClasses.count(Name))
return TokError("multiclass '" + Name + "' already defined");
-
+
CurMultiClass = MultiClasses[Name] = new MultiClass(Name, Lex.getLoc());
Lex.Lex(); // Eat the identifier.
-
+
// If there are template args, parse them.
if (Lex.getCode() == tgtok::less)
if (ParseTemplateArgList(0))
if (Lex.getCode() != tgtok::l_brace) {
if (!inherits)
return TokError("expected '{' in multiclass definition");
+ else if (Lex.getCode() != tgtok::semi)
+ return TokError("expected ';' in multiclass definition");
else
- if (Lex.getCode() != tgtok::semi)
- return TokError("expected ';' in multiclass definition");
- else
- Lex.Lex(); // eat the ';'.
- }
- else {
+ Lex.Lex(); // eat the ';'.
+ } else {
if (Lex.Lex() == tgtok::r_brace) // eat the '{'.
return TokError("multiclass must contain at least one def");
-
+
while (Lex.getCode() != tgtok::r_brace)
if (ParseMultiClassDef(CurMultiClass))
return true;
-
+
Lex.Lex(); // eat the '}'.
}
-
+
CurMultiClass = 0;
return false;
}
assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
if (Lex.Lex() != tgtok::Id) // eat the defm.
return TokError("expected identifier after defm");
-
+
SMLoc DefmPrefixLoc = Lex.getLoc();
std::string DefmPrefix = Lex.getCurStrVal();
if (Lex.Lex() != tgtok::colon)
return TokError("expected ':' after defm identifier");
-
+
// eat the colon.
Lex.Lex();
// template parameters.
MultiClass *MC = MultiClasses[Ref.Rec->getName()];
assert(MC && "Didn't lookup multiclass correctly?");
- std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
+ 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();
std::string::size_type idx = DefName.find("#NAME#");
if (idx != std::string::npos) {
DefName.replace(idx, 6, DefmPrefix);
- }
- else {
+ } else {
// Add the suffix to the defm name to get the new name.
DefName = DefmPrefix + DefName;
}
// Ensure redefinition doesn't happen.
if (Records.getDef(CurRec->getName()))
- return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
- "' already defined, instantiating defm with subdef '" +
+ return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
+ "' already defined, instantiating defm with subdef '" +
DefProto->getName() + "'");
Records.addDef(CurRec);
CurRec->resolveReferences();
if (Lex.getCode() != tgtok::semi)
return TokError("expected ';' at end of defm");
Lex.Lex();
-
+
return false;
}
return false;
}
-
bool TGParser::ParseFile() {
Lex.Lex(); // Prime the lexer.
if (ParseObjectList()) return true;
-
+
// If we have unread input at the end of the file, report it.
if (Lex.getCode() == tgtok::Eof)
return false;
-
+
return TokError("Unexpected input at top level");
}