diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h @@ -66,12 +66,11 @@ DwarfVersion Version; ///< Dwarf version where the Op was introduced. Encoding Op[2]; ///< Encoding for Op operands, or SizeNA. - Description(DwarfVersion Version = DwarfNA, Encoding Op1 = SizeNA, - Encoding Op2 = SizeNA) - : Version(Version) { - Op[0] = Op1; - Op[1] = Op2; - } + constexpr Description() : Description(DwarfNA, SizeNA, SizeNA) {} + constexpr Description(DwarfVersion Version, Encoding Op1 = SizeNA, + Encoding Op2 = SizeNA) + : Version(Version), Op{Op1, Op2} {} + ~Description() = default; }; private: diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -18,102 +18,99 @@ namespace llvm { -typedef std::vector DescVector; - -static DescVector getDescriptions() { - DescVector Descriptions; - typedef DWARFExpression::Operation Op; - typedef Op::Description Desc; - - Descriptions.resize(0xff); - Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr); - Descriptions[DW_OP_deref] = Desc(Op::Dwarf2); - Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1); - Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1); - Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2); - Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2); - Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4); - Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4); - Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8); - Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8); - Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB); - Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB); - Descriptions[DW_OP_dup] = Desc(Op::Dwarf2); - Descriptions[DW_OP_drop] = Desc(Op::Dwarf2); - Descriptions[DW_OP_over] = Desc(Op::Dwarf2); - Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1); - Descriptions[DW_OP_swap] = Desc(Op::Dwarf2); - Descriptions[DW_OP_rot] = Desc(Op::Dwarf2); - Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2); - Descriptions[DW_OP_abs] = Desc(Op::Dwarf2); - Descriptions[DW_OP_and] = Desc(Op::Dwarf2); - Descriptions[DW_OP_div] = Desc(Op::Dwarf2); - Descriptions[DW_OP_minus] = Desc(Op::Dwarf2); - Descriptions[DW_OP_mod] = Desc(Op::Dwarf2); - Descriptions[DW_OP_mul] = Desc(Op::Dwarf2); - Descriptions[DW_OP_neg] = Desc(Op::Dwarf2); - Descriptions[DW_OP_not] = Desc(Op::Dwarf2); - Descriptions[DW_OP_or] = Desc(Op::Dwarf2); - Descriptions[DW_OP_plus] = Desc(Op::Dwarf2); - Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB); - Descriptions[DW_OP_shl] = Desc(Op::Dwarf2); - Descriptions[DW_OP_shr] = Desc(Op::Dwarf2); - Descriptions[DW_OP_shra] = Desc(Op::Dwarf2); - Descriptions[DW_OP_xor] = Desc(Op::Dwarf2); - Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2); - Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2); - Descriptions[DW_OP_eq] = Desc(Op::Dwarf2); - Descriptions[DW_OP_ge] = Desc(Op::Dwarf2); - Descriptions[DW_OP_gt] = Desc(Op::Dwarf2); - Descriptions[DW_OP_le] = Desc(Op::Dwarf2); - Descriptions[DW_OP_lt] = Desc(Op::Dwarf2); - Descriptions[DW_OP_ne] = Desc(Op::Dwarf2); - for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA) - Descriptions[LA] = Desc(Op::Dwarf2); - for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA) - Descriptions[LA] = Desc(Op::Dwarf2); - for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA) - Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB); - Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB); - Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB); - Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB); - Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB); - Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1); - Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1); - Descriptions[DW_OP_nop] = Desc(Op::Dwarf2); - Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3); - Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2); - Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4); - Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr); - Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3); - Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3); - Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB); - Descriptions[DW_OP_implicit_value] = - Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock); - Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3); - Descriptions[DW_OP_WASM_location] = - Desc(Op::Dwarf4, Op::SizeLEB, Op::WasmLocationArg); - Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3); - Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB); - Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB); - Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB); - Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB); - - Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef); - Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB); - Descriptions[DW_OP_regval_type] = - Desc(Op::Dwarf5, Op::SizeLEB, Op::BaseTypeRef); - - return Descriptions; -} +typedef DWARFExpression::Operation Op; +typedef Op::Description Desc; -static DWARFExpression::Operation::Description getOpDesc(unsigned OpCode) { - // FIXME: Make this constexpr once all compilers are smart enough to do it. - static DescVector Descriptions = getDescriptions(); +static Desc getOpDescImpl(ArrayRef Descriptions, unsigned Opcode) { // Handle possible corrupted or unsupported operation. - if (OpCode >= Descriptions.size()) + if (Opcode >= Descriptions.size()) return {}; - return Descriptions[OpCode]; + return Descriptions[Opcode]; +} + +static Desc getOpDesc(unsigned Opcode) { + static constexpr auto Descriptions = []() { + std::array Descriptions; + Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr); + Descriptions[DW_OP_deref] = Desc(Op::Dwarf2); + Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1); + Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1); + Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2); + Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2); + Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4); + Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4); + Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8); + Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8); + Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB); + Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB); + Descriptions[DW_OP_dup] = Desc(Op::Dwarf2); + Descriptions[DW_OP_drop] = Desc(Op::Dwarf2); + Descriptions[DW_OP_over] = Desc(Op::Dwarf2); + Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1); + Descriptions[DW_OP_swap] = Desc(Op::Dwarf2); + Descriptions[DW_OP_rot] = Desc(Op::Dwarf2); + Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2); + Descriptions[DW_OP_abs] = Desc(Op::Dwarf2); + Descriptions[DW_OP_and] = Desc(Op::Dwarf2); + Descriptions[DW_OP_div] = Desc(Op::Dwarf2); + Descriptions[DW_OP_minus] = Desc(Op::Dwarf2); + Descriptions[DW_OP_mod] = Desc(Op::Dwarf2); + Descriptions[DW_OP_mul] = Desc(Op::Dwarf2); + Descriptions[DW_OP_neg] = Desc(Op::Dwarf2); + Descriptions[DW_OP_not] = Desc(Op::Dwarf2); + Descriptions[DW_OP_or] = Desc(Op::Dwarf2); + Descriptions[DW_OP_plus] = Desc(Op::Dwarf2); + Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB); + Descriptions[DW_OP_shl] = Desc(Op::Dwarf2); + Descriptions[DW_OP_shr] = Desc(Op::Dwarf2); + Descriptions[DW_OP_shra] = Desc(Op::Dwarf2); + Descriptions[DW_OP_xor] = Desc(Op::Dwarf2); + Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2); + Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2); + Descriptions[DW_OP_eq] = Desc(Op::Dwarf2); + Descriptions[DW_OP_ge] = Desc(Op::Dwarf2); + Descriptions[DW_OP_gt] = Desc(Op::Dwarf2); + Descriptions[DW_OP_le] = Desc(Op::Dwarf2); + Descriptions[DW_OP_lt] = Desc(Op::Dwarf2); + Descriptions[DW_OP_ne] = Desc(Op::Dwarf2); + for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA) + Descriptions[LA] = Desc(Op::Dwarf2); + for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA) + Descriptions[LA] = Desc(Op::Dwarf2); + for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA) + Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB); + Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB); + Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB); + Descriptions[DW_OP_bregx] = + Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB); + Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB); + Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1); + Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1); + Descriptions[DW_OP_nop] = Desc(Op::Dwarf2); + Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3); + Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2); + Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4); + Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr); + Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3); + Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3); + Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB); + Descriptions[DW_OP_implicit_value] = + Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock); + Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3); + Descriptions[DW_OP_WASM_location] = + Desc(Op::Dwarf4, Op::SizeLEB, Op::WasmLocationArg); + Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3); + Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB); + Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB); + Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB); + Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB); + Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef); + Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB); + Descriptions[DW_OP_regval_type] = + Desc(Op::Dwarf5, Op::SizeLEB, Op::BaseTypeRef); + return Descriptions; + }(); + return getOpDescImpl(Descriptions, Opcode); } bool DWARFExpression::Operation::extract(DataExtractor Data,