[cfe-commits] r65244 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/Sema/SemaType.cpp test/SemaObjC/protocol-archane.m

steve naroff snaroff at apple.com
Sat Feb 21 13:34:24 PST 2009


On Feb 21, 2009, at 4:19 PM, Daniel Dunbar wrote:

> On Sat, Feb 21, 2009 at 12:17 PM, Steve Naroff <snaroff at apple.com>  
> wrote:
>> Author: snaroff
>> Date: Sat Feb 21 14:17:11 2009
>> New Revision: 65244
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=65244&view=rev
>> Log:
>> Add support for GCC ObjC extension "Class<protocol>". Sigh.
>>
>> Found while researching <rdar://problem/6497631> Message lookup is  
>> sometimes different than gcc's.
>>
>> Will never be seen in user code. Needed to pass dejagnu testsuite.
>
> So... why do we care? Why not just keep this unsupported? Or at least,
> warn about it?
>

I'm in a conforming mood:-)

Kidding aside, I'm fine with not supporting it. I'd really like to  
avoid gratuitous changes to the type system like this.

I'd like Chris and Fariborz to weigh in before I revert any changes...

snaroff

> - Daniel
>
>>
>> Modified:
>>   cfe/trunk/include/clang/AST/ASTContext.h
>>   cfe/trunk/include/clang/AST/Type.h
>>   cfe/trunk/lib/AST/ASTContext.cpp
>>   cfe/trunk/lib/AST/Type.cpp
>>   cfe/trunk/lib/Sema/SemaType.cpp
>>   cfe/trunk/test/SemaObjC/protocol-archane.m
>>
>> Modified: cfe/trunk/include/clang/AST/ASTContext.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=65244&r1=65243&r2=65244&view=diff
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> =====================================================================
>> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
>> +++ cfe/trunk/include/clang/AST/ASTContext.h Sat Feb 21 14:17:11 2009
>> @@ -73,6 +73,7 @@
>>    ClassTemplateSpecializationTypes;
>>  llvm::FoldingSet<ObjCQualifiedInterfaceType>  
>> ObjCQualifiedInterfaceTypes;
>>  llvm::FoldingSet<ObjCQualifiedIdType> ObjCQualifiedIdTypes;
>> +  llvm::FoldingSet<ObjCQualifiedClassType> ObjCQualifiedClassTypes;
>>  /// ASTRecordLayouts - A cache mapping from RecordDecls to  
>> ASTRecordLayouts.
>>  ///  This is lazily created.  This is intentionally not serialized.
>>  llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>  
>> ASTRecordLayouts;
>> @@ -291,6 +292,10 @@
>>  QualType getObjCQualifiedIdType(ObjCProtocolDecl **ProtocolList,
>>                                  unsigned NumProtocols);
>>
>> +  /// getObjCQualifiedClassType - Return an ObjCQualifiedClassType  
>> for a
>> +  /// given 'Class' and conforming protocol list.
>> +  QualType getObjCQualifiedClassType(ObjCProtocolDecl  
>> **ProtocolList,
>> +                                     unsigned NumProtocols);
>>
>>  /// getTypeOfType - GCC extension.
>>  QualType getTypeOfExpr(Expr *e);
>>
>> Modified: cfe/trunk/include/clang/AST/Type.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=65244&r1=65243&r2=65244&view=diff
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> =====================================================================
>> --- cfe/trunk/include/clang/AST/Type.h (original)
>> +++ cfe/trunk/include/clang/AST/Type.h Sat Feb 21 14:17:11 2009
>> @@ -69,6 +69,7 @@
>>  class BuiltinType;
>>  class ObjCInterfaceType;
>>  class ObjCQualifiedIdType;
>> +  class ObjCQualifiedClassType;
>>  class ObjCQualifiedInterfaceType;
>>  class StmtIteratorBase;
>>  class ClassTemplateSpecializationType;
>> @@ -384,6 +385,7 @@
>>  bool isObjCInterfaceType() const;             // NSString or  
>> NSString<foo>
>>  bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
>>  bool isObjCQualifiedIdType() const;           // id<foo>
>> +  bool isObjCQualifiedClassType() const;        // Class<foo>
>>  bool isTemplateTypeParmType() const;          // C++ template type  
>> parameter
>>
>>  /// isDependentType - Whether this type is a dependent type, meaning
>> @@ -417,6 +419,7 @@
>>  const ObjCInterfaceType *getAsObjCInterfaceType() const;
>>  const ObjCQualifiedInterfaceType  
>> *getAsObjCQualifiedInterfaceType() const;
>>  const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const;
>> +  const ObjCQualifiedClassType *getAsObjCQualifiedClassType() const;
>>  const TemplateTypeParmType *getAsTemplateTypeParmType() const;
>>
>>  const ClassTemplateSpecializationType *
>> @@ -1744,6 +1747,49 @@
>>
>> };
>>
>> +/// ObjCQualifiedClassType - to represent Class<protocol-list>.
>> +///
>> +/// Duplicate protocols are removed and protocol list is  
>> canonicalized to be in
>> +/// alphabetical order.
>> +class ObjCQualifiedClassType : public Type,
>> +                               public llvm::FoldingSetNode {
>> +  // List of protocols for this protocol conforming 'id' type
>> +  // List is sorted on protocol name. No protocol is enterred more  
>> than once.
>> +  llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
>> +
>> +  ObjCQualifiedClassType(ObjCProtocolDecl **Protos, unsigned NumP)
>> +    : Type(ObjCQualifiedId, QualType()/*these are always  
>> canonical*/,
>> +           /*Dependent=*/false),
>> +  Protocols(Protos, Protos+NumP) { }
>> +  friend class ASTContext;  // ASTContext creates these.
>> +public:
>> +
>> +  ObjCProtocolDecl *getProtocols(unsigned i) const {
>> +    return Protocols[i];
>> +  }
>> +  unsigned getNumProtocols() const {
>> +    return Protocols.size();
>> +  }
>> +  ObjCProtocolDecl **getReferencedProtocols() {
>> +    return &Protocols[0];
>> +  }
>> +
>> +  typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator  
>> qual_iterator;
>> +  qual_iterator qual_begin() const { return Protocols.begin(); }
>> +  qual_iterator qual_end() const   { return Protocols.end(); }
>> +
>> +  virtual void getAsStringInternal(std::string &InnerString) const;
>> +
>> +  void Profile(llvm::FoldingSetNodeID &ID);
>> +  static void Profile(llvm::FoldingSetNodeID &ID,
>> +                      ObjCProtocolDecl **protocols, unsigned  
>> NumProtocols);
>> +
>> +  static bool classof(const Type *T) {
>> +    return T->getTypeClass() == ObjCQualifiedId;
>> +  }
>> +  static bool classof(const ObjCQualifiedClassType *) { return  
>> true; }
>> +
>> +};
>>
>> // Inline function definitions.
>>
>> @@ -1899,6 +1945,9 @@
>> inline bool Type::isObjCQualifiedIdType() const {
>>  return isa<ObjCQualifiedIdType>(CanonicalType.getUnqualifiedType());
>> }
>> +inline bool Type::isObjCQualifiedClassType() const {
>> +  return  
>> isa<ObjCQualifiedClassType>(CanonicalType.getUnqualifiedType());
>> +}
>> inline bool Type::isTemplateTypeParmType() const {
>>  return  
>> isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
>> }
>>
>> Modified: cfe/trunk/lib/AST/ASTContext.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=65244&r1=65243&r2=65244&view=diff
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> =====================================================================
>> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
>> +++ cfe/trunk/lib/AST/ASTContext.cpp Sat Feb 21 14:17:11 2009
>> @@ -1394,6 +1394,29 @@
>>  return QualType(QType, 0);
>> }
>>
>> +/// getObjCQualifiedClassType - Return an ObjCQualifiedIdType for  
>> the 'Class'
>> +/// decl and the conforming protocol list.
>> +QualType ASTContext::getObjCQualifiedClassType(ObjCProtocolDecl  
>> **Protocols,
>> +                                               unsigned  
>> NumProtocols) {
>> +  // Sort the protocol list alphabetically to canonicalize it.
>> +  SortAndUniqueProtocols(Protocols, NumProtocols);
>> +
>> +  llvm::FoldingSetNodeID ID;
>> +  ObjCQualifiedIdType::Profile(ID, Protocols, NumProtocols);
>> +
>> +  void *InsertPos = 0;
>> +  if (ObjCQualifiedClassType *QT =
>> +        ObjCQualifiedClassTypes.FindNodeOrInsertPos(ID, InsertPos))
>> +    return QualType(QT, 0);
>> +
>> +  // No Match;
>> +  ObjCQualifiedClassType *QType =
>> +    new (*this,8) ObjCQualifiedClassType(Protocols, NumProtocols);
>> +  Types.push_back(QType);
>> +  ObjCQualifiedClassTypes.InsertNode(QType, InsertPos);
>> +  return QualType(QType, 0);
>> +}
>> +
>> /// getTypeOfExpr - Unlike many "get<Type>" functions, we can't  
>> unique
>> /// TypeOfExpr AST's (since expression's are never shared). For  
>> example,
>> /// multiple declarations that refer to "typeof(x)" all contain  
>> different
>>
>> Modified: cfe/trunk/lib/AST/Type.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=65244&r1=65243&r2=65244&view=diff
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> =====================================================================
>> --- cfe/trunk/lib/AST/Type.cpp (original)
>> +++ cfe/trunk/lib/AST/Type.cpp Sat Feb 21 14:17:11 2009
>> @@ -869,6 +869,17 @@
>>  Profile(ID, &Protocols[0], getNumProtocols());
>> }
>>
>> +void ObjCQualifiedClassType::Profile(llvm::FoldingSetNodeID &ID,
>> +                                     ObjCProtocolDecl **protocols,
>> +                                     unsigned NumProtocols) {
>> +  for (unsigned i = 0; i != NumProtocols; i++)
>> +    ID.AddPointer(protocols[i]);
>> +}
>> +
>> +void ObjCQualifiedClassType::Profile(llvm::FoldingSetNodeID &ID) {
>> +  Profile(ID, &Protocols[0], getNumProtocols());
>> +}
>> +
>> /// LookThroughTypedefs - Return the ultimate type this typedef  
>> corresponds to
>> /// potentially looking through *all* consequtive typedefs.  This  
>> returns the
>> /// sum of the type qualifiers, so if you have:
>> @@ -1345,6 +1356,22 @@
>>  InnerString = ObjCQIString + InnerString;
>> }
>>
>> +void ObjCQualifiedClassType::getAsStringInternal(std::string  
>> &InnerString) const
>> +{
>> +  if (!InnerString.empty())    // Prefix the basic type, e.g.  
>> 'typedefname X'.
>> +    InnerString = ' ' + InnerString;
>> +  std::string ObjCQIString = "Class";
>> +  ObjCQIString += '<';
>> +  int num = getNumProtocols();
>> +  for (int i = 0; i < num; i++) {
>> +    ObjCQIString += getProtocols(i)->getNameAsString();
>> +    if (i < num-1)
>> +      ObjCQIString += ',';
>> +  }
>> +  ObjCQIString += '>';
>> +  InnerString = ObjCQIString + InnerString;
>> +}
>> +
>> void TagType::getAsStringInternal(std::string &InnerString) const {
>>  if (!InnerString.empty())    // Prefix the basic type, e.g.  
>> 'typedefname X'.
>>    InnerString = ' ' + InnerString;
>>
>> Modified: cfe/trunk/lib/Sema/SemaType.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=65244&r1=65243&r2=65244&view=diff
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> =====================================================================
>> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaType.cpp Sat Feb 21 14:17:11 2009
>> @@ -151,6 +151,10 @@
>>        // id<protocol-list>
>>        Result =  
>> Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ,
>>                                                 
>> DS.getNumProtocolQualifiers());
>> +      else if (Result == Context.getObjCClassType())
>> +        // Support the following GCC extension: Class<protocol-list>
>> +        Result =  
>> Context.getObjCQualifiedClassType((ObjCProtocolDecl**)PQ,
>> +                                                 
>> DS.getNumProtocolQualifiers());
>>      else
>>        Diag(DS.getSourceRange().getBegin(),
>>             diag::warn_ignoring_objc_qualifiers) <<  
>> DS.getSourceRange();
>>
>> Modified: cfe/trunk/test/SemaObjC/protocol-archane.m
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-archane.m?rev=65244&r1=65243&r2=65244&view=diff
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> =====================================================================
>> --- cfe/trunk/test/SemaObjC/protocol-archane.m (original)
>> +++ cfe/trunk/test/SemaObjC/protocol-archane.m Sat Feb 21 14:17:11  
>> 2009
>> @@ -27,3 +27,8 @@
>>
>> // GCC doesn't diagnose this.
>> NotAnObjCObjectType <SomeProtocol> *obj; // expected-warning  
>> {{ignoring protocol qualifiers on non-ObjC type}}
>> +
>> +// GCC extension (sigh). Found while researching rdar://6497631
>> +typedef struct objc_class *Class;
>> +
>> +Class <SomeProtocol> UnfortunateGCCExtension;
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>




More information about the cfe-commits mailing list