[cfe-commits] r103870 - in /cfe/trunk: include/clang/AST/ include/clang/Frontend/ lib/AST/ lib/Checker/ lib/CodeGen/ lib/Frontend/ lib/Index/ lib/Sema/ test/SemaObjCXX/ tools/libclang/

John McCall rjmccall at apple.com
Sat May 15 04:32:37 PDT 2010


Author: rjmccall
Date: Sat May 15 06:32:37 2010
New Revision: 103870

URL: http://llvm.org/viewvc/llvm-project?rev=103870&view=rev
Log:
Substantially alter the design of the Objective C type AST by introducing
ObjCObjectType, which is basically just a pair of
  one of {primitive-id, primitive-Class, user-defined @class}
with
  a list of protocols.
An ObjCObjectPointerType is therefore just a pointer which always points to
one of these types (possibly sugared).  ObjCInterfaceType is now just a kind
of ObjCObjectType which happens to not carry any protocols.

Alter a rather large number of use sites to use ObjCObjectType instead of
ObjCInterfaceType.  Store an ObjCInterfaceType as a pointer on the decl rather
than hashing them in a FoldingSet.  Remove some number of methods that are no
longer used, at least after this patch.

By simplifying ObjCObjectPointerType, we are now able to easily remove and apply
pointers to Objective-C types, which is crucial for a certain kind of ObjC++
metaprogramming common in WebKit.


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/CanonicalType.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/AST/TypeLoc.h
    cfe/trunk/include/clang/AST/TypeLocBuilder.h
    cfe/trunk/include/clang/AST/TypeNodes.def
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/AST/TypePrinter.cpp
    cfe/trunk/lib/Checker/CFRefCount.cpp
    cfe/trunk/lib/Checker/GRExprEngine.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.h
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Index/Analyzer.cpp
    cfe/trunk/lib/Index/ResolveLocation.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaObjCXX/deduction.mm
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CXTypes.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sat May 15 06:32:37 2010
@@ -98,7 +98,7 @@
   llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
   llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
   llvm::FoldingSet<DependentNameType> DependentNameTypes;
-  llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
+  llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
   llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
 
   llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
@@ -624,16 +624,15 @@
                                 const TemplateSpecializationType *TemplateId,
                                 QualType Canon = QualType());
 
-  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
-                                ObjCProtocolDecl **Protocols = 0,
-                                unsigned NumProtocols = 0);
-
-  /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for the
-  /// given interface decl and the conforming protocol list.
-  QualType getObjCObjectPointerType(QualType OIT,
-                                    ObjCProtocolDecl **ProtocolList = 0,
-                                    unsigned NumProtocols = 0,
-                                    unsigned Quals = 0);
+  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
+
+  QualType getObjCObjectType(QualType Base,
+                             ObjCProtocolDecl * const *Protocols,
+                             unsigned NumProtocols);
+
+  /// getObjCObjectPointerType - Return a ObjCObjectPointerType type
+  /// for the given ObjCObjectType.
+  QualType getObjCObjectPointerType(QualType OIT);
 
   /// getTypeOfType - GCC extension.
   QualType getTypeOfExprType(Expr *e);
@@ -1182,8 +1181,8 @@
   // Check the safety of assignment from LHS to RHS
   bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
                                const ObjCObjectPointerType *RHSOPT);
-  bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
-                               const ObjCInterfaceType *RHS);
+  bool canAssignObjCInterfaces(const ObjCObjectType *LHS,
+                               const ObjCObjectType *RHS);
   bool canAssignObjCInterfacesInBlockPointer(
                                           const ObjCObjectPointerType *LHSOPT,
                                           const ObjCObjectPointerType *RHSOPT);

Modified: cfe/trunk/include/clang/AST/CanonicalType.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CanonicalType.h?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CanonicalType.h (original)
+++ cfe/trunk/include/clang/AST/CanonicalType.h Sat May 15 06:32:37 2010
@@ -643,6 +643,24 @@
 };
 
 template<>
+struct CanProxyAdaptor<ObjCObjectType>
+  : public CanProxyBase<ObjCObjectType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
+                                      getInterface)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
+
+  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
+};
+
+template<>
 struct CanProxyAdaptor<ObjCObjectPointerType>
   : public CanProxyBase<ObjCObjectPointerType> {
   LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Sat May 15 06:32:37 2010
@@ -623,6 +623,17 @@
   template<typename Derived>
   bool RecursiveASTVisitor<Derived>::VisitObjCInterfaceType(
                                                         ObjCInterfaceType *T) {
+    return getDerived().VisitObjCObjectType(T);
+  }
+
+  template<typename Derived>
+  bool RecursiveASTVisitor<Derived>::VisitObjCObjectType(ObjCObjectType *T) {
+    // We have to watch out here because an ObjCInterfaceType's base
+    // type is itself.
+    if (T->getBaseType().getTypePtr() != T)
+      if (Visit(T->getBaseType()))
+        return true;
+
     return getDerived().VisitType(T);
   }
 

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat May 15 06:32:37 2010
@@ -755,6 +755,9 @@
   };
 
 private:
+  Type(const Type&);           // DO NOT IMPLEMENT.
+  void operator=(const Type&); // DO NOT IMPLEMENT.
+
   QualType CanonicalType;
 
   /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
@@ -765,9 +768,9 @@
   /// subclasses can pack their bitfields into the same word.
   bool Dependent : 1;
 
-  Type(const Type&);           // DO NOT IMPLEMENT.
-  void operator=(const Type&); // DO NOT IMPLEMENT.
 protected:
+  enum { BitsRemainingInType = 23 };
+
   // silence VC++ warning C4355: 'this' : used in base member initializer list
   Type *this_() { return this; }
   Type(TypeClass tc, QualType Canonical, bool dependent)
@@ -879,7 +882,7 @@
   bool isObjCObjectPointerType() const;         // Pointer to *any* ObjC object.
   // FIXME: change this to 'raw' interface type, so we can used 'interface' type
   // for the common case.
-  bool isObjCInterfaceType() const;             // NSString or NSString<foo>
+  bool isObjCObjectType() const;                // NSString or typeof(*(id)0)
   bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
   bool isObjCQualifiedIdType() const;           // id<foo>
   bool isObjCQualifiedClassType() const;        // Class<foo>
@@ -920,7 +923,7 @@
   // for object declared using an interface.
   const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
   const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
-  const ObjCInterfaceType *getAsObjCQualifiedInterfaceType() const;
+  const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
   const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
 
   /// \brief Retrieves the CXXRecordDecl that this type refers to, either
@@ -935,10 +938,6 @@
   // immediately following this class.
   template <typename T> const T *getAs() const;
 
-  /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
-  /// interface, return the interface type, otherwise return null.
-  const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const;
-
   /// getArrayElementTypeNoTypeQual - If this is an array type, return the
   /// element type of the array, potentially with type qualifiers missing.
   /// This method should never be used when type qualifiers are meaningful.
@@ -2750,65 +2749,184 @@
   static bool classof(const DependentNameType *T) { return true; }
 };
 
-/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
-/// object oriented design.  They basically correspond to C++ classes.  There
-/// are two kinds of interface types, normal interfaces like "NSString" and
-/// qualified interfaces, which are qualified with a protocol list like
-/// "NSString<NSCopyable, NSAmazing>".
-class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
-  ObjCInterfaceDecl *Decl;
+/// ObjCObjectType - Represents a class type in Objective C.
+/// Every Objective C type is a combination of a base type and a
+/// list of protocols.
+///
+/// Given the following declarations:
+///   @class C;
+///   @protocol P;
+///
+/// 'C' is an ObjCInterfaceType C.  It is sugar for an ObjCObjectType
+/// with base C and no protocols.
+///
+/// 'C<P>' is an ObjCObjectType with base C and protocol list [P].
+///
+/// 'id' is a TypedefType which is sugar for an ObjCPointerType with
+/// base BuiltinType::ObjCIdType and no protocols.
+///
+/// 'id<P>' is an ObjCPointerType with base BuiltinType::ObjCIdType
+/// and protocol list [P].  Eventually this should get its own sugar
+/// class to better represent the source.
+class ObjCObjectType : public Type {
+  // Pad the bit count up so that NumProtocols is 2-byte aligned
+  unsigned : BitsRemainingInType - 16;
 
-  /// \brief The number of protocols stored after the ObjCInterfaceType node.
-  /// The list of protocols is sorted on protocol name. No protocol is enterred 
-  /// more than once.
-  unsigned NumProtocols;
+  /// \brief The number of protocols stored after the
+  /// ObjCObjectPointerType node.
+  ///
+  /// In the canonical object type, these are sorted alphabetically
+  /// and uniqued.
+  unsigned NumProtocols : 16;
 
-  ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
-                    ObjCProtocolDecl **Protos, unsigned NumP);
-  friend class ASTContext;  // ASTContext creates these.
-public:
-  void Destroy(ASTContext& C);
+  /// Either a BuiltinType or an InterfaceType or sugar for either.
+  QualType BaseType;
 
-  ObjCInterfaceDecl *getDecl() const { return Decl; }
+  ObjCProtocolDecl * const *getProtocolStorage() const {
+    return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
+  }
+
+  ObjCProtocolDecl **getProtocolStorage();
+
+protected:
+  ObjCObjectType(QualType Canonical, QualType Base, 
+                 ObjCProtocolDecl * const *Protocols, unsigned NumProtocols);
+
+  enum Nonce_ObjCInterface { Nonce_ObjCInterface };
+  ObjCObjectType(enum Nonce_ObjCInterface)
+    : Type(ObjCInterface, QualType(), false),
+      NumProtocols(0),
+      BaseType(QualType(this_(), 0)) {}
+
+public:
+  QualType getBaseType() const { return BaseType; }
+
+  bool isObjCId() const {
+    return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
+  }
+  bool isObjCClass() const {
+    return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
+  }
+  bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
+  bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
+  bool isObjCUnqualifiedIdOrClass() const {
+    if (!qual_empty()) return false;
+    if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>())
+      return T->getKind() == BuiltinType::ObjCId ||
+             T->getKind() == BuiltinType::ObjCClass;
+    return false;
+  }
+  bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); }
+  bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); }
+
+  /// Gets the interface declaration for this object type, if the base type
+  /// really is an interface.
+  ObjCInterfaceDecl *getInterface() const;
+
+  typedef ObjCProtocolDecl * const *qual_iterator;
+
+  qual_iterator qual_begin() const { return getProtocolStorage(); }
+  qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
+
+  bool qual_empty() const { return getNumProtocols() == 0; }
 
   /// getNumProtocols - Return the number of qualifying protocols in this
   /// interface type, or 0 if there are none.
   unsigned getNumProtocols() const { return NumProtocols; }
 
-  /// \brief Retrieve the Ith protocol.
+  /// \brief Fetch a protocol by index.
   ObjCProtocolDecl *getProtocol(unsigned I) const {
     assert(I < getNumProtocols() && "Out-of-range protocol access");
     return qual_begin()[I];
   }
   
-  /// qual_iterator and friends: this provides access to the (potentially empty)
-  /// list of protocols qualifying this interface.
-  typedef ObjCProtocolDecl*  const * qual_iterator;
-  qual_iterator qual_begin() const {
-    return reinterpret_cast<qual_iterator>(this + 1);
-  }
-  qual_iterator qual_end() const   {
-    return qual_begin() + NumProtocols;
-  }
-  bool qual_empty() const { return NumProtocols == 0; }
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
+  Linkage getLinkage() const; // key function
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ObjCObject ||
+           T->getTypeClass() == ObjCInterface;
+  }
+  static bool classof(const ObjCObjectType *) { return true; }
+};
+
+/// ObjCObjectTypeImpl - A class providing a concrete implementation
+/// of ObjCObjectType, so as to not increase the footprint of
+/// ObjCInterfaceType.  Code outside of ASTContext and the core type
+/// system should not reference this type.
+class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
+  friend class ASTContext;
+
+  // If anyone adds fields here, ObjCObjectType::getProtocolStorage()
+  // will need to be modified.
+
+  ObjCObjectTypeImpl(QualType Canonical, QualType Base, 
+                     ObjCProtocolDecl * const *Protocols,
+                     unsigned NumProtocols)
+    : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {}
+
+public:
+  void Destroy(ASTContext& C); // key function
+
   void Profile(llvm::FoldingSetNodeID &ID);
   static void Profile(llvm::FoldingSetNodeID &ID,
-                      const ObjCInterfaceDecl *Decl,
-                      ObjCProtocolDecl * const *protocols, 
-                      unsigned NumProtocols);
+                      QualType Base,
+                      ObjCProtocolDecl *const *protocols, 
+                      unsigned NumProtocols);  
+};
 
