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

steve naroff snaroff at apple.com
Tue May 19 10:04:27 PDT 2009


Motivation: Simplify clang's representation of ObjC Type's.

Quick review: clang's Objective-C support currently implements 4  
distinct ways to refer to instances - they are:

(1) "id": No static type information (essentially an object-oriented  
"void *").
(2) "Interface *": Refers to an instance of type Interface.
(3) "id <p1, p2>": Refers to any instance that adopts the 'p1 & p2'  
protocols.
(4) "Interface <p1, p2> *": Refers to an instance of type Interface  
that adopts the 'p1 & p2' protocols.

Some brief historical notes relevant to this discussion:

(1) The original implementation of ObjC only supported "id" (which was  
implemented by a C typedef in "objc.h").
(2) Interface-based typing was later added. Unlike "id" (where the  
pointer was implicit), interface-based typing still involves an  
explicit C pointer declaration. This is because we didn't want to  
close the door on supporting value-based objects (circa 1988). After  
20 years, we've never seriously considered adding value objects to  
ObjC (since they don't support our release-to-release binary  
compatibility goals). In hindsight, it's too bad interface-based  
typing didn't have an implicit pointer (like Java). Oh well.
(3) Protocol-based typing was later added to both (1) and (2).
(4) Lastly, GCC supports "Class <p1, p2>". Chris and I decided to  
defer supporting this until we simplified the ObjC types under  
discussion.

This very brief history lesson might help explain the current set of  
ObjC type AST's. For example:

(1) We have no ObjC Type AST for "id" (it is currently a magic  
TypedefType AST installed by Sema and accessed through ASTContext).
(2) We have ObjCInterfaceType, which unlike "id", doesn't imply a  
pointer.
(3) Lastly, we have an ObjCQualifiedIdType (with no relation to the  
magic typedef) and ObjCQualifiedInterfaceType (which is related to  
ObjCInterfaceType).

So, reasoning about ObjC object pointer types involves knowing about  
all the subtle historical differences noted above.  
ASTContext::isObjCObjectPointerType() helps mask some of the  
complexity, however there are many other places in clang where the  
differences are explicit/cumbersome. To help simplify things, I'd like  
to consider moving to the following single AST that would represent  
all ObjC object pointer types. Here is some pseudo code:

class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {

   // We could used the lower order bits to encode id/Class (which are  
built-in, not user-defined).
   // Alternatively, we could synthesize built-in ObjCInterfaceDecl's  
that correspond to id/Class.
   ObjCInterfaceDecl *Decl;

   // List of protocols, sorted on protocol name. No protocol is  
entered more than once.
   llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;

public:
   bool isObjCIdType();
   bool isObjCInterfaceType();
   bool isObjCQualifiedIdType();
   bool isObjCQualifiedInterfaceType();
   ...
};

The following classes would be deprecated: ObjCQualifiedIdType,  
ObjCQualifiedInterfaceType. ObjCInterfaceType will still exist,  
however it's usage will be minimal (since you can't declare a variable/ 
field of ObjCInterfaceType). You can, however specify an  
ObjCInterfaceType as an argument to @encode(Interface).

Note that the implicit pointer is a little odd (since it doesn't  
directly reflect what the user typed). For example, the type for  
"Interface *" will contain 0 pointer types and the type for "Interface  
**" will contain 1 pointer type. While this may seem odd, it is more  
useful and reflects the common idiom. The fact that the common idiom  
doesn't reflect the language syntax is more of an historical artifact  
(as mentioned above).

Since a lot of code depends on the ObjC type classes, I wanted to get  
some feedback before I start tearing things up:-) The actual  
conversion will be done in several phases (assuming everyone likes the  
general direction).

Thanks in advance for any feedback!

snaroff
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20090519/80d56fc6/attachment.html>


More information about the cfe-dev mailing list