You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.2 KiB
Ruby

# frozen_string_literal: true
require_relative '../ext/ffi-clang/lib/ffi/clang'
require_relative '../tools/ci_lib'
class Parser
CLANG_VERSION = FFI::Clang.clang_version_string.match(/\d+\.\d+\.\d+/).match 0
alias inspect to_s
@@opts = %w(
-std=c++17 -Wno-undefined-inline -Wno-undefined-internal -Wno-assume
)
clangdir = File.join ENV['PREFIX'] || '/usr', 'lib/clang', CLANG_VERSION
if File.exist? File.join clangdir, 'include/stddef.h'
@@opts << "-resource-dir=#{clangdir}"
end
def self.add_opts opts
@@opts.concat opts
end
@@src = {}
def self.add_src handlers, src
src.each do |s|
(@@src[s] ||= Set.new).merge handlers
end
end
def self.src = @@src
def self.gen_binding src, dst, args
new.gen_binding src, dst, args
end
attr_reader :tu, :filter
def parse src, args
src_noext = src.gsub(/\.[^.]*$/, '')
fname_map = {}
@filter = ->c, parent do
c.visit_children do |c2|
if c2.kind == :annotate_attr && c2.spelling.start_with?('alias_file ')
fname_map[c2.location.file] = c2.spelling[11..]
end
:break
end
loc = c.location.file or return true
loc = fname_map[loc] || loc
loc.gsub(/\.[^.]*$/, '') == src_noext
end
parse_tu src, args
end
def parse_tu fname, extra_opts
index = FFI::Clang::Index.new
@tu = index.parse_translation_unit fname, @@opts + extra_opts, [],
%i(keep_going skip_function_bodies)
@tu.diagnostics.each do |d|
if d.severity == :error || d.severity == :fatal
CI.eerror d.format
else
CI.ewarn d.format
end
end
self
end
def gen dst
dst.puts <<EOS
// Auto generated code, do not edit. See gen_binding in project root.
#ifndef LIBSHIT_BINDING_GENERATOR
EOS
@hs.each {|h| h.generate dst }
dst.puts '#endif'
self
end
def gen_binding src, dst, args
dst ||= "#{src.sub /\.[^.]+\z/, ''}.binding.hpp"
hs = @@src[src] or fail "Unknown source #{src.inspect}"
parse src, args
@hs = hs.map {|h| h.new self }
@hs.each &:parse
if dst == '-'
gen $stdout
else
File.open(dst, 'w') {|f| gen f }
end
self
end
end