-  virtual Linkage getLinkage() const;
+inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
+  return reinterpret_cast<ObjCProtocolDecl**>(
+            static_cast<ObjCObjectTypeImpl*>(this) + 1);
+}
+
+/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
+/// object oriented design.  They basically correspond to C++ classes.  There
+/// are two kinds of interface types, normal interfaces like "NSString" and
+/// qualified interfaces, which are qualified with a protocol list like
+/// "NSString<NSCopyable, NSAmazing>".
+class ObjCInterfaceType : public ObjCObjectType {
+  ObjCInterfaceDecl *Decl;
+
+  ObjCInterfaceType(const ObjCInterfaceDecl *D)
+    : ObjCObjectType(Nonce_ObjCInterface),
+      Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  void Destroy(ASTContext& C); // key function
+
+  ObjCInterfaceDecl *getDecl() const { return Decl; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
 
   static bool classof(const Type *T) {
     return T->getTypeClass() == ObjCInterface;
   }
   static bool classof(const ObjCInterfaceType *) { return true; }
+
+  // Nonsense to "hide" certain members of ObjCObjectType within this
+  // class.  People asking for protocols on an ObjCInterfaceType are
+  // not going to get what they want: ObjCInterfaceTypes are
+  // guaranteed to have no protocols.
+  enum {
+    qual_iterator,
+    qual_begin,
+    qual_end,
+    getNumProtocols,
+    getProtocol
+  };
 };
 
+inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
+  if (const ObjCInterfaceType *T =
+        getBaseType()->getAs<ObjCInterfaceType>())
+    return T->getDecl();
+  return 0;
+}
+
 /// ObjCObjectPointerType - Used to represent 'id', 'Interface *', 'id <p>',
 /// and 'Interface <p> *'.
 ///
@@ -2817,15 +2935,9 @@
 class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
   QualType PointeeType; // A builtin or interface type.
 
-  /// \brief The number of protocols stored after the ObjCObjectPointerType 
-  /// node.
-  ///
-  /// The list of protocols is sorted on protocol name. No protocol is enterred 
-  /// more than once.
-  unsigned NumProtocols;
-
-  ObjCObjectPointerType(QualType Canonical, QualType T,
-                        ObjCProtocolDecl **Protos, unsigned NumP);
+  ObjCObjectPointerType(QualType Canonical, QualType Pointee)
+    : Type(ObjCObjectPointer, Canonical, false),
+      PointeeType(Pointee) {}
   friend class ASTContext;  // ASTContext creates these.
 
 public:
@@ -2838,8 +2950,12 @@
   //   For example: typedef NSObject T; T *var;
   QualType getPointeeType() const { return PointeeType; }
 
+  const ObjCObjectType *getObjectType() const {
+    return PointeeType->getAs<ObjCObjectType>();
+  }
+
   const ObjCInterfaceType *getInterfaceType() const {
-    return PointeeType->getAs<ObjCInterfaceType>();
+    return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>();
   }
   /// getInterfaceDecl - returns an interface decl for user-defined types.
   ObjCInterfaceDecl *getInterfaceDecl() const {
@@ -2847,45 +2963,42 @@
   }
   /// isObjCIdType - true for "id".
   bool isObjCIdType() const {
-    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
-           !NumProtocols;
+    return getObjectType()->isObjCUnqualifiedId();
   }
   /// isObjCClassType - true for "Class".
   bool isObjCClassType() const {
-    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
-           !NumProtocols;
+    return getObjectType()->isObjCUnqualifiedClass();
   }
   
   /// isObjCQualifiedIdType - true for "id <p>".
   bool isObjCQualifiedIdType() const {
-    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
-           NumProtocols;
+    return getObjectType()->isObjCQualifiedId();
   }
   /// isObjCQualifiedClassType - true for "Class <p>".
   bool isObjCQualifiedClassType() const {
-    return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
-           NumProtocols;
+    return getObjectType()->isObjCQualifiedClass();
   }
   /// qual_iterator and friends: this provides access to the (potentially empty)
   /// list of protocols qualifying this interface.
-  typedef ObjCProtocolDecl*  const * qual_iterator;
+  typedef ObjCObjectType::qual_iterator qual_iterator;
 
   qual_iterator qual_begin() const {
-    return reinterpret_cast<qual_iterator> (this + 1);
+    return getObjectType()->qual_begin();
   }
-  qual_iterator qual_end() const   {
-    return qual_begin() + NumProtocols;
+  qual_iterator qual_end() const {
+    return getObjectType()->qual_end();
   }
-  bool qual_empty() const { return NumProtocols == 0; }
+  bool qual_empty() const { return getObjectType()->qual_empty(); }
 
   /// getNumProtocols - Return the number of qualifying protocols in this
   /// interface type, or 0 if there are none.
-  unsigned getNumProtocols() const { return NumProtocols; }
+  unsigned getNumProtocols() const {
+    return getObjectType()->getNumProtocols();
+  }
 
   /// \brief Retrieve the Ith protocol.
   ObjCProtocolDecl *getProtocol(unsigned I) const {
-    assert(I < getNumProtocols() && "Out-of-range protocol access");
-    return qual_begin()[I];
+    return getObjectType()->getProtocol(I);
   }
   
   bool isSugared() const { return false; }
@@ -2894,9 +3007,9 @@
   virtual Linkage getLinkage() const;
 
   void Profile(llvm::FoldingSetNodeID &ID);
-  static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
-                      ObjCProtocolDecl *const *protocols, 
-                      unsigned NumProtocols);
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
+    ID.AddPointer(T.getAsOpaquePtr());
+  }
   static bool classof(const Type *T) {
     return T->getTypeClass() == ObjCObjectPointer;
   }
@@ -3135,12 +3248,6 @@
     return *this;
 }
 
-inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
-  if (const PointerType *PT = getAs<PointerType>())
-    return PT->getPointeeType()->getAs<ObjCInterfaceType>();
-  return 0;
-}
-
 inline bool Type::isFunctionType() const {
   return isa<FunctionType>(CanonicalType);
 }
@@ -3207,8 +3314,8 @@
 inline bool Type::isObjCObjectPointerType() const {
   return isa<ObjCObjectPointerType>(CanonicalType);
 }
-inline bool Type::isObjCInterfaceType() const {
-  return isa<ObjCInterfaceType>(CanonicalType);
+inline bool Type::isObjCObjectType() const {
+  return isa<ObjCObjectType>(CanonicalType);
 }
 inline bool Type::isObjCQualifiedIdType() const {
   if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
@@ -3257,13 +3364,11 @@
 
 inline bool Type::hasPointerRepresentation() const {
   return (isPointerType() || isReferenceType() || isBlockPointerType() ||
-          isObjCInterfaceType() || isObjCObjectPointerType() ||
-          isObjCQualifiedInterfaceType() || isNullPtrType());
+          isObjCObjectPointerType() || isNullPtrType());
 }
 
 inline bool Type::hasObjCPointerRepresentation() const {
-  return (isObjCInterfaceType() || isObjCObjectPointerType() ||
-          isObjCQualifiedInterfaceType());
+  return isObjCObjectPointerType();
 }
 
 /// Insertion operator for diagnostics.  This allows sending QualType's into a

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Sat May 15 06:32:37 2010
@@ -559,6 +559,7 @@
 struct ObjCProtocolListLocInfo {
   SourceLocation LAngleLoc;
   SourceLocation RAngleLoc;
+  bool HasBaseType;
 };
 
 // A helper class for defining ObjC TypeLocs that can qualified with
@@ -566,24 +567,15 @@
 //
 // TypeClass basically has to be either ObjCInterfaceType or
 // ObjCObjectPointerType.
-template <class Derived, class TypeClass, class LocalData>
-class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
-                                                       Derived,
-                                                       TypeClass,
-                                                       LocalData> {
+class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                 ObjCObjectTypeLoc,
+                                                 ObjCObjectType,
+                                                 ObjCProtocolListLocInfo> {
   // SourceLocations are stored after Info, one for each Protocol.
   SourceLocation *getProtocolLocArray() const {
     return (SourceLocation*) this->getExtraLocalData();
   }
 
-protected:
-  void initializeLocalBase(SourceLocation Loc) {
-    setLAngleLoc(Loc);
-    setRAngleLoc(Loc);
-    for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
-      setProtocolLoc(i, Loc);
-  }
-
 public:
   SourceLocation getLAngleLoc() const {
     return this->getLocalData()->LAngleLoc;
@@ -617,29 +609,48 @@
     return *(this->getTypePtr()->qual_begin() + i);
   }
   
+  bool hasBaseTypeAsWritten() const {
+    return getLocalData()->HasBaseType;
+  }
+
+  void setHasBaseTypeAsWritten(bool HasBaseType) {
+    getLocalData()->HasBaseType = HasBaseType;
+  }
+
+  TypeLoc getBaseLoc() const {
+    return getInnerTypeLoc();
+  }
+
   SourceRange getSourceRange() const {
     return SourceRange(getLAngleLoc(), getRAngleLoc());
   }
 
   void initializeLocal(SourceLocation Loc) {
-    initializeLocalBase(Loc);
+    setLAngleLoc(Loc);
+    setRAngleLoc(Loc);
+    for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+      setProtocolLoc(i, Loc);
   }
 
   unsigned getExtraLocalDataSize() const {
     return this->getNumProtocols() * sizeof(SourceLocation);
   }
+
+  QualType getInnerType() const {
+    return getTypePtr()->getBaseType();
+  }
 };
 
 
-struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo {
+struct ObjCInterfaceLocInfo {
   SourceLocation NameLoc;
 };
 
 /// \brief Wrapper for source info for ObjC interfaces.
-class ObjCInterfaceTypeLoc :
-    public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc,
-                                   ObjCInterfaceType,
-                                   ObjCInterfaceLocInfo> {
+class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                    ObjCInterfaceTypeLoc,
+                                                    ObjCInterfaceType,
+                                                    ObjCInterfaceLocInfo> {
 public:
   ObjCInterfaceDecl *getIFaceDecl() const {
     return getTypePtr()->getDecl();
@@ -654,84 +665,15 @@
   }
 
   SourceRange getSourceRange() const {
-    if (getNumProtocols()) 
-      return SourceRange(getNameLoc(), getRAngleLoc());
-    else
-      return SourceRange(getNameLoc(), getNameLoc());
+    return SourceRange(getNameLoc());
   }
 
   void initializeLocal(SourceLocation Loc) {
-    initializeLocalBase(Loc);
     setNameLoc(Loc);
   }
 };
 
 
-struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo {
-  SourceLocation StarLoc;
-  bool HasProtocols;
-  bool HasBaseType;
-};
-
-/// Wraps an ObjCPointerType with source location information.  Note
-/// that not all ObjCPointerTypes actually have a star location; nor
-/// are protocol locations necessarily written in the source just
-/// because they're present on the type.
-class ObjCObjectPointerTypeLoc :
-    public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc,
-                                   ObjCObjectPointerType,
-                                   ObjCObjectPointerLocInfo> {
-public:
-  bool hasProtocolsAsWritten() const {
-    return getLocalData()->HasProtocols;
-  }
-
-  void setHasProtocolsAsWritten(bool HasProtocols) {
-    getLocalData()->HasProtocols = HasProtocols;
-  }
-
-  bool hasBaseTypeAsWritten() const {
-    return getLocalData()->HasBaseType;
-  }
-
-  void setHasBaseTypeAsWritten(bool HasBaseType) {
-    getLocalData()->HasBaseType = HasBaseType;
-  }
-
-  SourceLocation getStarLoc() const {
-    return getLocalData()->StarLoc;
-  }
-
-  void setStarLoc(SourceLocation Loc) {
-    getLocalData()->StarLoc = Loc;
-  }
-
-  SourceRange getSourceRange() const {
-    // Being written with protocols is incompatible with being written
-    // with a star.
-    if (hasProtocolsAsWritten())
-      return SourceRange(getLAngleLoc(), getRAngleLoc());
-    else
-      return SourceRange(getStarLoc(), getStarLoc());
-  }
-
-  void initializeLocal(SourceLocation Loc) {
-    initializeLocalBase(Loc);
-    setHasProtocolsAsWritten(false);
-    setHasBaseTypeAsWritten(false);
-    setStarLoc(Loc);
-  }
-
-  TypeLoc getBaseTypeLoc() const {
-    return getInnerTypeLoc();
-  }
-
-  QualType getInnerType() const {
-    return getTypePtr()->getPointeeType();
-  }
-};
-
-
 struct PointerLikeLocInfo {
   SourceLocation StarLoc;
 };
@@ -804,6 +746,20 @@
   }
 };
 
+/// Wraps an ObjCPointerType with source location information.
+class ObjCObjectPointerTypeLoc :
+    public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
+                              ObjCObjectPointerType> {
+public:
+  SourceLocation getStarLoc() const {
+    return getSigilLoc();
+  }
+
+  void setStarLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
 
 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
                                                    ReferenceType> {

Modified: cfe/trunk/include/clang/AST/TypeLocBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLocBuilder.h?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeLocBuilder.h (original)
+++ cfe/trunk/include/clang/AST/TypeLocBuilder.h Sat May 15 06:32:37 2010
@@ -59,6 +59,20 @@
       grow(Requested);
   }
 
+  /// Pushes a copy of the given TypeLoc onto this builder.  The builder
+  /// must be empty for this to work.
+  void pushFullCopy(TypeLoc L) {
+#ifndef NDEBUG
+    assert(LastTy.isNull() && "pushing copy on non-empty TypeLocBuilder");
+    LastTy = L.getNextTypeLoc().getType();
+#endif
+    assert(Index == Capacity && "pushing copy on non-empty TypeLocBuilder");
+
+    unsigned Size = L.getFullDataSize();
+    TypeLoc Copy = pushImpl(L.getType(), Size);
+    memcpy(Copy.getOpaqueData(), L.getOpaqueData(), Size);
+  }
+
   /// Pushes space for a typespec TypeLoc.  Invalidates any TypeLocs
   /// previously retrieved from this builder.
   TypeSpecTypeLoc pushTypeSpec(QualType T) {

Modified: cfe/trunk/include/clang/AST/TypeNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)
+++ cfe/trunk/include/clang/AST/TypeNodes.def Sat May 15 06:32:37 2010
@@ -92,7 +92,8 @@
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
 DEPENDENT_TYPE(InjectedClassName, Type)
 DEPENDENT_TYPE(DependentName, Type)
-TYPE(ObjCInterface, Type)
+TYPE(ObjCObject, Type)
+TYPE(ObjCInterface, ObjCObjectType)
 TYPE(ObjCObjectPointer, Type)
 
 #ifdef LAST_TYPE

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Sat May 15 06:32:37 2010
@@ -415,7 +415,9 @@
       /// \brief An UnresolvedUsingType record.
       TYPE_UNRESOLVED_USING         = 26,
       /// \brief An InjectedClassNameType record.
-      TYPE_INJECTED_CLASS_NAME      = 27
+      TYPE_INJECTED_CLASS_NAME      = 27,
+      /// \brief An ObjCObjectType record.
+      TYPE_OBJC_OBJECT              = 28
     };
 
     /// \brief The type IDs for special types constructed by semantic

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat May 15 06:32:37 2010
@@ -595,6 +595,8 @@
     Align = EltInfo.second;
     break;
   }
+  case Type::ObjCObject:
+    return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());
   case Type::ObjCInterface: {
     const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
     const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@@ -1692,10 +1694,6 @@
   if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
     return getTypedefType(Typedef);
 
-  if (const ObjCInterfaceDecl *ObjCInterface
-               = dyn_cast<ObjCInterfaceDecl>(Decl))
-    return getObjCInterfaceType(ObjCInterface);
-
   assert(!isa<TemplateTypeParmDecl>(Decl) &&
          "Template type parameter types are always available.");
 
@@ -1991,7 +1989,7 @@
   return LHS->getDeclName() < RHS->getDeclName();
 }
 
