enum RecTyKind {
BitRecTyKind,
BitsRecTyKind,
+ CodeRecTyKind,
IntRecTyKind,
StringRecTyKind,
ListRecTyKind,
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
///
class IntRecTy : public RecTy {
public:
static bool classof(const RecTy *RT) {
- return RT->getRecTyKind() == StringRecTyKind;
+ return RT->getRecTyKind() == StringRecTyKind ||
+ RT->getRecTyKind() == CodeRecTyKind;
}
static StringRecTy *get() { return &Shared; }
IK_BitInit,
IK_FirstTypedInit,
IK_BitsInit,
+ IK_CodeInit,
IK_DagInit,
IK_DefInit,
IK_FieldInit,
std::string Value;
explicit StringInit(StringRef V)
- : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
+ : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
StringInit(const StringInit &Other) = delete;
StringInit &operator=(const StringInit &Other) = delete;
Init *convertInitializerTo(RecTy *Ty) const override;
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; }
/// resolveListElementReference - This method is used to implement
//===----------------------------------------------------------------------===//
BitRecTy BitRecTy::Shared;
+CodeRecTy CodeRecTy::Shared;
IntRecTy IntRecTy::Shared;
StringRecTy StringRecTy::Shared;
DagRecTy DagRecTy::Shared;
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) {
static StringMap<std::unique_ptr<StringInit>> ThePool;
return nullptr;
}
+Init *CodeInit::convertInitializerTo(RecTy *Ty) const {
+ if (isa<CodeRecTy>(Ty))
+ return const_cast<CodeInit *>(this);
+
+ return nullptr;
+}
+
static void ProfileListInit(FoldingSetNodeID &ID,
ArrayRef<Init *> Range,
RecTy *EltTy) {
return nullptr;
}
+ if (isa<CodeRecTy>(Ty)) {
+ if (isa<CodeRecTy>(getType()))
+ return const_cast<TypedInit *>(this);
+ return nullptr;
+ }
+
if (isa<BitRecTy>(Ty)) {
// Accept variable if it is already of bit type!
if (isa<BitRecTy>(getType()))
if (StringInit *SI = dyn_cast<StringInit>(R->getValue()))
return SI->getValue();
+ if (CodeInit *CI = dyn_cast<CodeInit>(R->getValue()))
+ return CI->getValue();
+
PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
FieldName + "' does not have a string initializer!");
}
switch (Lex.getCode()) {
default: TokError("Unknown token when expecting a type"); return nullptr;
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::Int: Lex.Lex(); return IntRecTy::get();
case tgtok::Dag: Lex.Lex(); return DagRecTy::get();
break;
}
case tgtok::CodeFragment:
- R = StringInit::get(Lex.getCurStrVal());
+ R = CodeInit::get(Lex.getCurStrVal());
Lex.Lex();
break;
case tgtok::question: