#define RECORD_H
#include "llvm/Support/SourceMgr.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
namespace llvm {
class raw_ostream;
-
+
// RecTy subclasses.
class BitRecTy;
class BitsRecTy;
class Record;
class RecordVal;
struct MultiClass;
+class RecordKeeper;
//===----------------------------------------------------------------------===//
// Type Classes
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);
/// initializer for the specified field. If getFieldType returns non-null
/// this method should return non-null, otherwise it returns null.
///
- virtual Init *getFieldInit(Record &R, const std::string &FieldName) const {
+ virtual Init *getFieldInit(Record &R, const RecordVal *RV,
+ const std::string &FieldName) const {
return 0;
}
/// resolveReferences - This method is used by classes that refer to other
- /// variables which may not be defined at the time they expression is formed.
+ /// variables which may not be defined at the time the expression is formed.
/// If a value is set for the variable later, this method will be called on
/// users of the value to allow the value to propagate out.
///
virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements);
+ /// 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.
+ ///
+ virtual RecTy *getFieldType(const std::string &FieldName) const;
+
/// resolveBitReference - This method is used to implement
/// VarBitInit::resolveReferences. If the bit is able to be resolved, we
/// simply return the resolved value, otherwise we return null.
if (!getBit(i)->isComplete()) return false;
return true;
}
+ bool allInComplete() const {
+ for (unsigned i = 0; i != getNumBits(); ++i)
+ if (getBit(i)->isComplete()) return false;
+ return true;
+ }
virtual std::string getAsString() const;
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
- // printXX - Print this bitstream with the specified format, returning true if
- // it is not possible.
- bool printInHex(raw_ostream &OS) const;
- bool printAsVariable(raw_ostream &OS) const;
- bool printAsUnset(raw_ostream &OS) const;
};
public:
explicit CodeInit(const std::string &V) : Value(V) {}
- const std::string getValue() const { return Value; }
+ const std::string &getValue() const { return Value; }
virtual Init *convertInitializerTo(RecTy *Ty) {
return Ty->convertValue(this);
}
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,
///
class UnOpInit : public OpInit {
public:
- enum UnaryOp { CAST, CAR, CDR, LNULL };
+ enum UnaryOp { CAST, HEAD, TAIL, EMPTY };
private:
UnaryOp Opc;
Init *LHS;
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.
- ///
- virtual RecTy *getFieldType(const std::string &FieldName) const;
virtual std::string getAsString() const;
};
///
class BinOpInit : public OpInit {
public:
- enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
+ enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, EQ };
private:
BinaryOp Opc;
Init *LHS, *RHS;
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 bool isComplete() const { return false; }
+
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
+
virtual std::string getAsString() const;
};
unsigned Elt);
virtual RecTy *getFieldType(const std::string &FieldName) const;
- virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
+ virtual Init *getFieldInit(Record &R, const RecordVal *RV,
+ const std::string &FieldName) const;
/// resolveReferences - This method is used by classes that refer to other
/// variables which may not be defined at the time they expression is formed.
//virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
virtual RecTy *getFieldType(const std::string &FieldName) const;
- virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
+ virtual Init *getFieldInit(Record &R, const RecordVal *RV,
+ const std::string &FieldName) const;
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<std::string> TemplateArgs;
std::vector<RecordVal> Values;
std::vector<Record*> SuperClasses;
+
+ // Tracks Record instances. Not owned by Record.
+ RecordKeeper &TrackedRecords;
+
public:
- explicit Record(const std::string &N, SMLoc loc) :
- ID(LastID++), Name(N), Loc(loc) {}
+ // Constructs a record.
+ explicit Record(const std::string &N, SMLoc loc, RecordKeeper &records) :
+ ID(LastID++), Name(N), Loc(loc), TrackedRecords(records) {}
~Record() {}
-
+
+
+ static unsigned getNewUID() { return LastID++; }
+
+
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;
}
}
void removeValue(StringRef Name) {
- assert(getValue(Name) && "Cannot remove an entry that does not exist!");
for (unsigned i = 0, e = Values.size(); i != e; ++i)
if (Values[i].getName() == Name) {
Values.erase(Values.begin()+i);
return;
}
- assert(0 && "Name does not exist in record!");
+ assert(0 && "Cannot remove an entry that does not exist!");
}
bool isSubClassOf(const Record *R) const {
/// possible references.
void resolveReferencesTo(const RecordVal *RV);
+ RecordKeeper &getRecords() const {
+ return TrackedRecords;
+ }
+
void dump() const;
//===--------------------------------------------------------------------===//
///
std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const;
- /// getValueAsListOfInts - This method looks up the specified field and returns
- /// 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.
+ /// getValueAsListOfInts - This method looks up the specified field and
+ /// returns 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> 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.
void dump() const;
- MultiClass(const std::string &Name, SMLoc Loc) : Rec(Name, Loc) {}
+ MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) :
+ Rec(Name, Loc, Records) {}
};
class RecordKeeper {
assert(Defs.count(Name) && "Def does not exist!");
Defs.erase(Name);
}
-
+
//===--------------------------------------------------------------------===//
// High-level helper methods, useful for tablegen backends...
std::vector<Record*>
getAllDerivedDefinitions(const std::string &ClassName) const;
-
void dump() const;
};
///
struct LessRecord {
bool operator()(const Record *Rec1, const Record *Rec2) const {
- return Rec1->getName() < Rec2->getName();
+ return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0;
}
};
-/// 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);
+raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
+
+void PrintError(SMLoc ErrorLoc, const Twine &Msg);
-
} // End llvm namespace
#endif