-static bool areSortedAndUniqued(ObjCProtocolDecl **Protocols,
+static bool areSortedAndUniqued(ObjCProtocolDecl * const *Protocols,
                                 unsigned NumProtocols) {
   if (NumProtocols == 0) return true;
 
@@ -2013,96 +2011,98 @@
   NumProtocols = ProtocolsEnd-Protocols;
 }
 
-/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
-/// the given interface decl and the conforming protocol list.
-QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
-                                              ObjCProtocolDecl **Protocols,
-                                              unsigned NumProtocols,
-                                              unsigned Quals) {
-  llvm::FoldingSetNodeID ID;
-  ObjCObjectPointerType::Profile(ID, InterfaceT, Protocols, NumProtocols);
-  Qualifiers Qs = Qualifiers::fromCVRMask(Quals);
+QualType ASTContext::getObjCObjectType(QualType BaseType,
+                                       ObjCProtocolDecl * const *Protocols,
+                                       unsigned NumProtocols) {
+  // If the base type is an interface and there aren't any protocols
+  // to add, then the interface type will do just fine.
+  if (!NumProtocols && isa<ObjCInterfaceType>(BaseType))
+    return BaseType;
 
+  // Look in the folding set for an existing type.
+  llvm::FoldingSetNodeID ID;
+  ObjCObjectTypeImpl::Profile(ID, BaseType, Protocols, NumProtocols);
   void *InsertPos = 0;
-  if (ObjCObjectPointerType *QT =
-              ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
-    return getQualifiedType(QualType(QT, 0), Qs);
+  if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(QT, 0);
 
-  // Sort the protocol list alphabetically to canonicalize it.
+  // Build the canonical type, which has the canonical base type and
+  // a sorted-and-uniqued list of protocols.
   QualType Canonical;
-  if (!InterfaceT.isCanonical() || 
-      !areSortedAndUniqued(Protocols, NumProtocols)) {
-    if (!areSortedAndUniqued(Protocols, NumProtocols)) {
+  bool ProtocolsSorted = areSortedAndUniqued(Protocols, NumProtocols);
+  if (!ProtocolsSorted || !BaseType.isCanonical()) {
+    if (!ProtocolsSorted) {
       llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(Protocols,
                                                      Protocols + NumProtocols);
       unsigned UniqueCount = NumProtocols;
 
       SortAndUniqueProtocols(&Sorted[0], UniqueCount);
-
-      Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT),
-                                           &Sorted[0], UniqueCount);
+      Canonical = getObjCObjectType(getCanonicalType(BaseType),
+                                    &Sorted[0], UniqueCount);
     } else {
-      Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT),
-                                           Protocols, NumProtocols);
+      Canonical = getObjCObjectType(getCanonicalType(BaseType),
+                                    Protocols, NumProtocols);
     }
 
     // Regenerate InsertPos.
-    ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+    ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos);
   }
 
-  // No match.
-  unsigned Size = sizeof(ObjCObjectPointerType) 
-                + NumProtocols * sizeof(ObjCProtocolDecl *);
+  unsigned Size = sizeof(ObjCObjectTypeImpl);
+  Size += NumProtocols * sizeof(ObjCProtocolDecl *);
   void *Mem = Allocate(Size, TypeAlignment);
-  ObjCObjectPointerType *QType = new (Mem) ObjCObjectPointerType(Canonical, 
-                                                                 InterfaceT, 
-                                                                 Protocols,
-                                                                 NumProtocols);
+  ObjCObjectTypeImpl *T =
+    new (Mem) ObjCObjectTypeImpl(Canonical, BaseType, Protocols, NumProtocols);
 
-  Types.push_back(QType);
-  ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
-  return getQualifiedType(QualType(QType, 0), Qs);
+  Types.push_back(T);
+  ObjCObjectTypes.InsertNode(T, InsertPos);
+  return QualType(T, 0);
 }
 
-/// getObjCInterfaceType - Return the unique reference to the type for the
-/// specified ObjC interface decl. The list of protocols is optional.
-QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
-                       ObjCProtocolDecl **Protocols, unsigned NumProtocols) {
+/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
+/// the given object type.
+QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) {
   llvm::FoldingSetNodeID ID;
-  ObjCInterfaceType::Profile(ID, Decl, Protocols, NumProtocols);
+  ObjCObjectPointerType::Profile(ID, ObjectT);
 
   void *InsertPos = 0;
-  if (ObjCInterfaceType *QT =
-      ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos))
+  if (ObjCObjectPointerType *QT =
+              ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(QT, 0);
 
-  // Sort the protocol list alphabetically to canonicalize it.
+  // Find the canonical object type.
   QualType Canonical;
-  if (NumProtocols && !areSortedAndUniqued(Protocols, NumProtocols)) {
-    llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(Protocols,
-                                                   Protocols + NumProtocols);
-
-    unsigned UniqueCount = NumProtocols;
-    SortAndUniqueProtocols(&Sorted[0], UniqueCount);
-
-    Canonical = getObjCInterfaceType(Decl, &Sorted[0], UniqueCount);
+  if (!ObjectT.isCanonical()) {
+    Canonical = getObjCObjectPointerType(getCanonicalType(ObjectT));
 
-    ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos);
+    // Regenerate InsertPos.
+    ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
   }
 
-  unsigned Size = sizeof(ObjCInterfaceType) 
-    + NumProtocols * sizeof(ObjCProtocolDecl *);
-  void *Mem = Allocate(Size, TypeAlignment);
-  ObjCInterfaceType *QType = new (Mem) ObjCInterfaceType(Canonical, 
-                                        const_cast<ObjCInterfaceDecl*>(Decl),
-                                                         Protocols, 
-                                                         NumProtocols);
+  // No match.
+  void *Mem = Allocate(sizeof(ObjCObjectPointerType), TypeAlignment);
+  ObjCObjectPointerType *QType =
+    new (Mem) ObjCObjectPointerType(Canonical, ObjectT);
 
   Types.push_back(QType);
-  ObjCInterfaceTypes.InsertNode(QType, InsertPos);
+  ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
   return QualType(QType, 0);
 }
 
+/// getObjCInterfaceType - Return the unique reference to the type for the
+/// specified ObjC interface decl. The list of protocols is optional.
+QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) {
+  if (Decl->TypeForDecl)
+    return QualType(Decl->TypeForDecl, 0);
+
+  // FIXME: redeclarations?
+  void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
+  ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
+  Decl->TypeForDecl = T;
+  Types.push_back(T);
+  return QualType(T, 0);
+}
+
 /// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
 /// TypeOfExprType AST's (since expression's are never shared). For example,
 /// multiple declarations that refer to "typeof(x)" all contain different
@@ -3620,6 +3620,10 @@
     return;
   }
 
+  // Ignore protocol qualifiers when mangling at this level.
+  if (const ObjCObjectType *OT = T->getAs<ObjCObjectType>())
+    T = OT->getBaseType();
+
   if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
     // @encode(class_name)
     ObjCInterfaceDecl *OI = OIT->getDecl();
@@ -4090,18 +4094,21 @@
 ///
 bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
                                          const ObjCObjectPointerType *RHSOPT) {
+  const ObjCObjectType* LHS = LHSOPT->getObjectType();
+  const ObjCObjectType* RHS = RHSOPT->getObjectType();
+
   // If either type represents the built-in 'id' or 'Class' types, return true.
-  if (LHSOPT->isObjCBuiltinType() || RHSOPT->isObjCBuiltinType())
+  if (LHS->isObjCUnqualifiedIdOrClass() ||
+      RHS->isObjCUnqualifiedIdOrClass())
     return true;
 
-  if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType())
+  if (LHS->isObjCQualifiedId() || RHS->isObjCQualifiedId())
     return ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0),
                                              QualType(RHSOPT,0),
                                              false);
 
-  const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
-  const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
-  if (LHS && RHS) // We have 2 user-defined types.
+  // If we have 2 user-defined types, fall into that path.
+  if (LHS->getInterface() && RHS->getInterface())
     return canAssignObjCInterfaces(LHS, RHS);
 
   return false;
@@ -4152,8 +4159,10 @@
                                 const ObjCObjectPointerType *RHSOPT,
       llvm::SmallVectorImpl<ObjCProtocolDecl *> &IntersectionOfProtocols) {
   
-  const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
-  const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
+  const ObjCObjectType* LHS = LHSOPT->getObjectType();
+  const ObjCObjectType* RHS = RHSOPT->getObjectType();
+  assert(LHS->getInterface() && "LHS must have an interface base");
+  assert(RHS->getInterface() && "RHS must have an interface base");
   
   llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocolSet;
   unsigned LHSNumProtocols = LHS->getNumProtocols();
@@ -4161,7 +4170,8 @@
     InheritedProtocolSet.insert(LHS->qual_begin(), LHS->qual_end());
   else {
     llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols;
-    Context.CollectInheritedProtocols(LHS->getDecl(), LHSInheritedProtocols);
+    Context.CollectInheritedProtocols(LHS->getInterface(),
+                                      LHSInheritedProtocols);
     InheritedProtocolSet.insert(LHSInheritedProtocols.begin(), 
                                 LHSInheritedProtocols.end());
   }
@@ -4176,7 +4186,8 @@
   }
   else {
     llvm::SmallPtrSet<ObjCProtocolDecl *, 8> RHSInheritedProtocols;
-    Context.CollectInheritedProtocols(RHS->getDecl(), RHSInheritedProtocols);
+    Context.CollectInheritedProtocols(RHS->getInterface(),
+                                      RHSInheritedProtocols);
     for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = 
          RHSInheritedProtocols.begin(),
          E = RHSInheritedProtocols.end(); I != E; ++I) 
