[cfe-dev] Proposal to simplify ObjC Type AST's

David Chisnall csdavec at swansea.ac.uk
Tue May 19 17:05:33 PDT 2009


On 20 May 2009, at 00:36, Eli Friedman wrote:

> As far as I can tell, that doesn't change in this scheme: typedefs are
> our standard way of introducing names of builtin types into the
> translation unit.  We'd just be typedef'ing "id" to an ObjCIdType
> rather than a pointer to a struct objc_object.
>
> The only tricky thing to get right is if we allow code to reference
> "struct objc_object" directly; I think we can take care of that with a
> check in ASTContext::getPointerType, though (essentially, the idea is
> to make it impossible to construct a "struct objc_object*").

The default definition of id in ASTContext is fall-back code which is  
only important if the program does not include headers that define  
this type.  The only Objective-C code I've ever seen where this is the  
case is the clang testsuite.  In the real world it never happens; you  
always include the header provided by whichever runtime you happen to  
be using (most commonly indirectly via Foundation.h) which defines id,  
SEL, Class, and IMP.

Constructing a struct objc_object* does happen in real code, but only  
if you have included the header, created a struct objc_object and  
taken its address.  GCC does accept this code:

#import <objc/Object.h>

int main(void)
{
     struct objc_object a;
     a.isa = objc_getClass("Object");
     [&a init];
     return 0;
}

This is incredibly ugly, however, and I think it would be marginally  
less bad if it required an explicit cast of the receiver to an object  
type to work.  If this breaks any existing code, it's code that  
deserves to have been broken a long time ago.  GCC actually accepts  
some even more wrong things, like this:

int main(void)
{
     struct {void* isa;} a;
     a.isa = objc_getClass("Object");
     [&a init];
     return 0;
}

This does raise a warning that a is not a valid receiver type (and  
that init is not known as a selector), but still compiles and runs.

If you are compiling bits of an Objective-C runtime or a similar  
supporting library then you will come across this kind of thing, but  
in this code you will already have a lot of explicit casts.

On 20 May 2009, at 00:50, Fariborz Jahanian wrote:

> I am not sure if any want want to do this. But following code is  
> legal:
> #include <objc/objc.h>
> id pi;
> Class min()
> {
>   return pi->isa;
> }

This is a much more common idiom.  Ideally, however, we would be  
treating this as an ivar access with a known offset of 0, rather than  
as a structure field access.  This probably ought to generate the same  
code irrespective of whether pi is an id, an NSObject* or an Object*  
(although it should give a warning / error on NSObject where isa is  
declared @protected).  Perhaps we should be declaring an implicit  
Class isa as an ivar on any ObjCIdType, so ObjCIdType defines a  
pointer to an object with a single ivar which accepts all messages.

David



More information about the cfe-dev mailing list