From fe71def43484098a46b6b0cd295525f25003c191 Mon Sep 17 00:00:00 2001 From: Nehal Patel Date: Fri, 17 Mar 2023 15:04:50 -0400 Subject: [PATCH] Create a TranslationUnit by loading ast file (aka precompiled header). --- src/Clang.jl | 2 +- src/trans_unit.jl | 55 ++++++++++++++++++++++++++++++++++++++++------- test/ast.jl | 17 +++++++++++++++ test/runtests.jl | 1 + 4 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 test/ast.jl diff --git a/src/Clang.jl b/src/Clang.jl index db9d40c3..86ebbf03 100644 --- a/src/Clang.jl +++ b/src/Clang.jl @@ -28,7 +28,7 @@ include("index.jl") export Index include("trans_unit.jl") -export TranslationUnit, spelling, parse_header, parse_headers +export TranslationUnit, getTranslationUnitCursor, spelling, parse_header, parse_headers, load_ast include("cursor.jl") export kind, name, spelling, value diff --git a/src/trans_unit.jl b/src/trans_unit.jl index 1344ddcf..6824321e 100644 --- a/src/trans_unit.jl +++ b/src/trans_unit.jl @@ -6,6 +6,34 @@ Parse the given source file and the translation unit corresponding to that file. mutable struct TranslationUnit ptr::CXTranslationUnit idx::Index + + function TranslationUnit( + ptr::CXTranslationUnit, + idx::Index, + ) + @assert ptr != C_NULL + obj = new(ptr, idx) + finalizer(obj) do x + if x.ptr != C_NULL + clang_disposeTranslationUnit(x) + x.ptr = C_NULL + end + end + return obj + end + + function TranslationUnit( + idx::Index, + ast_filename::AbstractString, + ) + ptr = clang_createTranslationUnit( + idx, + ast_filename) + @assert ptr != C_NULL "failed to parse file: $ast_filename" + return TranslationUnit(ptr, idx) + end + + function TranslationUnit( idx::Index, source_filename, @@ -25,14 +53,7 @@ mutable struct TranslationUnit options, ) @assert ptr != C_NULL "failed to parse file: $source_filename" - obj = new(ptr, idx) - finalizer(obj) do x - if x.ptr != C_NULL - clang_disposeTranslationUnit(x) - x.ptr = C_NULL - end - end - return obj + return TranslationUnit(ptr, idx) end end function TranslationUnit(idx, source, args, unsavedFiles, options) @@ -143,3 +164,21 @@ function parse_headers( parse_header(index, header, args, flags) end end + +""" + load_ast( + index::Index, + ast_file::AbstractString, + ) -> TranslationUnit +Return the [`TranslationUnit`](@ref) for a given precompiled header (aka an "ast file" in clang). + +# Arguments +- `index::Index`: Index. +- `ast_file::AbstractString`: the ast file to load`. + Ast files can be generated using clang e.g. `clang t.h -emit-ast -o t.pch` +""" +function load_ast( + index::Index, + ast_file::AbstractString) + TranslationUnit(index, ast_file) +end diff --git a/test/ast.jl b/test/ast.jl new file mode 100644 index 00000000..35b39c28 --- /dev/null +++ b/test/ast.jl @@ -0,0 +1,17 @@ +using Clang +using Clang.LibClang.Clang_jll +using Test + +@testset "Load AST" begin + mktempdir() do dir + header = joinpath(dir,"test.h") + pch = joinpath(dir,"test.pch") + open(header, "w") do io + write(io, "void foo();") + end + run(`$(clang()) -x c $header -emit-ast -o $pch`); + index = Index() + tu = load_ast(index, pch) + @test tu |> getTranslationUnitCursor |> children |> only |> spelling == "foo" + end +end diff --git a/test/runtests.jl b/test/runtests.jl index db6213b0..b53573c2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,7 @@ using Clang using Test +include("ast.jl") include("generators.jl") include("test_mpi.jl")