TableGen: promote "code" type from syntactic sugar.
It's being immediately converted to a "string", but being able to tell what type the field was originally can be useful in backends. llvm-svn: 274575
This commit is contained in:
parent
aaa0191be6
commit
88403d7a84
|
@ -44,6 +44,7 @@ public:
|
||||||
enum RecTyKind {
|
enum RecTyKind {
|
||||||
BitRecTyKind,
|
BitRecTyKind,
|
||||||
BitsRecTyKind,
|
BitsRecTyKind,
|
||||||
|
CodeRecTyKind,
|
||||||
IntRecTyKind,
|
IntRecTyKind,
|
||||||
StringRecTyKind,
|
StringRecTyKind,
|
||||||
ListRecTyKind,
|
ListRecTyKind,
|
||||||
|
@ -116,6 +117,22 @@ public:
|
||||||
bool typeIsConvertibleTo(const RecTy *RHS) const override;
|
bool typeIsConvertibleTo(const RecTy *RHS) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// CodeRecTy - 'code' - Represent a code fragment
|
||||||
|
///
|
||||||
|
class CodeRecTy : public RecTy {
|
||||||
|
static CodeRecTy Shared;
|
||||||
|
CodeRecTy() : RecTy(CodeRecTyKind) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool classof(const RecTy *RT) {
|
||||||
|
return RT->getRecTyKind() == CodeRecTyKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CodeRecTy *get() { return &Shared; }
|
||||||
|
|
||||||
|
std::string getAsString() const override { return "code"; }
|
||||||
|
};
|
||||||
|
|
||||||
/// IntRecTy - 'int' - Represent an integer value of no particular size
|
/// IntRecTy - 'int' - Represent an integer value of no particular size
|
||||||
///
|
///
|
||||||
class IntRecTy : public RecTy {
|
class IntRecTy : public RecTy {
|
||||||
|
@ -142,7 +159,8 @@ class StringRecTy : public RecTy {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool classof(const RecTy *RT) {
|
static bool classof(const RecTy *RT) {
|
||||||
return RT->getRecTyKind() == StringRecTyKind;
|
return RT->getRecTyKind() == StringRecTyKind ||
|
||||||
|
RT->getRecTyKind() == CodeRecTyKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringRecTy *get() { return &Shared; }
|
static StringRecTy *get() { return &Shared; }
|
||||||
|
@ -237,6 +255,7 @@ protected:
|
||||||
IK_BitInit,
|
IK_BitInit,
|
||||||
IK_FirstTypedInit,
|
IK_FirstTypedInit,
|
||||||
IK_BitsInit,
|
IK_BitsInit,
|
||||||
|
IK_CodeInit,
|
||||||
IK_DagInit,
|
IK_DagInit,
|
||||||
IK_DefInit,
|
IK_DefInit,
|
||||||
IK_FieldInit,
|
IK_FieldInit,
|
||||||
|
@ -556,7 +575,7 @@ class StringInit : public TypedInit {
|
||||||
std::string Value;
|
std::string Value;
|
||||||
|
|
||||||
explicit StringInit(StringRef V)
|
explicit StringInit(StringRef V)
|
||||||
: TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
|
: TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
|
||||||
|
|
||||||
StringInit(const StringInit &Other) = delete;
|
StringInit(const StringInit &Other) = delete;
|
||||||
StringInit &operator=(const StringInit &Other) = delete;
|
StringInit &operator=(const StringInit &Other) = delete;
|
||||||
|
@ -572,6 +591,46 @@ public:
|
||||||
Init *convertInitializerTo(RecTy *Ty) const override;
|
Init *convertInitializerTo(RecTy *Ty) const override;
|
||||||
|
|
||||||
std::string getAsString() const override { return "\"" + Value + "\""; }
|
std::string getAsString() const override { return "\"" + Value + "\""; }
|
||||||
|
|
||||||
|
std::string getAsUnquotedString() const override { return Value; }
|
||||||
|
|
||||||
|
/// resolveListElementReference - This method is used to implement
|
||||||
|
/// VarListElementInit::resolveReferences. If the list element is resolvable
|
||||||
|
/// now, we return the resolved value, otherwise we return null.
|
||||||
|
Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
||||||
|
unsigned Elt) const override {
|
||||||
|
llvm_unreachable("Illegal element reference off string");
|
||||||
|
}
|
||||||
|
|
||||||
|
Init *getBit(unsigned Bit) const override {
|
||||||
|
llvm_unreachable("Illegal bit reference off string");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CodeInit : public TypedInit {
|
||||||
|
std::string Value;
|
||||||
|
|
||||||
|
explicit CodeInit(StringRef V)
|
||||||
|
: TypedInit(IK_CodeInit, static_cast<RecTy *>(CodeRecTy::get())),
|
||||||
|
Value(V) {}
|
||||||
|
|
||||||
|
CodeInit(const StringInit &Other) = delete;
|
||||||
|
CodeInit &operator=(const StringInit &Other) = delete;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool classof(const Init *I) {
|
||||||
|
return I->getKind() == IK_CodeInit;
|
||||||
|
}
|
||||||
|
static CodeInit *get(StringRef);
|
||||||
|
|
||||||
|
const std::string &getValue() const { return Value; }
|
||||||
|
|
||||||
|
Init *convertInitializerTo(RecTy *Ty) const override;
|
||||||
|
|
||||||
|
std::string getAsString() const override {
|
||||||
|
return "[{" + Value + "}]";
|
||||||
|
}
|
||||||
|
|
||||||
std::string getAsUnquotedString() const override { return Value; }
|
std::string getAsUnquotedString() const override { return Value; }
|
||||||
|
|
||||||
/// resolveListElementReference - This method is used to implement
|
/// resolveListElementReference - This method is used to implement
|
||||||
|
|
|
@ -82,6 +82,7 @@ template<> struct DenseMapInfo<TableGenStringKey> {
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
BitRecTy BitRecTy::Shared;
|
BitRecTy BitRecTy::Shared;
|
||||||
|
CodeRecTy CodeRecTy::Shared;
|
||||||
IntRecTy IntRecTy::Shared;
|
IntRecTy IntRecTy::Shared;
|
||||||
StringRecTy StringRecTy::Shared;
|
StringRecTy StringRecTy::Shared;
|
||||||
DagRecTy DagRecTy::Shared;
|
DagRecTy DagRecTy::Shared;
|
||||||
|
@ -453,6 +454,14 @@ IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
|
||||||
return BitsInit::get(NewBits);
|
return BitsInit::get(NewBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CodeInit *CodeInit::get(StringRef V) {
|
||||||
|
static StringMap<std::unique_ptr<CodeInit>> ThePool;
|
||||||
|
|
||||||
|
std::unique_ptr<CodeInit> &I = ThePool[V];
|
||||||
|
if (!I) I.reset(new CodeInit(V));
|
||||||
|
return I.get();
|
||||||
|
}
|
||||||
|
|
||||||
StringInit *StringInit::get(StringRef V) {
|
StringInit *StringInit::get(StringRef V) {
|
||||||
static StringMap<std::unique_ptr<StringInit>> ThePool;
|
static StringMap<std::unique_ptr<StringInit>> ThePool;
|
||||||
|
|
||||||
|
@ -468,6 +477,13 @@ Init *StringInit::convertInitializerTo(RecTy *Ty) const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Init *CodeInit::convertInitializerTo(RecTy *Ty) const {
|
||||||
|
if (isa<CodeRecTy>(Ty))
|
||||||
|
return const_cast<CodeInit *>(this);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static void ProfileListInit(FoldingSetNodeID &ID,
|
static void ProfileListInit(FoldingSetNodeID &ID,
|
||||||
ArrayRef<Init *> Range,
|
ArrayRef<Init *> Range,
|
||||||
RecTy *EltTy) {
|
RecTy *EltTy) {
|
||||||
|
@ -1158,6 +1174,12 @@ TypedInit::convertInitializerTo(RecTy *Ty) const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isa<CodeRecTy>(Ty)) {
|
||||||
|
if (isa<CodeRecTy>(getType()))
|
||||||
|
return const_cast<TypedInit *>(this);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (isa<BitRecTy>(Ty)) {
|
if (isa<BitRecTy>(Ty)) {
|
||||||
// Accept variable if it is already of bit type!
|
// Accept variable if it is already of bit type!
|
||||||
if (isa<BitRecTy>(getType()))
|
if (isa<BitRecTy>(getType()))
|
||||||
|
@ -1744,6 +1766,9 @@ std::string Record::getValueAsString(StringRef FieldName) const {
|
||||||
|
|
||||||
if (StringInit *SI = dyn_cast<StringInit>(R->getValue()))
|
if (StringInit *SI = dyn_cast<StringInit>(R->getValue()))
|
||||||
return SI->getValue();
|
return SI->getValue();
|
||||||
|
if (CodeInit *CI = dyn_cast<CodeInit>(R->getValue()))
|
||||||
|
return CI->getValue();
|
||||||
|
|
||||||
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
|
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
|
||||||
FieldName + "' does not have a string initializer!");
|
FieldName + "' does not have a string initializer!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -660,7 +660,7 @@ RecTy *TGParser::ParseType() {
|
||||||
switch (Lex.getCode()) {
|
switch (Lex.getCode()) {
|
||||||
default: TokError("Unknown token when expecting a type"); return nullptr;
|
default: TokError("Unknown token when expecting a type"); return nullptr;
|
||||||
case tgtok::String: Lex.Lex(); return StringRecTy::get();
|
case tgtok::String: Lex.Lex(); return StringRecTy::get();
|
||||||
case tgtok::Code: Lex.Lex(); return StringRecTy::get();
|
case tgtok::Code: Lex.Lex(); return CodeRecTy::get();
|
||||||
case tgtok::Bit: Lex.Lex(); return BitRecTy::get();
|
case tgtok::Bit: Lex.Lex(); return BitRecTy::get();
|
||||||
case tgtok::Int: Lex.Lex(); return IntRecTy::get();
|
case tgtok::Int: Lex.Lex(); return IntRecTy::get();
|
||||||
case tgtok::Dag: Lex.Lex(); return DagRecTy::get();
|
case tgtok::Dag: Lex.Lex(); return DagRecTy::get();
|
||||||
|
@ -1164,7 +1164,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tgtok::CodeFragment:
|
case tgtok::CodeFragment:
|
||||||
R = StringInit::get(Lex.getCurStrVal());
|
R = CodeInit::get(Lex.getCurStrVal());
|
||||||
Lex.Lex();
|
Lex.Lex();
|
||||||
break;
|
break;
|
||||||
case tgtok::question:
|
case tgtok::question:
|
||||||
|
|
|
@ -1078,7 +1078,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
|
||||||
|
|
||||||
for (unsigned i = 0; i < MCOpPredicates.size(); ++i) {
|
for (unsigned i = 0; i < MCOpPredicates.size(); ++i) {
|
||||||
Init *MCOpPred = MCOpPredicates[i]->getValueInit("MCOperandPredicate");
|
Init *MCOpPred = MCOpPredicates[i]->getValueInit("MCOperandPredicate");
|
||||||
if (StringInit *SI = dyn_cast<StringInit>(MCOpPred)) {
|
if (CodeInit *SI = dyn_cast<CodeInit>(MCOpPred)) {
|
||||||
O << " case " << i + 1 << ": {\n"
|
O << " case " << i + 1 << ": {\n"
|
||||||
<< SI->getValue() << "\n"
|
<< SI->getValue() << "\n"
|
||||||
<< " }\n";
|
<< " }\n";
|
||||||
|
|
Loading…
Reference in New Issue