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:
Steve Naroff 2009-06-17 22:40:22 +00:00
parent b35e2caab5
commit fb4330f255
19 changed files with 196 additions and 136 deletions

View File

@ -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; }

View File

@ -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());

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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;

View File

@ -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);
}

View File

@ -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.

View File

@ -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());

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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.