Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata()

in llvm/lib/Bitcode/Reader/MetadataLoader.cpp [1137:2121]


Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
    SmallVectorImpl<uint64_t> &Record, unsigned Code,
    PlaceholderQueue &Placeholders, StringRef Blob, unsigned &NextMetadataNo) {

  bool IsDistinct = false;
  auto getMD = [&](unsigned ID) -> Metadata * {
    if (ID < MDStringRef.size())
      return lazyLoadOneMDString(ID);
    if (!IsDistinct) {
      if (auto *MD = MetadataList.lookup(ID))
        return MD;
      // If lazy-loading is enabled, we try recursively to load the operand
      // instead of creating a temporary.
      if (ID < (MDStringRef.size() + GlobalMetadataBitPosIndex.size())) {
        // Create a temporary for the node that is referencing the operand we
        // will lazy-load. It is needed before recursing in case there are
        // uniquing cycles.
        MetadataList.getMetadataFwdRef(NextMetadataNo);
        lazyLoadOneMetadata(ID, Placeholders);
        return MetadataList.lookup(ID);
      }
      // Return a temporary.
      return MetadataList.getMetadataFwdRef(ID);
    }
    if (auto *MD = MetadataList.getMetadataIfResolved(ID))
      return MD;
    return &Placeholders.getPlaceholderOp(ID);
  };
  auto getMDOrNull = [&](unsigned ID) -> Metadata * {
    if (ID)
      return getMD(ID - 1);
    return nullptr;
  };
  auto getMDOrNullWithoutPlaceholders = [&](unsigned ID) -> Metadata * {
    if (ID)
      return MetadataList.getMetadataFwdRef(ID - 1);
    return nullptr;
  };
  auto getMDString = [&](unsigned ID) -> MDString * {
    // This requires that the ID is not really a forward reference.  In
    // particular, the MDString must already have been resolved.
    auto MDS = getMDOrNull(ID);
    return cast_or_null<MDString>(MDS);
  };

  // Support for old type refs.
  auto getDITypeRefOrNull = [&](unsigned ID) {
    return MetadataList.upgradeTypeRef(getMDOrNull(ID));
  };

#define GET_OR_DISTINCT(CLASS, ARGS)                                           \
  (IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)

  switch (Code) {
  default: // Default behavior: ignore.
    break;
  case bitc::METADATA_NAME: {
    // Read name of the named metadata.
    SmallString<8> Name(Record.begin(), Record.end());
    Record.clear();
    if (Error E = Stream.ReadCode().moveInto(Code))
      return E;

    ++NumMDRecordLoaded;
    if (Expected<unsigned> MaybeNextBitCode = Stream.readRecord(Code, Record)) {
      if (MaybeNextBitCode.get() != bitc::METADATA_NAMED_NODE)
        return error("METADATA_NAME not followed by METADATA_NAMED_NODE");
    } else
      return MaybeNextBitCode.takeError();

    // Read named metadata elements.
    unsigned Size = Record.size();
    NamedMDNode *NMD = TheModule.getOrInsertNamedMetadata(Name);
    for (unsigned i = 0; i != Size; ++i) {
      MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[i]);
      if (!MD)
        return error("Invalid named metadata: expect fwd ref to MDNode");
      NMD->addOperand(MD);
    }
    break;
  }
  case bitc::METADATA_OLD_FN_NODE: {
    // Deprecated, but still needed to read old bitcode files.
    // This is a LocalAsMetadata record, the only type of function-local
    // metadata.
    if (Record.size() % 2 == 1)
      return error("Invalid record");

    // If this isn't a LocalAsMetadata record, we're dropping it.  This used
    // to be legal, but there's no upgrade path.
    auto dropRecord = [&] {
      MetadataList.assignValue(MDNode::get(Context, None), NextMetadataNo);
      NextMetadataNo++;
    };
    if (Record.size() != 2) {
      dropRecord();
      break;
    }

    Type *Ty = getTypeByID(Record[0]);
    if (Ty->isMetadataTy() || Ty->isVoidTy()) {
      dropRecord();
      break;
    }

    MetadataList.assignValue(
        LocalAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_OLD_NODE: {
    // Deprecated, but still needed to read old bitcode files.
    if (Record.size() % 2 == 1)
      return error("Invalid record");

    unsigned Size = Record.size();
    SmallVector<Metadata *, 8> Elts;
    for (unsigned i = 0; i != Size; i += 2) {
      Type *Ty = getTypeByID(Record[i]);
      if (!Ty)
        return error("Invalid record");
      if (Ty->isMetadataTy())
        Elts.push_back(getMD(Record[i + 1]));
      else if (!Ty->isVoidTy()) {
        auto *MD =
            ValueAsMetadata::get(ValueList.getValueFwdRef(Record[i + 1], Ty));
        assert(isa<ConstantAsMetadata>(MD) &&
               "Expected non-function-local metadata");
        Elts.push_back(MD);
      } else
        Elts.push_back(nullptr);
    }
    MetadataList.assignValue(MDNode::get(Context, Elts), NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_VALUE: {
    if (Record.size() != 2)
      return error("Invalid record");

    Type *Ty = getTypeByID(Record[0]);
    if (Ty->isMetadataTy() || Ty->isVoidTy())
      return error("Invalid record");

    MetadataList.assignValue(
        ValueAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_DISTINCT_NODE:
    IsDistinct = true;
    LLVM_FALLTHROUGH;
  case bitc::METADATA_NODE: {
    SmallVector<Metadata *, 8> Elts;
    Elts.reserve(Record.size());
    for (unsigned ID : Record)
      Elts.push_back(getMDOrNull(ID));
    MetadataList.assignValue(IsDistinct ? MDNode::getDistinct(Context, Elts)
                                        : MDNode::get(Context, Elts),
                             NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_LOCATION: {
    if (Record.size() != 5 && Record.size() != 6)
      return error("Invalid record");

    IsDistinct = Record[0];
    unsigned Line = Record[1];
    unsigned Column = Record[2];
    Metadata *Scope = getMD(Record[3]);
    Metadata *InlinedAt = getMDOrNull(Record[4]);
    bool ImplicitCode = Record.size() == 6 && Record[5];
    MetadataList.assignValue(
        GET_OR_DISTINCT(DILocation, (Context, Line, Column, Scope, InlinedAt,
                                     ImplicitCode)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_GENERIC_DEBUG: {
    if (Record.size() < 4)
      return error("Invalid record");

    IsDistinct = Record[0];
    unsigned Tag = Record[1];
    unsigned Version = Record[2];

    if (Tag >= 1u << 16 || Version != 0)
      return error("Invalid record");

    auto *Header = getMDString(Record[3]);
    SmallVector<Metadata *, 8> DwarfOps;
    for (unsigned I = 4, E = Record.size(); I != E; ++I)
      DwarfOps.push_back(getMDOrNull(Record[I]));
    MetadataList.assignValue(
        GET_OR_DISTINCT(GenericDINode, (Context, Tag, Header, DwarfOps)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_SUBRANGE: {
    Metadata *Val = nullptr;
    // Operand 'count' is interpreted as:
    // - Signed integer (version 0)
    // - Metadata node  (version 1)
    // Operand 'lowerBound' is interpreted as:
    // - Signed integer (version 0 and 1)
    // - Metadata node  (version 2)
    // Operands 'upperBound' and 'stride' are interpreted as:
    // - Metadata node  (version 2)
    switch (Record[0] >> 1) {
    case 0:
      Val = GET_OR_DISTINCT(DISubrange,
                            (Context, Record[1], unrotateSign(Record[2])));
      break;
    case 1:
      Val = GET_OR_DISTINCT(DISubrange, (Context, getMDOrNull(Record[1]),
                                         unrotateSign(Record[2])));
      break;
    case 2:
      Val = GET_OR_DISTINCT(
          DISubrange, (Context, getMDOrNull(Record[1]), getMDOrNull(Record[2]),
                       getMDOrNull(Record[3]), getMDOrNull(Record[4])));
      break;
    default:
      return error("Invalid record: Unsupported version of DISubrange");
    }

    MetadataList.assignValue(Val, NextMetadataNo);
    IsDistinct = Record[0] & 1;
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_GENERIC_SUBRANGE: {
    Metadata *Val = nullptr;
    Val = GET_OR_DISTINCT(DIGenericSubrange,
                          (Context, getMDOrNull(Record[1]),
                           getMDOrNull(Record[2]), getMDOrNull(Record[3]),
                           getMDOrNull(Record[4])));

    MetadataList.assignValue(Val, NextMetadataNo);
    IsDistinct = Record[0] & 1;
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_ENUMERATOR: {
    if (Record.size() < 3)
      return error("Invalid record");

    IsDistinct = Record[0] & 1;
    bool IsUnsigned = Record[0] & 2;
    bool IsBigInt = Record[0] & 4;
    APInt Value;

    if (IsBigInt) {
      const uint64_t BitWidth = Record[1];
      const size_t NumWords = Record.size() - 3;
      Value = readWideAPInt(makeArrayRef(&Record[3], NumWords), BitWidth);
    } else
      Value = APInt(64, unrotateSign(Record[1]), !IsUnsigned);

    MetadataList.assignValue(
        GET_OR_DISTINCT(DIEnumerator,
                        (Context, Value, IsUnsigned, getMDString(Record[2]))),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_BASIC_TYPE: {
    if (Record.size() < 6 || Record.size() > 7)
      return error("Invalid record");

    IsDistinct = Record[0];
    DINode::DIFlags Flags = (Record.size() > 6)
                                ? static_cast<DINode::DIFlags>(Record[6])
                                : DINode::FlagZero;

    MetadataList.assignValue(
        GET_OR_DISTINCT(DIBasicType,
                        (Context, Record[1], getMDString(Record[2]), Record[3],
                         Record[4], Record[5], Flags)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_STRING_TYPE: {
    if (Record.size() != 8)
      return error("Invalid record");

    IsDistinct = Record[0];
    MetadataList.assignValue(
        GET_OR_DISTINCT(DIStringType,
                        (Context, Record[1], getMDString(Record[2]),
                         getMDOrNull(Record[3]), getMDOrNull(Record[4]),
                         Record[5], Record[6], Record[7])),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_DERIVED_TYPE: {
    if (Record.size() < 12 || Record.size() > 14)
      return error("Invalid record");

    // DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means
    // that there is no DWARF address space associated with DIDerivedType.
    Optional<unsigned> DWARFAddressSpace;
    if (Record.size() > 12 && Record[12])
      DWARFAddressSpace = Record[12] - 1;

    Metadata *Annotations = nullptr;
    if (Record.size() > 13 && Record[13])
      Annotations = getMDOrNull(Record[13]);

    IsDistinct = Record[0];
    DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
    MetadataList.assignValue(
        GET_OR_DISTINCT(DIDerivedType,
                        (Context, Record[1], getMDString(Record[2]),
                         getMDOrNull(Record[3]), Record[4],
                         getDITypeRefOrNull(Record[5]),
                         getDITypeRefOrNull(Record[6]), Record[7], Record[8],
                         Record[9], DWARFAddressSpace, Flags,
                         getDITypeRefOrNull(Record[11]), Annotations)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_COMPOSITE_TYPE: {
    if (Record.size() < 16 || Record.size() > 22)
      return error("Invalid record");

    // If we have a UUID and this is not a forward declaration, lookup the
    // mapping.
    IsDistinct = Record[0] & 0x1;
    bool IsNotUsedInTypeRef = Record[0] >= 2;
    unsigned Tag = Record[1];
    MDString *Name = getMDString(Record[2]);
    Metadata *File = getMDOrNull(Record[3]);
    unsigned Line = Record[4];
    Metadata *Scope = getDITypeRefOrNull(Record[5]);
    Metadata *BaseType = nullptr;
    uint64_t SizeInBits = Record[7];
    if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
      return error("Alignment value is too large");
    uint32_t AlignInBits = Record[8];
    uint64_t OffsetInBits = 0;
    DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
    Metadata *Elements = nullptr;
    unsigned RuntimeLang = Record[12];
    Metadata *VTableHolder = nullptr;
    Metadata *TemplateParams = nullptr;
    Metadata *Discriminator = nullptr;
    Metadata *DataLocation = nullptr;
    Metadata *Associated = nullptr;
    Metadata *Allocated = nullptr;
    Metadata *Rank = nullptr;
    Metadata *Annotations = nullptr;
    auto *Identifier = getMDString(Record[15]);
    // If this module is being parsed so that it can be ThinLTO imported
    // into another module, composite types only need to be imported
    // as type declarations (unless full type definitions requested).
    // Create type declarations up front to save memory. Also, buildODRType
    // handles the case where this is type ODRed with a definition needed
    // by the importing module, in which case the existing definition is
    // used.
    if (IsImporting && !ImportFullTypeDefinitions && Identifier &&
        (Tag == dwarf::DW_TAG_enumeration_type ||
         Tag == dwarf::DW_TAG_class_type ||
         Tag == dwarf::DW_TAG_structure_type ||
         Tag == dwarf::DW_TAG_union_type)) {
      Flags = Flags | DINode::FlagFwdDecl;
    } else {
      BaseType = getDITypeRefOrNull(Record[6]);
      OffsetInBits = Record[9];
      Elements = getMDOrNull(Record[11]);
      VTableHolder = getDITypeRefOrNull(Record[13]);
      TemplateParams = getMDOrNull(Record[14]);
      if (Record.size() > 16)
        Discriminator = getMDOrNull(Record[16]);
      if (Record.size() > 17)
        DataLocation = getMDOrNull(Record[17]);
      if (Record.size() > 19) {
        Associated = getMDOrNull(Record[18]);
        Allocated = getMDOrNull(Record[19]);
      }
      if (Record.size() > 20) {
        Rank = getMDOrNull(Record[20]);
      }
      if (Record.size() > 21) {
        Annotations = getMDOrNull(Record[21]);
      }
    }
    DICompositeType *CT = nullptr;
    if (Identifier)
      CT = DICompositeType::buildODRType(
          Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
          SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
          VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
          Allocated, Rank, Annotations);

    // Create a node if we didn't get a lazy ODR type.
    if (!CT)
      CT = GET_OR_DISTINCT(DICompositeType,
                           (Context, Tag, Name, File, Line, Scope, BaseType,
                            SizeInBits, AlignInBits, OffsetInBits, Flags,
                            Elements, RuntimeLang, VTableHolder, TemplateParams,
                            Identifier, Discriminator, DataLocation, Associated,
                            Allocated, Rank, Annotations));
    if (!IsNotUsedInTypeRef && Identifier)
      MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));

    MetadataList.assignValue(CT, NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_SUBROUTINE_TYPE: {
    if (Record.size() < 3 || Record.size() > 4)
      return error("Invalid record");
    bool IsOldTypeRefArray = Record[0] < 2;
    unsigned CC = (Record.size() > 3) ? Record[3] : 0;

    IsDistinct = Record[0] & 0x1;
    DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[1]);
    Metadata *Types = getMDOrNull(Record[2]);
    if (LLVM_UNLIKELY(IsOldTypeRefArray))
      Types = MetadataList.upgradeTypeRefArray(Types);

    MetadataList.assignValue(
        GET_OR_DISTINCT(DISubroutineType, (Context, Flags, CC, Types)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }

  case bitc::METADATA_MODULE: {
    if (Record.size() < 5 || Record.size() > 9)
      return error("Invalid record");

    unsigned Offset = Record.size() >= 8 ? 2 : 1;
    IsDistinct = Record[0];
    MetadataList.assignValue(
        GET_OR_DISTINCT(
            DIModule,
            (Context, Record.size() >= 8 ? getMDOrNull(Record[1]) : nullptr,
             getMDOrNull(Record[0 + Offset]), getMDString(Record[1 + Offset]),
             getMDString(Record[2 + Offset]), getMDString(Record[3 + Offset]),
             getMDString(Record[4 + Offset]),
             Record.size() <= 7 ? 0 : Record[7],
             Record.size() <= 8 ? false : Record[8])),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }

  case bitc::METADATA_FILE: {
    if (Record.size() != 3 && Record.size() != 5 && Record.size() != 6)
      return error("Invalid record");

    IsDistinct = Record[0];
    Optional<DIFile::ChecksumInfo<MDString *>> Checksum;
    // The BitcodeWriter writes null bytes into Record[3:4] when the Checksum
    // is not present. This matches up with the old internal representation,
    // and the old encoding for CSK_None in the ChecksumKind. The new
    // representation reserves the value 0 in the ChecksumKind to continue to
    // encode None in a backwards-compatible way.
    if (Record.size() > 4 && Record[3] && Record[4])
      Checksum.emplace(static_cast<DIFile::ChecksumKind>(Record[3]),
                       getMDString(Record[4]));
    MetadataList.assignValue(
        GET_OR_DISTINCT(
            DIFile,
            (Context, getMDString(Record[1]), getMDString(Record[2]), Checksum,
             Record.size() > 5 ? Optional<MDString *>(getMDString(Record[5]))
                               : None)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_COMPILE_UNIT: {
    if (Record.size() < 14 || Record.size() > 22)
      return error("Invalid record");

    // Ignore Record[0], which indicates whether this compile unit is
    // distinct.  It's always distinct.
    IsDistinct = true;
    auto *CU = DICompileUnit::getDistinct(
        Context, Record[1], getMDOrNull(Record[2]), getMDString(Record[3]),
        Record[4], getMDString(Record[5]), Record[6], getMDString(Record[7]),
        Record[8], getMDOrNull(Record[9]), getMDOrNull(Record[10]),
        getMDOrNull(Record[12]), getMDOrNull(Record[13]),
        Record.size() <= 15 ? nullptr : getMDOrNull(Record[15]),
        Record.size() <= 14 ? 0 : Record[14],
        Record.size() <= 16 ? true : Record[16],
        Record.size() <= 17 ? false : Record[17],
        Record.size() <= 18 ? 0 : Record[18],
        Record.size() <= 19 ? false : Record[19],
        Record.size() <= 20 ? nullptr : getMDString(Record[20]),
        Record.size() <= 21 ? nullptr : getMDString(Record[21]));

    MetadataList.assignValue(CU, NextMetadataNo);
    NextMetadataNo++;

    // Move the Upgrade the list of subprograms.
    if (Metadata *SPs = getMDOrNullWithoutPlaceholders(Record[11]))
      CUSubprograms.push_back({CU, SPs});
    break;
  }
  case bitc::METADATA_SUBPROGRAM: {
    if (Record.size() < 18 || Record.size() > 21)
      return error("Invalid record");

    bool HasSPFlags = Record[0] & 4;

    DINode::DIFlags Flags;
    DISubprogram::DISPFlags SPFlags;
    if (!HasSPFlags)
      Flags = static_cast<DINode::DIFlags>(Record[11 + 2]);
    else {
      Flags = static_cast<DINode::DIFlags>(Record[11]);
      SPFlags = static_cast<DISubprogram::DISPFlags>(Record[9]);
    }

    // Support for old metadata when
    // subprogram specific flags are placed in DIFlags.
    const unsigned DIFlagMainSubprogram = 1 << 21;
    bool HasOldMainSubprogramFlag = Flags & DIFlagMainSubprogram;
    if (HasOldMainSubprogramFlag)
      // Remove old DIFlagMainSubprogram from DIFlags.
      // Note: This assumes that any future use of bit 21 defaults to it
      // being 0.
      Flags &= ~static_cast<DINode::DIFlags>(DIFlagMainSubprogram);

    if (HasOldMainSubprogramFlag && HasSPFlags)
      SPFlags |= DISubprogram::SPFlagMainSubprogram;
    else if (!HasSPFlags)
      SPFlags = DISubprogram::toSPFlags(
          /*IsLocalToUnit=*/Record[7], /*IsDefinition=*/Record[8],
          /*IsOptimized=*/Record[14], /*Virtuality=*/Record[11],
          /*IsMainSubprogram=*/HasOldMainSubprogramFlag);

    // All definitions should be distinct.
    IsDistinct = (Record[0] & 1) || (SPFlags & DISubprogram::SPFlagDefinition);
    // Version 1 has a Function as Record[15].
    // Version 2 has removed Record[15].
    // Version 3 has the Unit as Record[15].
    // Version 4 added thisAdjustment.
    // Version 5 repacked flags into DISPFlags, changing many element numbers.
    bool HasUnit = Record[0] & 2;
    if (!HasSPFlags && HasUnit && Record.size() < 19)
      return error("Invalid record");
    if (HasSPFlags && !HasUnit)
      return error("Invalid record");
    // Accommodate older formats.
    bool HasFn = false;
    bool HasThisAdj = true;
    bool HasThrownTypes = true;
    bool HasAnnotations = false;
    unsigned OffsetA = 0;
    unsigned OffsetB = 0;
    if (!HasSPFlags) {
      OffsetA = 2;
      OffsetB = 2;
      if (Record.size() >= 19) {
        HasFn = !HasUnit;
        OffsetB++;
      }
      HasThisAdj = Record.size() >= 20;
      HasThrownTypes = Record.size() >= 21;
    } else {
      HasAnnotations = Record.size() >= 19;
    }
    Metadata *CUorFn = getMDOrNull(Record[12 + OffsetB]);
    DISubprogram *SP = GET_OR_DISTINCT(
        DISubprogram,
        (Context,
         getDITypeRefOrNull(Record[1]),           // scope
         getMDString(Record[2]),                  // name
         getMDString(Record[3]),                  // linkageName
         getMDOrNull(Record[4]),                  // file
         Record[5],                               // line
         getMDOrNull(Record[6]),                  // type
         Record[7 + OffsetA],                     // scopeLine
         getDITypeRefOrNull(Record[8 + OffsetA]), // containingType
         Record[10 + OffsetA],                    // virtualIndex
         HasThisAdj ? Record[16 + OffsetB] : 0,   // thisAdjustment
         Flags,                                   // flags
         SPFlags,                                 // SPFlags
         HasUnit ? CUorFn : nullptr,              // unit
         getMDOrNull(Record[13 + OffsetB]),       // templateParams
         getMDOrNull(Record[14 + OffsetB]),       // declaration
         getMDOrNull(Record[15 + OffsetB]),       // retainedNodes
         HasThrownTypes ? getMDOrNull(Record[17 + OffsetB])
                        : nullptr, // thrownTypes
         HasAnnotations ? getMDOrNull(Record[18 + OffsetB])
                        : nullptr // annotations
         ));
    MetadataList.assignValue(SP, NextMetadataNo);
    NextMetadataNo++;

    // Upgrade sp->function mapping to function->sp mapping.
    if (HasFn) {
      if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(CUorFn))
        if (auto *F = dyn_cast<Function>(CMD->getValue())) {
          if (F->isMaterializable())
            // Defer until materialized; unmaterialized functions may not have
            // metadata.
            FunctionsWithSPs[F] = SP;
          else if (!F->empty())
            F->setSubprogram(SP);
        }
    }
    break;
  }
  case bitc::METADATA_LEXICAL_BLOCK: {
    if (Record.size() != 5)
      return error("Invalid record");

    IsDistinct = Record[0];
    MetadataList.assignValue(
        GET_OR_DISTINCT(DILexicalBlock,
                        (Context, getMDOrNull(Record[1]),
                         getMDOrNull(Record[2]), Record[3], Record[4])),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_LEXICAL_BLOCK_FILE: {
    if (Record.size() != 4)
      return error("Invalid record");

    IsDistinct = Record[0];
    MetadataList.assignValue(
        GET_OR_DISTINCT(DILexicalBlockFile,
                        (Context, getMDOrNull(Record[1]),
                         getMDOrNull(Record[2]), Record[3])),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_COMMON_BLOCK: {
    IsDistinct = Record[0] & 1;
    MetadataList.assignValue(
        GET_OR_DISTINCT(DICommonBlock,
                        (Context, getMDOrNull(Record[1]),
                         getMDOrNull(Record[2]), getMDString(Record[3]),
                         getMDOrNull(Record[4]), Record[5])),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_NAMESPACE: {
    // Newer versions of DINamespace dropped file and line.
    MDString *Name;
    if (Record.size() == 3)
      Name = getMDString(Record[2]);
    else if (Record.size() == 5)
      Name = getMDString(Record[3]);
    else
      return error("Invalid record");

    IsDistinct = Record[0] & 1;
    bool ExportSymbols = Record[0] & 2;
    MetadataList.assignValue(
        GET_OR_DISTINCT(DINamespace,
                        (Context, getMDOrNull(Record[1]), Name, ExportSymbols)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_MACRO: {
    if (Record.size() != 5)
      return error("Invalid record");

    IsDistinct = Record[0];
    MetadataList.assignValue(
        GET_OR_DISTINCT(DIMacro,
                        (Context, Record[1], Record[2], getMDString(Record[3]),
                         getMDString(Record[4]))),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_MACRO_FILE: {
    if (Record.size() != 5)
      return error("Invalid record");

    IsDistinct = Record[0];
    MetadataList.assignValue(
        GET_OR_DISTINCT(DIMacroFile,
                        (Context, Record[1], Record[2], getMDOrNull(Record[3]),
                         getMDOrNull(Record[4]))),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_TEMPLATE_TYPE: {
    if (Record.size() < 3 || Record.size() > 4)
      return error("Invalid record");

    IsDistinct = Record[0];
    MetadataList.assignValue(
        GET_OR_DISTINCT(DITemplateTypeParameter,
                        (Context, getMDString(Record[1]),
                         getDITypeRefOrNull(Record[2]),
                         (Record.size() == 4) ? getMDOrNull(Record[3])
                                              : getMDOrNull(false))),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_TEMPLATE_VALUE: {
    if (Record.size() < 5 || Record.size() > 6)
      return error("Invalid record");

    IsDistinct = Record[0];

    MetadataList.assignValue(
        GET_OR_DISTINCT(
            DITemplateValueParameter,
            (Context, Record[1], getMDString(Record[2]),
             getDITypeRefOrNull(Record[3]),
             (Record.size() == 6) ? getMDOrNull(Record[4]) : getMDOrNull(false),
             (Record.size() == 6) ? getMDOrNull(Record[5])
                                  : getMDOrNull(Record[4]))),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_GLOBAL_VAR: {
    if (Record.size() < 11 || Record.size() > 13)
      return error("Invalid record");

    IsDistinct = Record[0] & 1;
    unsigned Version = Record[0] >> 1;

    if (Version == 2) {
      Metadata *Annotations = nullptr;
      if (Record.size() > 12)
        Annotations = getMDOrNull(Record[12]);

      MetadataList.assignValue(
          GET_OR_DISTINCT(DIGlobalVariable,
                          (Context, getMDOrNull(Record[1]),
                           getMDString(Record[2]), getMDString(Record[3]),
                           getMDOrNull(Record[4]), Record[5],
                           getDITypeRefOrNull(Record[6]), Record[7], Record[8],
                           getMDOrNull(Record[9]), getMDOrNull(Record[10]),
                           Record[11], Annotations)),
          NextMetadataNo);

      NextMetadataNo++;
    } else if (Version == 1) {
      // No upgrade necessary. A null field will be introduced to indicate
      // that no parameter information is available.
      MetadataList.assignValue(
          GET_OR_DISTINCT(
              DIGlobalVariable,
              (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
               getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
               getDITypeRefOrNull(Record[6]), Record[7], Record[8],
               getMDOrNull(Record[10]), nullptr, Record[11], nullptr)),
          NextMetadataNo);

      NextMetadataNo++;
    } else if (Version == 0) {
      // Upgrade old metadata, which stored a global variable reference or a
      // ConstantInt here.
      NeedUpgradeToDIGlobalVariableExpression = true;
      Metadata *Expr = getMDOrNull(Record[9]);
      uint32_t AlignInBits = 0;
      if (Record.size() > 11) {
        if (Record[11] > (uint64_t)std::numeric_limits<uint32_t>::max())
          return error("Alignment value is too large");
        AlignInBits = Record[11];
      }
      GlobalVariable *Attach = nullptr;
      if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(Expr)) {
        if (auto *GV = dyn_cast<GlobalVariable>(CMD->getValue())) {
          Attach = GV;
          Expr = nullptr;
        } else if (auto *CI = dyn_cast<ConstantInt>(CMD->getValue())) {
          Expr = DIExpression::get(Context,
                                   {dwarf::DW_OP_constu, CI->getZExtValue(),
                                    dwarf::DW_OP_stack_value});
        } else {
          Expr = nullptr;
        }
      }
      DIGlobalVariable *DGV = GET_OR_DISTINCT(
          DIGlobalVariable,
          (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
           getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
           getDITypeRefOrNull(Record[6]), Record[7], Record[8],
           getMDOrNull(Record[10]), nullptr, AlignInBits, nullptr));

      DIGlobalVariableExpression *DGVE = nullptr;
      if (Attach || Expr)
        DGVE = DIGlobalVariableExpression::getDistinct(
            Context, DGV, Expr ? Expr : DIExpression::get(Context, {}));
      if (Attach)
        Attach->addDebugInfo(DGVE);

      auto *MDNode = Expr ? cast<Metadata>(DGVE) : cast<Metadata>(DGV);
      MetadataList.assignValue(MDNode, NextMetadataNo);
      NextMetadataNo++;
    } else
      return error("Invalid record");

    break;
  }
  case bitc::METADATA_LOCAL_VAR: {
    // 10th field is for the obseleted 'inlinedAt:' field.
    if (Record.size() < 8 || Record.size() > 10)
      return error("Invalid record");

    IsDistinct = Record[0] & 1;
    bool HasAlignment = Record[0] & 2;
    // 2nd field used to be an artificial tag, either DW_TAG_auto_variable or
    // DW_TAG_arg_variable, if we have alignment flag encoded it means, that
    // this is newer version of record which doesn't have artificial tag.
    bool HasTag = !HasAlignment && Record.size() > 8;
    DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7 + HasTag]);
    uint32_t AlignInBits = 0;
    Metadata *Annotations = nullptr;
    if (HasAlignment) {
      if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
        return error("Alignment value is too large");
      AlignInBits = Record[8];
      if (Record.size() > 9)
        Annotations = getMDOrNull(Record[9]);
    }

    MetadataList.assignValue(
        GET_OR_DISTINCT(DILocalVariable,
                        (Context, getMDOrNull(Record[1 + HasTag]),
                         getMDString(Record[2 + HasTag]),
                         getMDOrNull(Record[3 + HasTag]), Record[4 + HasTag],
                         getDITypeRefOrNull(Record[5 + HasTag]),
                         Record[6 + HasTag], Flags, AlignInBits, Annotations)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_LABEL: {
    if (Record.size() != 5)
      return error("Invalid record");

    IsDistinct = Record[0] & 1;
    MetadataList.assignValue(
        GET_OR_DISTINCT(DILabel, (Context, getMDOrNull(Record[1]),
                                  getMDString(Record[2]),
                                  getMDOrNull(Record[3]), Record[4])),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_EXPRESSION: {
    if (Record.size() < 1)
      return error("Invalid record");

    IsDistinct = Record[0] & 1;
    uint64_t Version = Record[0] >> 1;
    auto Elts = MutableArrayRef<uint64_t>(Record).slice(1);

    SmallVector<uint64_t, 6> Buffer;
    if (Error Err = upgradeDIExpression(Version, Elts, Buffer))
      return Err;

    MetadataList.assignValue(GET_OR_DISTINCT(DIExpression, (Context, Elts)),
                             NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_GLOBAL_VAR_EXPR: {
    if (Record.size() != 3)
      return error("Invalid record");

    IsDistinct = Record[0];
    Metadata *Expr = getMDOrNull(Record[2]);
    if (!Expr)
      Expr = DIExpression::get(Context, {});
    MetadataList.assignValue(
        GET_OR_DISTINCT(DIGlobalVariableExpression,
                        (Context, getMDOrNull(Record[1]), Expr)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_OBJC_PROPERTY: {
    if (Record.size() != 8)
      return error("Invalid record");

    IsDistinct = Record[0];
    MetadataList.assignValue(
        GET_OR_DISTINCT(DIObjCProperty,
                        (Context, getMDString(Record[1]),
                         getMDOrNull(Record[2]), Record[3],
                         getMDString(Record[4]), getMDString(Record[5]),
                         Record[6], getDITypeRefOrNull(Record[7]))),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_IMPORTED_ENTITY: {
    if (Record.size() < 6 && Record.size() > 8)
      return error("Invalid record");

    IsDistinct = Record[0];
    bool HasFile = (Record.size() >= 7);
    bool HasElements = (Record.size() >= 8);
    MetadataList.assignValue(
        GET_OR_DISTINCT(DIImportedEntity,
                        (Context, Record[1], getMDOrNull(Record[2]),
                         getDITypeRefOrNull(Record[3]),
                         HasFile ? getMDOrNull(Record[6]) : nullptr,
                         HasFile ? Record[4] : 0, getMDString(Record[5]),
                         HasElements ? getMDOrNull(Record[7]) : nullptr)),
        NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_STRING_OLD: {
    std::string String(Record.begin(), Record.end());

    // Test for upgrading !llvm.loop.
    HasSeenOldLoopTags |= mayBeOldLoopAttachmentTag(String);
    ++NumMDStringLoaded;
    Metadata *MD = MDString::get(Context, String);
    MetadataList.assignValue(MD, NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  case bitc::METADATA_STRINGS: {
    auto CreateNextMDString = [&](StringRef Str) {
      ++NumMDStringLoaded;
      MetadataList.assignValue(MDString::get(Context, Str), NextMetadataNo);
      NextMetadataNo++;
    };
    if (Error Err = parseMetadataStrings(Record, Blob, CreateNextMDString))
      return Err;
    break;
  }
  case bitc::METADATA_GLOBAL_DECL_ATTACHMENT: {
    if (Record.size() % 2 == 0)
      return error("Invalid record");
    unsigned ValueID = Record[0];
    if (ValueID >= ValueList.size())
      return error("Invalid record");
    if (auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID]))
      if (Error Err = parseGlobalObjectAttachment(
              *GO, ArrayRef<uint64_t>(Record).slice(1)))
        return Err;
    break;
  }
  case bitc::METADATA_KIND: {
    // Support older bitcode files that had METADATA_KIND records in a
    // block with METADATA_BLOCK_ID.
    if (Error Err = parseMetadataKindRecord(Record))
      return Err;
    break;
  }
  case bitc::METADATA_ARG_LIST: {
    SmallVector<ValueAsMetadata *, 4> Elts;
    Elts.reserve(Record.size());
    for (uint64_t Elt : Record) {
      Metadata *MD = getMD(Elt);
      if (isa<MDNode>(MD) && cast<MDNode>(MD)->isTemporary())
        return error(
            "Invalid record: DIArgList should not contain forward refs");
      if (!isa<ValueAsMetadata>(MD))
        return error("Invalid record");
      Elts.push_back(cast<ValueAsMetadata>(MD));
    }

    MetadataList.assignValue(DIArgList::get(Context, Elts), NextMetadataNo);
    NextMetadataNo++;
    break;
  }
  }
  return Error::success();
#undef GET_OR_DISTINCT
}