| 1638 | } |
| 1639 | |
| 1640 | llvm::StructType* TupleDescriptor::CreateLlvmStructTypeFromFieldTypes( |
| 1641 | LlvmCodeGen* codegen, const vector<llvm::Type*>& field_types, |
| 1642 | int parent_slot_offset) const { |
| 1643 | // Construct the struct type. Use the packed layout although not strictly necessary |
| 1644 | // because the fields are already aligned, so LLVM should not add any padding. The |
| 1645 | // fields are already aligned because we order the slots by descending size and only |
| 1646 | // have powers-of-two slot sizes. Note that STRING and TIMESTAMP slots both occupy |
| 1647 | // 16 bytes although their useful payload is only 12 bytes. |
| 1648 | llvm::StructType* tuple_struct = llvm::StructType::get(codegen->context(), |
| 1649 | llvm::ArrayRef<llvm::Type*>(field_types), true); |
| 1650 | DCHECK(tuple_struct != nullptr); |
| 1651 | const llvm::DataLayout& data_layout = codegen->execution_engine()->getDataLayout(); |
| 1652 | const llvm::StructLayout* layout = data_layout.getStructLayout(tuple_struct); |
| 1653 | for (SlotDescriptor* slot: slots()) { |
| 1654 | // Verify that the byte offset in the llvm struct matches the tuple offset |
| 1655 | // computed in the FE. |
| 1656 | DCHECK_EQ(layout->getElementOffset(slot->llvm_field_idx()) + parent_slot_offset, |
| 1657 | slot->tuple_offset()) << id_; |
| 1658 | } |
| 1659 | return tuple_struct; |
| 1660 | } |
| 1661 | |
| 1662 | string DescriptorTbl::DebugString() const { |
| 1663 | stringstream out; |
no test coverage detected