ffi-clang

FORK: Ruby FFI bindings for my custom patched clang 8.0.
git clone https://git.neptards.moe/neptards/ffi-clang.git
Log | Files | Refs | README

type_spec.rb (10009B)


      1 # -*- coding: utf-8 -*-
      2 # Copyright, 2013, by Carlos Martín Nieto <cmn@dwim.me>
      3 # Copyright, 2014, by Masahiro Sano.
      4 # 
      5 # Permission is hereby granted, free of charge, to any person obtaining a copy
      6 # of this software and associated documentation files (the "Software"), to deal
      7 # in the Software without restriction, including without limitation the rights
      8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9 # copies of the Software, and to permit persons to whom the Software is
     10 # furnished to do so, subject to the following conditions:
     11 # 
     12 # The above copyright notice and this permission notice shall be included in
     13 # all copies or substantial portions of the Software.
     14 # 
     15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     21 # THE SOFTWARE.
     22 
     23 describe Type do
     24 	let(:cursor) { Index.new.parse_translation_unit(fixture_path("a.c")).cursor }
     25 	let(:cursor_cxx) { Index.new.parse_translation_unit(fixture_path("test.cxx")).cursor }
     26 	let(:cursor_list) { Index.new.parse_translation_unit(fixture_path("list.c")).cursor }
     27 	let(:type) { find_first(cursor, :cursor_function).type }
     28 
     29 	it "can tell us about the main function" do
     30 		expect(type.variadic?).to equal(false)
     31 
     32 		expect(type.num_arg_types).to equal(2)
     33 		expect(type.arg_type(0).spelling).to eq("int")
     34 		expect(type.arg_type(1).spelling).to eq("const char *")
     35 		expect(type.result_type.spelling).to eq("int")
     36 	end
     37 
     38   describe '#kind_spelling' do
     39     let(:kind_spelling_type) { find_matching(cursor_cxx) { |child, parent|
     40       child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'}.type }
     41 
     42     it 'returns type kind name with string' do
     43       expect(kind_spelling_type.kind_spelling).to eq 'Typedef'
     44     end
     45   end
     46 
     47   describe '#canonical' do
     48     let(:canonical_type) { find_matching(cursor_cxx) { |child, parent|
     49         child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'
     50       }.type.canonical }
     51 
     52     it 'extracts typedef' do
     53       expect(canonical_type).to be_kind_of(Type)
     54       expect(canonical_type.kind).to be(:type_pointer)
     55       expect(canonical_type.spelling).to eq('const int *')
     56     end
     57   end
     58 
     59   describe '#pointee' do
     60     let(:pointee_type) { find_matching(cursor_cxx) { |child, parent|
     61         child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'
     62       }.type.canonical.pointee }
     63 
     64     it 'gets pointee type of pointer, C++ reference' do
     65       expect(pointee_type).to be_kind_of(Type)
     66       expect(pointee_type.kind).to be(:type_int)
     67       expect(pointee_type.spelling).to eq('const int')
     68     end
     69   end
     70 
     71   describe '#const_qualified?' do
     72     let(:pointer_type) { find_matching(cursor_cxx) { |child, parent|
     73         child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'
     74       }.type.canonical }
     75 
     76     let(:pointee_type) { find_matching(cursor_cxx) { |child, parent|
     77         child.kind == :cursor_typedef_decl and child.spelling == 'const_int_ptr'
     78       }.type.canonical.pointee }
     79 
     80     it 'checks type is const qualified' do
     81       expect(pointee_type.const_qualified?).to equal true
     82     end
     83 
     84     it 'cannot check whether pointee type is const qualified' do
     85       expect(pointer_type.const_qualified?).to equal false
     86     end
     87   end
     88 
     89   describe '#volatile_qualified?' do
     90     let(:pointer_type) { find_matching(cursor) { |child, parent|
     91         child.kind == :cursor_variable and child.spelling == 'volatile_int_ptr'
     92       }.type }
     93 
     94     it 'checks type is volatile qualified' do
     95       expect(pointer_type.volatile_qualified?).to be true
     96     end
     97   end
     98 
     99   describe '#restrict_qualified?' do
    100     let(:pointer_type) { find_matching(cursor) { |child, parent|
    101         child.kind == :cursor_variable and child.spelling == 'restrict_int_ptr'
    102       }.type }
    103 
    104     it 'checks type is restrict qualified' do
    105       expect(pointer_type.restrict_qualified?).to be true
    106     end
    107   end
    108 
    109   describe '#element_type' do
    110     let(:array_type) { find_matching(cursor_cxx) { |child, parent|
    111         child.kind == :cursor_variable and child.spelling == 'int_array'
    112       }.type }
    113 
    114     it 'returns the element type of the array type' do
    115       expect(array_type.element_type).to be_kind_of(Type)
    116       expect(array_type.element_type.kind).to eq(:type_int)
    117     end
    118   end
    119 
    120   describe '#num_elements' do
    121     let(:array_type) { find_matching(cursor_cxx) { |child, parent|
    122         child.kind == :cursor_variable and child.spelling == 'int_array'
    123       }.type }
    124 
    125     it 'returns the number of elements of the array' do
    126       expect(array_type.num_elements).to eq(8)
    127     end
    128   end
    129 
    130   describe '#array_element_type' do
    131     let(:array_type) { find_matching(cursor_cxx) { |child, parent|
    132         child.kind == :cursor_variable and child.spelling == 'int_array'
    133       }.type }
    134 
    135     it 'returns the array element type of the array type' do
    136       expect(array_type.array_element_type).to be_kind_of(Type)
    137       expect(array_type.array_element_type.kind).to eq(:type_int)
    138     end
    139   end
    140 
    141   describe '#array_size' do
    142     let(:array_type) { find_matching(cursor_cxx) { |child, parent|
    143         child.kind == :cursor_variable and child.spelling == 'int_array'
    144       }.type }
    145 
    146     it 'returns the number of elements of the array' do
    147       expect(array_type.array_size).to eq(8)
    148     end
    149   end
    150 
    151   describe '#alignof' do
    152     let(:array_type) { find_matching(cursor_cxx) { |child, parent|
    153         child.kind == :cursor_variable and child.spelling == 'int_array'
    154       }.type }
    155 
    156     it 'returns the alignment of the type in bytes' do
    157       expect(array_type.alignof).to be_kind_of(Integer)
    158       expect(array_type.alignof).to be > 0
    159     end
    160   end
    161 
    162   describe '#sizeof' do
    163     let(:array_type) { find_matching(cursor_cxx) { |child, parent|
    164         child.kind == :cursor_variable and child.spelling == 'int_array'
    165       }.type }
    166 
    167     it 'returns the size of the type in bytes' do
    168       expect(array_type.sizeof).to be_kind_of(Integer)
    169       expect(array_type.sizeof).to be(32)
    170     end
    171   end
    172 
    173   describe '#offsetof' do
    174     let(:struct) { find_matching(cursor_list) { |child, parent|
    175         child.kind == :cursor_struct and child.spelling == 'List'
    176       }.type }
    177 
    178     it 'returns the offset of a field in a record of the type in bits' do
    179       expect(struct.offsetof('Next')).to be_kind_of(Integer)
    180       expect(struct.offsetof('Next')).to be(64)
    181     end
    182   end
    183 
    184   describe '#ref_qualifier' do
    185     let(:lvalue) { find_matching(cursor_cxx) { |child, parent|
    186         child.kind == :cursor_cxx_method and child.spelling == 'func_lvalue_ref'
    187       }.type }
    188     let(:rvalue) { find_matching(cursor_cxx) { |child, parent|
    189         child.kind == :cursor_cxx_method and child.spelling == 'func_rvalue_ref'
    190       }.type }
    191     let(:none) { find_matching(cursor_cxx) { |child, parent|
    192         child.kind == :cursor_cxx_method and child.spelling == 'func_none'
    193       }.type }
    194 
    195     it 'returns :ref_qualifier_lvalue the type is ref-qualified with lvalue' do
    196       expect(lvalue.ref_qualifier).to be(:ref_qualifier_lvalue)
    197     end
    198 
    199     it 'returns :ref_qualifier_rvalue the type is ref-qualified with rvalue' do
    200       expect(rvalue.ref_qualifier).to be(:ref_qualifier_rvalue)
    201     end
    202 
    203     it 'returns :ref_qualifier_none the type is not ref-qualified' do
    204       expect(none.ref_qualifier).to be(:ref_qualifier_none)
    205     end
    206   end
    207 
    208   describe '#pod?' do
    209     let(:struct) { find_matching(cursor_list) { |child, parent|
    210         child.kind == :cursor_struct and child.spelling == 'List'
    211       }.type }
    212 
    213     it 'returns true if the type is a POD type' do
    214       expect(struct.pod?).to be true
    215     end
    216   end
    217 
    218   describe '#class_type' do
    219     let(:member_pointer) { find_matching(cursor_cxx) { |child, parent|
    220         child.kind == :cursor_variable and child.spelling == 'member_pointer'
    221       }.type }
    222 
    223     it 'returns the class type of the member pointer type' do
    224       expect(member_pointer.class_type).to be_kind_of(Type)
    225       expect(member_pointer.class_type.kind).to be(:type_record)
    226       expect(member_pointer.class_type.spelling).to eq('A')
    227     end
    228   end
    229 
    230   describe '#declaration' do
    231     let(:struct_ref) { find_matching(cursor_cxx) { |child, parent|
    232         child.kind == :cursor_type_ref and child.spelling == 'struct D'
    233       }.type }
    234     let(:struct_decl) { find_matching(cursor_cxx) { |child, parent|
    235         child.kind == :cursor_struct and child.spelling == 'D'
    236       } }
    237     let(:no_decl) { find_first(cursor_cxx, :cursor_cxx_method).type }
    238 
    239     it 'returns the class type of the member pointer type' do
    240       expect(struct_ref.declaration).to be_kind_of(Cursor)
    241       expect(struct_ref.declaration.kind).to be(:cursor_struct)
    242       expect(struct_ref.declaration).to eq(struct_decl)
    243     end
    244 
    245     it 'returns :cursor_no_decl_found if the type has no declaration' do
    246       expect(no_decl.declaration).to be_kind_of(Cursor)
    247       expect(no_decl.declaration.kind).to be(:cursor_no_decl_found)
    248     end
    249   end
    250 
    251   describe '#calling_conv' do
    252     let(:function) { find_matching(cursor_cxx) { |child, parent|
    253         child.kind == :cursor_function and child.spelling == 'f_variadic'
    254       }.type }
    255 
    256     it 'returns the calling convention associated with the function type' do
    257       expect(function.calling_conv).to be(:calling_conv_c)
    258     end
    259   end
    260 
    261   describe '#==' do
    262     let(:type_decl) { find_matching(cursor_cxx) { |child, parent|
    263         child.kind == :cursor_field_decl and child.spelling == 'int_member_a'
    264       }.type }
    265     let(:type_ref) { find_matching(cursor_cxx) { |child, parent|
    266         child.kind == :cursor_decl_ref_expr and child.spelling == 'int_member_a'
    267       }.type }
    268 
    269     it 'checks if two types represent the same type' do
    270       expect(type_decl == type_ref).to be true
    271     end
    272   end
    273 end