ffi-clang 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7bac4481c13b37b86189208dd7e0589bd96a42059319828c22ae623025ccc75
4
- data.tar.gz: 3d6cc4ebca61f93b710b5a8fcc80d6fa51eeb8aac466246775c5ba80d8274c32
3
+ metadata.gz: eed14776878ea1dd5fe61ec2b8c9bb57be78116944d5943722077dd958e65b90
4
+ data.tar.gz: 15acda164aae15f941ae12031e1f68a8a220f0b5e48c6ed07737e0d8a733893d
5
5
  SHA512:
6
- metadata.gz: 816df5fbe722de3c3bc513598455a076bc64a32ee0d4d1697bc51dca767d06b9645be1c6dba444bc50d9d3f073fc02b2d13c6afbce355617df03368dc416930c
7
- data.tar.gz: ec3be8892d6710742e173e54cb6c4f498b28a5178ca7c15ad9c08aae66f67824a039820f7ddff0a21c8aa50221c286dbeef9a2132e140bebb8c5f65fc69928c9
6
+ metadata.gz: bb918188b02394a8d21f863f1b989a2cb96789f11c97d83c417258ac25a590e63297daf7e7fb6851f06e4890051f9130b9c75d850f1662ad29f6652a244bceb4
7
+ data.tar.gz: 6b48dabf35dc7606859f18f4267800f4e6de1a2eec1496e3e89cbad282727cb8f80c4820b1405e772bad59bfd8559a98076804e2320b453d65e0d22104ba9bd0
checksums.yaml.gz.sig CHANGED
Binary file
@@ -20,11 +20,12 @@ require_relative 'printing_policy'
20
20
  require_relative 'source_location'
21
21
  require_relative 'source_range'
22
22
  require_relative 'comment'
23
- require_relative 'type'
24
23
 
25
24
  module FFI
26
25
  module Clang
27
26
  class Cursor
27
+ include Enumerable
28
+
28
29
  attr_reader :cursor
29
30
  attr_reader :translation_unit
30
31
 
@@ -62,6 +63,14 @@ module FFI
62
63
  CodeCompletion::String.new Lib.get_cursor_completion_string(@cursor)
63
64
  end
64
65
 
66
+ def anonymous?
67
+ Lib.cursor_is_anonymous(@cursor) != 0
68
+ end
69
+
70
+ def anonymous_record_declaration?
71
+ Lib.cursor_is_anonymous_record_decl(@cursor) != 0
72
+ end
73
+
65
74
  def declaration?
66
75
  Lib.is_declaration(kind) != 0
67
76
  end
@@ -155,7 +164,7 @@ module FFI
155
164
  end
156
165
 
157
166
  def kind
158
- @cursor[:kind]
167
+ @cursor ? @cursor[:kind] : nil
159
168
  end
160
169
 
161
170
  def kind_spelling
@@ -163,15 +172,15 @@ module FFI
163
172
  end
164
173
 
165
174
  def type
166
- Type.new Lib.get_cursor_type(@cursor), @translation_unit
175
+ Types::Type.create Lib.get_cursor_type(@cursor), @translation_unit
167
176
  end
168
177
 
169
178
  def result_type
170
- Type.new Lib.get_cursor_result_type(@cursor), @translation_unit
179
+ Types::Type.create Lib.get_cursor_result_type(@cursor), @translation_unit
171
180
  end
172
181
 
173
182
  def underlying_type
174
- Type.new Lib.get_typedef_decl_underlying_type(@cursor), @translation_unit
183
+ Types::Type.create Lib.get_typedef_decl_underlying_type(@cursor), @translation_unit
175
184
  end
176
185
 
177
186
  def virtual_base?
@@ -211,7 +220,7 @@ module FFI
211
220
  end
212
221
 
213
222
  def enum_type
214
- Type.new Lib.get_enum_decl_integer_type(@cursor), @translation_unit
223
+ Types::Type.create Lib.get_enum_decl_integer_type(@cursor), @translation_unit
215
224
  end
216
225
 
217
226
  def specialized_template
@@ -269,14 +278,53 @@ module FFI
269
278
  Lib.get_num_args @cursor
270
279
  end
271
280
 
272
- def visit_children(&block)
281
+ def each(recurse = true, &block)
282
+ return to_enum(:each, recurse) unless block_given?
283
+
273
284
  adapter = Proc.new do |cxcursor, parent_cursor, unused|
