aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-05-15 11:32:37 +0000
committerJohn McCall <rjmccall@apple.com>2010-05-15 11:32:37 +0000
commitc12c5bba6ceb6acd4e51e7a0fc03257da9cfd44e (patch)
treef6b386f56c0925da061036cb04ba79a0bff05d91
parentd86c477fb5d3fc34864afecbbb5443da9355e8fb (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103870 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/ASTContext.h23
-rw-r--r--include/clang/AST/CanonicalType.h18
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h11
-rw-r--r--include/clang/AST/Type.h267
-rw-r--r--include/clang/AST/TypeLoc.h134
-rw-r--r--include/clang/AST/TypeLocBuilder.h14
-rw-r--r--include/clang/AST/TypeNodes.def3
-rw-r--r--include/clang/Frontend/PCHBitCodes.h4
-rw-r--r--lib/AST/ASTContext.cpp220
-rw-r--r--lib/AST/ASTImporter.cpp58
-rw-r--r--lib/AST/Expr.cpp6
-rw-r--r--lib/AST/Type.cpp82
-rw-r--r--lib/AST/TypePrinter.cpp42
-rw-r--r--lib/Checker/CFRefCount.cpp3
-rw-r--r--lib/Checker/GRExprEngine.cpp4
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp9
-rw-r--r--lib/CodeGen/CGDebugInfo.h1
-rw-r--r--lib/CodeGen/CGExpr.cpp7
-rw-r--r--lib/CodeGen/CGExprScalar.cpp5
-rw-r--r--lib/CodeGen/CGObjC.cpp2
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp3
-rw-r--r--lib/CodeGen/CGObjCMac.cpp3
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp3
-rw-r--r--lib/CodeGen/Mangle.cpp6
-rw-r--r--lib/Frontend/PCHReader.cpp26
-rw-r--r--lib/Frontend/PCHWriter.cpp23
-rw-r--r--lib/Index/Analyzer.cpp8
-rw-r--r--lib/Index/ResolveLocation.cpp27
-rw-r--r--lib/Sema/Sema.cpp11
-rw-r--r--lib/Sema/SemaCodeComplete.cpp20
-rw-r--r--lib/Sema/SemaDecl.cpp8
-rw-r--r--lib/Sema/SemaDeclObjC.cpp24
-rw-r--r--lib/Sema/SemaExpr.cpp34
-rw-r--r--lib/Sema/SemaExprObjC.cpp6
-rw-r--r--lib/Sema/SemaInit.cpp2
-rw-r--r--lib/Sema/SemaObjCProperty.cpp21
-rw-r--r--lib/Sema/SemaOverload.cpp34
-rw-r--r--lib/Sema/SemaStmt.cpp2
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp1
-rw-r--r--lib/Sema/SemaType.cpp104
-rw-r--r--lib/Sema/TreeTransform.h36
-rw-r--r--test/SemaObjCXX/deduction.mm30
-rw-r--r--tools/libclang/CIndex.cpp22
-rw-r--r--tools/libclang/CXTypes.cpp3
44 files changed, 747 insertions, 623 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index a53d803ecd..d1646e00d6 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -98,7 +98,7 @@ class ASTContext {
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 @@ public:
const TemplateSpecializationType *TemplateId,
QualType Canon = QualType());
- QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **Protocols = 0,
- unsigned NumProtocols = 0);
+ QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
- /// 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 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 @@ public:
// 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);
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 93dcad7512..4afb81dd05 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -643,6 +643,24 @@ struct CanProxyAdaptor<TemplateTypeParmType>
};
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)
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index a7a13409eb..36b151ddf3 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -623,6 +623,17 @@ case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS, S);
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);
}
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 49022a8a61..b957708e3e 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -755,6 +755,9 @@ public:
};
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 @@ private:
/// 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 @@ public:
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 @@ public:
// 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 @@ public:
// 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 @@ public:
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
+ /// ObjCObjectPointerType node.
+ ///
+ /// In the canonical object type, these are sorted alphabetically
+ /// and uniqued.
+ unsigned NumProtocols : 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;
+ /// Either a BuiltinType or an InterfaceType or sugar for either.
+ QualType BaseType;
+
+ 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)) {}
- ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
- ObjCProtocolDecl **Protos, unsigned NumP);
- friend class ASTContext; // ASTContext creates these.
public:
- void Destroy(ASTContext& C);
+ QualType getBaseType() const { return BaseType; }
- ObjCInterfaceDecl *getDecl() const { return Decl; }
+ 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 @@ public:
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 @@ public:
// 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 @@ public:
}
/// 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 @@ public:
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 @@ inline QualType QualType::getNonReferenceType() const {
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::isExtVectorType() const {
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::isOverloadableType() const {
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
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 9927ae7edb..4896fe948b 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -559,6 +559,7 @@ class SubstTemplateTypeParmTypeLoc :
struct ObjCProtocolListLocInfo {
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
+ bool HasBaseType;
};
// A helper class for defining ObjC TypeLocs that can qualified with
@@ -566,24 +567,15 @@ struct ObjCProtocolListLocInfo {
//
// 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 @@ public:
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 @@ public:
}
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