@@ -4190,37 +4201,40 @@
 /// last type comparison in a ?-exp of ObjC pointer types before a 
 /// warning is issued. So, its invokation is extremely rare.
 QualType ASTContext::areCommonBaseCompatible(
-                                          const ObjCObjectPointerType *LHSOPT,
-                                          const ObjCObjectPointerType *RHSOPT) {
-  const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
-  const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
-  if (!LHS || !RHS)
+                                          const ObjCObjectPointerType *Lptr,
+                                          const ObjCObjectPointerType *Rptr) {
+  const ObjCObjectType *LHS = Lptr->getObjectType();
+  const ObjCObjectType *RHS = Rptr->getObjectType();
+  const ObjCInterfaceDecl* LDecl = LHS->getInterface();
+  const ObjCInterfaceDecl* RDecl = RHS->getInterface();
+  if (!LDecl || !RDecl)
     return QualType();
   
-  while (const ObjCInterfaceDecl *LHSIDecl = LHS->getDecl()->getSuperClass()) {
-    QualType LHSTy = getObjCInterfaceType(LHSIDecl);
-    LHS = LHSTy->getAs<ObjCInterfaceType>();
+  while ((LDecl = LDecl->getSuperClass())) {
+    LHS = cast<ObjCInterfaceType>(getObjCInterfaceType(LDecl));
     if (canAssignObjCInterfaces(LHS, RHS)) {
-      llvm::SmallVector<ObjCProtocolDecl *, 8> IntersectionOfProtocols;
-      getIntersectionOfProtocols(*this, 
-                                 LHSOPT, RHSOPT, IntersectionOfProtocols);
-      if (IntersectionOfProtocols.empty())
-        LHSTy = getObjCObjectPointerType(LHSTy);
-      else
-        LHSTy = getObjCObjectPointerType(LHSTy, &IntersectionOfProtocols[0],
-                                                IntersectionOfProtocols.size());
-      return LHSTy;
+      llvm::SmallVector<ObjCProtocolDecl *, 8> Protocols;
+      getIntersectionOfProtocols(*this, Lptr, Rptr, Protocols);
+
+      QualType Result = QualType(LHS, 0);
+      if (!Protocols.empty())
+        Result = getObjCObjectType(Result, Protocols.data(), Protocols.size());
+      Result = getObjCObjectPointerType(Result);
+      return Result;
     }
   }
     
   return QualType();
 }
 
-bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
-                                         const ObjCInterfaceType *RHS) {
+bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
+                                         const ObjCObjectType *RHS) {
+  assert(LHS->getInterface() && "LHS is not an interface type");
+  assert(RHS->getInterface() && "RHS is not an interface type");
+
   // Verify that the base decls are compatible: the RHS must be a subclass of
   // the LHS.
-  if (!LHS->getDecl()->isSuperClassOf(RHS->getDecl()))
+  if (!LHS->getInterface()->isSuperClassOf(RHS->getInterface()))
     return false;
 
   // RHS must have a superset of the protocols in the LHS.  If the LHS is not
@@ -4233,15 +4247,15 @@
   if (RHS->getNumProtocols() == 0)
     return true;  // FIXME: should return false!
 
-  for (ObjCInterfaceType::qual_iterator LHSPI = LHS->qual_begin(),
-                                        LHSPE = LHS->qual_end();
+  for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(),
+                                     LHSPE = LHS->qual_end();
        LHSPI != LHSPE; LHSPI++) {
     bool RHSImplementsProtocol = false;
 
     // If the RHS doesn't implement the protocol on the left, the types
     // are incompatible.
-    for (ObjCInterfaceType::qual_iterator RHSPI = RHS->qual_begin(),
-                                          RHSPE = RHS->qual_end();
+    for (ObjCObjectType::qual_iterator RHSPI = RHS->qual_begin(),
+                                       RHSPE = RHS->qual_end();
          RHSPI != RHSPE; RHSPI++) {
       if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) {
         RHSImplementsProtocol = true;
@@ -4467,6 +4481,10 @@
   if (RHSClass == Type::VariableArray || RHSClass == Type::IncompleteArray)
     RHSClass = Type::ConstantArray;
 
+  // ObjCInterfaces are just specialized ObjCObjects.
+  if (LHSClass == Type::ObjCInterface) LHSClass = Type::ObjCObject;
+  if (RHSClass == Type::ObjCInterface) RHSClass = Type::ObjCObject;
+
   // Canonicalize ExtVector -> Vector.
   if (LHSClass == Type::ExtVector) LHSClass = Type::Vector;
   if (RHSClass == Type::ExtVector) RHSClass = Type::Vector;
@@ -4506,6 +4524,7 @@
     assert(false && "C++ should never be in mergeTypes");
     return QualType();
 
+  case Type::ObjCInterface:
   case Type::IncompleteArray:
   case Type::VariableArray:
   case Type::FunctionProto:
@@ -4598,14 +4617,13 @@
                              RHSCan->getAs<VectorType>()))
       return LHS;
     return QualType();
-  case Type::ObjCInterface: {
-    // Check if the interfaces are assignment compatible.
+  case Type::ObjCObject: {
+    // Check if the types are assignment compatible.
     // FIXME: This should be type compatibility, e.g. whether
     // "LHS x; RHS x;" at global scope is legal.
-    const ObjCInterfaceType* LHSIface = LHS->getAs<ObjCInterfaceType>();
-    const ObjCInterfaceType* RHSIface = RHS->getAs<ObjCInterfaceType>();
-    if (LHSIface && RHSIface &&
-        canAssignObjCInterfaces(LHSIface, RHSIface))
+    const ObjCObjectType* LHSIface = LHS->getAs<ObjCObjectType>();
+    const ObjCObjectType* RHSIface = RHS->getAs<ObjCObjectType>();
+    if (canAssignObjCInterfaces(LHSIface, RHSIface))
       return LHS;
 
     return QualType();

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Sat May 15 06:32:37 2010
@@ -74,6 +74,7 @@
     QualType VisitElaboratedType(ElaboratedType *T);
     // FIXME: DependentNameType
     QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
+    QualType VisitObjCObjectType(ObjCObjectType *T);
     QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
                             
     // Importing declarations
@@ -632,12 +633,22 @@
     if (!IsStructurallyEquivalent(Context, 
                                   Iface1->getDecl(), Iface2->getDecl()))
       return false;
-    if (Iface1->getNumProtocols() != Iface2->getNumProtocols())
+    break;
+  }
+
+  case Type::ObjCObject: {
+    const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
+    const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  Obj1->getBaseType(),
+                                  Obj2->getBaseType()))
+      return false;
+    if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
       return false;
-    for (unsigned I = 0, N = Iface1->getNumProtocols(); I != N; ++I) {
+    for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
       if (!IsStructurallyEquivalent(Context,
-                                    Iface1->getProtocol(I),
-                                    Iface2->getProtocol(I)))
+                                    Obj1->getProtocol(I),
+                                    Obj2->getProtocol(I)))
         return false;
     }
     break;
@@ -650,14 +661,6 @@
                                   Ptr1->getPointeeType(),
                                   Ptr2->getPointeeType()))
       return false;
-    if (Ptr1->getNumProtocols() != Ptr2->getNumProtocols())
-      return false;
-    for (unsigned I = 0, N = Ptr1->getNumProtocols(); I != N; ++I) {
-      if (!IsStructurallyEquivalent(Context,
-                                    Ptr1->getProtocol(I),
-                                    Ptr2->getProtocol(I)))
-        return false;
-    }
     break;
   }
       
@@ -1305,8 +1308,16 @@
   if (!Class)
     return QualType();
 
+  return Importer.getToContext().getObjCInterfaceType(Class);
+}
+
+QualType ASTNodeImporter::VisitObjCObjectType(ObjCObjectType *T) {
+  QualType ToBaseType = Importer.Import(T->getBaseType());
+  if (ToBaseType.isNull())
+    return QualType();
+
   llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
-  for (ObjCInterfaceType::qual_iterator P = T->qual_begin(), 
+  for (ObjCObjectType::qual_iterator P = T->qual_begin(), 
                                      PEnd = T->qual_end();
        P != PEnd; ++P) {
     ObjCProtocolDecl *Protocol
@@ -1316,9 +1327,9 @@
     Protocols.push_back(Protocol);
   }
 
-  return Importer.getToContext().getObjCInterfaceType(Class,
-                                                      Protocols.data(),
-                                                      Protocols.size());
+  return Importer.getToContext().getObjCObjectType(ToBaseType,
+                                                   Protocols.data(),
+                                                   Protocols.size());
 }
 
 QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
@@ -1326,20 +1337,7 @@
   if (ToPointeeType.isNull())
     return QualType();
 
-  llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
-  for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(), 
-                                         PEnd = T->qual_end();
-       P != PEnd; ++P) {
-    ObjCProtocolDecl *Protocol
-      = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
-    if (!Protocol)
-      return QualType();
-    Protocols.push_back(Protocol);
-  }
-
-  return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
-                                                          Protocols.data(),
-                                                          Protocols.size());
+  return Importer.getToContext().getObjCObjectPointerType(ToPointeeType);
 }
 
 //----------------------------------------------------------------------------

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sat May 15 06:32:37 2010
@@ -2080,9 +2080,9 @@
     break;
 
   case Class:
-    if (const ObjCInterfaceType *Iface
-                       = getClassReceiver()->getAs<ObjCInterfaceType>())
-      return Iface->getDecl();
+    if (const ObjCObjectType *Ty
+          = getClassReceiver()->getAs<ObjCObjectType>())
+      return Ty->getInterface();
     break;
 
   case SuperInstance:

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sat May 15 06:32:37 2010
@@ -345,29 +345,36 @@
   return 0;
 }
 
-ObjCInterfaceType::ObjCInterfaceType(QualType Canonical,
-                                     ObjCInterfaceDecl *D,
-                                     ObjCProtocolDecl **Protos, unsigned NumP) :
-  Type(ObjCInterface, Canonical, /*Dependent=*/false),
-  Decl(D), NumProtocols(NumP)
-{
+void ObjCInterfaceType::Destroy(ASTContext& C) {
+  this->~ObjCInterfaceType();
+  C.Deallocate(this);
+}
+
+ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
+                               ObjCProtocolDecl * const *Protocols,
+                               unsigned NumProtocols)
+  : Type(ObjCObject, Canonical, false),
+    NumProtocols(NumProtocols),
+    BaseType(Base) {
+  assert(this->NumProtocols == NumProtocols &&
+         "bitfield overflow in protocol count");
   if (NumProtocols)
-    memcpy(reinterpret_cast<ObjCProtocolDecl**>(this + 1), Protos, 
-           NumProtocols * sizeof(*Protos));
+    memcpy(getProtocolStorage(), Protocols,
+           NumProtocols * sizeof(ObjCProtocolDecl*));
 }
 
