ffi-clang 0.13.0 → 0.14.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/ext/rakefile.rb +2 -2
  4. data/lib/ffi/clang/clang_version.rb +7 -3
  5. data/lib/ffi/clang/code_completion.rb +121 -44
  6. data/lib/ffi/clang/comment.rb +164 -57
  7. data/lib/ffi/clang/compilation_database.rb +79 -25
  8. data/lib/ffi/clang/cursor.rb +395 -149
  9. data/lib/ffi/clang/diagnostic.rb +57 -23
  10. data/lib/ffi/clang/error.rb +12 -0
  11. data/lib/ffi/clang/file.rb +30 -11
  12. data/lib/ffi/clang/index.rb +37 -13
  13. data/lib/ffi/clang/lib/clang_version.rb +2 -2
  14. data/lib/ffi/clang/lib/code_completion.rb +15 -11
  15. data/lib/ffi/clang/lib/comment.rb +16 -14
  16. data/lib/ffi/clang/lib/compilation_database.rb +5 -5
  17. data/lib/ffi/clang/lib/cursor.rb +74 -56
  18. data/lib/ffi/clang/lib/diagnostic.rb +14 -14
  19. data/lib/ffi/clang/lib/file.rb +10 -6
  20. data/lib/ffi/clang/lib/inclusions.rb +3 -3
  21. data/lib/ffi/clang/lib/index.rb +7 -5
  22. data/lib/ffi/clang/lib/printing_policy.rb +36 -36
  23. data/lib/ffi/clang/lib/source_location.rb +9 -7
  24. data/lib/ffi/clang/lib/source_range.rb +5 -3
  25. data/lib/ffi/clang/lib/string.rb +9 -4
  26. data/lib/ffi/clang/lib/token.rb +17 -4
  27. data/lib/ffi/clang/lib/translation_unit.rb +17 -13
  28. data/lib/ffi/clang/lib/type.rb +19 -17
  29. data/lib/ffi/clang/lib.rb +35 -19
  30. data/lib/ffi/clang/platform.rb +25 -0
  31. data/lib/ffi/clang/printing_policy.rb +31 -18
  32. data/lib/ffi/clang/source_location.rb +119 -36
  33. data/lib/ffi/clang/source_range.rb +30 -12
  34. data/lib/ffi/clang/token.rb +48 -23
  35. data/lib/ffi/clang/translation_unit.rb +97 -33
  36. data/lib/ffi/clang/types/array.rb +15 -1
  37. data/lib/ffi/clang/types/elaborated.rb +19 -4
  38. data/lib/ffi/clang/types/function.rb +35 -10
  39. data/lib/ffi/clang/types/pointer.rb +23 -7
  40. data/lib/ffi/clang/types/record.rb +23 -8
  41. data/lib/ffi/clang/types/type.rb +80 -36
  42. data/lib/ffi/clang/types/type_def.rb +14 -2
  43. data/lib/ffi/clang/types/vector.rb +13 -1
  44. data/lib/ffi/clang/unsaved_file.rb +18 -8
  45. data/lib/ffi/clang/version.rb +4 -2
  46. data/lib/ffi/clang.rb +23 -45
  47. data/license.md +3 -2
  48. data/readme.md +12 -13
  49. data/releases.md +5 -0
  50. data.tar.gz.sig +0 -0
  51. metadata +10 -5
  52. metadata.gz.sig +0 -0
@@ -1,25 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2013-2024, by Samuel Williams.
4
+ # Copyright, 2013-2025, by Samuel Williams.
5
5
 
6
6
  module FFI
7
7
  module Clang
8
8
  module Lib
9
+ # FFI struct representing a string returned by libclang.
10
+ # @private
9
11
  class CXString < FFI::Struct
10
12
  layout(
11
13
  :data, :pointer,
12
14
  :private_flags, :uint
13
15
  )
14
16
  end
15
-
17
+
16
18
  attach_function :get_string, :clang_getCString, [CXString.by_value], :string
17
19
  attach_function :dispose_string, :clang_disposeString, [CXString.by_value], :void
