func parse()

in Sources/SIL/BitcodeParser.swift [192:257]


    func parse() throws -> BitcodeBlock {
        if stream.isEmpty {
            guard blockStack.count == 1 else {
                throw Error.parseError(
                    "End of stream encountered with some blocks still open")
            }
            return blockStack[0]
        }
        let abbrev = try stream.next(bits: currentBlock.abbrLen)
        switch (abbrev) {
        case endBlock:
            // [endBlock, <align32bits>]
            stream.align(toMultipleOf: 32)

            let _ = blockStack.popLast()
            guard !blockStack.isEmpty else {
                throw Error.parseError("Unexpected endBlock")
            }

            return try parse()
        case enterSubBlock:
            // [enterSubBlock, blockid(vbr8), newabbrevlen(vbr4), <align32bits>, blocklen_32]
            let blockId = try read(vbr: 8)
            let newAbbrevLenBits = try read(vbr: 4)
            stream.align(toMultipleOf: 32)
            let blockLen32 = try Int(stream.next(bits: 32).uint32)

            let newAbbrevLen = newAbbrevLenBits.int
            // BLOCKINFO block is a bit special and we'll reparse it
            // into blockInfoTemplates instead of having it as a subblock
            if (blockId == blockInfoId) {
                try parseInfoBlock(abbrLen: newAbbrevLen)
            } else {
                var subblockInfo: BitcodeBlockInfo
                if let info = blockInfoTemplates[blockId] {
                    subblockInfo = BitcodeBlockInfo(from: info)
                } else {
                    subblockInfo = BitcodeBlockInfo(id: blockId)
                }
                let subblock = BitcodeBlock(
                    info: subblockInfo, abbrLen: newAbbrevLen, blockLen32: blockLen32)
                currentBlock.subblocks.append(subblock)
                blockStack.append(subblock)
                // XXX: At this point subblock is the currentBlock
            }

            return try parse()
        case defineAbbrev:
            // NB: Abbreviation IDs are assign in order of their declaration,
            //     but starting from 4 (because there are 4 builtin abbrevs).
            let abbrevId = Bits(currentBlock.info.abbreviations.count + 4)
            currentBlock.info.abbreviations[abbrevId] = try parseAbbrevStructure()

            return try parse()
        case unabbrevRecord:
            currentBlock.records.append(try parseUnabbrevRecord())
            return try parse()
        default:  // Abbreviated record
            guard let structure = currentBlock.info.abbreviations[abbrev] else {
                throw Error.parseError("Undeclared abbreviation: " + abbrev.description)
            }
            let record = try parseAbbrevRecord(structure)
            currentBlock.records.append(record)
            return try parse()
        }
    }