274
- block.call Cursor.new(cxcursor, @translation_unit), Cursor.new(parent_cursor, @translation_unit)
285
+ # Call the block and capture the result. This lets advanced users
286
+ # modify the recursion on a case by case basis if needed
287
+ result = block.call Cursor.new(cxcursor, @translation_unit), Cursor.new(parent_cursor, @translation_unit)
288
+ case result
289
+ when :continue
290
+ :continue
291
+ when :recurse
292
+ :recurse
293
+ else
294
+ recurse ? :recurse : :continue
295
+ end
275
296
  end
276
-
297
+
277
298
  Lib.visit_children(@cursor, adapter, nil)
278
299
  end
279
300
 
301
+ def ancestors_by_kind(*kinds)
302
+ result = Array.new
303
+
304
+ parent = self
305
+ while parent != self.semantic_parent
306
+ parent = self.semantic_parent
307
+ if kinds.include?(parent.kind)
308
+ result << parent
309
+ end
310
+ end
311
+ result
312
+ end
313
+
314
+ def find_by_kind(recurse, *kinds)
315
+ unless (recurse == nil || recurse == true || recurse == false)
316
+ raise("Recurse parameter must be nil or a boolean value. Value was: #{recurse}")
317
+ end
318
+
319
+ result = Array.new
320
+ self.each(recurse) do |child, parent|
321
+ if kinds.include?(child.kind)
322
+ result << child
323
+ end
324
+ end
325
+ result
326
+ end
327
+
280
328
  def find_references_in_file(file = nil, &block)
281
329
  file ||= Lib.extract_string Lib.get_translation_unit_spelling(@translation_unit)
282
330
 
@@ -384,46 +432,10 @@ module FFI
384
432
  Lib.get_cursor_hash(@cursor)
385
433
  end
386
434
 
387
- def find_all(*kinds)
388
- filter do |child, parent|
389
- kinds.include?(child.kind)
390
- end
391
- end
392
-
393
- def find_first(*kinds)
394
- find_all(*kinds).first
395
- end
396
-
397
- def filter
398
- return to_enum(:select) unless block_given?
399
-
400
- matching = []
401
-
402
- self.visit_children do |child, parent|
403
- if yield(child, parent)
404
- matching << child
405
- end
406
-
407
- :recurse
408
- end
409
-
410
- return matching
411
- end
412
-
413
- def select
414
- filter do |child, parent|
415
- yield(child)
416
- end
417
- end
418
-
419
435
  def to_s
420
436
  "Cursor <#{self.kind.to_s.gsub(/^cursor_/, '')}: #{self.spelling}>"
421
437
  end
422
438
 
423
- def to_a
424
- filter.collect{|child, parent| child}
425
- end
426
-
427
439
  def references(file = nil)
428
440
  refs = []
429
441
  self.find_references_in_file(file) do |cursor, unused|
@@ -441,6 +441,8 @@ module FFI
441
441
  attach_function :find_references_in_file, :clang_findReferencesInFile, [CXCursor.by_value, :CXFile, CXCursorAndRangeVisitor.by_value], :result
442
442
 
443
443
  attach_function :get_cursor_type, :clang_getCursorType, [CXCursor.by_value], CXType.by_value
444
+ attach_function :cursor_is_anonymous, :clang_Cursor_isAnonymous, [CXCursor.by_value], :uint
445
+ attach_function :cursor_is_anonymous_record_decl, :clang_Cursor_isAnonymousRecordDecl, [CXCursor.by_value], :uint
444
446
  attach_function :get_cursor_result_type, :clang_getCursorResultType, [CXCursor.by_value], CXType.by_value
445
447
  attach_function :get_typedef_decl_underlying_type, :clang_getTypedefDeclUnderlyingType, [CXCursor.by_value], CXType.by_value
446
448
  attach_function :get_enum_decl_integer_type, :clang_getEnumDeclIntegerType, [CXCursor.by_value], CXType.by_value