18
-
20
+
21
+ # Extract a Ruby string from a CXString and dispose of the CXString.
22
+ # @parameter cxstring [CXString] The CXString to extract from.
23
+ # @returns [String] The extracted string.
19
24
  def self.extract_string(cxstring)
20
25
  result = get_string(cxstring)
21
26
  dispose_string cxstring
22
-
27
+
23
28
  return result
24
29
  end
25
30
  end
@@ -2,28 +2,41 @@
2
2
 
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2014, by Masahiro Sano.
5
- # Copyright, 2014-2022, by Samuel Williams.
5
+ # Copyright, 2014-2025, by Samuel Williams.
6
6
 
7
7
  module FFI
8
8
  module Clang
9
9
  module Lib
10
+ # FFI struct representing a token in libclang.
11
+ # @private
10
12
  class CXToken < FFI::Struct
11
13
  layout(
12
14
  :int_data, [:uint, 4],
13
15
  :ptr_data, :pointer,
14
16
  )
15
17
  end
16
-
18
+
19
+ # FFI pointer wrapper for token arrays that tracks size and translation unit.
20
+ # @private
17
21
  class TokensPointer < FFI::Pointer
22
+ # @attribute [r] token_size
23
+ # @returns [Integer] The number of tokens.
24
+ # @attribute [r] translation_unit
25
+ # @returns [TranslationUnit] The translation unit these tokens belong to.
18
26
  attr_reader :token_size
19
27
  attr_reader :translation_unit
28
+
29
+ # Create a new tokens pointer.
30
+ # @parameter ptr [FFI::Pointer] The pointer to the token array.
31
+ # @parameter token_size [Integer] The number of tokens.
32
+ # @parameter translation_unit [TranslationUnit] The translation unit.
20
33
  def initialize(ptr, token_size, translation_unit)
21
34
  super ptr
22
35
  @token_size = token_size
23
36
  @translation_unit = translation_unit
24
37
  end
25
38
  end
26
-
39
+
27
40
  enum :token_kind, [
28
41
  :punctuation,
29
42
  :keyword,
@@ -31,7 +44,7 @@ module FFI
31
44
  :literal,
32
45
  :comment,
33
46
  ]
34
-
47
+
35
48
  attach_function :get_token_kind, :clang_getTokenKind, [CXToken.by_value], :token_kind
36
49
  attach_function :get_token_spelliing, :clang_getTokenSpelling, [:CXTranslationUnit, CXToken.by_value], CXString.by_value
37
50
  attach_function :get_token_location, :clang_getTokenLocation, [:CXTranslationUnit, CXToken.by_value], CXSourceLocation.by_value
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2013-2024, by Samuel Williams.
4
+ # Copyright, 2013-2025, by Samuel Williams.
5
5
  # Copyright, 2014, by Masahiro Sano.
6
6
  # Copyright, 2019, by Hayden Purdy.
7
7
  # Copyright, 2022, by Motonori Iwamuro.
8
8
  # Copyright, 2023, by Charlie Savage.
9
9
 
10
- require_relative 'index'
10
+ require_relative "index"
11
11
 
12
12
  module FFI
13
13
  module Clang
14
14
  module Lib
15
15
  typedef :pointer, :CXTranslationUnit
16
-
16
+
17
17
  TranslationUnitFlags = enum [
18
18
  :none, 0x0,
19
19
  :detailed_preprocessing_record, 0x01,
@@ -33,22 +33,22 @@ module FFI
33
33
  :ignore_non_errors_from_included_files, 0x4000,
34
34
  :retain_excluded_conditional_blocks, 0x8000,
35
35
  ]
36
-
36
+
37
37
  SaveTranslationUnitFlags = enum [
38
38
  :save_translation_unit_none, 0x0,
39
39
  ]
40
-
40
+
41
41
  SaveError = enum [
42
42
  :none, 0,
43
43
  :unknown, 1,
44
44
  :translation_errors, 2,
45
45
  :invalid_translation_unit, 3
46
46
  ]
47
-
47
+
48
48
  ReparseFlags = enum [
49
49
  :none, 0x0,
50
50
  ]
