Adding a collector name attribute to Function in the IR. These 
methods are new to Function:

  bool hasCollector() const;
  const std::string &getCollector() const;
  void setCollector(const std::string &);
  void clearCollector();

The assembly representation is as such:

  define void @f() gc "shadow-stack" { ...

The implementation uses an on-the-side table to map Functions to 
collector names, such that there is no overhead. A StringPool is 
further used to unique collector names, which are extremely
likely to be unique per process.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44769 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index c405feb..fd3ec9e 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -849,6 +849,7 @@
   
   SmallVector<uint64_t, 64> Record;
   std::vector<std::string> SectionTable;
+  std::vector<std::string> CollectorTable;
 
   // Read all the records for this module.
   while (!Stream.AtEndOfStream()) {
@@ -974,6 +975,13 @@
       SectionTable.push_back(S);
       break;
     }
+    case bitc::MODULE_CODE_COLLECTORNAME: {  // SECTIONNAME: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid MODULE_CODE_COLLECTORNAME record");
+      CollectorTable.push_back(S);
+      break;
+    }
     // GLOBALVAR: [type, isconst, initid, 
     //             linkage, alignment, section, visibility, threadlocal]
     case bitc::MODULE_CODE_GLOBALVAR: {
@@ -1016,7 +1024,7 @@
       break;
     }
     // FUNCTION:  [type, callingconv, isproto, linkage, paramattr,
-    //             alignment, section, visibility]
+    //             alignment, section, visibility, collector]
     case bitc::MODULE_CODE_FUNCTION: {
       if (Record.size() < 8)
         return Error("Invalid MODULE_CODE_FUNCTION record");
@@ -1044,6 +1052,11 @@
         Func->setSection(SectionTable[Record[6]-1]);
       }
       Func->setVisibility(GetDecodedVisibility(Record[7]));
+      if (Record.size() > 8 && Record[8]) {
+        if (Record[8]-1 > CollectorTable.size())
+          return Error("Invalid collector ID");
+        Func->setCollector(CollectorTable[Record[8]-1].c_str());
+      }
       
       ValueList.push_back(Func);