@@ -3870,6 +3870,84 @@ TEST_F(DIExpressionTest, createFragmentExpression) {
3870
3870
#undef EXPECT_INVALID_FRAGMENT
3871
3871
}
3872
3872
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
+ }
3950
+
3873
3951
TEST_F (DIExpressionTest, convertToUndefExpression) {
3874
3952
#define EXPECT_UNDEF_OPS_EQUAL (TestExpr, Expected ) \
3875
3953
do { \
0 commit comments