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

Repair breakage to #import lines in -H mode #10

Open
wants to merge 23 commits into
base: f73f4f9d
Choose a base branch
from
Open

Repair breakage to #import lines in -H mode #10

wants to merge 23 commits into from

Conversation

Quuxplusone
Copy link

Protocol declarations (@ protocol ... @ end) are generated in files named according to the scheme "MyProtocolName-Protocol.h". But sometime between September 2011 and May 2012, class-dump started emitting the corresponding #import directives using the scheme "MyProtocolName.h" --- missing the "-Protocol" part. This won't compile, because the file "MyProtocolName.h" doesn't exist. With this revision, I restore the old correct behavior.

I think this probably broke in revision 2ccd217, judging by that revision's commit message. :)

Arthur O'Dwyer and others added 23 commits May 24, 2012 16:06
Protocol declarations (@protocol ... @EnD) are generated in files
named according to the scheme "MyProtocolName-Protocol.h". But
sometime between September 2011 and May 2012, class-dump started
emitting the corresponding #import directives using the scheme
"MyProtocolName.h" --- missing the "-Protocol" part. With this
revision, I restore the old correct behavior.

I think this probably broke in revision 2ccd217, judging by that
revision's commit message. :)
Improved visibility hidden comment
The type-encoding "@?" means "block", and "^?" means "function pointer".
Unfortunately there is no way to determine the original parameter types
or return type of the function or block, so I arbitrarily pick
(void(*)()) and (void(^)()) as the type displayed by class-dump.
…ruct.

My revision 3a1c177 wasn't quite complete enough; we also need to include
cases for the two new types in [CDType typeString], or we'll get assertion
failures on code like

    struct FaceCoreAPI {
        void (^field1)();
    };
    @interface A -(struct FaceCoreAPI*)api; @EnD

This is now fixed.
If a property is listed as having the modifier "retain" or "copy",
but is not a garbage-collected type, then we need to decorate it with
__attribute__((NSObject)) to keep the compiler quiet.

Garbage-collected types, as far as I can tell, are only "Class", "id",
block types, and named types such as "InterfaceType *". Despite the
explicit pointer syntax in "InterfaceType *", the Objective-C encoding
of that type is

    @"myInterfaceType"

If it were a pointer to a C struct type instead, it would be encoded as

    ^{myStructType=}

and would not be considered a garbage-collected type.
This is pretty much just a cosmetic change, but the whole point of the
"zone" parameter is that you're supposed to pass it to allocWithZone:,
so let's do that.

-[CDType copyWithZone:] should also use the "zone" parameter, but
in fact it doesn't directly allocate the copied type; it simply
passes along the return value of -[parser parseType:], which is
allocated in an unknown zone.
The "// Template types" section of the generated CDStructures.h contains
typedef declarations such as

    typedef struct S<int> {
        int _field1;
    } S_9abcdef0;

This causes compiler errors even *after* flattening "S<int>" into the
Objective-C-friendly "S_int_", because the S<int> type was already
defined earlier in the file. What we really want to see here is simply

    typedef struct S<int> S_9abcdef0;

I'm not at all confident that this change is the best way to guarantee
this output, but it does seem to work on my test case.
This option is designed to do inside class-dump what I've been doing
for a long time outside it with a sed script (that has finally met
its match in a deeply nested template argument).

The output of "class-dump --mangle-template-types" should be identical
to the output without "--mangle-template-types", except that each
type-identifier will have all its non-alphanumeric characters
replaced with underscore (_) characters. This will allow the output
of "class-dump random-objective-c++-binary" to compile as Objective-C
with fewer hacks. (Some hacks are still needed: for example, Apple's
QuartzCore binary has a struct with a field named "_vptr$GenericContext".
I don't know how to reproduce this; it might be a quirk of Apple's
original source code rather than a quirk of the Objective-C++
implementation.)

Right now the output of "--mangle-template-types" is not quite
identical to the old output; it's missing some lines of the form

    typedef struct vector<int> vector_5a588309;

I don't understand why this should be.
The encoding of an empty struct type is sometimes "{?=}" and sometimes
"{?}", depending on its context. Either way, class-dump internally
represents it as a type whose "members" array has zero elements.
For some reason I don't fully understand (but have made an educated
guess at in my code comments), non-empty struct types also sometimes
show up with zero elements in their "members" array. This normally
allows us to print

    struct Foo { int i; }

on first reference, and

    struct Foo

thereafter; but in the case of an empty struct type, because the
"members" array is already empty, we end up with

    struct

on first and all subsequent references, and this generally doesn't
compile.

In the long run, we need to represent "my members have already been
printed" in a different way (e.g., set "members" to nil) from the way
we represent "I have no members at all" (i.e., an empty "members"
array). However, that's a bigger change than I feel comfortable making
right now.
This is not merely efficient, but also necessary, because the CDType
may hold more information than is directly visible in the type-encoding
represented by "type". Right now the only such information is the
variable name (which is irrelevant), but soon we'll also be tracking
bitfield underlying types.
In Objective-C 2.0, ivars have not only a type-encoding but also an
offset, alignment, and size. We can use the "size" field to make an
educated guess at the proper underlying type for bitfield types;
for example, if a bitfield has encoding "b7" and size 1, we should
output it as "unsigned char field:7;" in preference to "unsigned
int field:7;".  (It might originally have been signed char, or BOOL;
we have no way of knowing.)

Furthermore, even in Objective-C 1.0 (or inside a C struct), bitfields
wider than "int" should be printed as "unsigned long long" instead,
to avoid compiler errors.

Fixes https://github.com/nygard/class-dump/issues/18.
The encoding of an empty struct type is sometimes "{?=}" and sometimes
"{?}", depending on its context. Either way, class-dump internally
represents it as a type whose "members" array has zero elements.
For some reason I don't fully understand (but have made an educated
guess at in my code comments), non-empty struct types also sometimes
show up with zero elements in their "members" array. This normally
allows us to print

    struct Foo { int i; }

on first reference, and

    struct Foo

thereafter; but in the case of an empty struct type, because the
"members" array is already empty, we end up with

    struct

on first and all subsequent references, and this generally doesn't
compile.

In the long run, we need to represent "my members have already been
printed" in a different way (e.g., set "members" to nil) from the way
we represent "I have no members at all" (i.e., an empty "members"
array). However, that's a bigger change than I feel comfortable making
right now.
This option is designed to do inside class-dump what I've been doing
for a long time outside it with a sed script (that has finally met
its match in a deeply nested template argument).

The output of "class-dump --mangle-template-types" should be identical
to the output without "--mangle-template-types", except that each
type-identifier will have all its non-alphanumeric characters
replaced with underscore (_) characters. This will allow the output
of "class-dump random-objective-c++-binary" to compile as Objective-C
with fewer hacks. (Some hacks are still needed: for example, Apple's
QuartzCore binary has a struct with a field named "_vptr$GenericContext".
I don't know how to reproduce this; it might be a quirk of Apple's
original source code rather than a quirk of the Objective-C++
implementation.)

Right now the output of "--mangle-template-types" is not quite
identical to the old output; it's missing some lines of the form

    typedef struct vector<int> vector_5a588309;

I don't understand why this should be.
This merge was messy because I rewrote the history of 'template-types'.
Old commit 7fe1666 is garbage at this point, but it's not worth the
anguish for me to go back and erase it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants