corrode icon indicating copy to clipboard operation
corrode copied to clipboard

translate nicer type names by using typedef names

Open jameysharp opened this issue 8 years ago • 3 comments

A fairly common pattern in C looks like this:

typedef struct private private;
struct private {
    ...
};

Often the typedef is in a public header file and the full struct definition is in a private header file.

Corrode gets this case wrong at the moment: any uses of the private type alias see an empty struct type, even if the full definition appears later.

I think the best way to fix this is to make typedef resolution more lazy. When the typedef itself is processed, it should record an action that will look up the referenced struct as needed, instead of storing the definition the struct has at that instant. Then baseTypeOf needs to be able to run such actions when it sees a CTypeDef type specifier.

jameysharp avatar Jul 06 '16 11:07 jameysharp

Would you care to comment more on the following TODO? (Found in interpretDeclarations before the part that deals with CTypedef.)

TODO: It would be nice to emit a type-alias item for each typedef and use the alias names anywhere we can, instead of replacing the aliases with the underlying type everywhere. That way we preserve more of the structure of the input program. But it isn't always possible, so this requires careful thought.

harpocrates avatar Jul 21 '16 20:07 harpocrates

This is a good issue to ask that question in, yes! Consider these selected declarations (from xf86drm.h because I happen to have been reading it recently, not that the details matter much):

typedef unsigned int drmSize, *drmSizePtr;

typedef enum { ... } drm_context_tFlags, *drm_context_tFlagsPtr;

typedef struct _drmBufInfo { ... } drmBufInfo, *drmBufInfoPtr;

It would be nice to translate those to something like this:

type drmSize = u32;
type drmSizePtr = *mut u32;

enum drm_context_tFlags { ... }
type drm_context_tFlagsPtr = *mut drm_context_tFlags;

struct drmBufInfo { ... }
type drmBufInfoPtr = *mut drmBufInfo;

But actually getting that result seems tricky to me.

  • In the example, the enum is declared anonymously and only the typedef gives it a name. I'd like the typedef name applied to the enum, rather than generating a new unique name.
  • The struct is named "_drmBufInfo", and then typedef'd to "drmBufInfo". I'm inclined to throw away the first name and just use the second.
  • The typedef might appear before or after the struct declaration, not just at the same time as it does in this example. It would be unfortunate if different orderings led to different results.
  • There might be multiple typedef declarations for the same struct or enum and we'd need to pick one to use as its canonical name.
  • In C, typedef records type qualifiers like const and type specifiers like unsigned, but I believe both can be modified when the new type name is used—so const signed drmSize should be equivalent to an immutable i32. We can deal with changed qualifiers since those aren't encoded in Rust's type system directly anyway, but type specifiers would force us to write out the full type rather than using any type alias.

Hopefully that clarifies my thoughts on that?

jameysharp avatar Jul 21 '16 21:07 jameysharp

I think I fixed the original bug by committing 3346deb4005e12bc27e40f63132b62953859e9e3 a few days ago, so I'm re-purposing this issue for the wishlist item that it'd be nice if struct and enum names came from the typedef enclosing them, if any, and also if other typedefs translated to Rust type aliases.

jameysharp avatar Jul 31 '16 11:07 jameysharp