forked from OSchip/llvm-project
First step toward fixing <rdar://problem/6613046> refactor clang objc type representation.
Add a type (ObjCObjectPointerType) and remove a type (ObjCQualifiedIdType). This large/tedious patch is just a first step. Next step is to remove ObjCQualifiedInterfaceType. After that, I will remove the magic TypedefType for 'id' (installed by Sema). This work will enable various simplifications throughout clang (when dealing with ObjC types). No functionality change. llvm-svn: 73649
This commit is contained in:
parent
b35e2caab5
commit
fb4330f255
|
@ -80,7 +80,7 @@ class ASTContext {
|
|||
llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
|
||||
llvm::FoldingSet<TypenameType> TypenameTypes;
|
||||
llvm::FoldingSet<ObjCQualifiedInterfaceType> ObjCQualifiedInterfaceTypes;
|
||||
llvm::FoldingSet<ObjCQualifiedIdType> ObjCQualifiedIdTypes;
|
||||
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
|
||||
|
||||
llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
|
||||
llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
|
||||
|
@ -104,7 +104,7 @@ class ASTContext {
|
|||
/// This is initially null and set by Sema::LazilyCreateBuiltin when
|
||||
/// a builtin that takes a valist is encountered.
|
||||
QualType BuiltinVaListType;
|
||||
|
||||
|
||||
/// ObjCIdType - a pseudo built-in typedef type (set by Sema).
|
||||
QualType ObjCIdType;
|
||||
const RecordType *IdStructType;
|
||||
|
@ -325,6 +325,12 @@ public:
|
|||
const TemplateSpecializationType *TemplateId,
|
||||
QualType Canon = QualType());
|
||||
|
||||
/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for the
|
||||
/// given interface decl and the conforming protocol list.
|
||||
QualType getObjCObjectPointerType(ObjCInterfaceDecl *Decl,
|
||||
ObjCProtocolDecl **ProtocolList = 0,
|
||||
unsigned NumProtocols = 0);
|
||||
|
||||
/// getObjCQualifiedInterfaceType - Return a
|
||||
/// ObjCQualifiedInterfaceType type for the given interface decl and
|
||||
/// the conforming protocol list.
|
||||
|
@ -426,7 +432,7 @@ public:
|
|||
/// getObjCEncodingTypeSize returns size of type for objective-c encoding
|
||||
/// purpose.
|
||||
int getObjCEncodingTypeSize(QualType t);
|
||||
|
||||
|
||||
/// This setter/getter represents the ObjC 'id' type. It is setup lazily, by
|
||||
/// Sema. id is always a (typedef for a) pointer type, a pointer to a struct.
|
||||
QualType getObjCIdType() const { return ObjCIdType; }
|
||||
|
|
|
@ -393,6 +393,7 @@ public:
|
|||
bool isComplexIntegerType() const; // GCC _Complex integer type.
|
||||
bool isVectorType() const; // GCC vector type.
|
||||
bool isExtVectorType() const; // Extended vector type.
|
||||
bool isObjCObjectPointerType() const; // Pointer to *any* ObjC object.
|
||||
bool isObjCInterfaceType() const; // NSString or NSString<foo>
|
||||
bool isObjCQualifiedInterfaceType() const; // NSString<foo>
|
||||
bool isObjCQualifiedIdType() const; // id<foo>
|
||||
|
@ -439,9 +440,10 @@ public:
|
|||
const ComplexType *getAsComplexType() const;
|
||||
const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
|
||||
const ExtVectorType *getAsExtVectorType() const; // Extended vector type.
|
||||
const ObjCObjectPointerType *getAsObjCObjectPointerType() const;
|
||||
const ObjCInterfaceType *getAsObjCInterfaceType() const;
|
||||
const ObjCQualifiedInterfaceType *getAsObjCQualifiedInterfaceType() const;
|
||||
const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const;
|
||||
const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
|
||||
const TemplateTypeParmType *getAsTemplateTypeParmType() const;
|
||||
|
||||
const TemplateSpecializationType *
|
||||
|
@ -1683,6 +1685,53 @@ public:
|
|||
static bool classof(const TypenameType *T) { return true; }
|
||||
};
|
||||
|
||||
/// ObjCObjectPointerType - Used to represent 'id', 'Interface *', 'id <p>',
|
||||
/// and 'Interface <p> *'.
|
||||
///
|
||||
/// Duplicate protocols are removed and protocol list is canonicalized to be in
|
||||
/// alphabetical order.
|
||||
class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
|
||||
ObjCInterfaceDecl *Decl;
|
||||
// List of protocols for this protocol conforming object type
|
||||
// List is sorted on protocol name. No protocol is entered more than once.
|
||||
llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
|
||||
|
||||
ObjCObjectPointerType(ObjCInterfaceDecl *D,
|
||||
ObjCProtocolDecl **Protos, unsigned NumP) :
|
||||
Type(ObjCObjectPointer, QualType(), /*Dependent=*/false),
|
||||
Decl(D), Protocols(Protos, Protos+NumP) { }
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
|
||||
public:
|
||||
ObjCInterfaceDecl *getDecl() const { return Decl; }
|
||||
|
||||
/// isObjCQualifiedIdType - true for "id <p>".
|
||||
bool isObjCQualifiedIdType() const { return Decl == 0 && Protocols.size(); }
|
||||
|
||||
/// qual_iterator and friends: this provides access to the (potentially empty)
|
||||
/// list of protocols qualifying this interface.
|
||||
typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
|
||||
|
||||
qual_iterator qual_begin() const { return Protocols.begin(); }
|
||||
qual_iterator qual_end() const { return Protocols.end(); }
|
||||
bool qual_empty() const { return Protocols.size() == 0; }
|
||||
|
||||
/// getNumProtocols - Return the number of qualifying protocols in this
|
||||
/// interface type, or 0 if there are none.
|
||||
unsigned getNumProtocols() const { return Protocols.size(); }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID);
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
const ObjCInterfaceDecl *Decl,
|
||||
ObjCProtocolDecl **protocols, unsigned NumProtocols);
|
||||
virtual void getAsStringInternal(std::string &InnerString,
|
||||
const PrintingPolicy &Policy) const;
|
||||
static bool classof(const Type *T) {
|
||||
return T->getTypeClass() == ObjCObjectPointer;
|
||||
}
|
||||
static bool classof(const ObjCObjectPointerType *) { 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
|
||||
|
@ -1781,44 +1830,6 @@ inline unsigned ObjCInterfaceType::getNumProtocols() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// ObjCQualifiedIdType - to represent id<protocol-list>.
|
||||
///
|
||||
/// Duplicate protocols are removed and protocol list is canonicalized to be in
|
||||
/// alphabetical order.
|
||||
class ObjCQualifiedIdType : public Type,
|
||||
public llvm::FoldingSetNode {
|
||||
// List of protocols for this protocol conforming 'id' type
|
||||
// List is sorted on protocol name. No protocol is enterred more than once.
|
||||
llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
|
||||
|
||||
ObjCQualifiedIdType(ObjCProtocolDecl **Protos, unsigned NumP)
|
||||
: Type(ObjCQualifiedId, QualType()/*these are always canonical*/,
|
||||
/*Dependent=*/false),
|
||||
Protocols(Protos, Protos+NumP) { }
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
public:
|
||||
|
||||
unsigned getNumProtocols() const {
|
||||
return Protocols.size();
|
||||
}
|
||||
|
||||
typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
|
||||
qual_iterator qual_begin() const { return Protocols.begin(); }
|
||||
qual_iterator qual_end() const { return Protocols.end(); }
|
||||
|
||||
virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const;
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID);
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
ObjCProtocolDecl **protocols, unsigned NumProtocols);
|
||||
|
||||
static bool classof(const Type *T) {
|
||||
return T->getTypeClass() == ObjCQualifiedId;
|
||||
}
|
||||
static bool classof(const ObjCQualifiedIdType *) { return true; }
|
||||
|
||||
};
|
||||
|
||||
// Inline function definitions.
|
||||
|
||||
/// getUnqualifiedType - Return the type without any qualifiers.
|
||||
|
@ -1965,6 +1976,9 @@ inline bool Type::isVectorType() const {
|
|||
inline bool Type::isExtVectorType() const {
|
||||
return isa<ExtVectorType>(CanonicalType.getUnqualifiedType());
|
||||
}
|
||||
inline bool Type::isObjCObjectPointerType() const {
|
||||
return isa<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
|
||||
}
|
||||
inline bool Type::isObjCInterfaceType() const {
|
||||
return isa<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
|
||||
}
|
||||
|
@ -1972,7 +1986,10 @@ inline bool Type::isObjCQualifiedInterfaceType() const {
|
|||
return isa<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType());
|
||||
}
|
||||
inline bool Type::isObjCQualifiedIdType() const {
|
||||
return isa<ObjCQualifiedIdType>(CanonicalType.getUnqualifiedType());
|
||||
if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
|
||||
return OPT->isObjCQualifiedIdType();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline bool Type::isTemplateTypeParmType() const {
|
||||
return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
|
||||
|
|
|
@ -77,8 +77,8 @@ TYPE(TemplateSpecialization, Type)
|
|||
NON_CANONICAL_TYPE(QualifiedName, Type)
|
||||
DEPENDENT_TYPE(Typename, Type)
|
||||
TYPE(ObjCInterface, Type)
|
||||
TYPE(ObjCObjectPointer, Type)
|
||||
TYPE(ObjCQualifiedInterface, ObjCInterfaceType)
|
||||
TYPE(ObjCQualifiedId, Type)
|
||||
|
||||
#undef DEPENDENT_TYPE
|
||||
#undef NON_CANONICAL_TYPE
|
||||
|
|
|
@ -386,8 +386,8 @@ namespace clang {
|
|||
TYPE_OBJC_INTERFACE = 21,
|
||||
/// \brief An ObjCQualifiedInterfaceType record.
|
||||
TYPE_OBJC_QUALIFIED_INTERFACE = 22,
|
||||
/// \brief An ObjCQualifiedIdType record.
|
||||
TYPE_OBJC_QUALIFIED_ID = 23
|
||||
/// \brief An ObjCObjectPointerType record.
|
||||
TYPE_OBJC_OBJECT_POINTER = 23
|
||||
};
|
||||
|
||||
/// \brief The type IDs for special types constructed by semantic
|
||||
|
|
|
@ -258,7 +258,7 @@ NODE_XML(ObjCQualifiedInterfaceType, "ObjCQualifiedInterfaceType")
|
|||
ID_ATTRIBUTE_XML
|
||||
END_NODE_XML
|
||||
|
||||
NODE_XML(ObjCQualifiedIdType, "ObjCQualifiedIdType")
|
||||
NODE_XML(ObjCObjectPointerType, "ObjCObjectPointerType")
|
||||
ID_ATTRIBUTE_XML
|
||||
END_NODE_XML
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ ASTContext::getTypeInfo(const Type *T) {
|
|||
// FIXME: Pointers into different addr spaces could have different sizes and
|
||||
// alignment requirements: getPointerInfo should take an AddrSpace.
|
||||
return getTypeInfo(QualType(cast<ExtQualType>(T)->getBaseType(), 0));
|
||||
case Type::ObjCQualifiedId:
|
||||
case Type::ObjCObjectPointer:
|
||||
case Type::ObjCQualifiedInterface:
|
||||
Width = Target.getPointerWidth(0);
|
||||
Align = Target.getPointerAlign(0);
|
||||
|
@ -1578,6 +1578,31 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols,
|
|||
NumProtocols = ProtocolsEnd-Protocols;
|
||||
}
|
||||
|
||||
/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
|
||||
/// the given interface decl and the conforming protocol list.
|
||||
QualType ASTContext::getObjCObjectPointerType(ObjCInterfaceDecl *Decl,
|
||||
ObjCProtocolDecl **Protocols,
|
||||
unsigned NumProtocols) {
|
||||
// Sort the protocol list alphabetically to canonicalize it.
|
||||
if (NumProtocols)
|
||||
SortAndUniqueProtocols(Protocols, NumProtocols);
|
||||
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ObjCObjectPointerType::Profile(ID, Decl, Protocols, NumProtocols);
|
||||
|
||||
void *InsertPos = 0;
|
||||
if (ObjCObjectPointerType *QT =
|
||||
ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
return QualType(QT, 0);
|
||||
|
||||
// No Match;
|
||||
ObjCObjectPointerType *QType =
|
||||
new (*this,8) ObjCObjectPointerType(Decl, Protocols, NumProtocols);
|
||||
|
||||
Types.push_back(QType);
|
||||
ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
|
||||
return QualType(QType, 0);
|
||||
}
|
||||
|
||||
/// getObjCQualifiedInterfaceType - Return a ObjCQualifiedInterfaceType type for
|
||||
/// the given interface decl and the conforming protocol list.
|
||||
|
@ -1607,23 +1632,7 @@ QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl,
|
|||
/// and the conforming protocol list.
|
||||
QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols,
|
||||
unsigned NumProtocols) {
|
||||
// Sort the protocol list alphabetically to canonicalize it.
|
||||
SortAndUniqueProtocols(Protocols, NumProtocols);
|
||||
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ObjCQualifiedIdType::Profile(ID, Protocols, NumProtocols);
|
||||
|
||||
void *InsertPos = 0;
|
||||
if (ObjCQualifiedIdType *QT =
|
||||
ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
return QualType(QT, 0);
|
||||
|
||||
// No Match;
|
||||
ObjCQualifiedIdType *QType =
|
||||
new (*this,8) ObjCQualifiedIdType(Protocols, NumProtocols);
|
||||
Types.push_back(QType);
|
||||
ObjCQualifiedIdTypes.InsertNode(QType, InsertPos);
|
||||
return QualType(QType, 0);
|
||||
return getObjCObjectPointerType(0, Protocols, NumProtocols);
|
||||
}
|
||||
|
||||
/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
|
||||
|
@ -2413,9 +2422,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
if (FD || EncodingProperty) {
|
||||
// Note that we do extended encoding of protocol qualifer list
|
||||
// Only when doing ivar or property encoding.
|
||||
const ObjCQualifiedIdType *QIDT = T->getAsObjCQualifiedIdType();
|
||||
const ObjCObjectPointerType *QIDT = T->getAsObjCQualifiedIdType();
|
||||
S += '"';
|
||||
for (ObjCQualifiedIdType::qual_iterator I = QIDT->qual_begin(),
|
||||
for (ObjCObjectPointerType::qual_iterator I = QIDT->qual_begin(),
|
||||
E = QIDT->qual_end(); I != E; ++I) {
|
||||
S += '<';
|
||||
S += (*I)->getNameAsString();
|
||||
|
@ -3298,7 +3307,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
|
|||
|
||||
return QualType();
|
||||
}
|
||||
case Type::ObjCQualifiedId:
|
||||
case Type::ObjCObjectPointer:
|
||||
// FIXME: finish
|
||||
// Distinct qualified id's are not compatible.
|
||||
return QualType();
|
||||
case Type::FixedWidthInt:
|
||||
|
|
|
@ -562,6 +562,12 @@ const ObjCInterfaceType *Type::getAsObjCInterfaceType() const {
|
|||
return dyn_cast<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
|
||||
}
|
||||
|
||||
const ObjCObjectPointerType *Type::getAsObjCObjectPointerType() const {
|
||||
// There is no sugar for ObjCObjectPointerType's, just return the
|
||||
// canonical type pointer if it is the right class.
|
||||
return dyn_cast<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
|
||||
}
|
||||
|
||||
const ObjCQualifiedInterfaceType *
|
||||
Type::getAsObjCQualifiedInterfaceType() const {
|
||||
// There is no sugar for ObjCQualifiedInterfaceType's, just return the
|
||||
|
@ -569,10 +575,14 @@ Type::getAsObjCQualifiedInterfaceType() const {
|
|||
return dyn_cast<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType());
|
||||
}
|
||||
|
||||
const ObjCQualifiedIdType *Type::getAsObjCQualifiedIdType() const {
|
||||
const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
|
||||
// There is no sugar for ObjCQualifiedIdType's, just return the canonical
|
||||
// type pointer if it is the right class.
|
||||
return dyn_cast<ObjCQualifiedIdType>(CanonicalType.getUnqualifiedType());
|
||||
if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
|
||||
if (OPT->isObjCQualifiedIdType())
|
||||
return OPT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const TemplateTypeParmType *Type::getAsTemplateTypeParmType() const {
|
||||
|
@ -777,7 +787,7 @@ bool Type::isScalarType() const {
|
|||
isa<BlockPointerType>(CanonicalType) ||
|
||||
isa<MemberPointerType>(CanonicalType) ||
|
||||
isa<ComplexType>(CanonicalType) ||
|
||||
isa<ObjCQualifiedIdType>(CanonicalType);
|
||||
isa<ObjCObjectPointerType>(CanonicalType);
|
||||
}
|
||||
|
||||
/// \brief Determines whether the type is a C++ aggregate type or C
|
||||
|
@ -864,7 +874,7 @@ bool Type::isPODType() const {
|
|||
case MemberPointer:
|
||||
case Vector:
|
||||
case ExtVector:
|
||||
case ObjCQualifiedId:
|
||||
case ObjCObjectPointer:
|
||||
return true;
|
||||
|
||||
case Enum:
|
||||
|
@ -919,7 +929,7 @@ bool Type::isSpecifierType() const {
|
|||
case Typename:
|
||||
case ObjCInterface:
|
||||
case ObjCQualifiedInterface:
|
||||
case ObjCQualifiedId:
|
||||
case ObjCObjectPointer:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -980,6 +990,19 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) {
|
|||
getNumExceptions(), exception_begin());
|
||||
}
|
||||
|
||||
void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID,
|
||||
const ObjCInterfaceDecl *Decl,
|
||||
ObjCProtocolDecl **protocols,
|
||||
unsigned NumProtocols) {
|
||||
ID.AddPointer(Decl);
|
||||
for (unsigned i = 0; i != NumProtocols; i++)
|
||||
ID.AddPointer(protocols[i]);
|
||||
}
|
||||
|
||||
void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
|
||||
}
|
||||
|
||||
void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
|
||||
const ObjCInterfaceDecl *Decl,
|
||||
ObjCProtocolDecl **protocols,
|
||||
|
@ -993,17 +1016,6 @@ void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
|
|||
Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
|
||||
}
|
||||
|
||||
void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID,
|
||||
ObjCProtocolDecl **protocols,
|
||||
unsigned NumProtocols) {
|
||||
for (unsigned i = 0; i != NumProtocols; i++)
|
||||
ID.AddPointer(protocols[i]);
|
||||
}
|
||||
|
||||
void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, &Protocols[0], getNumProtocols());
|
||||
}
|
||||
|
||||
/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
|
||||
/// potentially looking through *all* consequtive typedefs. This returns the
|
||||
/// sum of the type qualifiers, so if you have:
|
||||
|
@ -1593,6 +1605,30 @@ void ObjCInterfaceType::getAsStringInternal(std::string &InnerString, const Prin
|
|||
InnerString = getDecl()->getIdentifier()->getName() + InnerString;
|
||||
}
|
||||
|
||||
void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
|
||||
const PrintingPolicy &Policy) const {
|
||||
if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
|
||||
InnerString = ' ' + InnerString;
|
||||
|
||||
std::string ObjCQIString;
|
||||
|
||||
if (getDecl())
|
||||
ObjCQIString = getDecl()->getNameAsString();
|
||||
else
|
||||
ObjCQIString = "id";
|
||||
|
||||
if (!qual_empty()) {
|
||||
ObjCQIString += '<';
|
||||
for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
|
||||
ObjCQIString += (*I)->getNameAsString();
|
||||
if (I+1 != E)
|
||||
ObjCQIString += ',';
|
||||
}
|
||||
ObjCQIString += '>';
|
||||
}
|
||||
InnerString = ObjCQIString + InnerString;
|
||||
}
|
||||
|
||||
void
|
||||
ObjCQualifiedInterfaceType::getAsStringInternal(std::string &InnerString,
|
||||
const PrintingPolicy &Policy) const {
|
||||
|
@ -1612,20 +1648,6 @@ ObjCQualifiedInterfaceType::getAsStringInternal(std::string &InnerString,
|
|||
InnerString = ObjCQIString + InnerString;
|
||||
}
|
||||
|
||||
void ObjCQualifiedIdType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
|
||||
if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
|
||||
InnerString = ' ' + InnerString;
|
||||
std::string ObjCQIString = "id";
|
||||
ObjCQIString += '<';
|
||||
for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
|
||||
ObjCQIString += (*I)->getNameAsString();
|
||||
if (I+1 != E)
|
||||
ObjCQIString += ',';
|
||||
}
|
||||
ObjCQIString += '>';
|
||||
InnerString = ObjCQIString + InnerString;
|
||||
}
|
||||
|
||||
void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
|
||||
if (Policy.SuppressTag)
|
||||
return;
|
||||
|
|
|
@ -668,7 +668,7 @@ RegionStoreManager::CastRegion(const GRState *state, const MemRegion* R,
|
|||
QualType ToTy = Ctx.getCanonicalType(CastToTy);
|
||||
|
||||
// Check cast to ObjCQualifiedID type.
|
||||
if (isa<ObjCQualifiedIdType>(ToTy)) {
|
||||
if (ToTy->isObjCQualifiedIdType()) {
|
||||
// FIXME: Record the type information aside.
|
||||
return CastResult(state, R);
|
||||
}
|
||||
|
|
|
@ -781,7 +781,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
|
|||
case Type::QualifiedName:
|
||||
// Unsupported types
|
||||
return llvm::DIType();
|
||||
case Type::ObjCQualifiedId: // Encode id<p> in debug info just like id.
|
||||
case Type::ObjCObjectPointer: // Encode id<p> in debug info just like id.
|
||||
return Slot = getOrCreateType(M->getContext().getObjCIdType(), Unit);
|
||||
|
||||
case Type::ObjCQualifiedInterface: // Drop protocols from interface.
|
||||
|
|
|
@ -353,7 +353,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
|
|||
return T;
|
||||
}
|
||||
|
||||
case Type::ObjCQualifiedId:
|
||||
case Type::ObjCObjectPointer:
|
||||
// Protocols don't influence the LLVM type.
|
||||
return ConvertTypeRecursive(Context.getObjCIdType());
|
||||
|
||||
|
|
|
@ -1729,13 +1729,15 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
|
|||
return Context->getObjCQualifiedInterfaceType(ItfD, Protos.data(), NumProtos);
|
||||
}
|
||||
|
||||
case pch::TYPE_OBJC_QUALIFIED_ID: {
|
||||
case pch::TYPE_OBJC_OBJECT_POINTER: {
|
||||
unsigned Idx = 0;
|
||||
ObjCInterfaceDecl *ItfD =
|
||||
cast_or_null<ObjCInterfaceDecl>(GetDecl(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->getObjCQualifiedIdType(Protos.data(), NumProtos);
|
||||
return Context->getObjCObjectPointerType(ItfD, Protos.data(), NumProtos);
|
||||
}
|
||||
}
|
||||
// Suppress a GCC warning
|
||||
|
|
|
@ -229,12 +229,14 @@ PCHTypeWriter::VisitObjCQualifiedInterfaceType(
|
|||
Code = pch::TYPE_OBJC_QUALIFIED_INTERFACE;
|
||||
}
|
||||
|
||||
void PCHTypeWriter::VisitObjCQualifiedIdType(const ObjCQualifiedIdType *T) {
|
||||
void
|
||||
PCHTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
|
||||
Writer.AddDeclRef(T->getDecl(), Record);
|
||||
Record.push_back(T->getNumProtocols());
|
||||
for (ObjCQualifiedIdType::qual_iterator I = T->qual_begin(),
|
||||
for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
|
||||
E = T->qual_end(); I != E; ++I)
|
||||
Writer.AddDeclRef(*I, Record);
|
||||
Code = pch::TYPE_OBJC_QUALIFIED_ID;
|
||||
Code = pch::TYPE_OBJC_OBJECT_POINTER;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -407,7 +409,7 @@ void PCHWriter::WriteBlockInfoBlock() {
|
|||
RECORD(TYPE_ENUM);
|
||||
RECORD(TYPE_OBJC_INTERFACE);
|
||||
RECORD(TYPE_OBJC_QUALIFIED_INTERFACE);
|
||||
RECORD(TYPE_OBJC_QUALIFIED_ID);
|
||||
RECORD(TYPE_OBJC_OBJECT_POINTER);
|
||||
// Statements and Exprs can occur in the Types block.
|
||||
AddStmtsExprs(Stream, Record);
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ public:
|
|||
|
||||
if (const PointerType *PT = OCT->getAsPointerType()) {
|
||||
if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
|
||||
isa<ObjCQualifiedIdType>(PT->getPointeeType()))
|
||||
PT->getPointeeType()->isObjCQualifiedIdType())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -356,7 +356,7 @@ namespace {
|
|||
|
||||
if (const PointerType *PT = OCT->getAsPointerType()) {
|
||||
if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
|
||||
isa<ObjCQualifiedIdType>(PT->getPointeeType()))
|
||||
PT->getPointeeType()->isObjCQualifiedIdType())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -164,7 +164,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
|
|||
// Synthesize "typedef struct objc_object { Class isa; } *id;"
|
||||
if (Context.getObjCIdType().isNull()) {
|
||||
RecordDecl *ObjectTag = CreateStructDecl(Context, "objc_object");
|
||||
|
||||
|
||||
QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
|
||||
PushOnScopeChains(ObjectTag, TUScope);
|
||||
TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext,
|
||||
|
|
|
@ -1969,13 +1969,13 @@ static Decl *FindGetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static Decl *FindGetterNameDecl(const ObjCQualifiedIdType *QIdTy,
|
||||
static Decl *FindGetterNameDecl(const ObjCObjectPointerType *QIdTy,
|
||||
IdentifierInfo &Member,
|
||||
const Selector &Sel,
|
||||
ASTContext &Context) {
|
||||
// Check protocols on qualified interfaces.
|
||||
Decl *GDecl = 0;
|
||||
for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(),
|
||||
for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
|
||||
E = QIdTy->qual_end(); I != E; ++I) {
|
||||
if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Context, &Member)) {
|
||||
GDecl = PD;
|
||||
|
@ -1988,7 +1988,7 @@ static Decl *FindGetterNameDecl(const ObjCQualifiedIdType *QIdTy,
|
|||
}
|
||||
}
|
||||
if (!GDecl) {
|
||||
for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(),
|
||||
for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
|
||||
E = QIdTy->qual_end(); I != E; ++I) {
|
||||
// Search in the protocol-qualifier list of current protocol.
|
||||
GDecl = FindGetterNameDeclFromProtocolList(*I, Member, Sel, Context);
|
||||
|
@ -2313,7 +2313,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
|
|||
<< &Member << BaseType);
|
||||
}
|
||||
// Handle properties on qualified "id" protocols.
|
||||
const ObjCQualifiedIdType *QIdTy;
|
||||
const ObjCObjectPointerType *QIdTy;
|
||||
if (OpKind == tok::period && (QIdTy = BaseType->getAsObjCQualifiedIdType())) {
|
||||
// Check protocols on qualified interfaces.
|
||||
Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
|
||||
|
|
|
@ -590,9 +590,10 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
|
|||
|
||||
// We allow sending a message to a qualified ID ("id<foo>"), which is ok as
|
||||
// long as one of the protocols implements the selector (if not, warn).
|
||||
if (ObjCQualifiedIdType *QIdTy = dyn_cast<ObjCQualifiedIdType>(ReceiverCType)) {
|
||||
if (const ObjCObjectPointerType *QIdTy =
|
||||
ReceiverCType->getAsObjCQualifiedIdType()) {
|
||||
// Search protocols for instance methods.
|
||||
for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(),
|
||||
for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
|
||||
E = QIdTy->qual_end(); I != E; ++I) {
|
||||
ObjCProtocolDecl *PDecl = *I;
|
||||
if (PDecl && (Method = PDecl->lookupInstanceMethod(Context, Sel)))
|
||||
|
@ -754,8 +755,8 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
|
||||
const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType();
|
||||
if (const ObjCObjectPointerType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
|
||||
const ObjCObjectPointerType *rhsQID = rhs->getAsObjCQualifiedIdType();
|
||||
const ObjCQualifiedInterfaceType *rhsQI = 0;
|
||||
QualType rtype;
|
||||
|
||||
|
@ -770,7 +771,7 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
// make sure we check the class hierarchy.
|
||||
if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
|
||||
ObjCInterfaceDecl *rhsID = IT->getDecl();
|
||||
for (ObjCQualifiedIdType::qual_iterator I = lhsQID->qual_begin(),
|
||||
for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
|
||||
E = lhsQID->qual_end(); I != E; ++I) {
|
||||
// when comparing an id<P> on lhs with a static type on rhs,
|
||||
// see if static class implements all of id's protocols, directly or
|
||||
|
@ -783,7 +784,7 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
}
|
||||
}
|
||||
|
||||
ObjCQualifiedIdType::qual_iterator RHSProtoI, RHSProtoE;
|
||||
ObjCObjectPointerType::qual_iterator RHSProtoI, RHSProtoE;
|
||||
if (rhsQI) { // We have a qualified interface (e.g. "NSObject<Proto> *").
|
||||
RHSProtoI = rhsQI->qual_begin();
|
||||
RHSProtoE = rhsQI->qual_end();
|
||||
|
@ -794,7 +795,7 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
return false;
|
||||
}
|
||||
|
||||
for (ObjCQualifiedIdType::qual_iterator I = lhsQID->qual_begin(),
|
||||
for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
|
||||
E = lhsQID->qual_end(); I != E; ++I) {
|
||||
ObjCProtocolDecl *lhsProto = *I;
|
||||
bool match = false;
|
||||
|
@ -815,7 +816,7 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
// make sure we check the class hierarchy.
|
||||
if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
|
||||
ObjCInterfaceDecl *rhsID = IT->getDecl();
|
||||
for (ObjCQualifiedIdType::qual_iterator I = lhsQID->qual_begin(),
|
||||
for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
|
||||
E = lhsQID->qual_end(); I != E; ++I) {
|
||||
// when comparing an id<P> on lhs with a static type on rhs,
|
||||
// see if static class implements all of id's protocols, directly or
|
||||
|
@ -834,7 +835,7 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
return true;
|
||||
}
|
||||
|
||||
const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType();
|
||||
const ObjCObjectPointerType *rhsQID = rhs->getAsObjCQualifiedIdType();
|
||||
assert(rhsQID && "One of the LHS/RHS should be id<x>");
|
||||
|
||||
if (!lhs->isPointerType())
|
||||
|
@ -843,12 +844,12 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
QualType ltype = lhs->getAsPointerType()->getPointeeType();
|
||||
if (const ObjCQualifiedInterfaceType *lhsQI =
|
||||
ltype->getAsObjCQualifiedInterfaceType()) {
|
||||
ObjCQualifiedIdType::qual_iterator LHSProtoI = lhsQI->qual_begin();
|
||||
ObjCQualifiedIdType::qual_iterator LHSProtoE = lhsQI->qual_end();
|
||||
ObjCObjectPointerType::qual_iterator LHSProtoI = lhsQI->qual_begin();
|
||||
ObjCObjectPointerType::qual_iterator LHSProtoE = lhsQI->qual_end();
|
||||
for (; LHSProtoI != LHSProtoE; ++LHSProtoI) {
|
||||
bool match = false;
|
||||
ObjCProtocolDecl *lhsProto = *LHSProtoI;
|
||||
for (ObjCQualifiedIdType::qual_iterator I = rhsQID->qual_begin(),
|
||||
for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(),
|
||||
E = rhsQID->qual_end(); I != E; ++I) {
|
||||
ObjCProtocolDecl *rhsProto = *I;
|
||||
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
|
||||
|
@ -867,7 +868,7 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
// for static type vs. qualified 'id' type, check that class implements
|
||||
// all of 'id's protocols.
|
||||
ObjCInterfaceDecl *lhsID = IT->getDecl();
|
||||
for (ObjCQualifiedIdType::qual_iterator I = rhsQID->qual_begin(),
|
||||
for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(),
|
||||
E = rhsQID->qual_end(); I != E; ++I) {
|
||||
if (!ClassImplementsProtocol(*I, lhsID, compare, true))
|
||||
return false;
|
||||
|
|
|
@ -847,7 +847,7 @@ MarkDeducedTemplateParameters(Sema &SemaRef, QualType T,
|
|||
case Type::Typename:
|
||||
case Type::ObjCInterface:
|
||||
case Type::ObjCQualifiedInterface:
|
||||
case Type::ObjCQualifiedId:
|
||||
case Type::ObjCObjectPointer:
|
||||
#define TYPE(Class, Base)
|
||||
#define ABSTRACT_TYPE(Class, Base)
|
||||
#define DEPENDENT_TYPE(Class, Base)
|
||||
|
|
|
@ -657,6 +657,14 @@ InstantiateTypenameType(const TypenameType *T, unsigned Quals) const {
|
|||
|
||||
QualType
|
||||
TemplateTypeInstantiator::
|
||||
InstantiateObjCObjectPointerType(const ObjCObjectPointerType *T,
|
||||
unsigned Quals) const {
|
||||
assert(false && "Objective-C types cannot be dependent");
|
||||
return QualType();
|
||||
}
|
||||
|
||||
QualType
|
||||
TemplateTypeInstantiator::
|
||||
InstantiateObjCInterfaceType(const ObjCInterfaceType *T,
|
||||
unsigned Quals) const {
|
||||
assert(false && "Objective-C types cannot be dependent");
|
||||
|
@ -671,14 +679,6 @@ InstantiateObjCQualifiedInterfaceType(const ObjCQualifiedInterfaceType *T,
|
|||
return QualType();
|
||||
}
|
||||
|
||||
QualType
|
||||
TemplateTypeInstantiator::
|
||||
InstantiateObjCQualifiedIdType(const ObjCQualifiedIdType *T,
|
||||
unsigned Quals) const {
|
||||
assert(false && "Objective-C types cannot be dependent");
|
||||
return QualType();
|
||||
}
|
||||
|
||||
/// \brief The actual implementation of Sema::InstantiateType().
|
||||
QualType TemplateTypeInstantiator::Instantiate(QualType T) const {
|
||||
// If T is not a dependent type, there is nothing to do.
|
||||
|
|
Loading…
Reference in New Issue