[cfe-commits] r75808 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Frontend/PCHBitCodes.h lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/Mangle.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp lib/Sema/Sema.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp test/SemaObjC/comptypes-3.m test/SemaObjC/conditional-expr-3.m
Fariborz Jahanian
fjahanian at apple.com
Wed Jul 15 18:03:25 PDT 2009
On Jul 15, 2009, at 2:22 PM, Steve Naroff wrote:
>
> On Jul 15, 2009, at 4:45 PM, Fariborz Jahanian wrote:
>
>> Nice. Few comments below.
>>
>
> Sure...
>
>> - Fariborz
>>
>> On Jul 15, 2009, at 11:40 AM, Steve Naroff wrote:
>>
>>> Author: snaroff
>>> Date: Wed Jul 15 13:40:39 2009
>>> New Revision: 75808
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=75808&view=rev
>>> Log:
>>> Implement the ObjC pseudo built-in types as clang "BuiltinType's".
>>> I say pseudo built-in types, since Sema still injects a typedef
>>> for recognition (i.e. they aren't truly built-ins from a parser
>>> perspective).
>>>
>>> This removes the static data/methods on ObjCObjectPointerType
>>> while preserving the nice API (no need to fiddle with ASTContext:-).
>>>
>>> This patch also adds Type::isObjCBuiltinType().
>>>
>>> This should be the last fairly large patch related to recrafting
>>> the ObjC type system. The follow-on patches should be fairly small.
>>>
>
> <snip>
>
>>> bool isObjCIdType(QualType T) const {
>>> - return T == ObjCIdType;
>>> + return T == ObjCIdTypedefType;
>>> }
>>> bool isObjCClassType(QualType T) const {
>>> - return T == ObjCClassType;
>>> + return T == ObjCClassTypedefType;
>>
>> I am not sure about this and isObjCIdType(). You are comparing
>> against a typedef AST node 'id' and typedef AST node for 'Class'.
>> what if 'T' is the builtin type for 'id' or 'Class'? This predicate
>> returns false.
>>
>
> All I changed is the name (to avoid confusion with ObjCIdTypedefType/
> ObjCClassTypedefType).
>
> Nevertheless, you are correct. From a source code perspective, the
> only real 'id' or 'Class' type is the Typedef type (injected by
> Sema). This has always been the case I believe.
>
> The Builtin type is simply a clever mechanism to preserve the nice
> API without resorting to static data. More specifically,
> ASTContext::ObjCBuiltinIdTy and ASTContext::ObjCBuiltinClassTy will
> *only* be referred to by ObjCIdTypedefType/ObjCClassTypedefType.
> Without it, I would have had to move many Type predicates to
> ASTContext (or fiddle with some weird union in
> ObjCObjectPointerType). This seemed like an elegant solution to the
> problem...especially since id/Class are in fact builtin now. The
> more I played with this solution, the more I liked it.
>
Very nice. OK.
>
>>
>>>
>>> }
>>> bool isObjCSelType(QualType T) const {
>>> assert(SelStructType && "isObjCSelType used before 'SEL' type is
>>> built");
>>>
>>> Modified: cfe/trunk/include/clang/AST/Type.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=75808&r1=75807&r2=75808&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- cfe/trunk/include/clang/AST/Type.h (original)
>>> +++ cfe/trunk/include/clang/AST/Type.h Wed Jul 15 13:40:39 2009
>>> @@ -404,6 +404,7 @@
>>> bool isObjCQualifiedIdType() const; // id<foo>
>>> bool isObjCIdType() const; // id
>>> bool isObjCClassType() const; // Class
>>> + bool isObjCBuiltinType() const; // 'id' or 'Class'
>>> bool isTemplateTypeParmType() const; // C++ template type
>>> parameter
>>> bool isNullPtrType() const; // C++0x nullptr_t
>>>
>>> @@ -592,8 +593,10 @@
>>> Overload, // This represents the type of an overloaded function
>>> declaration.
>>> Dependent, // This represents the type of a type-dependent
>>> expression.
>>>
>>> - UndeducedAuto // In C++0x, this represents the type of an
>>> auto variable
>>> + UndeducedAuto, // In C++0x, this represents the type of an
>>> auto variable
>>> // that has not been deduced yet.
>>> + ObjCId, // This represents the ObjC 'id' type.
>>> + ObjCClass // This represents the ObjC 'Class' type.
>>> };
>>> private:
>>> Kind TypeKind;
>>> @@ -1899,7 +1902,7 @@
>>> /// Duplicate protocols are removed and protocol list is
>>> canonicalized to be in
>>> /// alphabetical order.
>>> class ObjCObjectPointerType : public Type, public
>>> llvm::FoldingSetNode {
>>> - QualType PointeeType; // will always point to an interface type.
>>> + QualType PointeeType; // A builin or interface type.
>>>
>>> // List of protocols for this protocol conforming object type
>>> // List is sorted on protocol name. No protocol is entered more
>>> than once.
>>> @@ -1909,20 +1912,10 @@
>>> Type(ObjCObjectPointer, QualType(), /*Dependent=*/false),
>>> PointeeType(T), Protocols(Protos, Protos+NumP) { }
>>> friend class ASTContext; // ASTContext creates these.
>>> - friend class ObjCInterfaceType; // To enable 'id' and 'Class'
>>> predicates.
>>>
>>> - static ObjCInterfaceType *IdInterfaceT;
>>> - static ObjCInterfaceType *ClassInterfaceT;
>>> - static void setIdInterface(QualType T) {
>>> - IdInterfaceT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
>>> - }
>>> - static void setClassInterface(QualType T) {
>>> - ClassInterfaceT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
>>> - }
>>> - static ObjCInterfaceType *getIdInterface() { return
>>> IdInterfaceT; }
>>> - static ObjCInterfaceType *getClassInterface() { return
>>> ClassInterfaceT; }
>>> public:
>>> - // Get the pointee type. Pointee is required to always be an
>>> interface type.
>>> + // Get the pointee type. Pointee will either be a built-in type
>>> (for 'id' and
>>> + // 'Class') or will be an interface type (for user-defined
>>> types).
>>> // Note: Pointee can be a TypedefType whose canonical type is an
>>> interface.
>>> // Example: typedef NSObject T; T *var;
>>> QualType getPointeeType() const { return PointeeType; }
>> Name Pointee and comment above is confusing to me. To me Pointee is
>> what a pointer is pointing at.
>>
>> Here you mean several things as I understand it.
>> 1) For 'id' and 'Class' it holds the builtin type for 'id' and
>> 'Class' when their container is ObjCObjectPointerType
>> for the two typedefs 'id' and 'Class'.
>
> Yes.
>
>>
>>
>> 2) For an interface pointer type; such as, "NSObject *" is Pointee
>> for "NSObject" (as the name implies)?
>>
>
> Yes.
>
>> 3) For the example in the comment ( typedef NSObject T; T *var)
>> Pointee referes to "NSObject" right?
>>
>
> Nope. Pointee would be a TypedefType whose canonical type is an
> interface. I say this in the "Note:".
>
> Do you think I need to rewrite the comment?
Nope. Pointee would be for 'T' in your example. You may want to add
this for clarification, I guess.
>
You missed this addition comments (there are actually in two places in
ASTContext.cpp).
> + for (ObjCObjectPointerType::qual_iterator J = RHSOPT-
>> qual_begin(),
> + E = RHSOPT->qual_end(); J != E; ++J) {
> + if ((*J)->lookupProtocolNamed((*I)->getIdentifier()))
> + RHSImplementsProtocol = true;
> + }
After setting RHSImplementsProtocol = true; you want to break out of
the loop.
- Thanks, Fariborz
>
> snaroff
>
More information about the cfe-commits
mailing list