@@ -0,0 +1,15 @@
1
+ module FFI
2
+ module Clang
3
+ module Types
4
+ class Array < Type
5
+ def element_type
6
+ Type.create Lib.get_array_element_type(@type), @translation_unit
7
+ end
8
+
9
+ def size
10
+ Lib.get_array_size(@type)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ module FFI
2
+ module Clang
3
+ module Types
4
+ class Elaborated < Type
5
+ def canonical
6
+ Type.create Lib.get_canonical_type(@type), @translation_unit
7
+ end
8
+
9
+ # Example anonymous union where `u` is an elaborated type
10
+ #
11
+ # typedef struct {
12
+ # union {
13
+ # int idata;
14
+ # } u;
15
+ # } SomeStruct;
16
+ def anonymous?
17
+ self.declaration.anonymous?
18
+ end
19
+
20
+ def pointer?
21
+ self.canonical.is_a?(Pointer)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ module FFI
2
+ module Clang
3
+ module Types
4
+ class Function < Type
5
+ def variadic?
6
+ Lib.is_function_type_variadic(@type) != 0
7
+ end
8
+
9
+ def args_size
10
+ Lib.get_num_arg_types(@type)
11
+ end
12
+
13
+ def arg_type(i)
14
+ Type.create Lib.get_arg_type(@type, i), @translation_unit
15
+ end
16
+
17
+ def result_type
18
+ Type.create Lib.get_result_type(@type), @translation_unit
19
+ end
20
+
21
+ def calling_conv
22
+ Lib.get_fuction_type_calling_conv(@type)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,42 @@
1
+ module FFI
2
+ module Clang
3
+ module Types
4
+ class Pointer < Type
5
+ def pointee
6
+ Type.create Lib.get_pointee_type(@type), @translation_unit
7
+ end
8
+
9
+ def function?
10
+ self.pointee.is_a?(Types::Function)
11
+ end
12
+
13
+ def class_type
14
+ if self.kind == :type_member_pointer
15
+ Type.create Lib.type_get_class_type(@type), @translation_unit
16
+ else
17
+ nil
18
+ end
19
+ end
20
+
21
+ def forward_declaration?
22
+ # Is this a pointer to a record (struct or union) that referenced
23
+ # a forward declaration at the point of its inclusion in the translation unit?
24
+ if !self.function? && self.pointee.is_a?(Types::Elaborated) &&
25
+ self.pointee.canonical.is_a?(Types::Record)
26
+
27
+ # Get the universal symbol reference
28
+ usr = self.pointee.canonical.declaration.usr
29
+
30
+ # Now does that same usr occur earlier in the file?
31
+ first_declaration, _ = self.translation_unit.cursor.find do |child, parent|
32
+ child.usr == usr
33
+ end
34
+ # NOTE - Maybe should also check that the line number of
35
+ # is less than the line number of the declaration this type references
36
+ first_declaration.forward_declaration?
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,26 @@
1
+ module FFI
2
+ module Clang
3
+ module Types
4
+ class Record < Type
5
+ def offsetof(field)
6
+ Lib.type_get_offset_of(@type, field)
7
+ end
8
+
9
+ def anonymous?
10
+ self.spelling.match(/unnamed/)
11
+ end
12
+
13
+ def record_type
14
+ case self.spelling
15
+ when /struct/
16
+ :struct
17
+ when /union/
18
+ :union
19
+ else
20
+ raise("Unknown record type: #{self.spelling}")
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2013, by Carlos Martín Nieto.
5
+ # Copyright, 2013-2024, by Samuel Williams.
6
+ # Copyright, 2013, by Takeshi Watanabe.
7
+ # Copyright, 2014, by Masahiro Sano.
8
+ # Copyright, 2014, by Niklas Therning.
9
+ # Copyright, 2024, by Charlie Savage.
10
+
11
+ module FFI
12
+ module Clang
13
+ module Types
14
+ class Type
15
+ attr_reader :type, :translation_unit
16
+
17
+ # Just hard code the types - they don't likely to change
18
+ def self.create(cxtype, translation_unit)
19
+ case cxtype[:kind]
20
+ when :type_pointer, :type_block_pointer, :type_obj_c_object_pointer, :type_member_pointer
21
+ Pointer.new(cxtype, translation_unit)
22
+ when :type_constant_array, :type_incomplete_array, :type_variable_array, :type_dependent_sized_array
23
+ Array.new(cxtype, translation_unit)
24
+ when :type_vector
25
+ Vector.new(cxtype, translation_unit)
26
+ when :type_function_no_proto, :type_function_proto
27
+ Function.new(cxtype, translation_unit)
28
+ when :type_elaborated
29
+ Elaborated.new(cxtype, translation_unit)
30
+ when :type_typedef
31
+ TypeDef.new(cxtype, translation_unit)
32
+ when :type_record
33
+ Record.new(cxtype, translation_unit)
34
+ else
35
+ Type.new(cxtype, translation_unit)
36
+ end
37
+ end
38
+
39
+ def initialize(type, translation_unit)
40
+ @type = type
41
+ @translation_unit = translation_unit
42
+ end
43
+
44
+ def kind
45
+ @type[:kind]
46
+ end
47
+
48
+ def kind_spelling
49
+ Lib.extract_string Lib.get_type_kind_spelling @type[:kind]
50
+ end
51
+
52
+ def spelling
53
+ Lib.extract_string Lib.get_type_spelling(@type)
54
+ end
55
+
56
+ def pod?
57
+ Lib.is_pod_type(@type) != 0
58
+ end
59
+
60
+ def const_qualified?
61
+ Lib.is_const_qualified_type(@type) != 0
62
+ end
63
+
64
+ def volatile_qualified?
65
+ Lib.is_volatile_qualified_type(@type) != 0
66
+ end
67
+
68
+ def restrict_qualified?
69
+ Lib.is_restrict_qualified_type(@type) != 0
70
+ end
71
+
72
+ def alignof
73
+ Lib.type_get_align_of(@type)
74
+ end
75
+
76
+ def sizeof
77
+ Lib.type_get_size_of(@type)
78
+ end
79
+
80
+ def ref_qualifier
81
+ Lib.type_get_cxx_ref_qualifier(@type)
82
+ end
83
+
84
+ def declaration
85
+ Cursor.new Lib.get_type_declaration(@type), @translation_unit
86
+ end
87
+
88
+ def ==(other)
89
+ Lib.equal_types(@type, other.type) != 0
90
+ end
91
+
92
+ def to_s
93
+ "#{self.class.name} <#{self.kind}: #{self.spelling}>"
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,15 @@
1
+ module FFI
2
+ module Clang
3
+ module Types
4
+ class TypeDef < Type
5
+ def canonical
6
+ Type.create Lib.get_canonical_type(@type), @translation_unit
7
+ end
8
+
9
+ def anonymous?
10
+ self.canonical.kind == :type_record && self.canonical.anonymous?
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module FFI
2
+ module Clang
3
+ module Types
4
+ class Vector < Type
5
+ def element_type
6
+ Type.create Lib.get_element_type(@type), @translation_unit
7
+ end
8
+
9
+ def size
10
+ Lib.get_num_elements(@type)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -7,6 +7,6 @@
7
7
 