51
-
51
+
52
52
  enum :resource_usage_kind, [
53
53
  :ast, 1,
54
54
  :identifiers, 2,
@@ -65,7 +65,7 @@ module FFI
65
65
  :sourcemanager_data_structures, 13,
66
66
  :preprocessor_header_search, 14,
67
67
  ]
68
-
68
+
69
69
  ErrorCodes = enum [
70
70
  :cx_error_success, 0,
71
71
  :cx_error_failure, 1,
@@ -73,7 +73,9 @@ module FFI
73
73
  :cx_error_invalid_arguments, 3,
74
74
  :cx_error_ast_read_error, 4,
75
75
  ]
76
-
76
+
77
+ # FFI struct representing translation unit resource usage.
78
+ # @private
77
79
  class CXTUResourceUsage < FFI::Struct
78
80
  layout(
79
81
  :data, :pointer,
@@ -81,27 +83,29 @@ module FFI
81
83
  :entries, :pointer
82
84
  )
83
85
  end
84
-
86
+
87
+ # FFI struct representing a single resource usage entry.
88
+ # @private
85
89
  class CXTUResourceUsageEntry < FFI::Struct
86
90
  layout(
87
91
  :kind, :resource_usage_kind,
88
92
  :amount, :ulong,
89
93
  )
90
94
  end
91
-
95
+
92
96
  # Source code translation units:
93
97
  attach_function :parse_translation_unit, :clang_parseTranslationUnit, [:CXIndex, :string, :pointer, :int, :pointer, :uint, :uint], :CXTranslationUnit
94
98
  attach_function :parse_translation_unit2, :clang_parseTranslationUnit2, [:CXIndex, :string, :pointer, :int, :pointer, :uint, :uint, :pointer], ErrorCodes
95
99
  attach_function :create_translation_unit, :clang_createTranslationUnit, [:CXIndex, :string], :CXTranslationUnit
96
100
  attach_function :dispose_translation_unit, :clang_disposeTranslationUnit, [:CXTranslationUnit], :void
97
101
  attach_function :get_translation_unit_spelling, :clang_getTranslationUnitSpelling, [:CXTranslationUnit], CXString.by_value
98
-
102
+
99
103
  attach_function :default_editing_translation_unit_options, :clang_defaultEditingTranslationUnitOptions, [], :uint
100
104
  attach_function :default_save_options, :clang_defaultSaveOptions, [:CXTranslationUnit], :uint
101
105
  attach_function :save_translation_unit, :clang_saveTranslationUnit, [:CXTranslationUnit, :string, :uint], :int
102
106
  attach_function :default_reparse_options, :clang_defaultReparseOptions, [:CXTranslationUnit], :uint
103
107
  attach_function :reparse_translation_unit, :clang_reparseTranslationUnit, [:CXTranslationUnit, :uint, :pointer, :uint], :int
104
-
108
+
105
109
  attach_function :resource_usage, :clang_getCXTUResourceUsage, [:CXTranslationUnit], CXTUResourceUsage.by_value
106
110
  attach_function :dispose_resource_usage, :clang_disposeCXTUResourceUsage, [CXTUResourceUsage.by_value], :void
107
111
  attach_function :resource_usage_name, :clang_getTUResourceUsageName, [:resource_usage_kind], :string
@@ -2,11 +2,11 @@
2
2
 
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2013, by Carlos Martín Nieto.
5
- # Copyright, 2013-2024, by Samuel Williams.
5
+ # Copyright, 2013-2025, by Samuel Williams.
6
6
  # Copyright, 2013, by Takeshi Watanabe.
7
7
  # Copyright, 2013-2014, by Masahiro Sano.
8
8
  # Copyright, 2014, by Niklas Therning.
9
- # Copyright, 2024, by Charlie Savage.
9
+ # Copyright, 2024-2025, by Charlie Savage.
10
10
 
11
11
  module FFI
12
12
  module Clang
@@ -126,7 +126,7 @@ module FFI
126
126
  :type_atomic, 177,
