add support for reading the param attrs block
authorChris Lattner <sabre@nondot.org>
Fri, 4 May 2007 03:30:17 +0000 (03:30 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 4 May 2007 03:30:17 +0000 (03:30 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36731 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Reader/BitcodeReader.h

index 8d148ceb80571c75ef2ec40ef8bfac68ed8c675d..ca372d663e21026f4ba5b70a3ce5f9198f06e017 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
+#include "llvm/ParameterAttributes.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -26,6 +27,9 @@ BitcodeReader::~BitcodeReader() {
   delete Buffer;
 }
 
+//===----------------------------------------------------------------------===//
+//  Helper functions to implement forward reference resolution, etc.
+//===----------------------------------------------------------------------===//
 
 /// ConvertToString - Convert a string from a record into an std::string, return
 /// true on failure.
@@ -173,6 +177,67 @@ const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) {
   return TypeList.back().get();
 }
 
+//===----------------------------------------------------------------------===//
+//  Functions for parsing blocks from the bitcode file
+//===----------------------------------------------------------------------===//
+
+bool BitcodeReader::ParseParamAttrBlock() {
+  if (Stream.EnterSubBlock())
+    return Error("Malformed block record");
+  
+  if (!ParamAttrs.empty())
+    return Error("Multiple PARAMATTR blocks found!");
+  
+  SmallVector<uint64_t, 64> Record;
+  
+  ParamAttrsVector Attrs;
+  
+  // Read all the records.
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Error at end of PARAMATTR block");
+      return false;
+    }
+    
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock())
+        return Error("Malformed block record");
+      continue;
+    }
+    
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+    
+    // Read a record.
+    Record.clear();
+    switch (Stream.ReadRecord(Code, Record)) {
+    default:  // Default behavior: ignore.
+      break;
+    case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [paramidx0, attr0, ...]
+      if (Record.size() & 1)
+        return Error("Invalid ENTRY record");
+
+      ParamAttrsWithIndex PAWI;
+      for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
+        PAWI.index = Record[i];
+        PAWI.attrs = Record[i+1];
+        Attrs.push_back(PAWI);
+      }
+      ParamAttrs.push_back(ParamAttrsList::get(Attrs));
+      Attrs.clear();
+      break;
+    }
+    }    
+  }
+}
+
+
 bool BitcodeReader::ParseTypeTable() {
   if (Stream.EnterSubBlock())
     return Error("Malformed block record");
@@ -742,6 +807,10 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
         if (Stream.SkipBlock())
           return Error("Malformed block record");
         break;
+      case bitc::PARAMATTR_BLOCK_ID:
+        if (ParseParamAttrBlock())
+          return true;
+        break;
       case bitc::TYPE_BLOCK_ID:
         if (ParseTypeTable())
           return true;
index e537310ecaf7f0fb7972e26dfab0e564ad8f0979..44d69a6eca7d13cb50ba89a0d154cbdc115ae577 100644 (file)
@@ -24,6 +24,7 @@
 
 namespace llvm {
   class MemoryBuffer;
+  class ParamAttrsList;
   
 class BitcodeReaderValueList : public User {
   std::vector<Use> Uses;
@@ -85,6 +86,11 @@ class BitcodeReader : public ModuleProvider {
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
   std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
   
+  /// ParamAttrs - The set of parameter attributes by index.  Index zero in the
+  /// file is for null, and is thus not represented here.  As such all indices
+  /// are off by one.
+  std::vector<const ParamAttrsList*> ParamAttrs;
+  
   /// FunctionBBs - While parsing a function body, this is a list of the basic
   /// blocks for the function.
   std::vector<BasicBlock*> FunctionBBs;
@@ -136,8 +142,15 @@ private:
     if (ID >= FunctionBBs.size()) return 0; // Invalid ID
     return FunctionBBs[ID];
   }
+  const ParamAttrsList *getParamAttrs(unsigned i) const {
+    if (i-1 < ParamAttrs.size())
+      return ParamAttrs[i-1];
+    return 0;
+  }
+
   
   bool ParseModule(const std::string &ModuleID);
+  bool ParseParamAttrBlock();
   bool ParseTypeTable();
   bool ParseTypeSymbolTable();
   bool ParseValueSymbolTable();