-void ObjCInterfaceType::Destroy(ASTContext& C) {
-  this->~ObjCInterfaceType();
+void ObjCObjectTypeImpl::Destroy(ASTContext& C) {
+  this->~ObjCObjectTypeImpl();
   C.Deallocate(this);
 }
 
-const ObjCInterfaceType *Type::getAsObjCQualifiedInterfaceType() const {
-  // There is no sugar for ObjCInterfaceType's, just return the canonical
+const ObjCObjectType *Type::getAsObjCQualifiedInterfaceType() const {
+  // There is no sugar for ObjCObjectType's, just return the canonical
   // type pointer if it is the right class.  There is no typedef information to
   // return and these cannot be Address-space qualified.
-  if (const ObjCInterfaceType *OIT = getAs<ObjCInterfaceType>())
-    if (OIT->getNumProtocols())
-      return OIT;
+  if (const ObjCObjectType *T = getAs<ObjCObjectType>())
+    if (T->getNumProtocols() && T->getInterface())
+      return T;
   return 0;
 }
 
@@ -375,17 +382,6 @@
   return getAsObjCQualifiedInterfaceType() != 0;
 }
 
-ObjCObjectPointerType::ObjCObjectPointerType(QualType Canonical, QualType T,
-                                             ObjCProtocolDecl **Protos,
-                                             unsigned NumP) :
-  Type(ObjCObjectPointer, Canonical, /*Dependent=*/false),
-  PointeeType(T), NumProtocols(NumP)
-{
-  if (NumProtocols)
-    memcpy(reinterpret_cast<ObjCProtocolDecl **>(this + 1), Protos, 
-           NumProtocols * sizeof(*Protos));
-}
-
 void ObjCObjectPointerType::Destroy(ASTContext& C) {
   this->~ObjCObjectPointerType();
   C.Deallocate(this);
@@ -638,6 +634,8 @@
   case IncompleteArray:
     // An array of unknown size is an incomplete type (C99 6.2.5p22).
     return true;
+  case ObjCObject:
+    return cast<ObjCObjectType>(this)->getBaseType()->isIncompleteType();
   case ObjCInterface:
     // ObjC interfaces are incomplete if they are @class, not @interface.
     return cast<ObjCInterfaceType>(this)->getDecl()->isForwardDecl();
@@ -768,7 +766,8 @@
   case Elaborated:
   case DependentName:
   case ObjCInterface:
-  case ObjCObjectPointer:
+  case ObjCObject:
+  case ObjCObjectPointer: // FIXME: object pointers aren't really specifiers
     return true;
   default:
     return false;
@@ -953,17 +952,8 @@
           getExtInfo());
 }
 
-void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID,
-                                    QualType OIT, 
-                                    ObjCProtocolDecl * const *protocols,
-                                    unsigned NumProtocols) {
-  ID.AddPointer(OIT.getAsOpaquePtr());
-  for (unsigned i = 0; i != NumProtocols; i++)
-    ID.AddPointer(protocols[i]);
-}
-
 void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) {
-  Profile(ID, getPointeeType(), qual_begin(), getNumProtocols());
+  Profile(ID, getPointeeType());
 }
 
 /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
@@ -1163,17 +1153,17 @@
   return Context->getQualifiedType(T, *this);
 }
 
-void ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
-                                         const ObjCInterfaceDecl *Decl,
-                                         ObjCProtocolDecl * const *protocols,
-                                         unsigned NumProtocols) {
-  ID.AddPointer(Decl);
+void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID,
+                                 QualType BaseType,
+                                 ObjCProtocolDecl * const *Protocols,
+                                 unsigned NumProtocols) {
+  ID.AddPointer(BaseType.getAsOpaquePtr());
   for (unsigned i = 0; i != NumProtocols; i++)
-    ID.AddPointer(protocols[i]);
+    ID.AddPointer(Protocols[i]);
 }
 
-void ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
-  Profile(ID, getDecl(), qual_begin(), getNumProtocols());
+void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, getBaseType(), qual_begin(), getNumProtocols());
 }
 
 Linkage Type::getLinkage() const { 
@@ -1244,7 +1234,7 @@
   return L;
 }
 
-Linkage ObjCInterfaceType::getLinkage() const {
+Linkage ObjCObjectType::getLinkage() const {
   return ExternalLinkage;
 }
 

Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Sat May 15 06:32:37 2010
@@ -596,25 +596,37 @@
                                      std::string &S) { 
   if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
     S = ' ' + S;
-  
+
   std::string ObjCQIString = T->getDecl()->getNameAsString();
-  if (T->getNumProtocols()) {
-    ObjCQIString += '<';
-    bool isFirst = true;
-    for (ObjCInterfaceType::qual_iterator I = T->qual_begin(), 
-                                          E = T->qual_end(); 
-         I != E; ++I) {
-      if (isFirst)
-        isFirst = false;
-      else
-        ObjCQIString += ',';
-      ObjCQIString += (*I)->getNameAsString();
-    }
-    ObjCQIString += '>';
-  }
   S = ObjCQIString + S;
 }
 
+void TypePrinter::PrintObjCObject(const ObjCObjectType *T,
+                                  std::string &S) {
+  if (T->qual_empty())
+    return Print(T->getBaseType(), S);
+
+  std::string tmp;
+  Print(T->getBaseType(), tmp);
+  tmp += '<';
+  bool isFirst = true;
+  for (ObjCObjectType::qual_iterator
+         I = T->qual_begin(), E = T->qual_end(); I != E; ++I) {
+    if (isFirst)
+      isFirst = false;
+    else
+      tmp += ',';
+    tmp += (*I)->getNameAsString();
+  }
+  tmp += '>';
+
+  if (!S.empty()) {
+    tmp += ' ';
+    tmp += S;
+  }
+  std::swap(tmp, S);
+}
+
 void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 
                                          std::string &S) { 
   std::string ObjCQIString;

Modified: cfe/trunk/lib/Checker/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CFRefCount.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Checker/CFRefCount.cpp Sat May 15 06:32:37 2010
@@ -2552,7 +2552,8 @@
         // is a call to a class method whose type we can resolve.  In such
         // cases, promote the return type to XXX* (where XXX is the class).
         const ObjCInterfaceDecl *D = ME->getReceiverInterface();
-        return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
+        return !D ? RetTy :
+                    Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D));
       }
 
   return RetTy;

Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Sat May 15 06:32:37 2010
@@ -2621,8 +2621,8 @@
       Dst.Add(Pred);
       return;
     }
-    else if (T->isObjCInterfaceType()) {
-      // Some code tries to take the sizeof an ObjCInterfaceType, relying that
+    else if (T->getAs<ObjCObjectType>()) {
+      // Some code tries to take the sizeof an ObjCObjectType, relying that
       // the compiler has laid out its representation.  Just report Unknown
       // for these.
       Dst.Add(Pred);

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Sat May 15 06:32:37 2010
@@ -834,6 +834,13 @@
   return RealDecl;
 }
 
+/// CreateType - get objective-c object type.
+llvm::DIType CGDebugInfo::CreateType(const ObjCObjectType *Ty,
+                                     llvm::DIFile Unit) {
+  // Ignore protocols.
+  return getOrCreateType(Ty->getBaseType(), Unit);
+}
+
 /// CreateType - get objective-c interface type.
 llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
                                      llvm::DIFile Unit) {
@@ -1210,6 +1217,8 @@
     return CreateType(cast<VectorType>(Ty), Unit);
   case Type::ObjCObjectPointer:
     return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
+  case Type::ObjCObject:
+    return CreateType(cast<ObjCObjectType>(Ty), Unit);
   case Type::ObjCInterface:
     return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
   case Type::Builtin: return CreateType(cast<BuiltinType>(Ty), Unit);

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Sat May 15 06:32:37 2010
@@ -80,6 +80,7 @@
   llvm::DIType CreateType(const TagType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const RecordType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
+  llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const EnumType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const ArrayType *Ty, llvm::DIFile F);

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat May 15 06:32:37 2010
@@ -309,8 +309,7 @@
     llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), AmountVal);
     if (!isa<llvm::FunctionType>(PT->getElementType())) {
       QualType PTEE = ValTy->getPointeeType();
-      if (const ObjCInterfaceType *OIT =
-          dyn_cast<ObjCInterfaceType>(PTEE)) {
+      if (const ObjCObjectType *OIT = PTEE->getAs<ObjCObjectType>()) {
         // Handle interface types, which are not represented with a concrete
         // type.
         int size = getContext().getTypeSize(OIT) / 8;
@@ -1371,8 +1370,8 @@
                              llvm::ConstantInt::get(Idx->getType(),
                                  BaseTypeSize.getQuantity()));
     Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
-  } else if (const ObjCInterfaceType *OIT =
-             dyn_cast<ObjCInterfaceType>(E->getType())) {
+  } else if (const ObjCObjectType *OIT =
+               E->getType()->getAs<ObjCObjectType>()) {
     llvm::Value *InterfaceSize =
       llvm::ConstantInt::get(Idx->getType(),
           getContext().getTypeSizeInChars(OIT).getQuantity());

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sat May 15 06:32:37 2010
@@ -1334,7 +1334,7 @@
   }
   const QualType ElementType = PT ? PT->getPointeeType() : OPT->getPointeeType();
   // Handle interface types, which are not represented with a concrete type.
-  if (const ObjCInterfaceType *OIT = dyn_cast<ObjCInterfaceType>(ElementType)) {
+  if (const ObjCObjectType *OIT = ElementType->getAs<ObjCObjectType>()) {
     llvm::Value *InterfaceSize =
       llvm::ConstantInt::get(Idx->getType(),
           CGF.getContext().getTypeSizeInChars(OIT).getQuantity());
@@ -1402,8 +1402,7 @@
     Idx = Builder.CreateNeg(Idx, "sub.ptr.neg");
 
     // Handle interface types, which are not represented with a concrete type.
-    if (const ObjCInterfaceType *OIT =
-        dyn_cast<ObjCInterfaceType>(LHSElementType)) {
+    if (const ObjCObjectType *OIT = LHSElementType->getAs<ObjCObjectType>()) {
       llvm::Value *InterfaceSize =
         llvm::ConstantInt::get(Idx->getType(),
                                CGF.getContext().

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Sat May 15 06:32:37 2010
@@ -66,8 +66,8 @@
   case ObjCMessageExpr::Class: {
     const ObjCInterfaceType *IFace
       = E->getClassReceiver()->getAs<ObjCInterfaceType>();
-    OID = IFace->getDecl();
     assert(IFace && "Invalid Objective-C class message send");
+    OID = IFace->getDecl();
     Receiver = Runtime.GetClass(Builder, OID);
     isClassMessage = true;
     break;

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Sat May 15 06:32:37 2010
@@ -2225,7 +2225,8 @@
                                        llvm::Value *BaseValue,
                                        const ObjCIvarDecl *Ivar,
                                        unsigned CVRQualifiers) {
-  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
+  const ObjCInterfaceDecl *ID =
+    ObjectTy->getAs<ObjCObjectType>()->getInterface();
   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
                                   EmitIvarOffset(CGF, ID, Ivar));
 }

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Sat May 15 06:32:37 2010
@@ -2938,7 +2938,8 @@
                                        llvm::Value *BaseValue,
                                        const ObjCIvarDecl *Ivar,
                                        unsigned CVRQualifiers) {
-  const ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCInterfaceType>()->getDecl();
+  const ObjCInterfaceDecl *ID =
+    ObjectTy->getAs<ObjCObjectType>()->getInterface();
   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
                                   EmitIvarOffset(CGF, ID, Ivar));
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Sat May 15 06:32:37 2010
@@ -322,6 +322,9 @@
                            true);
   }
 
+  case Type::ObjCObject:
+    return ConvertTypeRecursive(cast<ObjCObjectType>(Ty).getBaseType());
+
   case Type::ObjCInterface: {
     // Objective-C interfaces are always opaque (outside of the
     // runtime, which can do whatever it likes); we never refine

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Sat May 15 06:32:37 2010
@@ -1206,6 +1206,12 @@
   mangleSourceName(T->getDecl()->getIdentifier());
 }
 
+void CXXNameMangler::mangleType(const ObjCObjectType *T) {
+  // FIXME: do we allow overloading by different protocols?
+  // If so, we need to mangle them in here.
+  mangleType(T->getBaseType());
+}
+
 void CXXNameMangler::mangleType(const BlockPointerType *T) {
   Out << "U13block_pointer";
   mangleType(T->getPointeeType());

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Sat May 15 06:32:37 2010
@@ -2174,21 +2174,23 @@
   case pch::TYPE_OBJC_INTERFACE: {
     unsigned Idx = 0;
     ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
+    return Context->getObjCInterfaceType(ItfD);
+  }
+
+  case pch::TYPE_OBJC_OBJECT: {
+    unsigned Idx = 0;
+    QualType Base = GetType(Record[Idx++]);
     unsigned NumProtos = Record[Idx++];
     llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
     for (unsigned I = 0; I != NumProtos; ++I)
       Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
-    return Context->getObjCInterfaceType(ItfD, Protos.data(), NumProtos);
+    return Context->getObjCObjectType(Base, Protos.data(), NumProtos);    
   }
 
   case pch::TYPE_OBJC_OBJECT_POINTER: {
     unsigned Idx = 0;
-    QualType OIT = GetType(Record[Idx++]);
-    unsigned NumProtos = Record[Idx++];
-    llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
-    for (unsigned I = 0; I != NumProtos; ++I)
-      Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
-    return Context->getObjCObjectPointerType(OIT, Protos.data(), NumProtos);
+    QualType Pointee = GetType(Record[Idx++]);
+    return Context->getObjCObjectPointerType(Pointee);
   }
 
   case pch::TYPE_SUBST_TEMPLATE_TYPE_PARM: {
@@ -2364,6 +2366,9 @@
 }
 void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+  TL.setHasBaseTypeAsWritten(Record[Idx++]);
   TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
@@ -2371,13 +2376,6 @@
 }
 void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
   TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  TL.setHasBaseTypeAsWritten(Record[Idx++]);
-  TL.setHasProtocolsAsWritten(Record[Idx++]);
-  if (TL.hasProtocolsAsWritten())
-    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
-      TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
 
 TypeSourceInfo *PCHReader::GetTypeSourceInfo(const RecordData &Record,

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Sat May 15 06:32:37 2010
@@ -244,20 +244,21 @@
 
 void PCHTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
   Writer.AddDeclRef(T->getDecl(), Record);
+  Code = pch::TYPE_OBJC_INTERFACE;
+}
+
+void PCHTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {
+  Writer.AddTypeRef(T->getBaseType(), Record);
   Record.push_back(T->getNumProtocols());
-  for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
+  for (ObjCObjectType::qual_iterator I = T->qual_begin(),
        E = T->qual_end(); I != E; ++I)
     Writer.AddDeclRef(*I, Record);
-  Code = pch::TYPE_OBJC_INTERFACE;
+  Code = pch::TYPE_OBJC_OBJECT;
 }
 
 void
 PCHTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
   Writer.AddTypeRef(T->getPointeeType(), Record);
-  Record.push_back(T->getNumProtocols());
-  for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
-       E = T->qual_end(); I != E; ++I)
-    Writer.AddDeclRef(*I, Record);
   Code = pch::TYPE_OBJC_OBJECT_POINTER;
 }
 