8
8
  module FFI
9
9
  module Clang
10
- VERSION = "0.9.0"
10
+ VERSION = "0.10.0"
11
11
  end
12
12
  end
data/lib/ffi/clang.rb CHANGED
@@ -46,3 +46,12 @@ require_relative 'clang/unsaved_file'
46
46
  require_relative 'clang/token'
47
47
  require_relative 'clang/code_completion'
48
48
  require_relative 'clang/compilation_database'
49
+
50
+ require_relative 'clang/types/type'
51
+ require_relative 'clang/types/array'
52
+ require_relative 'clang/types/elaborated'
53
+ require_relative 'clang/types/function'
54
+ require_relative 'clang/types/pointer'
55
+ require_relative 'clang/types/record'
56
+ require_relative 'clang/types/type_def'
57
+ require_relative 'clang/types/vector'
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-clang
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -55,7 +55,7 @@ cert_chain:
55
55
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
56
56
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
57
57
  -----END CERTIFICATE-----
58
- date: 2024-04-07 00:00:00.000000000 Z
58
+ date: 2024-06-14 00:00:00.000000000 Z
59
59
  dependencies:
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: ffi
@@ -110,7 +110,14 @@ files:
110
110
  - lib/ffi/clang/source_range.rb
111
111
  - lib/ffi/clang/token.rb
112
112
  - lib/ffi/clang/translation_unit.rb
113
- - lib/ffi/clang/type.rb
113
+ - lib/ffi/clang/types/array.rb
114
+ - lib/ffi/clang/types/elaborated.rb
115
+ - lib/ffi/clang/types/function.rb
116
+ - lib/ffi/clang/types/pointer.rb
117
+ - lib/ffi/clang/types/record.rb
118
+ - lib/ffi/clang/types/type.rb
119
+ - lib/ffi/clang/types/type_def.rb
120
+ - lib/ffi/clang/types/vector.rb
114
121
  - lib/ffi/clang/unsaved_file.rb
115
122
  - lib/ffi/clang/version.rb
116
123
  - license.md
@@ -136,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
143
  - !ruby/object:Gem::Version
137
144
  version: '0'
138
145
  requirements: []
139
- rubygems_version: 3.5.3
146
+ rubygems_version: 3.5.9
140
147
  signing_key:
