api-digester: diagnose adding conformances to existing protocols. rdar://48131686

This commit is contained in:
Xi Ge
2019-05-14 15:40:04 -07:00
parent f7881eed66
commit ae16a74af9
4 changed files with 16 additions and 0 deletions

View File

@@ -68,6 +68,8 @@ ERROR(conformance_removed,none,"%0 has removed %select{conformance to|inherited
ERROR(conformance_added,none,"%0 has added inherited protocol %1", (StringRef, StringRef))
ERROR(existing_conformance_added,none,"%0 has added a conformance to an existing protocol %1", (StringRef, StringRef))
ERROR(default_associated_type_removed,none,"%0 has removed default type %1", (StringRef, StringRef))
ERROR(protocol_req_added,none,"%0 has been added as a protocol requirement", (StringRef))

View File

@@ -73,7 +73,10 @@ cake1: Func ObjCProtocol.addOptional() is now an optional requirement
cake1: Func ObjCProtocol.removeOptional() is no longer an optional requirement
cake1: Protocol P3 has removed inherited protocol P2
cake1: Struct fixedLayoutStruct has removed conformance to P1
cake2: Class C7 has added a conformance to an existing protocol P1
cake2: Class SuperClassChange has added a conformance to an existing protocol P1
cake2: Protocol P3 has added inherited protocol P4
cake2: Struct fixedLayoutStruct has added a conformance to an existing protocol P2
/* Protocol Requirement Change */
cake1: Accessor HasMutatingMethodClone.bar.Get() now requires new witness table entry

View File

@@ -63,6 +63,7 @@ static StringRef getCategoryName(uint32_t ID) {
case LocalDiagID::conformance_added:
case LocalDiagID::conformance_removed:
case LocalDiagID::optional_req_changed:
case LocalDiagID::existing_conformance_added:
return "/* Protocol Conformance Change */";
case LocalDiagID::default_associated_type_removed:
case LocalDiagID::protocol_req_added:

View File

@@ -951,6 +951,8 @@ class PrunePass : public MatchedNodeListener, public SDKTreeDiffPass {
SDKContext &Ctx;
UpdatedNodesMap &UpdateMap;
llvm::StringSet<> ProtocolReqWhitelist;
SDKNodeRoot *LeftRoot;
SDKNodeRoot *RightRoot;
static void printSpaces(llvm::raw_ostream &OS, SDKNode *N) {
assert(N);
@@ -1028,6 +1030,12 @@ public:
auto *TD = Conf->getNominalTypeDecl();
if (TD->isProtocol()) {
TD->emitDiag(diag::conformance_added, Conf->getName());
} else {
// Adding conformance to an existing type can be ABI breaking.
if (Ctx.checkingABI() &&
!LeftRoot->getDescendantsByUsr(Conf->getUsr()).empty()) {
TD->emitDiag(diag::existing_conformance_added, Conf->getName());
}
}
}
@@ -1128,6 +1136,8 @@ public:
}
void pass(NodePtr Left, NodePtr Right) override {
LeftRoot = Left->getAs<SDKNodeRoot>();
RightRoot = Right->getAs<SDKNodeRoot>();
foundMatch(Left, Right, NodeMatchReason::Root);
}
};