@@ -406,6 +407,9 @@
 }
 void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
   Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+  Record.push_back(TL.hasBaseTypeAsWritten());
   Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
   Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
   for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
@@ -413,13 +417,6 @@
 }
 void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
   Writer.AddSourceLocation(TL.getStarLoc(), Record);
-  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
-  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
-  Record.push_back(TL.hasBaseTypeAsWritten());
-  Record.push_back(TL.hasProtocolsAsWritten());
-  if (TL.hasProtocolsAsWritten())
-    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
-      Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Index/Analyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/Analyzer.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Index/Analyzer.cpp (original)
+++ cfe/trunk/lib/Index/Analyzer.cpp Sat May 15 06:32:37 2010
@@ -180,7 +180,7 @@
       if (IsInstanceMethod)
         return false;
 
-      MsgD = Msg->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+      MsgD = Msg->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
       break;
     }
 
@@ -189,7 +189,7 @@
       if (IsInstanceMethod)
         return false;
 
-      MsgD = Msg->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+      MsgD = Msg->getSuperType()->getAs<ObjCObjectType>()->getInterface();
       break;
 
     case ObjCMessageExpr::SuperInstance:
@@ -292,12 +292,12 @@
         
       case ObjCMessageExpr::Class:
         CanBeClassMethod = true;
-        MsgD = Msg->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+        MsgD = Msg->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
         break;
 
       case ObjCMessageExpr::SuperClass:
         CanBeClassMethod = true;
-        MsgD = Msg->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+        MsgD = Msg->getSuperType()->getAs<ObjCObjectType>()->getInterface();
         break;
 
       case ObjCMessageExpr::SuperInstance:

Modified: cfe/trunk/lib/Index/ResolveLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/ResolveLocation.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Index/ResolveLocation.cpp (original)
+++ cfe/trunk/lib/Index/ResolveLocation.cpp Sat May 15 06:32:37 2010
@@ -130,7 +130,7 @@
   ASTLocation VisitFunctionTypeLoc(FunctionTypeLoc TL);
   ASTLocation VisitArrayTypeLoc(ArrayTypeLoc TL);
   ASTLocation VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
-  ASTLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
+  ASTLocation VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
   ASTLocation VisitTypeLoc(TypeLoc TL);
 };
 
@@ -454,6 +454,13 @@
   if (ContainsLocation(TL.getNameLoc()))
     return ASTLocation(ParentDecl, TL.getIFaceDecl(), TL.getNameLoc());
 
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
   for (unsigned i = 0; i != TL.getNumProtocols(); ++i) {
     SourceLocation L = TL.getProtocolLoc(i);
     RangePos RP = CheckRange(L);
@@ -466,24 +473,6 @@
   return ASTLocation(ParentDecl, TL);
 }
 
-ASTLocation TypeLocResolver::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
-  assert(ContainsLocation(TL) &&
-         "Should visit only after verifying that loc is in range");
-
-  if (TL.hasProtocolsAsWritten()) {
-    for (unsigned i = 0; i != TL.getNumProtocols(); ++i) {
-      SourceLocation L = TL.getProtocolLoc(i);
-      RangePos RP = CheckRange(L);
-      if (RP == AfterLoc)
-        break;
-      if (RP == ContainsLoc)
-        return ASTLocation(ParentDecl, TL.getProtocol(i), L);
-    }
-  }
-
-  return ASTLocation(ParentDecl, TL);
-}
-
 ASTLocation TypeLocResolver::VisitTypeLoc(TypeLoc TL) {
   assert(ContainsLocation(TL) &&
          "Should visit only after verifying that loc is in range");

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Sat May 15 06:32:37 2010
@@ -87,8 +87,9 @@
   }
   // Create the built-in typedef for 'id'.
   if (Context.getObjCIdType().isNull()) {
-    QualType IdT = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy);
-    TypeSourceInfo *IdInfo = Context.getTrivialTypeSourceInfo(IdT);
+    QualType T = Context.getObjCObjectType(Context.ObjCBuiltinIdTy, 0, 0);
+    T = Context.getObjCObjectPointerType(T);
+    TypeSourceInfo *IdInfo = Context.getTrivialTypeSourceInfo(T);
     TypedefDecl *IdTypedef
       = TypedefDecl::Create(Context, CurContext, SourceLocation(),
                             &Context.Idents.get("id"), IdInfo);
@@ -98,9 +99,9 @@
   }
   // Create the built-in typedef for 'Class'.
   if (Context.getObjCClassType().isNull()) {
-    QualType ClassType
-      = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy);
-    TypeSourceInfo *ClassInfo = Context.getTrivialTypeSourceInfo(ClassType);
+    QualType T = Context.getObjCObjectType(Context.ObjCBuiltinClassTy, 0, 0);
+    T = Context.getObjCObjectPointerType(T);
+    TypeSourceInfo *ClassInfo = Context.getTrivialTypeSourceInfo(T);
     TypedefDecl *ClassTypedef
       = TypedefDecl::Create(Context, CurContext, SourceLocation(),
                             &Context.Idents.get("Class"), ClassInfo);

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Sat May 15 06:32:37 2010
@@ -2047,14 +2047,14 @@
          I != E; ++I)
       AddObjCProperties(*I, true, CurContext, Results);
   } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
