Error BitcodeReader::parseConstants()

in llvm/lib/Bitcode/Reader/BitcodeReader.cpp [2338:2999]


Error BitcodeReader::parseConstants() {
  if (Error Err = Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
    return Err;

  SmallVector<uint64_t, 64> Record;

  // Read all the records for this value table.
  Type *CurTy = Type::getInt32Ty(Context);
  unsigned NextCstNo = ValueList.size();

  struct DelayedShufTy {
    VectorType *OpTy;
    VectorType *RTy;
    uint64_t Op0Idx;
    uint64_t Op1Idx;
    uint64_t Op2Idx;
    unsigned CstNo;
  };
  std::vector<DelayedShufTy> DelayedShuffles;
  struct DelayedSelTy {
    Type *OpTy;
    uint64_t Op0Idx;
    uint64_t Op1Idx;
    uint64_t Op2Idx;
    unsigned CstNo;
  };
  std::vector<DelayedSelTy> DelayedSelectors;

  while (true) {
    Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks();
    if (!MaybeEntry)
      return MaybeEntry.takeError();
    BitstreamEntry Entry = MaybeEntry.get();

    switch (Entry.Kind) {
    case BitstreamEntry::SubBlock: // Handled for us already.
    case BitstreamEntry::Error:
      return error("Malformed block");
    case BitstreamEntry::EndBlock:
      // Once all the constants have been read, go through and resolve forward
      // references.
      //
      // We have to treat shuffles specially because they don't have three
      // operands anymore.  We need to convert the shuffle mask into an array,
      // and we can't convert a forward reference.
      for (auto &DelayedShuffle : DelayedShuffles) {
        VectorType *OpTy = DelayedShuffle.OpTy;
        VectorType *RTy = DelayedShuffle.RTy;
        uint64_t Op0Idx = DelayedShuffle.Op0Idx;
        uint64_t Op1Idx = DelayedShuffle.Op1Idx;
        uint64_t Op2Idx = DelayedShuffle.Op2Idx;
        uint64_t CstNo = DelayedShuffle.CstNo;
        Constant *Op0 = ValueList.getConstantFwdRef(Op0Idx, OpTy);
        Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy);
        Type *ShufTy =
            VectorType::get(Type::getInt32Ty(Context), RTy->getElementCount());
        Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, ShufTy);
        if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2))
          return error("Invalid shufflevector operands");
        SmallVector<int, 16> Mask;
        ShuffleVectorInst::getShuffleMask(Op2, Mask);
        Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask);
        ValueList.assignValue(V, CstNo);
      }
      for (auto &DelayedSelector : DelayedSelectors) {
        Type *OpTy = DelayedSelector.OpTy;
        Type *SelectorTy = Type::getInt1Ty(Context);
        uint64_t Op0Idx = DelayedSelector.Op0Idx;
        uint64_t Op1Idx = DelayedSelector.Op1Idx;
        uint64_t Op2Idx = DelayedSelector.Op2Idx;
        uint64_t CstNo = DelayedSelector.CstNo;
        Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy);
        Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, OpTy);
        // The selector might be an i1 or an <n x i1>
        // Get the type from the ValueList before getting a forward ref.
        if (VectorType *VTy = dyn_cast<VectorType>(OpTy)) {
          Value *V = ValueList[Op0Idx];
          assert(V);
          if (SelectorTy != V->getType())
            SelectorTy = VectorType::get(SelectorTy, VTy->getElementCount());
        }
        Constant *Op0 = ValueList.getConstantFwdRef(Op0Idx, SelectorTy);
        Value *V = ConstantExpr::getSelect(Op0, Op1, Op2);
        ValueList.assignValue(V, CstNo);
      }

      if (NextCstNo != ValueList.size())
        return error("Invalid constant reference");

      ValueList.resolveConstantForwardRefs();
      return Error::success();
    case BitstreamEntry::Record:
      // The interesting case.
      break;
    }

    // Read a record.
    Record.clear();
    Type *VoidType = Type::getVoidTy(Context);
    Value *V = nullptr;
    Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record);
    if (!MaybeBitCode)
      return MaybeBitCode.takeError();
    switch (unsigned BitCode = MaybeBitCode.get()) {
    default:  // Default behavior: unknown constant
    case bitc::CST_CODE_UNDEF:     // UNDEF
      V = UndefValue::get(CurTy);
      break;
    case bitc::CST_CODE_POISON:    // POISON
      V = PoisonValue::get(CurTy);
      break;
    case bitc::CST_CODE_SETTYPE:   // SETTYPE: [typeid]
      if (Record.empty())
        return error("Invalid record");
      if (Record[0] >= TypeList.size() || !TypeList[Record[0]])
        return error("Invalid record");
      if (TypeList[Record[0]] == VoidType)
        return error("Invalid constant type");
      CurTy = TypeList[Record[0]];
      continue;  // Skip the ValueList manipulation.
    case bitc::CST_CODE_NULL:      // NULL
      if (CurTy->isVoidTy() || CurTy->isFunctionTy() || CurTy->isLabelTy())
        return error("Invalid type for a constant null value");
      V = Constant::getNullValue(CurTy);
      break;
    case bitc::CST_CODE_INTEGER:   // INTEGER: [intval]
      if (!CurTy->isIntegerTy() || Record.empty())
        return error("Invalid record");
      V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0]));
      break;
    case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval]
      if (!CurTy->isIntegerTy() || Record.empty())
        return error("Invalid record");

      APInt VInt =
          readWideAPInt(Record, cast<IntegerType>(CurTy)->getBitWidth());
      V = ConstantInt::get(Context, VInt);

      break;
    }
    case bitc::CST_CODE_FLOAT: {    // FLOAT: [fpval]
      if (Record.empty())
        return error("Invalid record");
      if (CurTy->isHalfTy())
        V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf(),
                                             APInt(16, (uint16_t)Record[0])));
      else if (CurTy->isBFloatTy())
        V = ConstantFP::get(Context, APFloat(APFloat::BFloat(),
                                             APInt(16, (uint32_t)Record[0])));
      else if (CurTy->isFloatTy())
        V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle(),
                                             APInt(32, (uint32_t)Record[0])));
      else if (CurTy->isDoubleTy())
        V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble(),
                                             APInt(64, Record[0])));
      else if (CurTy->isX86_FP80Ty()) {
        // Bits are not stored the same way as a normal i80 APInt, compensate.
        uint64_t Rearrange[2];
        Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16);
        Rearrange[1] = Record[0] >> 48;
        V = ConstantFP::get(Context, APFloat(APFloat::x87DoubleExtended(),
                                             APInt(80, Rearrange)));
      } else if (CurTy->isFP128Ty())
        V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad(),
                                             APInt(128, Record)));
      else if (CurTy->isPPC_FP128Ty())
        V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble(),
                                             APInt(128, Record)));
      else
        V = UndefValue::get(CurTy);
      break;
    }

    case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n x value number]
      if (Record.empty())
        return error("Invalid record");

      unsigned Size = Record.size();
      SmallVector<Constant*, 16> Elts;

      if (StructType *STy = dyn_cast<StructType>(CurTy)) {
        for (unsigned i = 0; i != Size; ++i)
          Elts.push_back(ValueList.getConstantFwdRef(Record[i],
                                                     STy->getElementType(i)));
        V = ConstantStruct::get(STy, Elts);
      } else if (ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) {
        Type *EltTy = ATy->getElementType();
        for (unsigned i = 0; i != Size; ++i)
          Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy));
        V = ConstantArray::get(ATy, Elts);
      } else if (VectorType *VTy = dyn_cast<VectorType>(CurTy)) {
        Type *EltTy = VTy->getElementType();
        for (unsigned i = 0; i != Size; ++i)
          Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy));
        V = ConstantVector::get(Elts);
      } else {
        V = UndefValue::get(CurTy);
      }
      break;
    }
    case bitc::CST_CODE_STRING:    // STRING: [values]
    case bitc::CST_CODE_CSTRING: { // CSTRING: [values]
      if (Record.empty())
        return error("Invalid record");

      SmallString<16> Elts(Record.begin(), Record.end());
      V = ConstantDataArray::getString(Context, Elts,
                                       BitCode == bitc::CST_CODE_CSTRING);
      break;
    }
    case bitc::CST_CODE_DATA: {// DATA: [n x value]
      if (Record.empty())
        return error("Invalid record");

      Type *EltTy;
      if (auto *Array = dyn_cast<ArrayType>(CurTy))
        EltTy = Array->getElementType();
      else
        EltTy = cast<VectorType>(CurTy)->getElementType();
      if (EltTy->isIntegerTy(8)) {
        SmallVector<uint8_t, 16> Elts(Record.begin(), Record.end());
        if (isa<VectorType>(CurTy))
          V = ConstantDataVector::get(Context, Elts);
        else
          V = ConstantDataArray::get(Context, Elts);
      } else if (EltTy->isIntegerTy(16)) {
        SmallVector<uint16_t, 16> Elts(Record.begin(), Record.end());
        if (isa<VectorType>(CurTy))
          V = ConstantDataVector::get(Context, Elts);
        else
          V = ConstantDataArray::get(Context, Elts);
      } else if (EltTy->isIntegerTy(32)) {
        SmallVector<uint32_t, 16> Elts(Record.begin(), Record.end());
        if (isa<VectorType>(CurTy))
          V = ConstantDataVector::get(Context, Elts);
        else
          V = ConstantDataArray::get(Context, Elts);
      } else if (EltTy->isIntegerTy(64)) {
        SmallVector<uint64_t, 16> Elts(Record.begin(), Record.end());
        if (isa<VectorType>(CurTy))
          V = ConstantDataVector::get(Context, Elts);
        else
          V = ConstantDataArray::get(Context, Elts);
      } else if (EltTy->isHalfTy()) {
        SmallVector<uint16_t, 16> Elts(Record.begin(), Record.end());
        if (isa<VectorType>(CurTy))
          V = ConstantDataVector::getFP(EltTy, Elts);
        else
          V = ConstantDataArray::getFP(EltTy, Elts);
      } else if (EltTy->isBFloatTy()) {
        SmallVector<uint16_t, 16> Elts(Record.begin(), Record.end());
        if (isa<VectorType>(CurTy))
          V = ConstantDataVector::getFP(EltTy, Elts);
        else
          V = ConstantDataArray::getFP(EltTy, Elts);
      } else if (EltTy->isFloatTy()) {
        SmallVector<uint32_t, 16> Elts(Record.begin(), Record.end());
        if (isa<VectorType>(CurTy))
          V = ConstantDataVector::getFP(EltTy, Elts);
        else
          V = ConstantDataArray::getFP(EltTy, Elts);
      } else if (EltTy->isDoubleTy()) {
        SmallVector<uint64_t, 16> Elts(Record.begin(), Record.end());
        if (isa<VectorType>(CurTy))
          V = ConstantDataVector::getFP(EltTy, Elts);
        else
          V = ConstantDataArray::getFP(EltTy, Elts);
      } else {
        return error("Invalid type for value");
      }
      break;
    }
    case bitc::CST_CODE_CE_UNOP: {  // CE_UNOP: [opcode, opval]
      if (Record.size() < 2)
        return error("Invalid record");
      int Opc = getDecodedUnaryOpcode(Record[0], CurTy);
      if (Opc < 0) {
        V = UndefValue::get(CurTy);  // Unknown unop.
      } else {
        Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
        unsigned Flags = 0;
        V = ConstantExpr::get(Opc, LHS, Flags);
      }
      break;
    }
    case bitc::CST_CODE_CE_BINOP: {  // CE_BINOP: [opcode, opval, opval]
      if (Record.size() < 3)
        return error("Invalid record");
      int Opc = getDecodedBinaryOpcode(Record[0], CurTy);
      if (Opc < 0) {
        V = UndefValue::get(CurTy);  // Unknown binop.
      } else {
        Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
        Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
        unsigned Flags = 0;
        if (Record.size() >= 4) {
          if (Opc == Instruction::Add ||
              Opc == Instruction::Sub ||
              Opc == Instruction::Mul ||
              Opc == Instruction::Shl) {
            if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
              Flags |= OverflowingBinaryOperator::NoSignedWrap;
            if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
              Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
          } else if (Opc == Instruction::SDiv ||
                     Opc == Instruction::UDiv ||
                     Opc == Instruction::LShr ||
                     Opc == Instruction::AShr) {
            if (Record[3] & (1 << bitc::PEO_EXACT))
              Flags |= SDivOperator::IsExact;
          }
        }
        V = ConstantExpr::get(Opc, LHS, RHS, Flags);
      }
      break;
    }
    case bitc::CST_CODE_CE_CAST: {  // CE_CAST: [opcode, opty, opval]
      if (Record.size() < 3)
        return error("Invalid record");
      int Opc = getDecodedCastOpcode(Record[0]);
      if (Opc < 0) {
        V = UndefValue::get(CurTy);  // Unknown cast.
      } else {
        Type *OpTy = getTypeByID(Record[1]);
        if (!OpTy)
          return error("Invalid record");
        Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
        V = UpgradeBitCastExpr(Opc, Op, CurTy);
        if (!V) V = ConstantExpr::getCast(Opc, Op, CurTy);
      }
      break;
    }
    case bitc::CST_CODE_CE_INBOUNDS_GEP: // [ty, n x operands]
    case bitc::CST_CODE_CE_GEP: // [ty, n x operands]
    case bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX: { // [ty, flags, n x
                                                     // operands]
      unsigned OpNum = 0;
      Type *PointeeType = nullptr;
      if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX ||
          Record.size() % 2)
        PointeeType = getTypeByID(Record[OpNum++]);

      bool InBounds = false;
      Optional<unsigned> InRangeIndex;
      if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX) {
        uint64_t Op = Record[OpNum++];
        InBounds = Op & 1;
        InRangeIndex = Op >> 1;
      } else if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP)
        InBounds = true;

      SmallVector<Constant*, 16> Elts;
      Type *Elt0FullTy = nullptr;
      while (OpNum != Record.size()) {
        if (!Elt0FullTy)
          Elt0FullTy = getTypeByID(Record[OpNum]);
        Type *ElTy = getTypeByID(Record[OpNum++]);
        if (!ElTy)
          return error("Invalid record");
        Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy));
      }

      if (Elts.size() < 1)
        return error("Invalid gep with no operands");

      PointerType *OrigPtrTy = cast<PointerType>(Elt0FullTy->getScalarType());
      if (!PointeeType)
        PointeeType = OrigPtrTy->getElementType();
      else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType))
        return error("Explicit gep operator type does not match pointee type "
                     "of pointer operand");

      ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
      V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices,
                                         InBounds, InRangeIndex);
      break;
    }
    case bitc::CST_CODE_CE_SELECT: {  // CE_SELECT: [opval#, opval#, opval#]
      if (Record.size() < 3)
        return error("Invalid record");

      DelayedSelectors.push_back(
          {CurTy, Record[0], Record[1], Record[2], NextCstNo});
      (void)ValueList.getConstantFwdRef(NextCstNo, CurTy);
      ++NextCstNo;
      continue;
    }
    case bitc::CST_CODE_CE_EXTRACTELT
        : { // CE_EXTRACTELT: [opty, opval, opty, opval]
      if (Record.size() < 3)
        return error("Invalid record");
      VectorType *OpTy =
        dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
      if (!OpTy)
        return error("Invalid record");
      Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
      Constant *Op1 = nullptr;
      if (Record.size() == 4) {
        Type *IdxTy = getTypeByID(Record[2]);
        if (!IdxTy)
          return error("Invalid record");
        Op1 = ValueList.getConstantFwdRef(Record[3], IdxTy);
      } else {
        // Deprecated, but still needed to read old bitcode files.
        Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
      }
      if (!Op1)
        return error("Invalid record");
      V = ConstantExpr::getExtractElement(Op0, Op1);
      break;
    }
    case bitc::CST_CODE_CE_INSERTELT
        : { // CE_INSERTELT: [opval, opval, opty, opval]
      VectorType *OpTy = dyn_cast<VectorType>(CurTy);
      if (Record.size() < 3 || !OpTy)
        return error("Invalid record");
      Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
      Constant *Op1 = ValueList.getConstantFwdRef(Record[1],
                                                  OpTy->getElementType());
      Constant *Op2 = nullptr;
      if (Record.size() == 4) {
        Type *IdxTy = getTypeByID(Record[2]);
        if (!IdxTy)
          return error("Invalid record");
        Op2 = ValueList.getConstantFwdRef(Record[3], IdxTy);
      } else {
        // Deprecated, but still needed to read old bitcode files.
        Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
      }
      if (!Op2)
        return error("Invalid record");
      V = ConstantExpr::getInsertElement(Op0, Op1, Op2);
      break;
    }
    case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval]
      VectorType *OpTy = dyn_cast<VectorType>(CurTy);
      if (Record.size() < 3 || !OpTy)
        return error("Invalid record");
      DelayedShuffles.push_back(
          {OpTy, OpTy, Record[0], Record[1], Record[2], NextCstNo});
      ++NextCstNo;
      continue;
    }
    case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval]
      VectorType *RTy = dyn_cast<VectorType>(CurTy);
      VectorType *OpTy =
        dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
      if (Record.size() < 4 || !RTy || !OpTy)
        return error("Invalid record");
      DelayedShuffles.push_back(
          {OpTy, RTy, Record[1], Record[2], Record[3], NextCstNo});
      ++NextCstNo;
      continue;
    }
    case bitc::CST_CODE_CE_CMP: {     // CE_CMP: [opty, opval, opval, pred]
      if (Record.size() < 4)
        return error("Invalid record");
      Type *OpTy = getTypeByID(Record[0]);
      if (!OpTy)
        return error("Invalid record");
      Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
      Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);

      if (OpTy->isFPOrFPVectorTy())
        V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
      else
        V = ConstantExpr::getICmp(Record[3], Op0, Op1);
      break;
    }
    // This maintains backward compatibility, pre-asm dialect keywords.
    // Deprecated, but still needed to read old bitcode files.
    case bitc::CST_CODE_INLINEASM_OLD: {
      if (Record.size() < 2)
        return error("Invalid record");
      std::string AsmStr, ConstrStr;
      bool HasSideEffects = Record[0] & 1;
      bool IsAlignStack = Record[0] >> 1;
      unsigned AsmStrSize = Record[1];
      if (2+AsmStrSize >= Record.size())
        return error("Invalid record");
      unsigned ConstStrSize = Record[2+AsmStrSize];
      if (3+AsmStrSize+ConstStrSize > Record.size())
        return error("Invalid record");

      for (unsigned i = 0; i != AsmStrSize; ++i)
        AsmStr += (char)Record[2+i];
      for (unsigned i = 0; i != ConstStrSize; ++i)
        ConstrStr += (char)Record[3+AsmStrSize+i];
      UpgradeInlineAsmString(&AsmStr);
      // FIXME: support upgrading in opaque pointers mode.
      V = InlineAsm::get(
          cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()),
          AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
      break;
    }
    // This version adds support for the asm dialect keywords (e.g.,
    // inteldialect).
    case bitc::CST_CODE_INLINEASM_OLD2: {
      if (Record.size() < 2)
        return error("Invalid record");
      std::string AsmStr, ConstrStr;
      bool HasSideEffects = Record[0] & 1;
      bool IsAlignStack = (Record[0] >> 1) & 1;
      unsigned AsmDialect = Record[0] >> 2;
      unsigned AsmStrSize = Record[1];
      if (2+AsmStrSize >= Record.size())
        return error("Invalid record");
      unsigned ConstStrSize = Record[2+AsmStrSize];
      if (3+AsmStrSize+ConstStrSize > Record.size())
        return error("Invalid record");

      for (unsigned i = 0; i != AsmStrSize; ++i)
        AsmStr += (char)Record[2+i];
      for (unsigned i = 0; i != ConstStrSize; ++i)
        ConstrStr += (char)Record[3+AsmStrSize+i];
      UpgradeInlineAsmString(&AsmStr);
      // FIXME: support upgrading in opaque pointers mode.
      V = InlineAsm::get(
          cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()),
          AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
          InlineAsm::AsmDialect(AsmDialect));
      break;
    }
    // This version adds support for the unwind keyword.
    case bitc::CST_CODE_INLINEASM_OLD3: {
      if (Record.size() < 2)
        return error("Invalid record");
      unsigned OpNum = 0;
      std::string AsmStr, ConstrStr;
      bool HasSideEffects = Record[OpNum] & 1;
      bool IsAlignStack = (Record[OpNum] >> 1) & 1;
      unsigned AsmDialect = (Record[OpNum] >> 2) & 1;
      bool CanThrow = (Record[OpNum] >> 3) & 1;
      ++OpNum;
      unsigned AsmStrSize = Record[OpNum];
      ++OpNum;
      if (OpNum + AsmStrSize >= Record.size())
        return error("Invalid record");
      unsigned ConstStrSize = Record[OpNum + AsmStrSize];
      if (OpNum + 1 + AsmStrSize + ConstStrSize > Record.size())
        return error("Invalid record");

      for (unsigned i = 0; i != AsmStrSize; ++i)
        AsmStr += (char)Record[OpNum + i];
      ++OpNum;
      for (unsigned i = 0; i != ConstStrSize; ++i)
        ConstrStr += (char)Record[OpNum + AsmStrSize + i];
      UpgradeInlineAsmString(&AsmStr);
      // FIXME: support upgrading in opaque pointers mode.
      V = InlineAsm::get(
          cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()),
          AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
          InlineAsm::AsmDialect(AsmDialect), CanThrow);
      break;
    }
    // This version adds explicit function type.
    case bitc::CST_CODE_INLINEASM: {
      if (Record.size() < 3)
        return error("Invalid record");
      unsigned OpNum = 0;
      auto *FnTy = dyn_cast_or_null<FunctionType>(getTypeByID(Record[OpNum]));
      ++OpNum;
      if (!FnTy)
        return error("Invalid record");
      std::string AsmStr, ConstrStr;
      bool HasSideEffects = Record[OpNum] & 1;
      bool IsAlignStack = (Record[OpNum] >> 1) & 1;
      unsigned AsmDialect = (Record[OpNum] >> 2) & 1;
      bool CanThrow = (Record[OpNum] >> 3) & 1;
      ++OpNum;
      unsigned AsmStrSize = Record[OpNum];
      ++OpNum;
      if (OpNum + AsmStrSize >= Record.size())
        return error("Invalid record");
      unsigned ConstStrSize = Record[OpNum + AsmStrSize];
      if (OpNum + 1 + AsmStrSize + ConstStrSize > Record.size())
        return error("Invalid record");

      for (unsigned i = 0; i != AsmStrSize; ++i)
        AsmStr += (char)Record[OpNum + i];
      ++OpNum;
      for (unsigned i = 0; i != ConstStrSize; ++i)
        ConstrStr += (char)Record[OpNum + AsmStrSize + i];
      UpgradeInlineAsmString(&AsmStr);
      V = InlineAsm::get(FnTy, AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
                         InlineAsm::AsmDialect(AsmDialect), CanThrow);
      break;
    }
    case bitc::CST_CODE_BLOCKADDRESS:{
      if (Record.size() < 3)
        return error("Invalid record");
      Type *FnTy = getTypeByID(Record[0]);
      if (!FnTy)
        return error("Invalid record");
      Function *Fn =
        dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
      if (!Fn)
        return error("Invalid record");

      // If the function is already parsed we can insert the block address right
      // away.
      BasicBlock *BB;
      unsigned BBID = Record[2];
      if (!BBID)
        // Invalid reference to entry block.
        return error("Invalid ID");
      if (!Fn->empty()) {
        Function::iterator BBI = Fn->begin(), BBE = Fn->end();
        for (size_t I = 0, E = BBID; I != E; ++I) {
          if (BBI == BBE)
            return error("Invalid ID");
          ++BBI;
        }
        BB = &*BBI;
      } else {
        // Otherwise insert a placeholder and remember it so it can be inserted
        // when the function is parsed.
        auto &FwdBBs = BasicBlockFwdRefs[Fn];
        if (FwdBBs.empty())
          BasicBlockFwdRefQueue.push_back(Fn);
        if (FwdBBs.size() < BBID + 1)
          FwdBBs.resize(BBID + 1);
        if (!FwdBBs[BBID])
          FwdBBs[BBID] = BasicBlock::Create(Context);
        BB = FwdBBs[BBID];
      }
      V = BlockAddress::get(Fn, BB);
      break;
    }
    case bitc::CST_CODE_DSO_LOCAL_EQUIVALENT: {
      if (Record.size() < 2)
        return error("Invalid record");
      Type *GVTy = getTypeByID(Record[0]);
      if (!GVTy)
        return error("Invalid record");
      GlobalValue *GV = dyn_cast_or_null<GlobalValue>(
          ValueList.getConstantFwdRef(Record[1], GVTy));
      if (!GV)
        return error("Invalid record");

      V = DSOLocalEquivalent::get(GV);
      break;
    }
    case bitc::CST_CODE_NO_CFI_VALUE: {
      if (Record.size() < 2)
        return error("Invalid record");
      Type *GVTy = getTypeByID(Record[0]);
      if (!GVTy)
        return error("Invalid record");
      GlobalValue *GV = dyn_cast_or_null<GlobalValue>(
          ValueList.getConstantFwdRef(Record[1], GVTy));
      if (!GV)
        return error("Invalid record");
      V = NoCFIValue::get(GV);
      break;
    }
    }

    ValueList.assignValue(V, NextCstNo);
    ++NextCstNo;
  }
}