@@ -3870,6 +3870,85 @@ TEST_F(DIExpressionTest, createFragmentExpression) {
38703870#undef EXPECT_INVALID_FRAGMENT
38713871}
38723872
3873+ TEST_F (DIExpressionTest, extractLeadingOffset) {
3874+ int64_t Offset;
3875+ SmallVector<uint64_t > Remaining;
3876+ using namespace dwarf ;
3877+ #define OPS (...) SmallVector<uint64_t >(ArrayRef<uint64_t >{__VA_ARGS__})
3878+ #define EXTRACT_FROM (...) \
3879+ DIExpression::get (Context, {__VA_ARGS__}) \
3880+ ->extractLeadingOffset (Offset, Remaining)
3881+ // Test the number of expression inputs
3882+ // ------------------------------------
3883+ //
3884+ // Single location expressions are permitted.
3885+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_plus_uconst, 2 ));
3886+ EXPECT_EQ (Offset, 2 );
3887+ EXPECT_EQ (Remaining.size (), 0 );
3888+ // This is also a single-location.
3889+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_LLVM_arg, 0 , DW_OP_plus_uconst, 2 ));
3890+ EXPECT_EQ (Offset, 2 );
3891+ EXPECT_EQ (Remaining.size (), 0 );
3892+ // Variadic locations are not permitted. A non-zero arg is assumed to
3893+ // indicate multiple inputs.
3894+ EXPECT_FALSE (EXTRACT_FROM (DW_OP_LLVM_arg, 1 ));
3895+ EXPECT_FALSE (EXTRACT_FROM (DW_OP_LLVM_arg, 0 , DW_OP_LLVM_arg, 1 , DW_OP_plus));
3896+
3897+ // Test offsets expressions
3898+ // ------------------------
3899+ EXPECT_TRUE (EXTRACT_FROM ());
3900+ EXPECT_EQ (Offset, 0 );
3901+ EXPECT_EQ (Remaining.size (), 0u );
3902+
3903+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_constu, 4 , DW_OP_plus));
3904+ EXPECT_EQ (Offset, 4 );
3905+ EXPECT_EQ (Remaining.size (), 0u );
3906+
3907+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_constu, 2 , DW_OP_minus));
3908+ EXPECT_EQ (Offset, -2 );
3909+ EXPECT_EQ (Remaining.size (), 0u );
3910+
3911+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_plus_uconst, 8 ));
3912+ EXPECT_EQ (Offset, 8 );
3913+ EXPECT_EQ (Remaining.size (), 0u );
3914+
3915+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_plus_uconst, 4 , DW_OP_constu, 2 , DW_OP_minus));
3916+ EXPECT_EQ (Offset, 2 );
3917+ EXPECT_EQ (Remaining.size (), 0u );
3918+
3919+ // Not all operations are permitted for simplicity. Can be added
3920+ // if needed in future.
3921+ EXPECT_FALSE (EXTRACT_FROM (DW_OP_constu, 2 , DW_OP_mul));
3922+
3923+ // Test "remaining ops"
3924+ // --------------------
3925+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_plus_uconst, 4 , DW_OP_constu, 8 , DW_OP_minus,
3926+ DW_OP_LLVM_fragment, 0 , 32 ));
3927+ EXPECT_EQ (Remaining, OPS (DW_OP_LLVM_fragment, 0 , 32 ));
3928+ EXPECT_EQ (Offset, -4 );
3929+
3930+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_deref));
3931+ EXPECT_EQ (Remaining, OPS (DW_OP_deref));
3932+ EXPECT_EQ (Offset, 0 );
3933+
3934+ // Check things after the non-offset ops are added too.
3935+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_plus_uconst, 2 , DW_OP_deref_size, 4 ,
3936+ DW_OP_stack_value));
3937+ EXPECT_EQ (Remaining, OPS (DW_OP_deref_size, 4 , DW_OP_stack_value));
3938+ EXPECT_EQ (Offset, 2 );
3939+
3940+ // DW_OP_deref_type isn't supported in LLVM so this currently fails.
3941+ EXPECT_FALSE (EXTRACT_FROM (DW_OP_deref_type, 0 ));
3942+
3943+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_LLVM_extract_bits_zext, 0 , 8 ));
3944+ EXPECT_EQ (Remaining, OPS (DW_OP_LLVM_extract_bits_zext, 0 , 8 ));
3945+
3946+ EXPECT_TRUE (EXTRACT_FROM (DW_OP_LLVM_extract_bits_sext, 4 , 4 ));
3947+ EXPECT_EQ (Remaining, OPS (DW_OP_LLVM_extract_bits_sext, 4 , 4 ));
3948+ #undef EXTRACT_FROM
3949+ #undef OPS
3950+ }
3951+
38733952TEST_F (DIExpressionTest, convertToUndefExpression) {
38743953#define EXPECT_UNDEF_OPS_EQUAL (TestExpr, Expected ) \
38753954 do { \
0 commit comments