diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -1369,14 +1369,22 @@ class RecordVal { friend class Record; +public: + enum FieldKind { + FK_Normal, // A normal record field. + FK_NonconcreteOK, // A field that can be nonconcrete ('field' keyword). + FK_TemplateArg, // A template argument. + }; + +private: Init *Name; SMLoc Loc; // Source location of definition of name. - PointerIntPair TyAndPrefix; + PointerIntPair TyAndKind; Init *Value; public: - RecordVal(Init *N, RecTy *T, bool P); - RecordVal(Init *N, SMLoc Loc, RecTy *T, bool P); + RecordVal(Init *N, RecTy *T, FieldKind K); + RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K); /// Get the name of the field as a StringRef. StringRef getName() const; @@ -1392,10 +1400,18 @@ /// Get the source location of the point where the field was defined. const SMLoc &getLoc() const { return Loc; } - bool getPrefix() const { return TyAndPrefix.getInt(); } + /// Is this a field where nonconcrete values are okay? + bool isNonconcreteOK() const { + return TyAndKind.getInt() == FK_NonconcreteOK; + } + + /// Is this a template argument? + bool isTemplateArg() const { + return TyAndKind.getInt() == FK_TemplateArg; + } /// Get the type of the field value as a RecTy. - RecTy *getType() const { return TyAndPrefix.getPointer(); } + RecTy *getType() const { return TyAndKind.getPointer(); } /// Get the type of the field for printing purposes. std::string getPrintType() const; diff --git a/llvm/lib/TableGen/JSONBackend.cpp b/llvm/lib/TableGen/JSONBackend.cpp --- a/llvm/lib/TableGen/JSONBackend.cpp +++ b/llvm/lib/TableGen/JSONBackend.cpp @@ -144,7 +144,7 @@ for (const RecordVal &RV : Def.getValues()) { if (!Def.isTemplateArg(RV.getNameInit())) { auto Name = RV.getNameInitAsString(); - if (RV.getPrefix()) + if (RV.isNonconcreteOK()) fields.push_back(Name); obj[Name] = translateInit(*RV.getValue()); } diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -2141,16 +2141,16 @@ // Other implementations //===----------------------------------------------------------------------===// -RecordVal::RecordVal(Init *N, RecTy *T, bool P) - : Name(N), TyAndPrefix(T, P) { +RecordVal::RecordVal(Init *N, RecTy *T, FieldKind K) + : Name(N), TyAndKind(T, K) { setValue(UnsetInit::get()); assert(Value && "Cannot create unset value for current type!"); } // This constructor accepts the same arguments as the above, but also // a source location. -RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, bool P) - : Name(N), Loc(Loc), TyAndPrefix(T, P) { +RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K) + : Name(N), Loc(Loc), TyAndKind(T, K) { setValue(UnsetInit::get()); assert(Value && "Cannot create unset value for current type!"); } @@ -2170,7 +2170,7 @@ return "string"; } } else { - return TyAndPrefix.getPointer()->getAsString(); + return TyAndKind.getPointer()->getAsString(); } } @@ -2227,7 +2227,7 @@ #endif void RecordVal::print(raw_ostream &OS, bool PrintSem) const { - if (getPrefix()) OS << "field "; + if (isNonconcreteOK()) OS << "field "; OS << getPrintType() << " " << getNameInitAsString(); if (getValue()) @@ -2368,10 +2368,10 @@ OS << "\n"; for (const RecordVal &Val : R.getValues()) - if (Val.getPrefix() && !R.isTemplateArg(Val.getNameInit())) + if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit())) OS << Val; for (const RecordVal &Val : R.getValues()) - if (!Val.getPrefix() && !R.isTemplateArg(Val.getNameInit())) + if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit())) OS << Val; return OS << "}\n"; diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -95,7 +95,7 @@ // done merely because existing targets have legitimate cases of // non-concrete variables in helper defs. Ideally, we'd introduce a // 'maybe' or 'optional' modifier instead of this. - if (RV.getPrefix()) + if (RV.isNonconcreteOK()) continue; if (Init *V = RV.getValue()) { @@ -1596,8 +1596,9 @@ ParseRec = ParseRecTmp.get(); } - ParseRec->addValue(RecordVal(A, Start->getType(), false)); - ParseRec->addValue(RecordVal(B, ListType->getElementType(), false)); + ParseRec->addValue(RecordVal(A, Start->getType(), RecordVal::FK_Normal)); + ParseRec->addValue(RecordVal(B, ListType->getElementType(), + RecordVal::FK_Normal)); Init *ExprUntyped = ParseValue(ParseRec); ParseRec->removeValue(A); ParseRec->removeValue(B); @@ -1845,7 +1846,7 @@ ParseRec = ParseRecTmp.get(); } - ParseRec->addValue(RecordVal(LHS, InEltType, false)); + ParseRec->addValue(RecordVal(LHS, InEltType, RecordVal::FK_Normal)); Init *RHS = ParseValue(ParseRec, ExprEltType); ParseRec->removeValue(LHS); if (!RHS) @@ -2618,8 +2619,10 @@ "::"); } - // Add the value. - if (AddValue(CurRec, IdLoc, RecordVal(DeclName, IdLoc, Type, HasField))) + // Add the field to the record. + if (AddValue(CurRec, IdLoc, RecordVal(DeclName, IdLoc, Type, + HasField ? RecordVal::FK_NonconcreteOK + : RecordVal::FK_Normal))) return nullptr; // If a value is present, parse it. diff --git a/llvm/utils/TableGen/CodeEmitterGen.cpp b/llvm/utils/TableGen/CodeEmitterGen.cpp --- a/llvm/utils/TableGen/CodeEmitterGen.cpp +++ b/llvm/utils/TableGen/CodeEmitterGen.cpp @@ -311,7 +311,7 @@ for (const RecordVal &RV : EncodingDef->getValues()) { // Ignore fixed fields in the record, we're looking for values like: // bits<5> RST = { ?, ?, ?, ?, ? }; - if (RV.getPrefix() || RV.getValue()->isComplete()) + if (RV.isNonconcreteOK() || RV.getValue()->isComplete()) continue; AddCodeToMergeInOperand(R, BI, std::string(RV.getName()), NumberedOp, diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp --- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -1887,7 +1887,7 @@ for (unsigned i = 0, e = Vals.size(); i != e; ++i) { // Ignore fixed fields in the record, we're looking for values like: // bits<5> RST = { ?, ?, ?, ?, ? }; - if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete()) + if (Vals[i].isNonconcreteOK() || Vals[i].getValue()->isComplete()) continue; // Determine if Vals[i] actually contributes to the Inst encoding.