r281353 - ObjectiveC: Refactor applyObjCProtocolQualifiers.
Manman Ren via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 13 10:03:12 PDT 2016
Author: mren
Date: Tue Sep 13 12:03:12 2016
New Revision: 281353
URL: http://llvm.org/viewvc/llvm-project?rev=281353&view=rev
Log:
ObjectiveC: Refactor applyObjCProtocolQualifiers.
To construct the canonical type of ObjCTypeParamType, we need to apply
qualifiers on ObjCObjectPointerType. The updated applyObjCProtocolQualifiers
handles this case by merging the protocol lists, constructing a new
ObjCObjectType, then a new ObjCObjectPointerType.
rdar://24619481
rdar://25060179
Differential Revision: http://reviews.llvm.org/D24059
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/Sema/SemaType.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=281353&r1=281352&r2=281353&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Sep 13 12:03:12 2016
@@ -1030,6 +1030,14 @@ public:
/// replaced.
QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
+ /// \brief Apply Objective-C protocol qualifiers to the given type.
+ /// \param allowOnPointerType specifies if we can apply protocol
+ /// qualifiers on ObjCObjectPointerType. It can be set to true when
+ /// contructing the canonical type of a Objective-C type parameter.
+ QualType applyObjCProtocolQualifiers(QualType type,
+ ArrayRef<ObjCProtocolDecl *> protocols, bool &hasError,
+ bool allowOnPointerType = false) const;
+
/// \brief Return the uniqued reference to the type for an Objective-C
/// gc-qualified type.
///
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=281353&r1=281352&r2=281353&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Sep 13 12:03:12 2016
@@ -3871,6 +3871,76 @@ QualType ASTContext::getObjCObjectType(
return QualType(T, 0);
}
+/// Apply Objective-C protocol qualifiers to the given type.
+/// If this is for the canonical type of a type parameter, we can apply
+/// protocol qualifiers on the ObjCObjectPointerType.
+QualType
+ASTContext::applyObjCProtocolQualifiers(QualType type,
+ ArrayRef<ObjCProtocolDecl *> protocols, bool &hasError,
+ bool allowOnPointerType) const {
+ hasError = false;
+
+ // Apply protocol qualifiers to ObjCObjectPointerType.
+ if (allowOnPointerType) {
+ if (const ObjCObjectPointerType *objPtr =
+ dyn_cast<ObjCObjectPointerType>(type.getTypePtr())) {
+ const ObjCObjectType *objT = objPtr->getObjectType();
+ // Merge protocol lists and construct ObjCObjectType.
+ SmallVector<ObjCProtocolDecl*, 8> protocolsVec;
+ protocolsVec.append(objT->qual_begin(),
+ objT->qual_end());
+ protocolsVec.append(protocols.begin(), protocols.end());
+ ArrayRef<ObjCProtocolDecl *> protocols = protocolsVec;
+ type = getObjCObjectType(
+ objT->getBaseType(),
+ objT->getTypeArgsAsWritten(),
+ protocols,
+ objT->isKindOfTypeAsWritten());
+ return getObjCObjectPointerType(type);
+ }
+ }
+
+ // Apply protocol qualifiers to ObjCObjectType.
+ if (const ObjCObjectType *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){
+ // FIXME: Check for protocols to which the class type is already
+ // known to conform.
+
+ return getObjCObjectType(objT->getBaseType(),
+ objT->getTypeArgsAsWritten(),
+ protocols,
+ objT->isKindOfTypeAsWritten());
+ }
+
+ // If the canonical type is ObjCObjectType, ...
+ if (type->isObjCObjectType()) {
+ // Silently overwrite any existing protocol qualifiers.
+ // TODO: determine whether that's the right thing to do.
+
+ // FIXME: Check for protocols to which the class type is already
+ // known to conform.
+ return getObjCObjectType(type, { }, protocols, false);
+ }
+
+ // id<protocol-list>
+ if (type->isObjCIdType()) {
+ const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
+ type = getObjCObjectType(ObjCBuiltinIdTy, { }, protocols,
+ objPtr->isKindOfType());
+ return getObjCObjectPointerType(type);
+ }
+
+ // Class<protocol-list>
+ if (type->isObjCClassType()) {
+ const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
+ type = getObjCObjectType(ObjCBuiltinClassTy, { }, protocols,
+ objPtr->isKindOfType());
+ return getObjCObjectPointerType(type);
+ }
+
+ hasError = true;
+ return type;
+}
+
/// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's
/// protocol list adopt all protocols in QT's qualified-id protocol
/// list.
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=281353&r1=281352&r2=281353&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Sep 13 12:03:12 2016
@@ -1000,57 +1000,6 @@ static QualType applyObjCTypeArgs(Sema &
return S.Context.getObjCObjectType(type, finalTypeArgs, { }, false);
}
-/// Apply Objective-C protocol qualifiers to the given type.
-static QualType applyObjCProtocolQualifiers(
- Sema &S, SourceLocation loc, SourceRange range, QualType type,
- ArrayRef<ObjCProtocolDecl *> protocols,
- const SourceLocation *protocolLocs,
- bool failOnError = false) {
- ASTContext &ctx = S.Context;
- if (const ObjCObjectType *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){
- // FIXME: Check for protocols to which the class type is already
- // known to conform.
-
- return ctx.getObjCObjectType(objT->getBaseType(),
- objT->getTypeArgsAsWritten(),
- protocols,
- objT->isKindOfTypeAsWritten());
- }
-
- if (type->isObjCObjectType()) {
- // Silently overwrite any existing protocol qualifiers.
- // TODO: determine whether that's the right thing to do.
-
- // FIXME: Check for protocols to which the class type is already
- // known to conform.
- return ctx.getObjCObjectType(type, { }, protocols, false);
- }
-
- // id<protocol-list>
- if (type->isObjCIdType()) {
- const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
- type = ctx.getObjCObjectType(ctx.ObjCBuiltinIdTy, { }, protocols,
- objPtr->isKindOfType());
- return ctx.getObjCObjectPointerType(type);
- }
-
- // Class<protocol-list>
- if (type->isObjCClassType()) {
- const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
- type = ctx.getObjCObjectType(ctx.ObjCBuiltinClassTy, { }, protocols,
- objPtr->isKindOfType());
- return ctx.getObjCObjectPointerType(type);
- }
-
- S.Diag(loc, diag::err_invalid_protocol_qualifiers)
- << range;
-
- if (failOnError)
- return QualType();
-
- return type;
-}
-
QualType Sema::BuildObjCObjectType(QualType BaseType,
SourceLocation Loc,
SourceLocation TypeArgsLAngleLoc,
@@ -1072,12 +1021,14 @@ QualType Sema::BuildObjCObjectType(QualT
}
if (!Protocols.empty()) {
- Result = applyObjCProtocolQualifiers(*this, Loc,
- SourceRange(ProtocolLAngleLoc,
- ProtocolRAngleLoc),
- Result, Protocols,
- ProtocolLocs.data(),
- FailOnError);
+ bool HasError;
+ Result = Context.applyObjCProtocolQualifiers(Result, Protocols,
+ HasError);
+ if (HasError) {
+ Diag(Loc, diag::err_invalid_protocol_qualifiers)
+ << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);
+ if (FailOnError) Result = QualType();
+ }
if (FailOnError && Result.isNull())
return QualType();
}
More information about the cfe-commits
mailing list