[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