/// The suboperand index within SrcOpName, or -1 for the entire operand.
int SubOpIdx;
+ /// Whether the token is "isolated", i.e., it is preceded and followed
+ /// by separators.
+ bool IsIsolatedToken;
+
/// Register record if this token is singleton register.
Record *SingletonReg;
- explicit AsmOperand(StringRef T) : Token(T), Class(nullptr), SubOpIdx(-1),
- SingletonReg(nullptr) {}
+ explicit AsmOperand(bool IsIsolatedToken, StringRef T)
+ : Token(T), Class(nullptr), SubOpIdx(-1),
+ IsIsolatedToken(IsIsolatedToken), SingletonReg(nullptr) {}
};
/// ResOperand - This represents a single operand in the result instruction
TheDef->getValueAsBit("UseInstAsmMatchConverter")) {
}
+ // Could remove this and the dtor if PointerUnion supported unique_ptr
+ // elements with a dynamic failure/assertion (like the one below) in the case
+ // where it was copied while being in an owning state.
+ MatchableInfo(const MatchableInfo &RHS)
+ : AsmVariantID(RHS.AsmVariantID), AsmString(RHS.AsmString),
+ TheDef(RHS.TheDef), DefRec(RHS.DefRec), ResOperands(RHS.ResOperands),
+ Mnemonic(RHS.Mnemonic), AsmOperands(RHS.AsmOperands),
+ RequiredFeatures(RHS.RequiredFeatures),
+ ConversionFnKind(RHS.ConversionFnKind),
+ HasDeprecation(RHS.HasDeprecation),
+ UseInstAsmMatchConverter(RHS.UseInstAsmMatchConverter) {
+ assert(!DefRec.is<const CodeGenInstAlias *>());
+ }
+
~MatchableInfo() {
delete DefRec.dyn_cast<const CodeGenInstAlias*>();
}
/// Append an AsmOperand for the given substring of AsmString.
void MatchableInfo::addAsmOperand(size_t Start, size_t End) {
StringRef String = AsmString;
- AsmOperands.push_back(AsmOperand(String.slice(Start, End)));
+ StringRef Separators = "[]*! \t,";
+ // Look for separators before and after to figure out is this token is
+ // isolated. Accept '$$' as that's how we escape '$'.
+ bool IsIsolatedToken =
+ (!Start || Separators.find(String[Start - 1]) != StringRef::npos ||
+ String.substr(Start - 1, 2) == "$$") &&
+ (End >= String.size() || Separators.find(String[End]) != StringRef::npos);
+ AsmOperands.push_back(AsmOperand(IsIsolatedToken, String.slice(Start, End)));
}
/// tokenizeAsmString - Tokenize a simplified assembly string.
InTok = false;
}
- // If this isn't "${", treat like a normal token.
+ // If this isn't "${", start new identifier looking like "$xxx"
if (i + 1 == String.size() || String[i + 1] != '{') {
Prev = i;
break;
}
+ // If this is "${" find the next "}" and make an identifier like "${xxx}"
StringRef::iterator End = std::find(String.begin() + i, String.end(),'}');
assert(End != String.end() && "Missing brace in operand reference!");
size_t EndPos = End - String.begin();
const AsmMatcherInfo &Info,
std::string &RegisterPrefix) {
StringRef Tok = AsmOperands[OperandNo].Token;
+
+ // If this token is not an isolated token, i.e., it isn't separated from
+ // other tokens (e.g. with whitespace), don't interpret it as a register name.
+ if (!AsmOperands[OperandNo].IsIsolatedToken)
+ return;
+
if (RegisterPrefix.empty()) {
std::string LoweredTok = Tok.lower();
if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok))
CI->Kind = ClassInfo::UserClass0 + Index;
ListInit *Supers = Rec->getValueAsListInit("SuperClasses");
- for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) {
- DefInit *DI = dyn_cast<DefInit>(Supers->getElement(i));
+ for (Init *I : Supers->getValues()) {
+ DefInit *DI = dyn_cast<DefInit>(I);
if (!DI) {
PrintError(Rec->getLoc(), "Invalid super class reference!");
continue;
if (CGI->TheDef->getValueAsBit("isCodeGenOnly"))
continue;
- std::unique_ptr<MatchableInfo> II(new MatchableInfo(*CGI));
+ auto II = llvm::make_unique<MatchableInfo>(*CGI);
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
.startswith( MatchPrefix))
continue;
- std::unique_ptr<MatchableInfo> II(new MatchableInfo(std::move(Alias)));
+ auto II = llvm::make_unique<MatchableInfo>(std::move(Alias));
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
II->TheDef->getValueAsString("TwoOperandAliasConstraint");
if (Constraint != "") {
// Start by making a copy of the original matchable.
- std::unique_ptr<MatchableInfo> AliasII(new MatchableInfo(*II));
+ auto AliasII = llvm::make_unique<MatchableInfo>(*II);
// Adjust it to be a two-operand alias.
AliasII->formTwoOperandAlias(Constraint);
// Insert remaining suboperands after AsmOpIdx in II->AsmOperands.
StringRef Token = Op->Token; // save this in case Op gets moved
for (unsigned SI = 1, SE = Operands[Idx].MINumOperands; SI != SE; ++SI) {
- MatchableInfo::AsmOperand NewAsmOp(Token);
+ MatchableInfo::AsmOperand NewAsmOp(/*IsIsolatedToken=*/true, Token);
NewAsmOp.SubOpIdx = SI;
II->AsmOperands.insert(II->AsmOperands.begin()+AsmOpIdx+SI, NewAsmOp);
}
getEnumNameForToken(AsmMatchConverter));
// Add the converter row for this instruction.
- ConversionTable.push_back(std::vector<uint8_t>());
+ ConversionTable.emplace_back();
ConversionTable.back().push_back(KindID);
ConversionTable.back().push_back(CVT_Done);
continue;
// Add the row to the table.
- ConversionTable.push_back(ConversionRow);
+ ConversionTable.push_back(std::move(ConversionRow));
}
// Finish up the converter driver function.
// Output the instruction conversion kind enum.
OS << "enum InstructionConversionKind {\n";
- for (SetVector<std::string>::const_iterator
- i = InstructionConversionKinds.begin(),
- e = InstructionConversionKinds.end(); i != e; ++i)
- OS << " " << *i << ",\n";
+ for (const std::string &Signature : InstructionConversionKinds)
+ OS << " " << Signature << ",\n";
OS << " CVT_NUM_SIGNATURES\n";
OS << "};\n\n";
std::vector<StringMatcher::StringPair> Matches;
for (const auto &CI : Infos) {
if (CI.Kind == ClassInfo::Token)
- Matches.push_back(
- StringMatcher::StringPair(CI.ValueName, "return " + CI.Name + ";"));
+ Matches.emplace_back(CI.ValueName, "return " + CI.Name + ";");
}
OS << "static MatchClassKind matchTokenString(StringRef Name) {\n";
if (Reg.TheDef->getValueAsString("AsmName").empty())
continue;
- Matches.push_back(
- StringMatcher::StringPair(Reg.TheDef->getValueAsString("AsmName"),
- "return " + utostr(Reg.EnumValue) + ";"));
+ Matches.emplace_back(Reg.TheDef->getValueAsString("AsmName"),
+ "return " + utostr(Reg.EnumValue) + ";");
}
OS << "static unsigned MatchRegisterName(StringRef Name) {\n";