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

Cleanup CXFile support and add unique_id #424

Merged
merged 2 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Clang.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ end

include("string.jl")

include("file.jl")
export CLFile, name, unique_id, get_filename

include("index.jl")
export Index

Expand All @@ -41,6 +44,7 @@ export TranslationUnit, spelling, parse_header, parse_headers

include("cursor.jl")
export kind, name, spelling, value
export file, file_line_column
export get_filename, get_file_line_column, get_function_args
export is_typedef_anon, is_forward_declaration, is_inclusion_directive
export search, children
Expand Down
57 changes: 24 additions & 33 deletions src/cursor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -434,55 +434,46 @@ function spelling(k::CXCursorKind)
return s
end


"""
get_filename(x::CXFile) -> String
Return the complete file and path name of the given file
file_line_column(CLCursor) -> (CLFile, Int, Int)
Return file, line and column number.
"""
function get_filename(x::CXFile)
cxstr = clang_getFileName(x)
ptr = clang_getCString(cxstr)
ptr == C_NULL && return ""
s = unsafe_string(ptr)
clang_disposeString(cxstr)
return s
function file_line_column(c::CLCursor)
file = Ref{CXFile}(C_NULL)
line = Ref{Cuint}(0)
column = Ref{Cuint}(0)
offset = Ref{Cuint}(0)
location = clang_getCursorLocation(c)
clang_getExpansionLocation(location, file, line, column, offset)
return CLFile(file[]), Int(line[]), Int(column[])
end

"""
file(c::CLCursor) -> CLFile
Return the file referenced by the input cursor.
"""
function file(c::CLCursor)
f, _, _ = file_line_column(c)
return f
end

"""
get_filename(c::Union{CXCursor,CLCursor}) -> String
Return the complete file and path name of the given file referenced by the input cursor.
"""
function get_filename(c::Union{CXCursor,CLCursor})
file = Ref{CXFile}(C_NULL)
location = clang_getCursorLocation(c)
clang_getExpansionLocation(location, file, Ref{Cuint}(0), Ref{Cuint}(0), Ref{Cuint}(0))
if file[] != C_NULL
str = GC.@preserve file get_filename(file[])
return str
else
return ""
end
f, _, _ = get_file_line_column(c)
return f
end

"""
get_file_line_column(c::Union{CXCursor,CLCursor}) -> (String, Int, Int)
Return file name, line and column number.
"""
function get_file_line_column(c::Union{CXCursor,CLCursor})
file = Ref{CXFile}(C_NULL)
line = Ref{Cuint}(0)
column = Ref{Cuint}(0)
offset = Ref{Cuint}(0)
location = clang_getCursorLocation(c)
clang_getExpansionLocation(location, file, line, column, offset)
if file[] != C_NULL
cxstr = clang_getFileName(file[])
ptr = clang_getCString(cxstr)
s = unsafe_string(ptr)
clang_disposeString(cxstr)
return s, Int(line[]), Int(column[])
else
return "", 0, 0
end
f, l, c = file_line_column(c)
return name(f), l, c
end

"""
Expand Down
38 changes: 38 additions & 0 deletions src/file.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
struct CLFile
file::CXFile
end

Base.convert(::Type{CLFile}, x::CXFile) = CLFile(x)
Base.cconvert(::Type{CXFile}, x::CLFile) = x
Base.unsafe_convert(::Type{CXFile}, x::CLFile) = x.file

Base.show(io::IO, x::CLFile) = print(io, """CLFile ("$(name(x))")""")


"""
get_filename(x::CXFile) -> String
Return the complete file and path name of the given file
"""
function get_filename(file::CXFile)
name(CLFile(file))
end


"""
name(x::CLFile) -> String
Return the complete file and path name of the given file
"""
function name(file::CLFile)
file |> clang_getFileName |> _cxstring_to_string
end

"""
unique_id(file::CLFile) -> CXFileUniqueID
Return the unique id of the given file.
"""
function unique_id(file::CLFile)
id = Ref{CXFileUniqueID}()
ret = clang_getFileUniqueID(file, id)
@assert ret==0 "Error getting unique id for $file"
id[]
end
2 changes: 1 addition & 1 deletion src/platform/system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ function get_system_includes!(env::MacEnv, prefix::String, isys::Vector{String})
joinpath(prefix, triple, "sys-root", "System", "Library", "Frameworks"))
end
else # "aarch64-apple-darwin20"
ver = VersionNumber(version.major,version.minor,version.patch)
if env.is_cxx
ver = VersionNumber(version.major,version.minor,version.patch)
push!(isys, joinpath(prefix, triple, "include", "c++", string(ver)))
push!(isys, joinpath(prefix, triple, "include", "c++", string(ver), triple))
push!(isys, joinpath(prefix, triple, "include", "c++", string(ver), "backward"))
Expand Down
51 changes: 51 additions & 0 deletions test/file.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Clang
using Test

@testset "File" begin

@testset "Null File" begin
@test name(CLFile(C_NULL)) == ""
end

@testset "Cursor filename" begin
mktempdir() do dir
header = joinpath(dir,"test.h")
open(header, "w") do io
write(io, "void foo();")
end
index = Index()
tu = parse_header(index, header)
fname = tu |> Clang.getTranslationUnitCursor |> children |>
only |> file |> name |> normpath
@test fname == header |> normpath
end
end

@testset "Unique ID" begin
@test_throws AssertionError unique_id(CLFile(C_NULL))
mktempdir() do dir
header = joinpath(dir,"test.h")
open(header, "w") do io
println(io, "void foo();")
end
a = joinpath(dir,"a.h")
open(a, "w") do io
println(io, "#include \"test.h\"")
end

b = joinpath(dir,"b.h")
open(b, "w") do io
println(io, "#include \"test.h\"")
end

index = Index()
tu_a = parse_header(index, a)
tu_b = parse_header(index, b)
cu_a = tu_a |> Clang.getTranslationUnitCursor |> children |> only
cu_b = tu_b |> Clang.getTranslationUnitCursor |> children |> only
@test (cu_a |> file |> unique_id) === (cu_b |> file |> unique_id)
end

end

end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ using Test
# https://github.com/JuliaLang/julia/issues/52986
using REPL

include("file.jl")
include("generators.jl")

include("test_mpi.jl")
Expand Down