add bitcode alias support


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36461 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 6f824c6..6f18f7e 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -398,6 +398,47 @@
   return 1ULL << 63;
 }
 
+/// ResolveGlobalAndAliasInits - Resolve all of the initializers for global
+/// values and aliases that we can.
+bool BitcodeReader::ResolveGlobalAndAliasInits() {
+  std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;
+  std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist;
+  
+  GlobalInitWorklist.swap(GlobalInits);
+  AliasInitWorklist.swap(AliasInits);
+
+  while (!GlobalInitWorklist.empty()) {
+    unsigned ValID = GlobalInits.back().second;
+    if (ValID >= ValueList.size()) {
+      // Not ready to resolve this yet, it requires something later in the file.
+      GlobalInitWorklist.push_back(GlobalInits.back());
+    } else {
+      if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
+        GlobalInitWorklist.back().first->setInitializer(C);
+      else
+        return Error("Global variable initializer is not a constant!");
+    }
+    GlobalInitWorklist.pop_back(); 
+  }
+
+  while (!AliasInitWorklist.empty()) {
+    unsigned ValID = AliasInitWorklist.back().second;
+    if (ValID >= ValueList.size()) {
+      AliasInits.push_back(AliasInitWorklist.back());
+    } else {
+      if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
+        AliasInitWorklist.back().first->setAliasee(
+                                            // FIXME:
+                                            cast<GlobalValue>(C));
+      else
+        return Error("Alias initializer is not a constant!");
+    }
+    AliasInitWorklist.pop_back(); 
+  }
+  return false;
+}
+
+
 bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
   if (Stream.EnterSubBlock())
     return Error("Malformed block record");
@@ -410,20 +451,6 @@
   while (1) {
     unsigned Code = Stream.ReadCode();
     if (Code == bitc::END_BLOCK) {
-      // If there are global var inits to process, do so now.
-      if (!GlobalInits.empty()) {
-        while (!GlobalInits.empty()) {
-          unsigned ValID = GlobalInits.back().second;
-          if (ValID >= ValueList.size())
-            return Error("Invalid value ID for global var init!");
-          if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
-            GlobalInits.back().first->setInitializer(C);
-          else
-            return Error("Global variable initializer is not a constant!");
-          GlobalInits.pop_back(); 
-        }
-      }
-      
       if (NextCstNo != ValueList.size())
         return Error("Invalid constant reference!");
       
@@ -646,7 +673,8 @@
   while (!Stream.AtEndOfStream()) {
     unsigned Code = Stream.ReadCode();
     if (Code == bitc::END_BLOCK) {
-      if (!GlobalInits.empty())
+      ResolveGlobalAndAliasInits();
+      if (!GlobalInits.empty() || !AliasInits.empty())
         return Error("Malformed global initializer set");
       if (Stream.ReadBlockEnd())
         return Error("Error at end of module block");
@@ -672,7 +700,7 @@
           return true;
         break;
       case bitc::CONSTANTS_BLOCK_ID:
-        if (ParseConstants(Stream))
+        if (ParseConstants(Stream) || ResolveGlobalAndAliasInits())
           return true;
         break;
       }
@@ -795,9 +823,21 @@
       Func->setVisibility(GetDecodedVisibility(Record[6]));
       
       ValueList.push_back(Func);
-      // TODO: remember initializer/global pair for later substitution.
       break;
     }
+    // ALIAS: [alias type, aliasee val#, linkage]
+    case bitc::MODULE_CODE_ALIAS:
+      if (Record.size() < 3)
+        return Error("Invalid MODULE_ALIAS record");
+      const Type *Ty = getTypeByID(Record[0]);
+      if (!isa<PointerType>(Ty))
+        return Error("Function not a pointer type!");
+      
+      GlobalAlias *NewGA = new GlobalAlias(Ty, GetDecodedLinkage(Record[2]),
+                                           "", 0, TheModule);
+      ValueList.push_back(NewGA);
+      AliasInits.push_back(std::make_pair(NewGA, Record[1]));
+      break;
     }
     Record.clear();
   }
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index 3935ebb..79bf8ea 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -57,6 +57,7 @@
   std::vector<PATypeHolder> TypeList;
   BitcodeReaderValueList ValueList;
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
+  std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
 public:
   BitcodeReader() : ErrorString(0) {}
   virtual ~BitcodeReader() {}
@@ -93,6 +94,7 @@
   bool ParseTypeSymbolTable(BitstreamReader &Stream);
   bool ParseValueSymbolTable(BitstreamReader &Stream);
   bool ParseConstants(BitstreamReader &Stream);
+  bool ResolveGlobalAndAliasInits();
 };
   
 } // End llvm namespace