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

Clang 16 fixes #472

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
75 changes: 38 additions & 37 deletions gen/generator.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Clang.Generators
using Clang.LibClang.Clang_jll

cd(@__DIR__)

options = load_options(joinpath(@__DIR__, "generator.toml"))

Expand Down Expand Up @@ -58,42 +57,44 @@ const dependencies = PkgSpec[PkgSpec(; name = "LLVM_full_jll")]

const libdir = joinpath(@__DIR__, "..", "lib")

for (llvm_version, julia_version) in (#=(v"12.0.1", v"1.7"),=#
(v"13.0.1", v"1.8"),
(v"14.0.5", v"1.9"),
(v"15.0.6", v"1.10"),
(v"16.0.6", v"1.11"))
@info "Generating..." llvm_version julia_version
temp_prefix() do prefix
# let prefix = Prefix(mktempdir())
platform = Pkg.BinaryPlatforms.HostPlatform()
platform["llvm_version"] = string(llvm_version.major)
platform["julia_version"] = string(julia_version)
artifact_paths = setup_dependencies(prefix, dependencies, platform; verbose=true)

let options = deepcopy(options)
options["general"]["callback_documentation"] = get_docs
output_file_path = joinpath(libdir, string(llvm_version.major), options["general"]["output_file_path"])
isdir(dirname(output_file_path)) || mkpath(dirname(output_file_path))
options["general"]["output_file_path"] = output_file_path

include_dir = joinpath(destdir(prefix, platform), "include")
libclang_header_dir = joinpath(include_dir, "clang-c")
args = Generators.get_default_args()
push!(args, "-I$include_dir")

headers = detect_headers(libclang_header_dir, args)
ctx = create_context(headers, args, options)

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

rewrite!(ctx.dag)

# print
build!(ctx, BUILDSTAGE_PRINTING_ONLY)
cd(@__DIR__) do
for (llvm_version, julia_version) in (#=(v"12.0.1", v"1.7"),=#
(v"13.0.1", v"1.8"),
(v"14.0.5", v"1.9"),
(v"15.0.6", v"1.10"),
(v"16.0.6", v"1.11"))
@info "Generating..." llvm_version julia_version
temp_prefix() do prefix
# let prefix = Prefix(mktempdir())
platform = Pkg.BinaryPlatforms.HostPlatform()
platform["llvm_version"] = string(llvm_version.major)
platform["julia_version"] = string(julia_version)
artifact_paths = setup_dependencies(prefix, dependencies, platform; verbose=true)

let options = deepcopy(options)
options["general"]["callback_documentation"] = get_docs
output_file_path = joinpath(libdir, string(llvm_version.major), options["general"]["output_file_path"])
isdir(dirname(output_file_path)) || mkpath(dirname(output_file_path))
options["general"]["output_file_path"] = output_file_path

include_dir = joinpath(destdir(prefix, platform), "include")
libclang_header_dir = joinpath(include_dir, "clang-c")
args = Generators.get_default_args()
push!(args, "-I$include_dir")

headers = detect_headers(libclang_header_dir, args)
ctx = create_context(headers, args, options)

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

rewrite!(ctx.dag)

# print
build!(ctx, BUILDSTAGE_PRINTING_ONLY)
end

cleanup_dependencies(prefix, artifact_paths, platform)
end

cleanup_dependencies(prefix, artifact_paths, platform)
end
end
25 changes: 25 additions & 0 deletions lib/16/LibClang.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4330,6 +4330,19 @@ function clang_visitChildren(parent, visitor, client_data)
@ccall libclang.clang_visitChildren(parent::CXCursor, visitor::CXCursorVisitor, client_data::CXClientData)::Cuint
end

mutable struct _CXChildVisitResult end

const CXCursorVisitorBlock = Ptr{_CXChildVisitResult}

"""
clang_visitChildrenWithBlock(parent, block)

Visits the children of a cursor using the specified block. Behaves identically to [`clang_visitChildren`](@ref)() in all other respects.
"""
function clang_visitChildrenWithBlock(parent, block)
@ccall libclang.clang_visitChildrenWithBlock(parent::CXCursor, block::CXCursorVisitorBlock)::Cuint
end

