зеркало из https://github.com/microsoft/clang-1.git
5 cleanups to ObjCObjectPointerType work:
- Remove Sema::CheckPointeeTypesForAssignment(), a temporary API I added to ease migration to ObjCObjectPointerType. Convert Sema::CheckAssignmentConstraints() to no longer depend on the temporary API. - Sema::ConvertDeclSpecToType(): Replace a couple FIXME's with an important comment/example. - Sema::GetTypeForDeclarator(): Get the protocol's from the interface, NOT the declspec (to support the following C typedef idiom: "typedef C<P> T; T *obj"). - Sema::ObjCQualifiedIdTypesAreCompatible(): Removed some dead code. - ASTContext::getObjCEncodingForTypeImpl(): Some minor cleanups. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76443 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
d33c868d38
Коммит
67ef8eaea8
|
@ -2758,10 +2758,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 ObjCObjectPointerType *QIDT = T->getAsObjCQualifiedIdType();
|
||||
S += '"';
|
||||
for (ObjCObjectPointerType::qual_iterator I = QIDT->qual_begin(),
|
||||
E = QIDT->qual_end(); I != E; ++I) {
|
||||
for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
|
||||
E = OPT->qual_end(); I != E; ++I) {
|
||||
S += '<';
|
||||
S += (*I)->getNameAsString();
|
||||
S += '>';
|
||||
|
@ -2786,12 +2785,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
|
||||
S += '@';
|
||||
if (FD || EncodingProperty) {
|
||||
const ObjCInterfaceType *OIT = OPT->getInterfaceType();
|
||||
ObjCInterfaceDecl *OI = OIT->getDecl();
|
||||
S += '"';
|
||||
S += OI->getNameAsCString();
|
||||
for (ObjCInterfaceType::qual_iterator I = OIT->qual_begin(),
|
||||
E = OIT->qual_end(); I != E; ++I) {
|
||||
S += OPT->getInterfaceDecl()->getNameAsCString();
|
||||
for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
|
||||
E = OPT->qual_end(); I != E; ++I) {
|
||||
S += '<';
|
||||
S += (*I)->getNameAsString();
|
||||
S += '>';
|
||||
|
|
|
@ -3033,8 +3033,6 @@ public:
|
|||
// Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
|
||||
AssignConvertType CheckPointerTypesForAssignment(QualType lhsType,
|
||||
QualType rhsType);
|
||||
AssignConvertType CheckPointeeTypesForAssignment(QualType lhsType,
|
||||
QualType rhsType);
|
||||
|
||||
// Helper function for CheckAssignmentConstraints involving two
|
||||
// block pointer types.
|
||||
|
|
|
@ -2398,8 +2398,8 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
|
|||
MemberLoc, BaseExpr));
|
||||
}
|
||||
// Check protocols on qualified interfaces.
|
||||
for (ObjCObjectPointerType::qual_iterator I = IFaceT->qual_begin(),
|
||||
E = IFaceT->qual_end(); I != E; ++I)
|
||||
for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
|
||||
E = OPT->qual_end(); I != E; ++I)
|
||||
if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
|
||||
// Check whether we can reference this property.
|
||||
if (DiagnoseUseOfDecl(PD, MemberLoc))
|
||||
|
@ -3303,7 +3303,6 @@ Action::OwningExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
|
|||
RHSExpr, result));
|
||||
}
|
||||
|
||||
|
||||
// CheckPointerTypesForAssignment - This is a very tricky routine (despite
|
||||
// being closely modeled after the C99 spec:-). The odd characteristic of this
|
||||
// routine is it effectively iqnores the qualifiers on the top level pointee.
|
||||
|
@ -3317,11 +3316,6 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
|
|||
lhptee = lhsType->getAsPointerType()->getPointeeType();
|
||||
rhptee = rhsType->getAsPointerType()->getPointeeType();
|
||||
|
||||
return CheckPointeeTypesForAssignment(lhptee, rhptee);
|
||||
}
|
||||
|
||||
Sema::AssignConvertType
|
||||
Sema::CheckPointeeTypesForAssignment(QualType lhptee, QualType rhptee) {
|
||||
// make sure we operate on the canonical type
|
||||
lhptee = Context.getCanonicalType(lhptee);
|
||||
rhptee = Context.getCanonicalType(rhptee);
|
||||
|
@ -3495,12 +3489,12 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
|
|||
if (isa<PointerType>(rhsType))
|
||||
return CheckPointerTypesForAssignment(lhsType, rhsType);
|
||||
|
||||
// In general, C pointers are not compatible with ObjC object pointers.
|
||||
if (isa<ObjCObjectPointerType>(rhsType)) {
|
||||
QualType rhptee = rhsType->getAsObjCObjectPointerType()->getPointeeType();
|
||||
QualType lhptee = lhsType->getAsPointerType()->getPointeeType();
|
||||
return CheckPointeeTypesForAssignment(lhptee, rhptee);
|
||||
if (lhsType->isVoidPointerType()) // an exception to the rule.
|
||||
return Compatible;
|
||||
return IncompatiblePointer;
|
||||
}
|
||||
|
||||
if (rhsType->getAsBlockPointerType()) {
|
||||
if (lhsType->getAsPointerType()->getPointeeType()->isVoidType())
|
||||
return Compatible;
|
||||
|
@ -3533,18 +3527,19 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
|
|||
if (isa<ObjCObjectPointerType>(lhsType)) {
|
||||
if (rhsType->isIntegerType())
|
||||
return IntToPointer;
|
||||
|
||||
|
||||
// In general, C pointers are not compatible with ObjC object pointers.
|
||||
if (isa<PointerType>(rhsType)) {
|
||||
QualType lhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType();
|
||||
QualType rhptee = rhsType->getAsPointerType()->getPointeeType();
|
||||
return CheckPointeeTypesForAssignment(lhptee, rhptee);
|
||||
if (rhsType->isVoidPointerType()) // an exception to the rule.
|
||||
return Compatible;
|
||||
return IncompatiblePointer;
|
||||
}
|
||||
if (rhsType->isObjCObjectPointerType()) {
|
||||
if (lhsType->isObjCBuiltinType() || rhsType->isObjCBuiltinType())
|
||||
return Compatible;
|
||||
QualType lhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType();
|
||||
QualType rhptee = rhsType->getAsObjCObjectPointerType()->getPointeeType();
|
||||
return CheckPointeeTypesForAssignment(lhptee, rhptee);
|
||||
if (Context.typesAreCompatible(lhsType, rhsType))
|
||||
return Compatible;
|
||||
return IncompatiblePointer;
|
||||
}
|
||||
if (const PointerType *RHSPT = rhsType->getAsPointerType()) {
|
||||
if (RHSPT->getPointeeType()->isVoidType())
|
||||
|
@ -3579,10 +3574,11 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
|
|||
if (lhsType->isIntegerType())
|
||||
return PointerToInt;
|
||||
|
||||
// In general, C pointers are not compatible with ObjC object pointers.
|
||||
if (isa<PointerType>(lhsType)) {
|
||||
QualType rhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType();
|
||||
QualType lhptee = rhsType->getAsPointerType()->getPointeeType();
|
||||
return CheckPointeeTypesForAssignment(lhptee, rhptee);
|
||||
if (lhsType->isVoidPointerType()) // an exception to the rule.
|
||||
return Compatible;
|
||||
return IncompatiblePointer;
|
||||
}
|
||||
if (isa<BlockPointerType>(lhsType) &&
|
||||
rhsType->getAsPointerType()->getPointeeType()->isVoidType())
|
||||
|
|
|
@ -854,34 +854,6 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
}
|
||||
return true;
|
||||
}
|
||||
// FIXME: The code below will be removed when ObjCQualifiedInterfaceType is
|
||||
// removed.
|
||||
if (!lhs->isPointerType())
|
||||
return false;
|
||||
|
||||
QualType ltype = lhs->getAsPointerType()->getPointeeType();
|
||||
if (const ObjCInterfaceType *lhsQI =
|
||||
ltype->getAsObjCQualifiedInterfaceType()) {
|
||||
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 (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(),
|
||||
E = rhsQID->qual_end(); I != E; ++I) {
|
||||
ObjCProtocolDecl *rhsProto = *I;
|
||||
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
|
||||
(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,12 +205,16 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
|
|||
Result = QualType::getFromOpaquePtr(DS.getTypeRep());
|
||||
|
||||
if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
|
||||
// FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so we have
|
||||
// this "hack" for now...
|
||||
if (const ObjCInterfaceType *Interface = Result->getAsObjCInterfaceType())
|
||||
// FIXME: Investigate removing the protocol list in ObjCInterfaceType.
|
||||
// To simply this, Sema::GetTypeForDeclarator() uses the declspec
|
||||
// protocol list, not the list we are storing here.
|
||||
// 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());
|
||||
|
@ -901,10 +905,10 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip,
|
|||
// Build the type anyway.
|
||||
}
|
||||
if (getLangOptions().ObjC1 && T->isObjCInterfaceType()) {
|
||||
const DeclSpec &DS = D.getDeclSpec();
|
||||
const ObjCInterfaceType *OIT = T->getAsObjCInterfaceType();
|
||||
T = Context.getObjCObjectPointerType(T,
|
||||
(ObjCProtocolDecl **)DS.getProtocolQualifiers(),
|
||||
DS.getNumProtocolQualifiers());
|
||||
(ObjCProtocolDecl **)OIT->qual_begin(),
|
||||
OIT->getNumProtocols());
|
||||
break;
|
||||
}
|
||||
T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name);
|
||||
|
|
Загрузка…
Ссылка в новой задаче