Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework the package -- Take 1 #278

Merged
merged 52 commits into from
Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
1d8601c
Rework the package
Gnimuc Jan 3, 2021
349356c
Add back basic macro support
Gnimuc Feb 23, 2021
d4b6071
Add an option to ignore header guards
Gnimuc Feb 23, 2021
94604e3
Add `CLANG_INCLUDE` if `auto_detect_system_headers` is `true`
Gnimuc Feb 23, 2021
2832928
Default behavior auditing
Gnimuc Feb 23, 2021
33e861b
Automatically detect those missing inclusion directive headers and ot…
Gnimuc Feb 24, 2021
7047e90
Fix `pretty_print` for `opaque_as_mutable_struct`
Gnimuc Feb 24, 2021
d47704e
Add a handy macro `add_def` for adding extra definitions
Gnimuc Feb 25, 2021
c651f2b
Remove extra space
Gnimuc Feb 25, 2021
02d3086
Fix the condition for `StructMutualRef`
Gnimuc Feb 25, 2021
97cea24
Fall back to use `children` if `fields` returns an empty array
Gnimuc Feb 25, 2021
2be54b9
Add `is_same` function for comparing cursors in different TUs
Gnimuc Feb 25, 2021
639d460
Print blocked headers
Gnimuc Feb 25, 2021
f25e2a8
Duplicated tag-types should also be marked
Gnimuc Feb 25, 2021
73bde47
Implement `CatchDuplicatedAnonymousTags` pass
Gnimuc Feb 25, 2021
fceb8a4
Add `TypedefMutualRef`
Gnimuc Feb 27, 2021
aef113e
Clean C code in the test folder since real-world C libraries are now …
Gnimuc Feb 27, 2021
46d5877
Implement `CollectNestedRecord` pass for collecting nested record typ…
Gnimuc Feb 27, 2021
0149486
Recursively collect nested record nodes
Gnimuc Feb 28, 2021
e3704fc
Do not cut the cycle at a typedef unless we must do
Gnimuc Feb 28, 2021
3c8c1d1
Add codegen method for generating `getproperty`
Gnimuc Mar 1, 2021
9c0bb28
Generate `Base.setproperty!`
Gnimuc Mar 1, 2021
f01399e
Support C11's nested anonymous records
Gnimuc Mar 1, 2021
9c05d38
Ignore function-like macros in the "basic" macro mode
Gnimuc Mar 2, 2021
9a1450a
Add an option for ignoring nodes in the printing passes
Gnimuc Mar 2, 2021
734f6d1
Add `StdPrinter`
Gnimuc Mar 3, 2021
246a061
Don't convert UInt to Int through type-assert (#282)
vchuravy Mar 5, 2021
429c052
Minor updates
Gnimuc Mar 10, 2021
139c600
Fix wrong translation for the return type of `FunctionNoProto` decls
Gnimuc Mar 10, 2021
6ce9801
Bump version for Julia 1.6
Gnimuc Mar 30, 2021
aa39920
Bump CI version
Gnimuc Mar 30, 2021
d2e4083
Add `TweakMutability` pass
Gnimuc Apr 2, 2021
60254e9
Use more strict rules for "auto-mutability"
Gnimuc Apr 3, 2021
68bbff3
Fix offset
Gnimuc Apr 4, 2021
fe61454
Add the `field_access_method_list` entry for generating field access …
Gnimuc Apr 4, 2021
c49cf36
Add `definition_whitelist` for peeking some definitions in the stdlib
Gnimuc Apr 5, 2021
d12ca65
Add experimental support for generating field access methods for bitf…
Gnimuc Apr 5, 2021
946e964
Correct the illegal use of `isa`
Gnimuc Apr 6, 2021
22950d4
Allow multiple jll pkgs
Gnimuc Apr 8, 2021
c7c797f
Fix a comment printing issue
Gnimuc Apr 8, 2021
88ecf0c
Add naive compiler integer types
Gnimuc Apr 8, 2021
56f71a9
Misc. fixes on Windows
Gnimuc Apr 10, 2021
084d3b4
Merge branch 'dag' of https://github.com/ihnorton/Clang.jl into dag
Gnimuc Apr 10, 2021
305a797
Fix a `normpath` issue
Gnimuc Apr 10, 2021
c7ed768
Merge branch 'dag' of https://github.com/ihnorton/Clang.jl into dag
Gnimuc Apr 10, 2021
7d7127b
Add an option for selecting compiler headers
Gnimuc Apr 11, 2021
5418e89
Generate more helper overloading methods for mutual-referenced struct…
Gnimuc Apr 11, 2021
471242f
Add support for generating deterministic symbols
Gnimuc Apr 11, 2021
f476f99
Macro: support simple binary operator macro and other improvements
Gnimuc Apr 12, 2021
63e0e78
Support `function_argument_conflict_symbols`
Gnimuc Apr 14, 2021
af19b7c
Add support for ignoring useless pure definition macros
Gnimuc Apr 14, 2021
fe798d9
Add more macro cases
Gnimuc Apr 14, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
strategy:
matrix:
version:
- '1.5'
- '1.6'
os:
- ubuntu-latest
- macOS-latest
Expand Down Expand Up @@ -38,7 +38,7 @@ jobs:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
version: '1.5'
version: '1.6'
- run: |
julia --project=docs -e '
using Pkg
Expand Down
23 changes: 6 additions & 17 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
*.so
*.dylib
*.o
*.swp
*~
*.kate-swp
*.jl.*.cov
*.jl.cov
*.jl.mem
.DS_Store
/Manifest.toml

