llvm.org GIT mirror llvm / edff068
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274575 91177308-0d34-0410-b5e6-96231b3b80d8 Tim Northover 3 years ago
4 changed file(s) with 89 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
4343 enum RecTyKind {
4444 BitRecTyKind,
4545 BitsRecTyKind,
46 CodeRecTyKind,
4647 IntRecTyKind,
4748 StringRecTyKind,
4849 ListRecTyKind,
115116 bool typeIsConvertibleTo(const RecTy *RHS) const override;
116117 };
117118
119 /// CodeRecTy - 'code' - Represent a code fragment
120 ///
121 class CodeRecTy : public RecTy {
122 static CodeRecTy Shared;
123 CodeRecTy() : RecTy(CodeRecTyKind) {}
124
125 public:
126 static bool classof(const RecTy *RT) {
127 return RT->getRecTyKind() == CodeRecTyKind;
128 }
129
130 static CodeRecTy *get() { return &Shared; }
131
132 std::string getAsString() const override { return "code"; }
133 };
134
118135 /// IntRecTy - 'int' - Represent an integer value of no particular size
119136 ///
120137 class IntRecTy : public RecTy {
141158
142159 public:
143160 static bool classof(const RecTy *RT) {
144 return RT->getRecTyKind() == StringRecTyKind;
161 return RT->getRecTyKind() == StringRecTyKind ||
162 RT->getRecTyKind() == CodeRecTyKind;
145163 }
146164
147165 static StringRecTy *get() { return &Shared; }
236254 IK_BitInit,
237255 IK_FirstTypedInit,
238256 IK_BitsInit,
257 IK_CodeInit,
239258 IK_DagInit,
240259 IK_DefInit,
241260 IK_FieldInit,
555574 std::string Value;
556575
557576 explicit StringInit(StringRef V)
558 : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
577 : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
559578
560579 StringInit(const StringInit &Other) = delete;
561580 StringInit &operator=(const StringInit &Other) = delete;
571590 Init *convertInitializerTo(RecTy *Ty) const override;
572591
573592 std::string getAsString() const override { return "\"" + Value + "\""; }
593
594 std::string getAsUnquotedString() const override { return Value; }
595
596 /// resolveListElementReference - This method is used to implement
597 /// VarListElementInit::resolveReferences. If the list element is resolvable
598 /// now, we return the resolved value, otherwise we return null.
599 Init *resolveListElementReference(Record &R, const RecordVal *RV,
600 unsigned Elt) const override {
601 llvm_unreachable("Illegal element reference off string");
602 }
603
604 Init *getBit(unsigned Bit) const override {
605 llvm_unreachable("Illegal bit reference off string");
606 }
607 };
608
609 class CodeInit : public TypedInit {
610 std::string Value;
611
612 explicit CodeInit(StringRef V)
613 : TypedInit(IK_CodeInit, static_cast(CodeRecTy::get())),
614 Value(V) {}
615
616 CodeInit(const StringInit &Other) = delete;
617 CodeInit &operator=(const StringInit &Other) = delete;
618
619 public:
620 static bool classof(const Init *I) {
621 return I->getKind() == IK_CodeInit;
622 }
623 static CodeInit *get(StringRef);
624
625 const std::string &getValue() const { return Value; }
626
627 Init *convertInitializerTo(RecTy *Ty) const override;
628
629 std::string getAsString() const override {
630 return "[{" + Value + "}]";
631 }
632
574633 std::string getAsUnquotedString() const override { return Value; }
575634
576635 /// resolveListElementReference - This method is used to implement
8181 //===----------------------------------------------------------------------===//
8282
8383 BitRecTy BitRecTy::Shared;
84 CodeRecTy CodeRecTy::Shared;
8485 IntRecTy IntRecTy::Shared;
8586 StringRecTy StringRecTy::Shared;
8687 DagRecTy DagRecTy::Shared;
452453 return BitsInit::get(NewBits);
453454 }
454455
456 CodeInit *CodeInit::get(StringRef V) {
457 static StringMap> ThePool;
458
459 std::unique_ptr &I = ThePool[V];
460 if (!I) I.reset(new CodeInit(V));
461 return I.get();
462 }
463
455464 StringInit *StringInit::get(StringRef V) {
456465 static StringMap> ThePool;
457466
463472 Init *StringInit::convertInitializerTo(RecTy *Ty) const {
464473 if (isa(Ty))
465474 return const_cast(this);
475
476 return nullptr;
477 }
478
479 Init *CodeInit::convertInitializerTo(RecTy *Ty) const {
480 if (isa(Ty))
481 return const_cast(this);
466482
467483 return nullptr;
468484 }
11571173 return nullptr;
11581174 }
11591175
1176 if (isa(Ty)) {
1177 if (isa(getType()))
1178 return const_cast(this);
1179 return nullptr;
1180 }
1181
11601182 if (isa(Ty)) {
11611183 // Accept variable if it is already of bit type!
11621184 if (isa(getType()))
17431765
17441766 if (StringInit *SI = dyn_cast(R->getValue()))
17451767 return SI->getValue();
1768 if (CodeInit *CI = dyn_cast(R->getValue()))
1769 return CI->getValue();
1770
17461771 PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
17471772 FieldName + "' does not have a string initializer!");
17481773 }
659659 switch (Lex.getCode()) {
660660 default: TokError("Unknown token when expecting a type"); return nullptr;
661661 case tgtok::String: Lex.Lex(); return StringRecTy::get();
662 case tgtok::Code: Lex.Lex(); return StringRecTy::get();
662 case tgtok::Code: Lex.Lex(); return CodeRecTy::get();
663663 case tgtok::Bit: Lex.Lex(); return BitRecTy::get();
664664 case tgtok::Int: Lex.Lex(); return IntRecTy::get();
665665 case tgtok::Dag: Lex.Lex(); return DagRecTy::get();
11631163 break;
11641164 }
11651165 case tgtok::CodeFragment:
1166 R = StringInit::get(Lex.getCurStrVal());
1166 R = CodeInit::get(Lex.getCurStrVal());
11671167 Lex.Lex();
11681168 break;
11691169 case tgtok::question:
10771077
10781078 for (unsigned i = 0; i < MCOpPredicates.size(); ++i) {
10791079 Init *MCOpPred = MCOpPredicates[i]->getValueInit("MCOperandPredicate");
1080 if (StringInit *SI = dyn_castInit>(MCOpPred)) {
1080 if (CodeInit *SI = dyn_castInit>(MCOpPred)) {
10811081 O << " case " << i + 1 << ": {\n"
10821082 << SI->getValue() << "\n"
10831083 << " }\n";