127
127
  :type_btf_tag_attributed, 178
128
128
  ]
129
-
129
+
130
130
  enum :calling_conv, [
131
131
  :calling_conv_default, 0,
132
132
  :calling_conv_c, 1,
@@ -153,13 +153,13 @@ module FFI
153
153
  :calling_conv_invalid, 100,
154
154
  :calling_conv_unexposed, 200
155
155
  ]
156
-
156
+
157
157
  enum :ref_qualifier_kind, [
158
158
  :ref_qualifier_none, 0,
159
159
  :ref_qualifier_lvalue, 1,
160
160
  :ref_qualifier_rvalue, 2,
161
161
  ]
162
-
162
+
163
163
  enum :layout_error, [
164
164
  :layout_error_invalid, -1,
165
165
  :layout_error_incomplete, -2,
@@ -168,7 +168,7 @@ module FFI
168
168
  :layout_error_invalid_field_name, -5,
169
169
  :layout_error_undeduced, -6
170
170
  ]
171
-
171
+
172
172
  # Also defined in cursor.rb
173
173
  enum :exception_specification_type, [
174
174
  :none,
@@ -182,47 +182,49 @@ module FFI
182
182
  :unparsed,
183
183
  :no_throw
184
184
  ]
185
-
185
+
186
+ # FFI struct representing a type in libclang.
187
+ # @private
186
188
  class CXType < FFI::Struct
187
189
  layout(
188
190
  :kind, :kind,
189
191
  :data, [:pointer, 2]
190
192
  )
191
193
  end
192
-
194
+
193
195
  attach_function :get_type_kind_spelling, :clang_getTypeKindSpelling, [:kind], CXString.by_value
194
196
  attach_function :get_type_spelling, :clang_getTypeSpelling, [CXType.by_value], CXString.by_value
195
197
  attach_function :get_named_type, :clang_Type_getNamedType, [CXType.by_value], CXType.by_value
196
-
198
+
197
199
  attach_function :is_function_type_variadic, :clang_isFunctionTypeVariadic, [CXType.by_value], :uint
198
200
  attach_function :is_pod_type, :clang_isPODType, [CXType.by_value], :uint
199
-
201
+
200
202
  attach_function :get_pointee_type, :clang_getPointeeType, [CXType.by_value], CXType.by_value
201
203
  attach_function :get_result_type, :clang_getResultType, [CXType.by_value], CXType.by_value
202
204
  attach_function :get_canonical_type, :clang_getCanonicalType, [CXType.by_value], CXType.by_value
203
-
205
+
204
206
  attach_function :type_get_class_type, :clang_Type_getClassType, [CXType.by_value], CXType.by_value
205
-
207
+
206
208
  attach_function :is_const_qualified_type, :clang_isConstQualifiedType, [CXType.by_value], :uint
207
209
  attach_function :is_volatile_qualified_type, :clang_isVolatileQualifiedType, [CXType.by_value], :uint
208
210
  attach_function :is_restrict_qualified_type, :clang_isRestrictQualifiedType, [CXType.by_value], :uint
209
-
211
+
210
212
  attach_function :get_num_arg_types, :clang_getNumArgTypes, [CXType.by_value], :int
211
213
  attach_function :get_arg_type, :clang_getArgType, [CXType.by_value, :uint], CXType.by_value
212
214
  attach_function :get_num_elements, :clang_getNumElements, [CXType.by_value], :long_long
213
215
  attach_function :get_element_type, :clang_getElementType, [CXType.by_value], CXType.by_value
214
216
  attach_function :get_array_size, :clang_getArraySize, [CXType.by_value], :long_long
215
217
  attach_function :get_array_element_type ,:clang_getArrayElementType, [CXType.by_value], CXType.by_value
216
-
218
+
217
219
  attach_function :type_get_align_of, :clang_Type_getAlignOf, [CXType.by_value], :long_long
218
220
  attach_function :type_get_size_of, :clang_Type_getSizeOf, [CXType.by_value], :long_long
219
221
  attach_function :type_get_offset_of, :clang_Type_getOffsetOf, [CXType.by_value, :string], :long_long