deps/usr
deps/deps.jl
deps/build.log
gen/LibTemplate.jl
gen/CEnum.jl
gen/ctypes.jl

test/test_api.jl
test/test_common.jl
Manifest.toml
test/libclang_api.jl
test/libclang_common.jl
test/LibClang.jl
5 changes: 2 additions & 3 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
MIT License

Copyright (c) 2018 Isaiah Norton and other [contributors](https://github.com/ihnorton/Clang.jl/graphs/contributors)
Copyright (c) 2021 JuliaInterop

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -18,4 +17,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
14 changes: 7 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
name = "Clang"
uuid = "40e3b903-d033-50b4-a0cc-940c62c95e31"
authors = ["Isaiah Norton"]
version = "0.12.1"
authors = ["Isaiah Norton", "Yupei Qi <qiyupei@gmail.com>"]
version = "0.13.0"

[deps]
CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82"
Clang_jll = "0ee61d77-7f21-5576-8119-9fcc46b10100"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[compat]
CEnum = "0.4"
DataStructures = "0.17, 0.18"
julia = "~1.5.0"
Clang_jll = "~11.0.1"
julia = "~1.6.0"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[targets]
test = ["Test"]
test = ["Test", "Pkg"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ for trans_unit in ctx.trans_units
ctx.children = children(root_cursor)
for (i, child) in enumerate(ctx.children)
child_name = name(child)
child_header = filename(child)
child_header = get_filename(child)
ctx.children_index = i
# choose which cursor to wrap
startswith(child_name, "__") && continue # skip compiler definitions
Expand Down
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ for trans_unit in ctx.trans_units
ctx.children = children(root_cursor)
for (i, child) in enumerate(ctx.children)
child_name = name(child)
child_header = filename(child)
child_header = get_filename(child)
ctx.children_index = i
# choose which cursor to wrap
startswith(child_name, "__") && continue # skip compiler definitions
Expand Down
10 changes: 5 additions & 5 deletions docs/src/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ julia> struct_cursor = search(root_cursor, "ExStruct")[1]
CLCursor (CLStructDecl) ExStruct

julia> for c in children(struct_cursor) # print children
println("Cursor: ", c, "\n Kind: ", kind(c), "\n Name: ", name(c), "\n Type: ", type(c))
println("Cursor: ", c, "\n Kind: ", kind(c), "\n Name: ", name(c), "\n Type: ", getCursorType(c))
end
Cursor: CLCursor (CLFieldDecl) kind
Kind: CXCursor_FieldDecl(6)
Expand Down Expand Up @@ -166,15 +166,15 @@ julia> fdecl_children = [c for c in children(fdecl)]
```
The first three children are `CLParmDecl` cursors with the same name as the arguments in the function signature. Checking the types of the `CLParmDecl` cursors indicates a similarity to the function signature:
```julia
julia> [type(t) for t in fdecl_children[1:3]]
julia> [getCursorType(t) for t in fdecl_children[1:3]]
3-element Array{CLType,1}:
CLType (CLInt)
CLType (CLPointer)
CLType (CLPointer)
```
And, finally, retrieving the target type of each `CLPointer` argument confirms that these cursors represent the function argument type declaration:
```julia
julia> [pointee_type(type(t)) for t in fdecl_children[2:3]]
julia> [getPointeeType(getCursorType(t)) for t in fdecl_children[2:3]]
2-element Array{CLType,1}:
CLType (CLChar_S)
CLType (CLFloat)
Expand All @@ -188,11 +188,11 @@ printind(ind::Int, st...) = println(join([repeat(" ", 2*ind), st...]))
printobj(cursor::CLCursor) = printobj(0, cursor)
printobj(t::CLType) = join(typeof(t), " ", spelling(t))
printobj(t::CLInt) = t
printobj(t::CLPointer) = pointee_type(t)
printobj(t::CLPointer) = getPointeeType(t)
printobj(ind::Int, t::CLType) = printind(ind, printobj(t))

function printobj(ind::Int, cursor::Union{CLFieldDecl, CLParmDecl})
printind(ind+1, typeof(cursor), " ", printobj(type(cursor)), " ", name(cursor))
printind(ind+1, typeof(cursor), " ", printobj(getCursorType(cursor)), " ", name(cursor))
end

function printobj(ind::Int, node::Union{CLCursor, CLStructDecl, CLCompoundStmt,
Expand Down
95 changes: 33 additions & 62 deletions gen/generator.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
using Clang
using Clang.Generators
using Clang.LibClang.Clang_jll

const LIBCLANG_INCLUDE = joinpath(dirname(Clang_jll.libclang_path), "..", "include", "clang-c") |> normpath
const LIBCLANG_HEADERS = [joinpath(LIBCLANG_INCLUDE, header) for header in readdir(LIBCLANG_INCLUDE) if endswith(header, ".h")]
cd(@__DIR__)

const INCLUDE_DIR = joinpath(Clang_jll.artifact_dir, "include") |> normpath
const CLANG_C_DIR = joinpath(INCLUDE_DIR, "clang-c")

headers = [joinpath(CLANG_C_DIR, header) for header in readdir(CLANG_C_DIR) if endswith(header, ".h")]
options = load_options(joinpath(@__DIR__, "generator.toml"))

# add compiler flags
args = ["-I$INCLUDE_DIR"]

@static if Sys.iswindows()
include("windows.jl")
push!(args, "--sysroot=$mingw_sys", "-I$mingw_inc")
end

# add extra definition
@add_def time_t AbstractJuliaSIT JuliaCtime_t Ctime_t

# create context
ctx = create_context(headers, args, options)

# build without printing so we can do custom rewriting
build!(ctx, BUILDSTAGE_NO_PRINTING)

# custom rewriter
function rewrite!(e::Expr)
Meta.isexpr(e, :function) || return e
# Add deprecated warning to some functions
# ref: [Remove unused CompilationDatabase::MappedSources](https://reviews.llvm.org/D32351)
fname = e.args[1].args[1]
Expand All @@ -20,75 +43,23 @@ function rewrite!(e::Expr)
`$fname` Left here for backward compatibility.
No mapped sources exists in the C++ backend anymore.
This function just return Null `CXString`.

See:
- [Remove unused CompilationDatabase::MappedSources](https://reviews.llvm.org/D32351)
"""
insert!(e.args[2].args, 1, Expr(:macrocall, Symbol("@warn"), :Base, msg))
end
return e
end
rewrite!(x) = x
rewrite(v::Vector) = map(rewrite!, v)

# create a work context
ctx = DefaultContext()

# parse headers
parse_headers!(ctx, LIBCLANG_HEADERS,
args=["-I", joinpath(LIBCLANG_INCLUDE, ".."), map(x->"-I"*x, find_std_headers())...],
includes=vcat(LIBCLANG_INCLUDE, CLANG_INCLUDE),
)

# settings
ctx.libname = "libclang"
ctx.options["is_function_strictly_typed"] = false
ctx.options["is_struct_mutable"] = false

# write output
api_file = joinpath(@__DIR__, "libclang_api.jl")
api_stream = open(api_file, "w")

for trans_unit in ctx.trans_units
root_cursor = getcursor(trans_unit)
push!(ctx.cursor_stack, root_cursor)
header = spelling(root_cursor)
@info "wrapping header: $header ..."
# loop over all of the child cursors and wrap them, if appropriate.
ctx.children = children(root_cursor)
for (i, child) in enumerate(ctx.children)
child_name = name(child)
child_header = filename(child)
ctx.children_index = i
# choose which cursor to wrap
startswith(child_name, "__") && continue # skip compiler definitions
child_name in keys(ctx.common_buffer) && continue # already wrapped
child_header != header && continue # skip if cursor filename is not in the headers to be wrapped

# issues#243
if occursin("clang_CompileCommand_getNumMappedSources", child_name)
@info "Ignore $child_name, because this function is not export anymore."
continue
function rewrite!(dag::ExprDAG)
for node in get_nodes(dag)
for expr in get_exprs(node)
rewrite!(expr)
end

wrap!(ctx, child)
end
@info "writing $(api_file)"
println(api_stream, "# Julia wrapper for header: $(basename(header))")
println(api_stream, "# Automatically generated using Clang.jl\n")
ctx.api_buffer = rewrite(ctx.api_buffer)
print_buffer(api_stream, ctx.api_buffer)
empty!(ctx.api_buffer) # clean up api_buffer for the next header
end
close(api_stream)

# write "common" definitions: types, typealiases, etc.
common_file = joinpath(@__DIR__, "libclang_common.jl")
open(common_file, "w") do f
println(f, "# Automatically generated using Clang.jl\n")
return print_buffer(f, dump_to_buffer(ctx.common_buffer))
end
rewrite!(ctx.dag)

# uncomment the following code to generate dependency and template files
# copydeps(dirname(api_file))
# print_template(joinpath(dirname(api_file), "LibTemplate.jl"))
# print
build!(ctx, BUILDSTAGE_PRINTING_ONLY)
Loading