141
148
  specification_version: 4
142
149
  summary: Ruby FFI bindings for libclang C interface.
metadata.gz.sig CHANGED
Binary file
@@ -1,160 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Released under the MIT License.
4
- # Copyright, 2013, by Carlos Martín Nieto.
5
- # Copyright, 2013-2024, by Samuel Williams.
6
- # Copyright, 2013, by Takeshi Watanabe.
7
- # Copyright, 2014, by Masahiro Sano.
8
- # Copyright, 2014, by Niklas Therning.
9
- # Copyright, 2024, by Charlie Savage.
10
-
11
- module FFI
12
- module Clang
13
- class Type
14
- attr_reader :type
15
-
16
- def initialize(type, translation_unit)
17
- @type = type
18
- @translation_unit = translation_unit
19
- end
20
-
21
- def kind
22
- @type[:kind]
23
- end
24
-
25
- def kind_spelling
26
- Lib.extract_string Lib.get_type_kind_spelling @type[:kind]
27
- end
28
-
29
- def spelling
30
- Lib.extract_string Lib.get_type_spelling(@type)
31
- end
32
-
33
- def variadic?
34
- Lib.is_function_type_variadic(@type) != 0
35
- end
36
-
37
- def pod?
38
- Lib.is_pod_type(@type) != 0
39
- end
40
-
41
- def num_arg_types
42
- Lib.get_num_arg_types(@type)
43
- end
44
-
45
- def pointer?
46
- [:type_pointer, :type_block_pointer, :type_obj_c_object_pointer, :type_member_pointer].
47
- include?(self.kind)
48
- end
49
-
50
- def pointee
51
- if self.pointer?
52
- Type.new Lib.get_pointee_type(@type), @translation_unit
53
- else
54
- nil
55
- end
56
- end
57
-
58
- def canonical
59
- Type.new Lib.get_canonical_type(@type), @translation_unit
60
- end
61
-
62
- def class_type
63
- if self.kind == :type_member_pointer
64
- Type.new Lib.type_get_class_type(@type), @translation_unit
65
- else
66
- nil
67
- end
68
- end
69
-
70
- def const_qualified?
71
- Lib.is_const_qualified_type(@type) != 0
72
- end
73
-
74
- def volatile_qualified?
75
- Lib.is_volatile_qualified_type(@type) != 0
76
- end
77
-
78
- def restrict_qualified?
79
- Lib.is_restrict_qualified_type(@type) != 0
80
- end
81
-
82
- def function?
83
- [:type_function_no_proto, :type_function_proto].include?(self.kind)
84
- end
85
-
86
- def arg_type(i)
87
- if self.function?
88
- Type.new Lib.get_arg_type(@type, i), @translation_unit
89
- else
90
- nil
91
- end
92
- end
93
-
94
- def result_type
95
- if self.function?
96
- Type.new Lib.get_result_type(@type), @translation_unit
97
- else
98
- nil
99
- end
100
- end
101
-
102
- def element_type
103
- if self.array? || [:type_vector, :type_complex].include?(self.kind)
104
- Type.new Lib.get_element_type(@type), @translation_unit
105
- else
106
- nil
107
- end
108
- end
109
-
110
- def num_elements
111
- Lib.get_num_elements(@type)
112
- end
113
-
114
- def array?
115
- [:type_constant_array, :type_incomplete_array, :type_variable_array, :type_dependent_sized_array].
116
- include?(self.kind)
117
- end
118
-
119
- def array_element_type
120
- if self.array?
121
- Type.new Lib.get_array_element_type(@type), @translation_unit
122
- else
123
- nil
124
- end
125
- end
126
-
127
- def array_size
128
- Lib.get_array_size(@type)
129
- end
130
-
131
- def alignof
132
- Lib.type_get_align_of(@type)
133
- end
134
-
135
- def sizeof
136
- Lib.type_get_size_of(@type)
137
- end
138
-
139
- def offsetof(field)
140
- Lib.type_get_offset_of(@type, field)
141
- end
142
-
143
- def ref_qualifier
144
- Lib.type_get_cxx_ref_qualifier(@type)
145
- end
146
-
147
- def calling_conv
148
- Lib.get_fuction_type_calling_conv(@type)
149
- end
150
-
151
- def declaration
152
- Cursor.new Lib.get_type_declaration(@type), @translation_unit
153
- end
154
-
155
- def ==(other)
156
- Lib.equal_types(@type, other.type) != 0
157
- end
158
- end
159
- end
160
- end