220
-
222
+
221
223
  attach_function :type_get_cxx_ref_qualifier, :clang_Type_getCXXRefQualifier, [CXType.by_value], :ref_qualifier_kind
222
-
224
+
223
225
  attach_function :get_fuction_type_calling_conv, :clang_getFunctionTypeCallingConv, [CXType.by_value], :calling_conv
224
226
  attach_function :get_exception_specification_type, :clang_getExceptionSpecificationType, [CXType.by_value], :exception_specification_type
225
-
227
+
226
228
  attach_function :equal_types, :clang_equalTypes, [CXType.by_value, CXType.by_value], :uint
227
229
  end
228
230
  end
data/lib/ffi/clang/lib.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2010-2012, by Jari Bakken.
5
5
  # Copyright, 2012, by Hal Brodigan.
6
- # Copyright, 2013-2024, by Samuel Williams.
6
+ # Copyright, 2013-2025, by Samuel Williams.
7
7
  # Copyright, 2013-2014, by Carlos Martín Nieto.
8
8
  # Copyright, 2013, by Takeshi Watanabe.
9
9
  # Copyright, 2014, by Masahiro Sano.
@@ -14,41 +14,47 @@
14
14
  # Copyright, 2019, by Dominic Sisnero.
15
15
  # Copyright, 2020, by Zete Lui.
16
16
  # Copyright, 2023, by Charlie Savage.
17
+ # Copyright, 2024, by msepga.
17
18
 
18
- require 'mkmf'
19
+ require "ffi"
20
+ require "mkmf"
21
+
22
+ require_relative "platform"
23
+ require_relative "error"
19
24
 
20
25
  module FFI
21
26
  module Clang
27
+ # @namespace
22
28
  module Lib
23
29
  extend FFI::Library
24
30
 
25
31
  # Use LLVM_CONFIG if it was explicitly specified:
26
- llvm_config = ENV['LLVM_CONFIG']
32
+ llvm_config = ENV["LLVM_CONFIG"]
27
33
 
28
34
  # If we aren't building for a specific version (e.g. travis) try to find llvm-config
29
- unless ENV['LLVM_VERSION']
35
+ unless ENV["LLVM_VERSION"]
30
36
  llvm_config ||= MakeMakefile.find_executable("llvm-config")
31
37
  end
32
-
38
+
33
39
  libs = []
34
-
35
- if ENV['LIBCLANG']
36
- libs << ENV['LIBCLANG']
40
+
41
+ if ENV["LIBCLANG"]
42
+ libs << ENV["LIBCLANG"]
37
43
  elsif llvm_config
38
44
  llvm_library_dir = `#{llvm_config} --libdir`.chomp
39
45
  platform = FFI::Clang.platform
40
46
 
41
47
  case platform
42
48
  when :darwin
43
- libs << llvm_library_dir + '/libclang.dylib'
49
+ libs << llvm_library_dir + "/libclang.dylib"
44
50
  when :windows
45
51
  llvm_bin_dir = `#{llvm_config} --bindir`.chomp
46
- libs << llvm_bin_dir + '/libclang.dll'
52
+ libs << llvm_bin_dir + "/libclang.dll"
47
53
  else
48
- libs << llvm_library_dir + '/libclang.so'
54
+ libs << llvm_library_dir + "/libclang.so"
49
55
  end
50
56
  end
51
-
57
+
52
58
  begin
53
59
  xcode_dir = `xcode-select -p`.chomp