-             (!IsArrow && BaseType->isObjCInterfaceType())) {
+             (!IsArrow && BaseType->isObjCObjectType())) {
     // Objective-C instance variable access.
     ObjCInterfaceDecl *Class = 0;
     if (const ObjCObjectPointerType *ObjCPtr
                                     = BaseType->getAs<ObjCObjectPointerType>())
       Class = ObjCPtr->getInterfaceDecl();
     else
-      Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
+      Class = BaseType->getAs<ObjCObjectType>()->getInterface();
     
     // Add all ivars from this class and its superclasses.
     if (Class) {
@@ -2911,9 +2911,9 @@
   ObjCInterfaceDecl *IFace = 0;
   switch (Msg->getReceiverKind()) {
   case ObjCMessageExpr::Class:
-    if (const ObjCInterfaceType *IFaceType
-                           = Msg->getClassReceiver()->getAs<ObjCInterfaceType>())
-      IFace = IFaceType->getDecl();
+    if (const ObjCObjectType *ObjType
+                           = Msg->getClassReceiver()->getAs<ObjCObjectType>())
+      IFace = ObjType->getInterface();
     break;
 
   case ObjCMessageExpr::Instance: {
@@ -2994,9 +2994,9 @@
     if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
       // "super" names an interface. Use it.
     } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
-      if (const ObjCInterfaceType *Iface
-            = Context.getTypeDeclType(TD)->getAs<ObjCInterfaceType>())
-        CDecl = Iface->getDecl();
+      if (const ObjCObjectType *Iface
+            = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
+        CDecl = Iface->getInterface();
     } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
       // "super" names an unresolved type; we can't be more specific.
     } else {
@@ -3030,8 +3030,8 @@
   if (Receiver) {
     QualType T = GetTypeFromParser(Receiver, 0);
     if (!T.isNull()) 
-      if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
-        CDecl = Interface->getDecl();
+      if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
+        CDecl = Interface->getInterface();
   }
 
   // Add all of the factory methods in this Objective-C class, its protocols,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat May 15 06:32:37 2010
@@ -2719,7 +2719,7 @@
 
   QualType T = NewVD->getType();
 
-  if (T->isObjCInterfaceType()) {
+  if (T->isObjCObjectType()) {
     Diag(NewVD->getLocation(), diag::err_statically_allocated_object);
     return NewVD->setInvalidDecl();
   }
@@ -2937,7 +2937,7 @@
     D.setInvalidType();
 
   // Do not allow returning a objc interface by-value.
-  if (R->getAs<FunctionType>()->getResultType()->isObjCInterfaceType()) {
+  if (R->getAs<FunctionType>()->getResultType()->isObjCObjectType()) {
     Diag(D.getIdentifierLoc(),
          diag::err_object_cannot_be_passed_returned_by_value) << 0
       << R->getAs<FunctionType>()->getResultType();
@@ -4330,7 +4330,7 @@
 
   // Parameter declarators cannot be interface types. All ObjC objects are
   // passed by reference.
-  if (T->isObjCInterfaceType()) {
+  if (T->isObjCObjectType()) {
     Diag(NameLoc,
          diag::err_object_cannot_be_passed_returned_by_value) << 1 << T;
     New->setInvalidDecl();
@@ -6146,7 +6146,7 @@
       }
       if (Record && FDTTy->getDecl()->hasObjectMember())
         Record->setHasObjectMember(true);
-    } else if (FDTy->isObjCInterfaceType()) {
+    } else if (FDTy->isObjCObjectType()) {
       /// A field cannot be an Objective-c object
       Diag(FD->getLocation(), diag::err_statically_allocated_object);
       FD->setInvalidDecl();

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Sat May 15 06:32:37 2010
@@ -142,8 +142,8 @@
         // typedef. If we do, get the underlying class type.
         if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
           QualType T = TDecl->getUnderlyingType();
-          if (T->isObjCInterfaceType()) {
-            if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl())
+          if (T->isObjCObjectType()) {
+            if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface())
               SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
           }
         }
@@ -210,8 +210,8 @@
                                        LookupOrdinaryName, ForRedeclaration);
   if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
     QualType T = TDecl->getUnderlyingType();
-    if (T->isObjCInterfaceType()) {
-      if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl()) {
+    if (T->isObjCObjectType()) {
+      if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
         ClassName = IDecl->getIdentifier();
         CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
                                   LookupOrdinaryName, ForRedeclaration);
@@ -1024,15 +1024,15 @@
       //
       // FIXME: Make an extension?
       TypedefDecl *TDD = dyn_cast<TypedefDecl>(PrevDecl);
-      if (!TDD || !isa<ObjCInterfaceType>(TDD->getUnderlyingType())) {
+      if (!TDD || !TDD->getUnderlyingType()->isObjCObjectType()) {
         Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
         Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-      } else if (TDD) {
+      } else {
         // a forward class declaration matching a typedef name of a class refers
         // to the underlying class.
-        if (ObjCInterfaceType * OI =
-              dyn_cast<ObjCInterfaceType>(TDD->getUnderlyingType()))
-          PrevDecl = OI->getDecl();
+        if (const ObjCObjectType *OI =
+              TDD->getUnderlyingType()->getAs<ObjCObjectType>())
+          PrevDecl = OI->getInterface();
       }
     }
     ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
@@ -1532,7 +1532,7 @@
 
     // Methods cannot return interface types. All ObjC objects are
     // passed by reference.
-    if (resultDeclType->isObjCInterfaceType()) {
+    if (resultDeclType->isObjCObjectType()) {
       Diag(MethodLoc, diag::err_object_cannot_be_passed_returned_by_value)
         << 0 << resultDeclType;
       return DeclPtrTy();
@@ -1570,7 +1570,7 @@
                             ArgInfo[i].Name, ArgType, DI,
                             VarDecl::None, VarDecl::None, 0);
 
-    if (ArgType->isObjCInterfaceType()) {
+    if (ArgType->isObjCObjectType()) {
       Diag(ArgInfo[i].NameLoc,
            diag::err_object_cannot_be_passed_returned_by_value)
         << 1 << ArgType;
@@ -1594,7 +1594,7 @@
     else
       // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
       ArgType = adjustParameterType(ArgType);
-    if (ArgType->isObjCInterfaceType()) {
+    if (ArgType->isObjCObjectType()) {
       Diag(Param->getLocation(),
            diag::err_object_cannot_be_passed_returned_by_value)
       << 1 << ArgType;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat May 15 06:32:37 2010
@@ -294,7 +294,7 @@
 bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
   DefaultArgumentPromotion(Expr);
 
-  if (Expr->getType()->isObjCInterfaceType() &&
+  if (Expr->getType()->isObjCObjectType() &&
       DiagRuntimeBehavior(Expr->getLocStart(),
         PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
           << Expr->getType() << CT))
@@ -2040,7 +2040,7 @@
     return true;
 
   // Reject sizeof(interface) and sizeof(interface<proto>) in 64-bit mode.
-  if (LangOpts.ObjCNonFragileABI && exprType->isObjCInterfaceType()) {
+  if (LangOpts.ObjCNonFragileABI && exprType->isObjCObjectType()) {
     Diag(OpLoc, diag::err_sizeof_nonfragile_interface)
       << exprType << isSizeof << ExprRange;
     return true;
@@ -2316,7 +2316,7 @@
     return ExprError();
 
   // Diagnose bad cases where we step over interface counts.
-  if (ResultType->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+  if (ResultType->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
     Diag(LLoc, diag::err_subscript_nonfragile_interface)
       << ResultType << BaseExpr->getSourceRange();
     return ExprError();
@@ -2924,7 +2924,7 @@
       // Handle the following exceptional case PObj->isa.
       if (const ObjCObjectPointerType *OPT =
           BaseType->getAs<ObjCObjectPointerType>()) {
-        if (OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+        if (OPT->getObjectType()->isObjCId() &&
             MemberName.getAsIdentifierInfo()->isStr("isa"))
           return Owned(new (Context) ObjCIsaExpr(BaseExpr, true, MemberLoc,
                                                  Context.getObjCClassType()));
@@ -3048,8 +3048,7 @@
     }
   }
 
-  // Handle field access to simple records.  This also handles access
-  // to fields of the ObjC 'id' struct.
+  // Handle field access to simple records.
   if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
     if (LookupMemberExprInRecord(*this, R, BaseExpr->getSourceRange(),
                                  RTy, OpLoc, SS))
@@ -3060,14 +3059,14 @@
   // Handle access to Objective-C instance variables, such as "Obj->ivar" and
   // (*Obj).ivar.
   if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
-      (!IsArrow && BaseType->isObjCInterfaceType())) {
+      (!IsArrow && BaseType->isObjCObjectType())) {
     const ObjCObjectPointerType *OPT = BaseType->getAs<ObjCObjectPointerType>();
-    const ObjCInterfaceType *IFaceT =
-      OPT ? OPT->getInterfaceType() : BaseType->getAs<ObjCInterfaceType>();
-    if (IFaceT) {
+    ObjCInterfaceDecl *IDecl =
+      OPT ? OPT->getInterfaceDecl()
+          : BaseType->getAs<ObjCObjectType>()->getInterface();
+    if (IDecl) {
       IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
 
-      ObjCInterfaceDecl *IDecl = IFaceT->getDecl();
       ObjCInterfaceDecl *ClassDeclared;
       ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
 
@@ -3180,7 +3179,8 @@
 
   // Handle the following exceptional case (*Obj).isa.
   if (!IsArrow &&
-      BaseType->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+      BaseType->isObjCObjectType() &&
+      BaseType->getAs<ObjCObjectType>()->isObjCId() &&
       MemberName.getAsIdentifierInfo()->isStr("isa"))
     return Owned(new (Context) ObjCIsaExpr(BaseExpr, false, MemberLoc,
                                            Context.getObjCClassType()));
@@ -5064,7 +5064,7 @@
           return QualType();
       }
       // Diagnose bad cases where we step over interface counts.
-      if (PointeeTy->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+      if (PointeeTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
         Diag(Loc, diag::err_arithmetic_nonfragile_interface)
           << PointeeTy << PExp->getSourceRange();
         return QualType();
@@ -5140,7 +5140,7 @@
       return QualType();
 
     // Diagnose bad cases where we step over interface counts.
-    if (lpointee->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+    if (lpointee->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
       Diag(Loc, diag::err_arithmetic_nonfragile_interface)
         << lpointee << lex->getSourceRange();
       return QualType();
@@ -5907,7 +5907,7 @@
                              << ResType))
       return QualType();
     // Diagnose bad cases where we step over interface counts.
-    else if (PointeeTy->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+    else if (PointeeTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
       Diag(OpLoc, diag::err_arithmetic_nonfragile_interface)
         << PointeeTy << Op->getSourceRange();
       return QualType();
@@ -7021,7 +7021,7 @@
     QualType RetTy = T.getTypePtr()->getAs<FunctionType>()->getResultType();
 
     // Do not allow returning a objc interface by-value.
-    if (RetTy->isObjCInterfaceType()) {
+    if (RetTy->isObjCObjectType()) {
       Diag(ParamInfo.getSourceRange().getBegin(),
            diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy;
       return;
@@ -7093,7 +7093,7 @@
   QualType RetTy = T->getAs<FunctionType>()->getResultType();
 
   // Do not allow returning a objc interface by-value.
-  if (RetTy->isObjCInterfaceType()) {
+  if (RetTy->isObjCObjectType()) {
     Diag(ParamInfo.getSourceRange().getBegin(),
          diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy;
   } else if (!RetTy->isDependentType())

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Sat May 15 06:32:37 2010
@@ -722,10 +722,8 @@
 
   // Find the class to which we are sending this message.
   ObjCInterfaceDecl *Class = 0;
-  if (const ObjCInterfaceType *ClassType
-                                 = ReceiverType->getAs<ObjCInterfaceType>())
-    Class = ClassType->getDecl();
-  else {
+  const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>();
+  if (!ClassType || !(Class = ClassType->getInterface())) {
     Diag(Loc, diag::err_invalid_receiver_class_message)
       << ReceiverType;
     return ExprError();

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sat May 15 06:32:37 2010
@@ -624,7 +624,7 @@
   } else if (DeclType->isReferenceType()) {
     CheckReferenceType(Entity, IList, DeclType, Index,
                        StructuredList, StructuredIndex);
-  } else if (DeclType->isObjCInterfaceType()) {
+  } else if (DeclType->isObjCObjectType()) {
     SemaRef.Diag(IList->getLocStart(), diag::err_init_objc_class)
       << DeclType;
     hadError = true;

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Sat May 15 06:32:37 2010
@@ -199,19 +199,16 @@
   // gc'able conforms to NSCopying protocol
   if (getLangOptions().getGCMode() != LangOptions::NonGC &&
       isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign))
-    if (T->isObjCObjectPointerType()) {
-      QualType InterfaceTy = T->getPointeeType();
-      if (const ObjCInterfaceType *OIT =
-          InterfaceTy->getAs<ObjCInterfaceType>()) {
-        ObjCInterfaceDecl *IDecl = OIT->getDecl();
-        if (IDecl)
-          if (ObjCProtocolDecl* PNSCopying =
-              LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc))
-            if (IDecl->ClassImplementsProtocol(PNSCopying, true))
-              Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
-      }
+    if (const ObjCObjectPointerType *ObjPtrTy =
+          T->getAs<ObjCObjectPointerType>()) {
+      ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
+      if (IDecl)
+        if (ObjCProtocolDecl* PNSCopying =
+            LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc))
+          if (IDecl->ClassImplementsProtocol(PNSCopying, true))
+            Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
     }
-  if (T->isObjCInterfaceType())
+  if (T->isObjCObjectType())
     Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object);
 
   DeclContext *DC = cast<DeclContext>(CDecl);

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat May 15 06:32:37 2010
@@ -1543,16 +1543,12 @@
                PTFr->getPointeeType()->isObjCQualifiedClassType()))
             continue;
       }
-      else if (ToType->isObjCObjectPointerType() &&
-               FromType->isObjCObjectPointerType()) {
-        QualType ToInterfaceTy = ToType->getPointeeType();
-        QualType FromInterfaceTy = FromType->getPointeeType();
-        if (const ObjCInterfaceType *OITTo =
-            ToInterfaceTy->getAs<ObjCInterfaceType>())
-          if (const ObjCInterfaceType *OITFr =
-              FromInterfaceTy->getAs<ObjCInterfaceType>())
-            if (OITTo->getDecl() == OITFr->getDecl())
-              continue;
+      else if (const ObjCObjectPointerType *PTTo =
+                 ToType->getAs<ObjCObjectPointerType>()) {
+        if (const ObjCObjectPointerType *PTFr = 
+              FromType->getAs<ObjCObjectPointerType>())
+          if (PTTo->getInterfaceDecl() == PTFr->getInterfaceDecl())
+            continue;
       }
       return false;  
     }
@@ -2141,8 +2137,8 @@
 
     // Objective-C++: If one interface is more specific than the
     // other, it is the better one.
-    const ObjCInterfaceType* FromIface1 = FromPointee1->getAs<ObjCInterfaceType>();
-    const ObjCInterfaceType* FromIface2 = FromPointee2->getAs<ObjCInterfaceType>();
+    const ObjCObjectType* FromIface1 = FromPointee1->getAs<ObjCObjectType>();
+    const ObjCObjectType* FromIface2 = FromPointee2->getAs<ObjCObjectType>();
     if (FromIface1 && FromIface1) {
       if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
         return ImplicitConversionSequence::Better;
@@ -2348,10 +2344,10 @@
     QualType ToPointee2
       = ToType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
 
-    const ObjCInterfaceType* FromIface1 = FromPointee1->getAs<ObjCInterfaceType>();
-    const ObjCInterfaceType* FromIface2 = FromPointee2->getAs<ObjCInterfaceType>();
-    const ObjCInterfaceType* ToIface1 = ToPointee1->getAs<ObjCInterfaceType>();
-    const ObjCInterfaceType* ToIface2 = ToPointee2->getAs<ObjCInterfaceType>();
+    const ObjCObjectType* FromIface1 = FromPointee1->getAs<ObjCObjectType>();
+    const ObjCObjectType* FromIface2 = FromPointee2->getAs<ObjCObjectType>();
+    const ObjCObjectType* ToIface1 = ToPointee1->getAs<ObjCObjectType>();
+    const ObjCObjectType* ToIface2 = ToPointee2->getAs<ObjCObjectType>();
 
     //   -- conversion of C* to B* is better than conversion of C* to A*,
     if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
@@ -2935,8 +2931,8 @@
 /// TryContextuallyConvertToObjCId - Attempt to contextually convert the
 /// expression From to 'id'.
 ImplicitConversionSequence Sema::TryContextuallyConvertToObjCId(Expr *From) {
-  QualType Ty = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy);
-    return TryImplicitConversion(From, Ty,
+  QualType Ty = Context.getObjCIdType();
+  return TryImplicitConversion(From, Ty,
                                  // FIXME: Are these flags correct?
                                  /*SuppressUserConversions=*/false,
                                  /*AllowExplicit=*/true,
@@ -2946,7 +2942,7 @@
 /// PerformContextuallyConvertToObjCId - Perform a contextual conversion
 /// of the expression From to 'id'.
 bool Sema::PerformContextuallyConvertToObjCId(Expr *&From) {
-  QualType Ty = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy);
+  QualType Ty = Context.getObjCIdType();
   ImplicitConversionSequence ICS = TryContextuallyConvertToObjCId(From);
   if (!ICS.isBad())
     return PerformImplicitConversion(From, Ty, ICS, AA_Converting);

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Sat May 15 06:32:37 2010
@@ -30,7 +30,7 @@
 Sema::OwningStmtResult Sema::ActOnExprStmt(FullExprArg expr) {
   Expr *E = expr->takeAs<Expr>();
   assert(E && "ActOnExprStmt(): missing expression");
-  if (E->getType()->isObjCInterfaceType()) {
+  if (E->getType()->isObjCObjectType()) {
     if (LangOpts.ObjCNonFragileABI)
       Diag(E->getLocEnd(), diag::err_indirection_requires_nonfragile_object)
              << E->getType();

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Sat May 15 06:32:37 2010
@@ -2652,6 +2652,7 @@
   case Type::Record:
   case Type::Enum:
   case Type::ObjCInterface:
+  case Type::ObjCObject:
   case Type::ObjCObjectPointer:
   case Type::UnresolvedUsing:
 #define TYPE(Class, Base)

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Sat May 15 06:32:37 2010
@@ -162,9 +162,10 @@
   case DeclSpec::TST_unspecified:
     // "<proto1,proto2>" is an objc qualified ID with a missing id.
     if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
-      Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy,
-                                                (ObjCProtocolDecl**)PQ,
-                                                DS.getNumProtocolQualifiers());
+      Result = Context.getObjCObjectType(Context.ObjCBuiltinIdTy,
+                                         (ObjCProtocolDecl**)PQ,
+                                         DS.getNumProtocolQualifiers());
+      Result = Context.getObjCObjectPointerType(Result);
       break;
     }
     
@@ -299,28 +300,28 @@
     Result = TheSema.GetTypeFromParser(DS.getTypeRep());
 
     if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
-      if (const ObjCInterfaceType *
-            Interface = Result->getAs<ObjCInterfaceType>()) {
-        // It would be nice if protocol qualifiers were only stored with the
-        // ObjCObjectPointerType. Unfortunately, this isn't possible due
-        // to the following typedef idiom (which is uncommon, but allowed):
-        //
-        // typedef Foo<P> T;
-        // static void func() {
-        //   Foo<P> *yy;
-        //   T *zz;
-        // }
-        Result = Context.getObjCInterfaceType(Interface->getDecl(),
-                                              (ObjCProtocolDecl**)PQ,
-                                              DS.getNumProtocolQualifiers());
-      } else if (Result->isObjCIdType())
+      if (const ObjCObjectType *ObjT = Result->getAs<ObjCObjectType>()) {
+        // Silently drop any existing protocol qualifiers.
+        // TODO: determine whether that's the right thing to do.
+        if (ObjT->getNumProtocols())
+          Result = ObjT->getBaseType();
+
+        if (DS.getNumProtocolQualifiers())
+          Result = Context.getObjCObjectType(Result,
+                                             (ObjCProtocolDecl**) PQ,
+                                             DS.getNumProtocolQualifiers());
+      } else if (Result->isObjCIdType()) {
         // id<protocol-list>
-        Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy,
-                        (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
-      else if (Result->isObjCClassType()) {
+        Result = Context.getObjCObjectType(Context.ObjCBuiltinIdTy,
+                                           (ObjCProtocolDecl**) PQ,
+                                           DS.getNumProtocolQualifiers());
+        Result = Context.getObjCObjectPointerType(Result);
+      } else if (Result->isObjCClassType()) {
         // Class<protocol-list>
-        Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy,
-                        (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
+        Result = Context.getObjCObjectType(Context.ObjCBuiltinClassTy,
+                                           (ObjCProtocolDecl**) PQ,
+                                           DS.getNumProtocolQualifiers());
+        Result = Context.getObjCObjectPointerType(Result);
       } else {
         TheSema.Diag(DeclLoc, diag::err_invalid_protocol_qualifiers)
           << DS.getSourceRange();
@@ -503,7 +504,7 @@
     Qs.removeRestrict();
   }
 
-  assert(!T->isObjCInterfaceType() && "Should build ObjCObjectPointerType");
+  assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType");
 
   // Build the pointer type.
   return Context.getQualifiedType(Context.getPointerType(T), Qs);
@@ -658,7 +659,7 @@
     // array, accept it as a GNU extension: C99 6.7.2.1p2.
     if (EltTy->getDecl()->hasFlexibleArrayMember())
       Diag(Loc, diag::ext_flexible_array_in_array) << T;
-  } else if (T->isObjCInterfaceType()) {
+  } else if (T->isObjCObjectType()) {
     Diag(Loc, diag::err_objc_array_of_interfaces) << T;
     return QualType();
   }
@@ -1055,13 +1056,9 @@
         D.setInvalidType(true);
         // Build the type anyway.
       }
-      if (getLangOptions().ObjC1 && T->isObjCInterfaceType()) {
-        const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>();
-        T = Context.getObjCObjectPointerType(T,
-                                         const_cast<ObjCProtocolDecl **>(
-                                           OIT->qual_begin()),
-                                         OIT->getNumProtocols(),
-                                         DeclType.Ptr.TypeQuals);
+      if (getLangOptions().ObjC1 && T->getAs<ObjCObjectType>()) {
+        T = Context.getObjCObjectPointerType(T);
+        T = Context.getCVRQualifiedType(T, DeclType.Ptr.TypeQuals);
         break;
       }
       T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name);
@@ -1400,7 +1397,18 @@
     }
     void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
       TL.setNameLoc(DS.getTypeSpecTypeLoc());
+    }
+    void VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+      // Handle the base type, which might not have been written explicitly.
+      if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
+        TL.setHasBaseTypeAsWritten(false);
+        TL.getBaseLoc().initialize(SourceLocation());
+      } else {
+        TL.setHasBaseTypeAsWritten(true);
+        Visit(TL.getBaseLoc());
+      }
 
+      // Protocol qualifiers.
       if (DS.getProtocolQualifiers()) {
         assert(TL.getNumProtocols() > 0);
         assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());
@@ -1415,34 +1423,8 @@
       }
     }
     void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
-      assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());
-
       TL.setStarLoc(SourceLocation());
-
-      if (DS.getProtocolQualifiers()) {
-        assert(TL.getNumProtocols() > 0);
-        assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());
-        TL.setHasProtocolsAsWritten(true);
-        TL.setLAngleLoc(DS.getProtocolLAngleLoc());
-        TL.setRAngleLoc(DS.getSourceRange().getEnd());
-        for (unsigned i = 0, e = DS.getNumProtocolQualifiers(); i != e; ++i)
-          TL.setProtocolLoc(i, DS.getProtocolLocs()[i]);
-
-      } else {
-        assert(TL.getNumProtocols() == 0);
-        TL.setHasProtocolsAsWritten(false);
-        TL.setLAngleLoc(SourceLocation());
-        TL.setRAngleLoc(SourceLocation());
-      }
-
-      // This might not have been written with an inner type.
-      if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
-        TL.setHasBaseTypeAsWritten(false);
-        TL.getBaseTypeLoc().initialize(SourceLocation());
-      } else {
-        TL.setHasBaseTypeAsWritten(true);
-        Visit(TL.getBaseTypeLoc());
-      }
+      Visit(TL.getPointeeLoc());
     }
     void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
       TypeSourceInfo *TInfo = 0;
@@ -1515,10 +1497,6 @@
     void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
       assert(Chunk.Kind == DeclaratorChunk::Pointer);
       TL.setStarLoc(Chunk.Loc);
-      TL.setHasBaseTypeAsWritten(true);
-      TL.setHasProtocolsAsWritten(false);
-      TL.setLAngleLoc(SourceLocation());
-      TL.setRAngleLoc(SourceLocation());
     }
     void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
       assert(Chunk.Kind == DeclaratorChunk::MemberPointer);

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sat May 15 06:32:37 2010
@@ -2445,31 +2445,15 @@
     return QualType();
 
   QualType Result = TL.getType();
-  if (PointeeType->isObjCInterfaceType() ||
-      PointeeType->isSpecificBuiltinType(BuiltinType::ObjCId)) {
+  if (PointeeType->getAs<ObjCObjectType>()) {
     // A dependent pointer type 'T *' has is being transformed such
     // that an Objective-C class type is being replaced for 'T'. The
     // resulting pointer type is an ObjCObjectPointerType, not a
     // PointerType.
-    ObjCProtocolDecl **Protocols = 0;
-    unsigned NumProtocols = 0;
-
-    if (const ObjCInterfaceType *IFace
-          = PointeeType->getAs<ObjCInterfaceType>()) {
-      Protocols = const_cast<ObjCProtocolDecl**>(IFace->qual_begin());
-      NumProtocols = IFace->getNumProtocols();
-    }
-
-    Result = SemaRef.Context.getObjCObjectPointerType(PointeeType,
-                                                      Protocols,
-                                                      NumProtocols);
+    Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
     
-    ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);   
-    NewT.setStarLoc(TL.getSigilLoc());       
-    NewT.setHasProtocolsAsWritten(false);
-    NewT.setLAngleLoc(SourceLocation());
-    NewT.setRAngleLoc(SourceLocation());
-    NewT.setHasBaseTypeAsWritten(true);
+    ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
+    NewT.setStarLoc(TL.getStarLoc());
     return Result;
   }
                                                             
@@ -3327,6 +3311,17 @@
                                                    ObjCInterfaceTypeLoc TL,
                                                    QualType ObjectType) {
   // ObjCInterfaceType is never dependent.
+  TLB.pushFullCopy(TL);
+  return TL.getType();
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
+                                                ObjCObjectTypeLoc TL,
+                                                QualType ObjectType) {
+  // ObjCObjectType is never dependent.
+  TLB.pushFullCopy(TL);
   return TL.getType();
 }
 
@@ -3336,6 +3331,7 @@
                                                ObjCObjectPointerTypeLoc TL,
                                                        QualType ObjectType) {
   // ObjCObjectPointerType is never dependent.
+  TLB.pushFullCopy(TL);
   return TL.getType();
 }
 

Modified: cfe/trunk/test/SemaObjCXX/deduction.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/deduction.mm?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/deduction.mm (original)
+++ cfe/trunk/test/SemaObjCXX/deduction.mm Sat May 15 06:32:37 2010
@@ -26,3 +26,33 @@
     RetainPtr<id> ptr(S);
   }
 }
+
+ at class Test1Class;
+ at protocol Test1Protocol;
+namespace test1 {
+  template <typename T> struct RemovePointer {
+    typedef T type;
+  };
+  template <typename T> struct RemovePointer<T*> {
+    typedef T type;
+  };
+  template <typename A, typename B> struct is_same {};
+  template <typename A> struct is_same<A,A> {
+    static void foo();
+  };
+  template <typename T> struct tester {
+    void test() {
+      is_same<T, typename RemovePointer<T>::type*>::foo(); // expected-error 2 {{no member named 'foo'}}
+    }
+  };
+
+  template struct tester<id>;
+  template struct tester<id<Test1Protocol> >;
+  template struct tester<Class>;
+  template struct tester<Class<Test1Protocol> >;
+  template struct tester<Test1Class*>;
+  template struct tester<Test1Class<Test1Protocol>*>;
+
+  template struct tester<Test1Class>; // expected-note {{in instantiation}}
+  template struct tester<Test1Class<Test1Protocol> >; // expected-note {{in instantiation}}
+}

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Sat May 15 06:32:37 2010
@@ -317,6 +317,7 @@
   bool VisitTagTypeLoc(TagTypeLoc TL);
   // FIXME: TemplateTypeParmTypeLoc doesn't provide any location information
   bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
+  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
   bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
   bool VisitPointerTypeLoc(PointerTypeLoc TL);
   bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
@@ -811,6 +812,13 @@
   if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
     return true;
 
+  return false;
+}
+
+bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
+    return true;
+
   for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
     if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
                                         TU)))
@@ -821,19 +829,7 @@
 }
 
 bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
-  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseTypeLoc()))
-    return true;
-
-  if (TL.hasProtocolsAsWritten()) {
-    for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
-      if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I),
-                                          TL.getProtocolLoc(I),
-                                          TU)))
-        return true;
-    }
-  }
-
-  return false;
+  return Visit(TL.getPointeeLoc());
 }
 
 bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {

Modified: cfe/trunk/tools/libclang/CXTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXTypes.cpp?rev=103870&r1=103869&r2=103870&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXTypes.cpp (original)
+++ cfe/trunk/tools/libclang/CXTypes.cpp Sat May 15 06:32:37 2010
@@ -173,6 +173,9 @@
     case Type::Typedef:
       D = cast<TypedefType>(TP)->getDecl();
       break;
+    case Type::ObjCObject:
+      D = cast<ObjCObjectType>(TP)->getInterface();
+      break;
     case Type::ObjCInterface:
       D = cast<ObjCInterfaceType>(TP)->getDecl();
       break;





More information about the cfe-commits mailing list