AsmParser: Make the code for parsing unnamed aliases more closely resemble that for...
authorPeter Collingbourne <peter@pcc.me.uk>
Wed, 25 Nov 2015 02:54:07 +0000 (02:54 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Wed, 25 Nov 2015 02:54:07 +0000 (02:54 +0000)
This fixes parsing of forward references to unnamed aliases.

While here, remove an unnecessary isa check.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254054 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AsmParser/LLParser.cpp
test/Assembler/alias-redefinition.ll
test/Assembler/unnamed-alias.ll

index 399364e5eb248ac5816c9f1524f17adddf473baf..307ed397834c44532aa127b9ee3367a1a0d5c27e 100644 (file)
@@ -713,6 +713,24 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
         ExplicitTypeLoc,
         "explicit pointee type doesn't match operand's pointee type");
 
+  GlobalValue *GVal = nullptr;
+
+  // See if the alias was forward referenced, if so, prepare to replace the
+  // forward reference.
+  if (!Name.empty()) {
+    GVal = M->getNamedValue(Name);
+    if (GVal) {
+      if (!ForwardRefVals.erase(Name))
+        return Error(NameLoc, "redefinition of global '@" + Name + "'");
+    }
+  } else {
+    auto I = ForwardRefValIDs.find(NumberedVals.size());
+    if (I != ForwardRefValIDs.end()) {
+      GVal = I->second.first;
+      ForwardRefValIDs.erase(I);
+    }
+  }
+
   // Okay, create the alias but do not insert it into the module yet.
   std::unique_ptr<GlobalAlias> GA(
       GlobalAlias::create(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage,
@@ -725,26 +743,17 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
   if (Name.empty())
     NumberedVals.push_back(GA.get());
 
-  // See if this value already exists in the symbol table.  If so, it is either
-  // a redefinition or a definition of a forward reference.
-  if (GlobalValue *Val = M->getNamedValue(Name)) {
-    // See if this was a redefinition.  If so, there is no entry in
-    // ForwardRefVals.
-    auto I = ForwardRefVals.find(Name);
-    if (I == ForwardRefVals.end())
-      return Error(NameLoc, "redefinition of global named '@" + Name + "'");
-
-    // Otherwise, this was a definition of forward ref.  Verify that types
-    // agree.
-    if (Val->getType() != GA->getType())
-      return Error(NameLoc,
-              "forward reference and definition of alias have different types");
+  if (GVal) {
+    // Verify that types agree.
+    if (GVal->getType() != GA->getType())
+      return Error(
+          ExplicitTypeLoc,
+          "forward reference and definition of alias have different types");
 
     // If they agree, just RAUW the old value with the alias and remove the
     // forward ref info.
-    Val->replaceAllUsesWith(GA.get());
-    Val->eraseFromParent();
-    ForwardRefVals.erase(I);
+    GVal->replaceAllUsesWith(GA.get());
+    GVal->eraseFromParent();
   }
 
   // Insert into the module, we know its name won't collide now.
@@ -809,7 +818,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
   if (!Name.empty()) {
     GVal = M->getNamedValue(Name);
     if (GVal) {
-      if (!ForwardRefVals.erase(Name) || !isa<GlobalValue>(GVal))
+      if (!ForwardRefVals.erase(Name))
         return Error(NameLoc, "redefinition of global '@" + Name + "'");
     }
   } else {
index 7c57b63b66f6b72d322b28f57d96d3212eb6f007..3c36c81d81382ac9fc7967b9bc50718039317019 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: not llvm-as %s 2>&1 | FileCheck %s
 
-; CHECK: error: redefinition of global named '@bar'
+; CHECK: error: redefinition of global '@bar'
 
 @foo = global i32 0
 @bar = alias i32, i32* @foo
index ebba091d770055154cf7c929db4e7d07b1ab7d35..121e54b7d07934f0cc3af86f4f1283a1f9a3bf3d 100644 (file)
@@ -5,7 +5,7 @@
 @1 = private constant i32 1
 ; CHECK: @1 = private constant i32 1
 
-@2 = private alias i32, i32* @0
-; CHECK: @2 = private alias i32, i32* @0
+@2 = private alias i32, i32* @3
+; CHECK: @2 = private alias i32, i32* @3
 @3 = private alias i32, i32* @1
 ; CHECK: @3 = private alias i32, i32* @1