-
Notifications
You must be signed in to change notification settings - Fork 68
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
Generator errors with struct in union #307
Comments
I guess this is a bug that may be related to handling nested tags for system nodes. I don't have time to look into this at the moment, does manually adding the definition via |
It's |
Thanks for the help. Yes, I can have a look but I wasn't entirely sure whether it should:
Looking at generated code it seems like (1) is likely appropriate as it does generate a |
The error complains about missing definition for |
Supporting collecting anonymous union alone won't solve this. struct s* p = NULL; // tag naming an unknown struct declares it
struct s { int a; }; // definition for the struct pointed to by p
void g(void)
{
struct s; // forward declaration of a new, local struct s
// this hides global struct s until the end of this block
struct s *p; // pointer to local struct s
// without the forward declaration above,
// this would point at the file-scope s
struct s { char* p; }; // definitions of the local struct s
} Currently Clang assumes all As a result, I think collecting all declarations in system headers before collecting system-dependent nodes might help. |
we don't even parse function body, so this will not be a problem.
to be clear, the reason is that non-top-level system decls are not collected in the I guess a simple fix might be:
|
This looks good. But tracing it I find even stranger situation: typedef struct
{
struct {
pthread_mutex_t lock;
} s;
} test_t; Here function collect_dependent_system_nodes!(dag::ExprDAG, node::ExprNode{<:AbstractTagType}, system_nodes)
cursor = node.cursor
for c in fields(getCursorType(cursor))
ty = getCursorType(c)
jlty = tojulia(ty)
leaf_ty = get_jl_leaf_type(jlty)
is_jl_basic(leaf_ty) && continue
hasref = has_elaborated_reference(ty)
if (hasref && haskey(dag.tags, leaf_ty.sym)) ||
(!hasref && haskey(dag.ids, leaf_ty.sym)) ||
haskey(dag.ids_extra, leaf_ty.sym)
# pass (anonymous tags now are not skipped)
elseif occursin("anonymous", spelling(ty))
# do not add this tag, but still need to trace through it
ty = UnionDuplicated() # placeholder
ndef_node = ExprNode(leaf_ty.sym, ty, ndef_cursor, Expr[], Int[])
collect_dependent_system_nodes!(dag, ndef_node, system_nodes)
else
# as suggested above
end
end
return dag
end |
As a workaround I did: function collect_dependent_system_nodes!(dag::ExprDAG, node::ExprNode{<:Union{AbstractStructNodeType,AbstractUnionNodeType}}, system_nodes)
cursor = node.cursor
for c in fields(getCursorType(cursor))
ty = getCursorType(c)
jlty = tojulia(ty)
leaf_ty = get_jl_leaf_type(jlty)
is_jl_basic(leaf_ty) && continue
hasref = has_elaborated_reference(ty)
if (hasref && haskey(dag.tags, leaf_ty.sym)) ||
(!hasref && haskey(dag.ids, leaf_ty.sym)) ||
haskey(dag.ids_extra, leaf_ty.sym) ||
occursin("anonymous", spelling(ty))
# pass
else
# add all sys nodes with the same id
for (i, n) in enumerate(dag.sys)
if n.id == leaf_ty.sym
system_nodes[n] = i
end
end
# Nested structs/unions are not dealt with above as they aren't in dag.sys.
# They will be added in the CollectNestedRecord pass but with unresolved
# system types. So just descend through them and add referenced system types.
if is_elaborated(ty)
collect_nested_dependent_system_nodes!(dag, ty, system_nodes)
end
end
end
return dag
end
function collect_nested_dependent_system_nodes!(dag::ExprDAG, ty::CLElaborated, system_nodes)
for c in fields(ty)
ty = getCursorType(c)
jlty = tojulia(ty)
leaf_ty = get_jl_leaf_type(jlty)
is_jl_basic(leaf_ty) && continue
hasref = has_elaborated_reference(ty)
if (hasref && haskey(dag.tags, leaf_ty.sym)) ||
(!hasref && haskey(dag.ids, leaf_ty.sym)) ||
haskey(dag.ids_extra, leaf_ty.sym) ||
occursin("anonymous", spelling(ty))
# pass
else
# add all sys nodes with the same id
for (i, n) in enumerate(dag.sys)
if n.id == jlty.sym
system_nodes[n] = i
end
end
# Recurse for any nested struct/union
if is_elaborated(ty)
collect_nested_dependent_system_nodes!(dag, ty, system_nodes)
end
end
end
return dag
end (Note I just copied the code for the |
hi @melonedo, would you like to submit a PR for the fix you proposed in #307 (comment) ? |
Sure. I will check it tomorrow. |
I'm trying to generate code for a library that uses pthread which includes (simplified from
pthreadtypes.h
):This results in an error:
Debugging it seems
CollectDependentSystemNode
adds__pthread_mutex_t
(and the anonymous struct) to thedag.nodes
but does not add__pthread_mutex_s
as it's anAnonymousUnion
which is ignored. Then inCollectNestedRecord
it processes__pthread_mutex_t
and adds__pthread_mutex_s
todag.nodes
but not__pthread_list_t
. Thenresolve_dependency!
tries to resolve fields of__pthread_mutex_s
and fails.Not suite sure how to properly fix this as I don't fully understand implications of various approaches.
Minimal reproduction at https://gist.github.com/thomasbrandon/32001bcb6b8275a6afd7d5782c7162ea
The text was updated successfully, but these errors were encountered: