implement more checking to reject things like:
  (someinst GR16:$foo, GR32:$foo)

Reimplement BuildAliasOperandReference to be correctly
based on the names of operands in the result pattern,
instead of on the instruction operand definitions.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118328 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index f1ba6f7..a2989b1 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -15,6 +15,7 @@
 #include "CodeGenTarget.h"
 #include "Record.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include <set>
 using namespace llvm;
@@ -407,6 +408,10 @@
                   " arguments, but " + ResultInst->TheDef->getName() +
                   " instruction expects " + utostr(ResultInst->Operands.size())+
                   " operands!");
+  
+  // NameClass - If argument names are repeated, we need to verify they have
+  // the same class.
+  StringMap<Record*> NameClass;
     
   // Decode and validate the arguments of the result.
   for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
@@ -425,6 +430,15 @@
                       ", instruction operand is class " + 
                       ResultInst->Operands[i].Rec->getName());
       
+      // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
+      // $foo can exist multiple times in the result list, but it must have the
+      // same type.
+      Record *&Entry = NameClass[Result->getArgName(i)];
+      if (Entry && Entry != ADI->getDef())
+        throw TGError(R->getLoc(), "result value $" + Result->getArgName(i) +
+                      " is both " + Entry->getName() + " and " +
+                      ADI->getDef()->getName() + "!");
+      
       // Now that it is validated, add it.
       ResultOperands.push_back(ResultOperand(Result->getArgName(i),
                                              ADI->getDef()));