-Wdeprecated-clean: Fix cases of violating the rule of 5 in ways that are deprecated...
[oota-llvm.git] / utils / TableGen / AsmMatcherEmitter.cpp
index a3932cd4e86f1a916b5c288d24dd65295c9be81b..d4a0616584bd8ec3ade467d289162879f7c23d31 100644 (file)
@@ -310,11 +310,16 @@ struct MatchableInfo {
     /// 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
@@ -455,6 +460,20 @@ struct MatchableInfo {
         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*>();
   }
@@ -815,7 +834,14 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info,
 /// 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.
@@ -969,6 +995,12 @@ extractSingletonRegisterForAsmOperand(unsigned OperandNo,
                                       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))
@@ -1231,8 +1263,8 @@ void AsmMatcherInfo::buildOperandClasses() {
     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;
@@ -1517,7 +1549,7 @@ buildInstructionOperandReference(MatchableInfo *II,
       // 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);
       }
@@ -1779,7 +1811,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
                                     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);
 
@@ -2143,8 +2175,7 @@ static void emitMatchTokenString(CodeGenTarget &Target,
   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";
@@ -2166,9 +2197,8 @@ static void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
     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";