<commit_before># Clang
This package provides a Julia language wrapper for libclang: the stable, C-exported
interface to the LLVM Clang compiler. The [libclang API documentation](http://clang.llvm.org/doxygen/group__CINDEX.html)
provides background on the functionality available through libclang, and thus
through the Julia wrapper. The repository also hosts related tools built
on top of libclang functionality.

## Installation
Now, the package provides an out-of-box installation experience on Linux, macOS and Windows. You
could simply install it by running:
```
pkg> add Clang
```

## C-bindings generator
The package includes a generator to create Julia wrappers for C libraries from a collection of header files. The following declarations are currently supported:

- function: translated to Julia ccall(`va_list` and vararg argument are not supported)
- struct: translated to Julia struct
- enum: translated to [`CEnum`](https://github.com/JuliaInterop/CEnum.jl)
- union: translated to Julia struct
- typedef: translated to Julia typealias to underlying intrinsic type
- macro: limited support(see src/wrap_c.jl)

Here is a simple example:
```julia
using Clang
using Clang_jll # `pkg> activate Clang`

# LIBCLANG_HEADERS are those headers to be wrapped.
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")]

wc = init(; headers = LIBCLANG_HEADERS,
            output_file = joinpath(@__DIR__, "libclang_api.jl"),
            common_file = joinpath(@__DIR__, "libclang_common.jl"),
            clang_includes = vcat(LIBCLANG_INCLUDE, CLANG_INCLUDE),
            clang_args = ["-I", joinpath(LIBCLANG_INCLUDE, "..")],
            header_wrapped = (root, current)->root == current,
            header_library = x->"libclang",
            clang_diagnostics = true,
            )

run(wc)
```
Note that it might complain about missing some std headers, e.g. `fatal error: 'time.h' file not found`,
which could be fixed by adding `-Istdlib/include/on/your/specific/platform` to `clang_args`, for example,
```
# on macOS
using Clang: find_std_headers
for header in find_std_headers()
    push!(clang_args, "-I"*header)
end
```

#### Backward compatibility
If you miss those old behaviors before v0.8, please `Pkg.pin` the package to v0.8 and
make the following change in your old generator script:
```julia
using Clang: CLANG_INCLUDE
using Clang.Deprecated.wrap_c
using Clang.Deprecated.cindex
```

## Build a custom C-bindings generator
A custom C-bindings generator tends to be used on large codebases, often with multiple API versions to support. Building a generator requires some customization effort, so for small libraries the initial
investment may not pay off.

The above-mentioned C-bindings generator only exposes several entry points for customization.
In fact, it's actually not that hard to directly build your own C-bindings generator,
for example, the following script is used for generating `LibClang`, you could refer to [Tutorial](@ref) for
further details.
```julia
using Clang
using Clang_jll # `pkg> activate Clang`

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")]

# create a work context
ctx = DefaultContext()

# parse headers
parse_headers!(ctx, LIBCLANG_HEADERS,
               args=["-I", joinpath(LIBCLANG_INCLUDE, "..")],
               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")
<commit_msg>Update documentation for new generator wrapper<commit_after># Clang
This package provides a Julia language wrapper for libclang: the stable, C-exported
interface to the LLVM Clang compiler. The [libclang API documentation](http://clang.llvm.org/doxygen/group__CINDEX.html)
provides background on the functionality available through libclang, and thus
through the Julia wrapper. The repository also hosts related tools built
on top of libclang functionality.

## Installation
Now, the package provides an out-of-box installation experience on Linux, macOS and Windows. You
could simply install it by running:
```
pkg> add Clang
```

## C-bindings generator
The package includes a generator to create Julia wrappers for C libraries from a collection of header files. The following declarations are currently supported:

- function: translated to Julia ccall(`va_list` and vararg argument are not supported)
- struct: translated to Julia struct
- enum: translated to [`CEnum`](https://github.com/JuliaInterop/CEnum.jl)
- union: translated to Julia struct
- typedef: translated to Julia typealias to underlying intrinsic type
- macro: limited support(see src/wrap_c.jl)

Here is a simple example:
```julia
using Clang
using Clang_jll # `pkg> activate Clang`

# LIBCLANG_HEADERS are those headers to be wrapped.
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")]

wc = init(; headers = LIBCLANG_HEADERS,
            output_file = joinpath(@__DIR__, "libclang_api.jl"),
            common_file = joinpath(@__DIR__, "libclang_common.jl"),
            clang_includes = vcat(LIBCLANG_INCLUDE, CLANG_INCLUDE),
            clang_args = ["-I", joinpath(LIBCLANG_INCLUDE, "..")],
            header_wrapped = (root, current)->root == current,
            header_library = x->"libclang",
            clang_diagnostics = true,
            )

run(wc)
```
Note that it might complain about missing some std headers, e.g. `fatal error: 'time.h' file not found`,
which could be fixed by adding `-Istdlib/include/on/your/specific/platform` to `clang_args`, for example,
```
# on macOS
using Clang: find_std_headers
for header in find_std_headers()
    push!(clang_args, "-I"*header)
end
```

#### v0.8 compatibility
If you miss those old behaviors before v0.8, please `Pkg.pin` the package to v0.8 and
make the following change in your old generator script:
```julia
using Clang: CLANG_INCLUDE
using Clang.Deprecated.wrap_c
using Clang.Deprecated.cindex
```

## Build a custom C-bindings generator
A custom C-bindings generator tends to be used on large codebases, often with multiple API versions to support. Building a generator requires some customization effort, so for small libraries the initial
investment may not pay off.

The above-mentioned C-bindings generator only exposes several entry points for customization.
In fact, it's actually not that hard to directly build your own C-bindings generator,
for example, the following script is used for generating `LibClang`, you could refer to [Tutorial](@ref) for
further details.

Write a config file `generator.toml`:
```
[general]
library_name = "libclang"
output_file_path = "./LibClang.jl"
module_name = "LibClang"
jll_pkg_name = "Clang_jll"
export_symbol_prefixes = ["CX", "clang_"]
```

and a Julia script `generator.jl`:
```julia
using Clang.Generators
using Clang.LibClang.Clang_jll

cd(@__DIR__)

include_dir = joinpath(Clang_jll.artifact_dir, "include") |> normpath
clang_dir = joinpath(include_dir, "clang-c")

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

# add compiler flags, e.g. "-DXXXXXXXXX"
args = get_default_args()
push!(args, "-I$include_dir")

headers = [joinpath(clang_dir, header) for header in readdir(clang_dir) if endswith(header, ".h")]
# there is also an experimental `detect_headers` function for auto-detecting top-level headers in the directory
# headers = detect_headers(clang_dir, args)

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

# run generator
build!(ctx)
```

Please refer to [this toml file](https://github.com/JuliaInterop/Clang.jl/blob/master/gen/generator.toml) for a full list of configuration options.

### v0.12 example
The generator above is the recommended generator for v0.13 and above. There was another generator wrappper before, here is an example.
```julia
using Clang
using Clang_jll # `pkg> activate Clang`

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")]

# create a work context
ctx = DefaultContext()

# parse headers
parse_headers!(ctx, LIBCLANG_HEADERS,
               args=["-I", joinpath(LIBCLANG_INCLUDE, "..")],
               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")

{'fraction_non_alphanumeric': 0.09892027483913186, 'fraction_numerical': 0.0017450103609990184, 'mean_word_length': 4.720524017467249, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 18, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6565961', 'n_tokens_mistral': 2881, 'n_tokens_neox': 2733, 'n_words': 948}