-
Notifications
You must be signed in to change notification settings - Fork 7
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
Fix opaque types usages #114
Conversation
tests/samples/include/opaqueTypes.h
Outdated
@@ -0,0 +1,7 @@ | |||
struct s; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to start with upper case: OpaqueTypes.h
bindgen/ir/TypeDef.h
Outdated
|
||
bool usesOpaqueType() const override; | ||
|
||
using TypeAndName::replaceType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeDef
inherits from Type
and TypeAndName
, so we need to specify what version of replaceType
should be used.
A typedef may contain pointer to opaque type that should be replaced with pointer to Byte
:
typedef struct s *s;
type s = native.Ptr[Byte]
tests/samples/OpaqueTypes.scala
Outdated
def move(point: native.Ptr[struct_point], x: native.CInt, y: native.CInt): native.Ptr[struct_point] = native.extern | ||
def processPoints(p: native.Ptr[points]): native.Ptr[union_u] = native.extern | ||
def usePointerToUndefinedStruct(anonymous0: native.Ptr[Byte]): Unit = native.extern |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at this I think it would be better to have
type struct_structWithPointerToUndefinedStruct = native.CStruct0
type union_unionWithPointerToUndefinedStruct = native.CArray[Byte, native.Nat._0] // not sure if 0 length is supported
def usePointerToUndefinedStruct(anonymous0: native.Ptr[struct_structWithPointerToUndefinedStruct]): Unit = native.extern
So CStruct0
for opaque structs and then use the type alias in the pointers. With default opaque representations for structs and unions it should be possible to remove most use of replaceType
except for updates to structs and unions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No helper class should be generated for such types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a good solution.
Should we leave a comment beside CStruct0
that it is an incomplete type or opaque type, so no one will think that it is indeed empty structure?
bindgen/ir/types/PointerType.cpp
Outdated
@@ -23,3 +23,14 @@ bool PointerType::operator==(const Type &other) const { | |||
} | |||
return false; | |||
} | |||
|
|||
bool PointerType::usesOpaqueType() const { return type->usesOpaqueType(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A pointer to an opaque type is always sound, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but by the time this method is called, all pointers to opaque type are replaced with pointers to Byte
, so this method is used to finds illegal usages of opaque type
errs == "Error: type definition for struct_undefinedStruct was not found.\n" + | ||
"Error: Function useUndefinedStruct is skipped because it references an opaque type.") | ||
case _ => assert(errs == "") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To keep the tests clean, I would prefer to have checks for errors in a separate Spec.
Opaque types may be only
|
3660984
to
926ae00
Compare
926ae00
to
3a792b8
Compare
I decided not to remove structs with fields of opaque types because it is not normal situation, clangs prints error in this case. |
3a792b8
to
072189c
Compare
98b3cdc
to
ff5491e
Compare
if (typeDef.type) { | ||
s << typeDef.getType()->str(); | ||
} else { | ||
s << "native.CStruct0 // incomplete type"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to remove the comment completely, else please change it to say: opaque type
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used incomplete because it is the term that clang uses in error messages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay makes sense then.
case "LiteralDefine" => | ||
assert( | ||
errs == "Warning: integer value does not fit into 8 bytes: 18446744073709551615\n" + | ||
"Warning: integer value does not fit into 8 bytes: 9223372036854775809") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for not being more clear, what I meant by "have checks for errors in a separate Spec" was to do something like:
class BindgenReportingSpec extends FunSpec {
it("Skip variable with opaque type") {
val result = bindgen(
input = "struct undefinedStruct;
|extern struct undefinedStruct removedExtern;
|#define removedExternAlias removedExtern
|".stripMargin)
assert(
result.error == "Error: Variable alias removedExternAlias is skipped because it has incomplete type")
)
}
}
That is avoid mixing code with errors into the header files used by BindgenSpec
and instead have focused tests.
I know it is a bit more work but I think the clarity it brings will pay off in the long run.
0048a24
to
8e88cf7
Compare
f527470
to
65450fd
Compare
b1b7d5f
to
591b889
Compare
Add comment line to incomplete types
591b889
to
8c598e7
Compare
Closes #106
Replaces pointers to opaque types with pointers to
Byte
If there exists a declaration that uses an opaque type value then the declaration is skipped and error messages are printed: