mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Allow [class_protocol] protocols to be [objc].
Swift SVN r5591
This commit is contained in:
@@ -1023,6 +1023,8 @@ ERROR(conversion_params,sema_tcd,none,
|
||||
"conversion function %0 has non-defaulted parameters", (Identifier))
|
||||
ERROR(invalid_objc_decl,sema_tcd,none,
|
||||
"only classes and their methods can be declared 'objc'", ())
|
||||
ERROR(objc_protocol_not_class_protocol,sema_tcd,none,
|
||||
"only [class_protocol] protocols can be declared 'objc'", ())
|
||||
ERROR(invalid_iboutlet,sema_tcd,none,
|
||||
"only properties can be declared 'iboutlet'", ())
|
||||
ERROR(invalid_ibaction_decl,sema_tcd,none,
|
||||
|
||||
@@ -1546,6 +1546,7 @@ static void buildValueWitnessFunction(IRGenModule &IGM,
|
||||
= emitTypeMetadataRefForClassBoundedExistential(IGF, existential,
|
||||
concreteType);
|
||||
IGF.Builder.CreateRet(result);
|
||||
|
||||
} else {
|
||||
llvm::Value *result
|
||||
= emitTypeMetadataRefForOpaqueExistential(IGF, obj, concreteType);
|
||||
|
||||
@@ -461,6 +461,20 @@ public:
|
||||
void visitProtocolDecl(ProtocolDecl *PD) {
|
||||
if (IsSecondPass)
|
||||
return;
|
||||
|
||||
// The protocol requires ObjC interop if the protocol or any of the
|
||||
// protocols it refines are [objc].
|
||||
if (PD->getAttrs().isObjC())
|
||||
PD->setIsObjC(true);
|
||||
else {
|
||||
PD->setIsObjC(false);
|
||||
for (auto *parent : PD->getProtocols()) {
|
||||
if (parent->isObjC()) {
|
||||
PD->setIsObjC(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fix the 'This' associated type.
|
||||
TypeAliasDecl *thisDecl = nullptr;
|
||||
@@ -1116,17 +1130,25 @@ void DeclChecker::validateAttributes(ValueDecl *VD) {
|
||||
};
|
||||
|
||||
if (Attrs.isObjC()) {
|
||||
// Only classes, instance properties, and methods can be ObjC.
|
||||
bool isLegal = false;
|
||||
// Only classes, class protocols, instance properties, and methods can be
|
||||
// ObjC.
|
||||
Optional<Diag<>> error;
|
||||
if (isa<ClassDecl>(VD)) {
|
||||
isLegal = true;
|
||||
/* ok */
|
||||
} else if (isa<FuncDecl>(VD) && isInClassContext(VD)) {
|
||||
isLegal = !isOperator;
|
||||
if (isOperator)
|
||||
error = diag::invalid_objc_decl;
|
||||
} else if (isa<VarDecl>(VD) && isInClassContext(VD)) {
|
||||
isLegal = true;
|
||||
/* ok */
|
||||
} else if (auto *protocol = dyn_cast<ProtocolDecl>(VD)) {
|
||||
if (!protocol->isClassBounded())
|
||||
error = diag::objc_protocol_not_class_protocol;
|
||||
} else {
|
||||
error = diag::invalid_objc_decl;
|
||||
}
|
||||
if (!isLegal) {
|
||||
TC.diagnose(VD->getStartLoc(), diag::invalid_objc_decl);
|
||||
|
||||
if (error) {
|
||||
TC.diagnose(VD->getStartLoc(), *error);
|
||||
VD->getMutableAttrs().ObjC = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user