"""
clang_getCursorUSR(arg1)

Expand Down Expand Up @@ -6086,6 +6099,18 @@ function clang_findIncludesInFile(TU, file, visitor)
@ccall libclang.clang_findIncludesInFile(TU::CXTranslationUnit, file::CXFile, visitor::CXCursorAndRangeVisitor)::CXResult
end

mutable struct _CXCursorAndRangeVisitorBlock end

const CXCursorAndRangeVisitorBlock = Ptr{_CXCursorAndRangeVisitorBlock}

function clang_findReferencesInFileWithBlock(arg1, arg2, arg3)
@ccall libclang.clang_findReferencesInFileWithBlock(arg1::CXCursor, arg2::CXFile, arg3::CXCursorAndRangeVisitorBlock)::CXResult
end

function clang_findIncludesInFileWithBlock(arg1, arg2, arg3)
@ccall libclang.clang_findIncludesInFileWithBlock(arg1::CXTranslationUnit, arg2::CXFile, arg3::CXCursorAndRangeVisitorBlock)::CXResult
end

"""
The client's data object that is associated with a [`CXFile`](@ref).
"""
Expand Down
2 changes: 1 addition & 1 deletion src/Clang.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export is_typedef_anon, is_forward_declaration, is_inclusion_directive
export search, children

include("type.jl")
export has_elaborated_reference, get_elaborated_cursor
export has_elaborated_reference, has_elaborated_tag_reference, get_elaborated_cursor
export has_function_reference
export fields

Expand Down
6 changes: 1 addition & 5 deletions src/generator/jltypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,7 @@ tojulia(x::CLFloat16) = JuliaCfloat16() # Float16
tojulia(x::CLNullPtr) = JuliaUnknown(x) # C++11 nullptr
tojulia(x::CLPointer) = JuliaCpointer(x)
tojulia(x::CLBlockPointer) = JuliaUnknown(x) # ObjectveC's block pointer
function tojulia(x::CLElaborated)
jlty = tojulia(getNamedType(x))
@assert jlty isa JuliaCenum || jlty isa JuliaCrecord
return jlty
end
tojulia(x::CLElaborated) = tojulia(getNamedType(x))
tojulia(x::CLInvalid) = JuliaUnknown(x)
tojulia(x::CLFunctionProto) = JuliaCfunction(spelling(getTypeDeclaration(x)))
tojulia(x::CLFunctionNoProto) = JuliaCfunction(spelling(getTypeDeclaration(x)))
Expand Down
2 changes: 1 addition & 1 deletion src/generator/nested.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ function collect_nested_record!(dag::ExprDAG, node::ExprNode, new_tags, isdeterm
field_cursors = isempty(field_cursors) ? children(node.cursor) : field_cursors
for field_cursor in field_cursors
field_ty = getCursorType(field_cursor)
has_elaborated_reference(field_ty) || continue
has_elaborated_tag_reference(field_ty) || continue
field_jlty = tojulia(field_ty)
leaf_jlty = get_jl_leaf_type(field_jlty)
leaf_jlty isa JuliaCrecord || continue # nested enums are not legal in C
Expand Down
6 changes: 3 additions & 3 deletions src/generator/resolve_deps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function resolve_dependency!(dag::ExprDAG, node::ExprNode{FunctionProto}, option
# do nothing for unknowns since we just skip them in the downstream passes
is_jl_unknown(leaf_ty) && return dag

hasref = has_elaborated_reference(ty)
hasref = has_elaborated_tag_reference(ty)
if hasref && haskey(dag.tags, leaf_ty.sym)
push!(node.adj, dag.tags[leaf_ty.sym])
elseif !hasref && haskey(dag.ids, leaf_ty.sym)
Expand Down Expand Up @@ -59,7 +59,7 @@ function resolve_dependency!(dag::ExprDAG, node::ExprNode{FunctionNoProto}, opti

is_jl_basic(leaf_ty) && return dag

hasref = has_elaborated_reference(ty)
hasref = has_elaborated_tag_reference(ty)
if hasref && haskey(dag.tags, leaf_ty.sym)
push!(node.adj, dag.tags[leaf_ty.sym])
elseif !hasref && haskey(dag.ids, leaf_ty.sym)
Expand Down Expand Up @@ -145,7 +145,7 @@ function resolve_dependency!(dag::ExprDAG, node::ExprNode{<:AbstractStructNodeTy

is_jl_basic(leaf_ty) && continue

hasref = has_elaborated_reference(ty)
hasref = has_elaborated_tag_reference(ty)
if hasref && haskey(dag.tags, leaf_ty.sym)
push!(node.adj, dag.tags[leaf_ty.sym])
elseif !hasref && haskey(dag.ids, leaf_ty.sym)
Expand Down
6 changes: 3 additions & 3 deletions src/generator/system_deps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function collect_dependent_system_nodes!(dag::ExprDAG, node::ExprNode{FunctionPr

# FIXME: typedef func proto

hasref = has_elaborated_reference(ty)
hasref = has_elaborated_tag_reference(ty)
if (hasref && haskey(dag.tags, leaf_ty.sym)) ||
(!hasref && haskey(dag.ids, leaf_ty.sym)) ||
haskey(dag.ids_extra, leaf_ty.sym) ||
Expand All @@ -50,7 +50,7 @@ function collect_dependent_system_nodes!(dag::ExprDAG, node::ExprNode{FunctionNo

is_jl_basic(leaf_ty) && return system_nodes

hasref = has_elaborated_reference(ty)
hasref = has_elaborated_tag_reference(ty)
if (hasref && haskey(dag.tags, leaf_ty.sym)) ||
(!hasref && haskey(dag.ids, leaf_ty.sym)) ||
haskey(dag.ids_extra, leaf_ty.sym)
Expand Down Expand Up @@ -134,7 +134,7 @@ function collect_dependent_system_nodes!(dag::ExprDAG, type::CLType, system_node

# FIXME: typedef func proto

hasref = has_elaborated_reference(ty)
hasref = has_elaborated_tag_reference(ty)
if (hasref && haskey(dag.tags, leaf_ty.sym)) ||
(!hasref && haskey(dag.ids, leaf_ty.sym)) ||
haskey(dag.ids_extra, leaf_ty.sym) ||
Expand Down
2 changes: 1 addition & 1 deletion src/generator/top_level.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ end
function collect_top_level_nodes!(nodes::Vector{ExprNode}, cursor::CLTypedefDecl, options)
lhs_type = getTypedefDeclUnderlyingType(cursor)

if has_elaborated_reference(lhs_type)
if has_elaborated_tag_reference(lhs_type)
ty = TypedefElaborated()
elseif has_function_reference(lhs_type)
ty = TypedefFunction()
Expand Down
29 changes: 29 additions & 0 deletions src/type.jl
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,35 @@ function has_elaborated_reference(ty::CXType)
end
has_elaborated_reference(ty::CLType) = has_elaborated_reference(ty.type)


"""
has_elaborated_tag_reference(ty::CLType) -> Bool
has_elaborated_tag_reference(ty::CXType) -> Bool
Return true if the type is an elaborated tag type or the type indirectly refers to an
elaborated tag type.
"""
function has_elaborated_tag_reference(ty::CXType)
if kind(ty) == CXType_Pointer
ptreety = getPointeeType(ty)
return has_elaborated_tag_reference(ptreety)
elseif kind(ty) == CXType_ConstantArray || kind(ty) == CXType_IncompleteArray
elty = getElementType(ty)
return has_elaborated_tag_reference(elty)
elseif is_elaborated(ty)
nty = getNamedType(ty)
if kind(nty) == CXType_Enum || kind(nty) == CXType_Record
return true
else
return has_elaborated_tag_reference(nty)
end
else
return false
end
end
has_elaborated_tag_reference(ty::CLType) = has_elaborated_tag_reference(ty.type)



"""
get_elaborated_cursor(ty::CLType) -> CLCursor
get_elaborated_cursor(ty::CXType) -> CXCursor
Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ BinaryBuilder = "12aac903-9f7c-5d81-afc2-d9565ea332ae"
CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82"
CMake_jll = "3f4e10e2-61f2-5801-8945-23b9d642d0e6"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
Tar = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
4 changes: 4 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
using Clang
using Test

# Temporary hack to make @doc work in 1.11 for the documentation tests. See:
# https://github.com/JuliaLang/julia/issues/52986
using REPL

include("generators.jl")

include("test_mpi.jl")
Expand Down
Loading