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

steve naroff snaroff at apple.com
Tue May 19 12:49:25 PDT 2009


On May 19, 2009, at 1:45 PM, Fariborz Jahanian wrote:

> Few comments; please see below.
>
> On May 19, 2009, at 10:04 AM, steve naroff wrote:
>
>> 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();
>
> Is there going to be isObjCClassType() in the future?
>

Sure...

>>   bool isObjCInterfaceType();
> This name is confusing to me. Since this AST is for pointers only,  
> shouldn't it be named something like isObjCInterfacePointerType()?
>

That's fine with me...

>>   bool isObjCQualifiedIdType();
>>   bool isObjCQualifiedInterfaceType();
> Same as my last question.
>>   ...
>> };
>>
>> 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).
>
> You are keeping ObjCInterfaceType for stand-alone interface (and  
> presumably a variation for qualified interface type).
> If so, then it is not clear to me how you do a type conversion from  
> ObjCObjectPointerType to ObjCInterfaceType when user asks for it.
> I know that it is rare, but it can happen as in the following test  
> case:
>
> @interface I @end
> I *pi;
> int main()
> {
> 	return sizeof (*pi);
> }
>
> I guess a more general question is does a pointer to  
> ObjCInterfaceType conforms to  ObjCObjectPointerType?

Great example. I think ObjCObjectPointerType would implement  
getPointeeType(), which would return an ObjCInterfaceType. This is  
what BlockPointerType and MemberPointerType do.

Sema::CheckIndirectionOperand() will need to allow for this, since the  
"*" will be implicit.

Make sense?

snaroff

> - Fariborz
>
>
>>
>> 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
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>

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


More information about the cfe-dev mailing list