<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Motivation: Simplify clang's representation of ObjC Type's.</div><div><br></div><div>Quick review: clang's Objective-C support currently implements 4 distinct ways to refer to instances - they are:</div><div><br></div><div>(1) "id": No static type information (essentially an object-oriented "void *"). </div><div>(2) "<i>Interface</i> *": Refers to an instance of type <i>Interface</i>.</div><div>(3) "id <p1, p2>": Refers to any instance that adopts the 'p1 & p2' protocols.</div><div>(4) "<i>Interface</i> <p1, p2> *": Refers to an instance of type <i>Interface</i> that adopts the 'p1 & p2' protocols.</div><div><br></div><div>Some brief historical notes relevant to this discussion:</div><div><br></div><div>(1) The original implementation of ObjC only supported "id" (which was implemented by a C typedef in "objc.h").</div><div>(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.</div><div>(3) Protocol-based typing was later added to both (1) and (2).</div><div>(4) Lastly, GCC supports "Class <p1, p2>". Chris and I decided to defer supporting this until we simplified the ObjC types under discussion.</div><div><br></div><div>This very brief history lesson might help explain the current set of ObjC type AST's. For example:</div><div><br></div><div>(1) We have no ObjC Type AST for "id" (it is currently a magic TypedefType AST installed by Sema and accessed through ASTContext).</div><div>(2) We have ObjCInterfaceType, which unlike "id", doesn't imply a pointer.</div><div>(3) Lastly, we have an ObjCQualifiedIdType (with no relation to the magic typedef) and ObjCQualifiedInterfaceType (which is related to ObjCInterfaceType).</div><div><br></div><div>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:</div><div><br></div><div>class <b>ObjCObjectPointerType</b> : public Type, public llvm::FoldingSetNode {</div><div><br></div><div>  // We could used the lower order bits to encode id/Class (which are built-in, not user-defined).</div><div>  // Alternatively, we could synthesize built-in ObjCInterfaceDecl's that correspond to id/Class.</div><div>  ObjCInterfaceDecl *Decl;</div><div><br></div><div><div>  // List of protocols, sorted on protocol name. No protocol is entered more than once.</div><div>  llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;</div><div><br></div></div><div><div>public:</div><div>  bool isObjCIdType();</div><div>  bool isObjCInterfaceType();</div><div>  bool isObjCQualifiedIdType();</div><div>  bool isObjCQualifiedInterfaceType();</div><div>  ...</div><div>};</div><div><br></div><div>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(<i>Interface</i>).</div><div><br></div></div><div><div>Note that the implicit pointer is a little odd (since it doesn't directly reflect what the user typed). For example, the type for "<i>Interface</i> *" will contain 0 pointer types and the type for "<span class="Apple-style-span" style="font-style: italic; ">Interface</span> **" 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).</div><div><br></div><div>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).</div><div><br></div><div>Thanks in advance for any feedback!</div><div><br></div><div>snaroff</div></div></body></html>