54
60
  %W[
@@ -63,25 +69,35 @@ module FFI
63
69
  rescue Errno::ENOENT
64
70
  # Ignore
65
71
  end
66
-
72
+
67
73
  libs << "clang"
68
-
74
+
69
75
  ffi_lib libs
70
-
76
+
77
+ # Convert an options hash to a bitmask for libclang enums.
78
+ # @parameter enum [FFI::Enum] The enum type.
79
+ # @parameter opts [Array(Symbol)] The array of option symbols.
80
+ # @returns [Integer] The bitmask representing the options.
81
+ # @raises [Error] If an unknown option is provided.
71
82
  def self.bitmask_from(enum, opts)
72
83
  bitmask = 0
73
-
84
+
74
85
  opts.each do |symbol|
75
86
  if int = enum[symbol]
76
87
  bitmask |= int
77
88
  else
78
- raise Error, "unknown option: #{symbol}, expected one of #{enum.symbols}"
89
+ raise Error, "unknown option: #{symbol}, expected one of #{enum.symbols}"
79
90
  end
80
91
  end
81
-
92
+
82
93
  bitmask
83
94
  end
84
-
95
+
96
+ # Convert a bitmask to an array of option symbols.
97
+ # @parameter enum [FFI::Enum] The enum type.
98
+ # @parameter bitmask [Integer] The bitmask to convert.
99
+ # @returns [Array(Symbol)] The array of option symbols.
100
+ # @raises [Error] If unknown bits are set in the bitmask.
85
101
  def self.opts_from(enum, bitmask)
86
102
  bit = 1
87
103
  result = []
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Samuel Williams.
5
+
6
+ require "rbconfig"
7
+
8
+ module FFI
9
+ module Clang
10
+ # Get the current platform identifier.
11
+ # @returns [Symbol] The platform identifier (`:darwin`, `:linux`, `:windows`, or a custom platform string).
12
+ def self.platform
13
+ case RUBY_PLATFORM
14
+ when /darwin/
15
+ :darwin
16
+ when /linux/
17
+ :linux
18
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
19
+ :windows
20
+ else
21
+ RUBY_PLATFORM.split("-").last
22
+ end
23
+ end
24
+ end
25
+ end
@@ -2,35 +2,48 @@
2
2
 
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2024, by Charlie Savage.
5
- # Copyright, 2024, by Samuel Williams.
5
+ # Copyright, 2024-2025, by Samuel Williams.
6
6
 
7
- require_relative 'lib/printing_policy'
7
+ require_relative "lib/printing_policy"
8
8
 
9
9
  module FFI
10
10
  module Clang
11
+ # Represents a printing policy that controls how declarations are formatted.
11
12
  class PrintingPolicy < AutoPointer
13
+ # Initialize a printing policy for a cursor.
14
+ # @parameter cursor [FFI::Pointer] The cursor to get the policy from.
12
15
  def initialize(cursor)
13
- policy = Lib.get_printing_policy(cursor)
16
+ policy = Lib.get_printing_policy(cursor)
14
17
  super(policy)
15
- @cursor = cursor
18
+ @cursor = cursor
16
19
  end
17
-
20
+
21
+ # Release the printing policy pointer.
22
+ # @parameter pointer [FFI::Pointer] The pointer to release.
18
23
  def self.release(pointer)
19
24
  Lib.dispose_printing_policy(pointer)
20
25
  end
21
-
22
- def get_property(property)
23
- result = Lib.printing_policy_get_property(self, property)
24
- result == 0 ? false : true
25
- end
26
-
27
- def set_property(property, value)
28
- Lib.printing_policy_set_property(self, property, value ? 1 : 0)
29
- end
30
-
31
- def pretty_print
32
- Lib.extract_string Lib.pretty_print(@cursor, self)
33
- end
26
+
27
+ # Get a printing policy property value.
28
+ # @parameter property [Symbol] The property name.
29
+ # @returns [Boolean] The property value.
30
+ def get_property(property)
31
+ result = Lib.printing_policy_get_property(self, property)
32
+ result == 0 ? false : true
33
+ end
34
+
35
+ # Set a printing policy property value.
36
+ # @parameter property [Symbol] The property name.
37
+ # @parameter value [Boolean] The property value.
38
+ def set_property(property, value)
39
+ Lib.printing_policy_set_property(self, property, value ? 1 : 0)
40
+ end
41
+
42
+ # Pretty print the cursor using this policy.
43
+ # @returns [String] The formatted cursor string.
44
+ def pretty_print
45
+ Lib.extract_string Lib.pretty_print(@cursor, self)
46
+ end
34
47
  end
35
48
  end
36
49
  end