Files
swift-mirror/lib/IDE/APIDigesterData.cpp
Saleem Abdulrasool 910fbee14e gardening: make c++98-compat-extra-semi an error
This cleans up 90 instances of this warning and reduces the build spew
when building on Linux.  This helps identify actual issues when
building which can get lost in the stream of warning messages.  It also
helps restore the ability to build the compiler with gcc.
2021-11-27 11:40:17 -08:00

597 lines
21 KiB
C++

//===--- APIDigesterData.cpp - api digester data implementation -----------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/MemoryBuffer.h"
#include "swift/Basic/JSONSerialization.h"
#include "swift/IDE/APIDigesterData.h"
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/DiagnosticsDriver.h"
using namespace swift;
using namespace ide;
using namespace api;
raw_ostream &swift::ide::api::
operator<<(raw_ostream &Out, const SDKNodeKind Value) {
switch (Value) {
#define NODE_KIND(Name, Value) case SDKNodeKind::Name: return Out << #Value;
#include "swift/IDE/DigesterEnums.def"
}
llvm_unreachable("Undefined SDK node kind.");
}
raw_ostream &swift::ide::api::
operator<<(raw_ostream &Out, const NodeAnnotation Value) {
#define NODE_ANNOTATION(X) if (Value == NodeAnnotation::X) { return Out << #X; }
#include "swift/IDE/DigesterEnums.def"
llvm_unreachable("Undefined SDK node kind.");
}
static StringRef getDeclKindStrRaw(const DeclKind Value) {
switch (Value) {
#define DECL(X, PARENT) case DeclKind::X: return #X;
#include "swift/AST/DeclNodes.def"
}
llvm_unreachable("Unhandled DeclKind in switch.");
}
StringRef swift::ide::api::getDeclKindStr(const DeclKind Value, bool lower) {
if (lower) {
switch (Value) {
#define DECL(X, PARENT) case DeclKind::X: { \
static std::string lowered = StringRef(#X).lower(); \
return lowered; \
}
#include "swift/AST/DeclNodes.def"
}
llvm_unreachable("Unhandled DeclKind in switch.");
} else {
return getDeclKindStrRaw(Value);
}
}
raw_ostream &swift::ide::api::operator<<(raw_ostream &Out, const DeclKind Value) {
return Out << getDeclKindStrRaw(Value);
}
Optional<SDKNodeKind> swift::ide::api::parseSDKNodeKind(StringRef Content) {
return llvm::StringSwitch<Optional<SDKNodeKind>>(Content)
#define NODE_KIND(NAME, VALUE) .Case(#VALUE, SDKNodeKind::NAME)
#include "swift/IDE/DigesterEnums.def"
.Default(None)
;
}
NodeAnnotation swift::ide::api::parseSDKNodeAnnotation(StringRef Content) {
return llvm::StringSwitch<NodeAnnotation>(Content)
#define NODE_ANNOTATION_CHANGE_KIND(NAME) .Case(#NAME, NodeAnnotation::NAME)
#include "swift/IDE/DigesterEnums.def"
;
}
SpecialCaseId swift::ide::api::parseSpecialCaseId(StringRef Content) {
return llvm::StringSwitch<SpecialCaseId>(Content)
#define SPECIAL_CASE_ID(NAME) .Case(#NAME, SpecialCaseId::NAME)
#include "swift/IDE/DigesterEnums.def"
;
}
swift::ide::api::CommonDiffItem::
CommonDiffItem(SDKNodeKind NodeKind, NodeAnnotation DiffKind,
StringRef ChildIndex, StringRef LeftUsr, StringRef RightUsr,
StringRef LeftComment, StringRef RightComment,
StringRef ModuleName) : NodeKind(NodeKind),
DiffKind(DiffKind), ChildIndex(ChildIndex), LeftUsr(LeftUsr),
RightUsr(RightUsr), LeftComment(LeftComment),
RightComment(RightComment), ModuleName(ModuleName) {
assert(!ChildIndex.empty() && "Child index is empty.");
llvm::SmallVector<StringRef, 4> Pieces;
ChildIndex.split(Pieces, ":");
llvm::transform(Pieces, std::back_inserter(ChildIndexPieces),
[](StringRef Piece) { return std::stoi(Piece.str()); });
}
StringRef swift::ide::api::CommonDiffItem::head() {
return "SDK_CHANGE";
}
bool swift::ide::api::CommonDiffItem::operator<(CommonDiffItem Other) const {
if (auto UsrCompare = LeftUsr.compare(Other.LeftUsr))
return UsrCompare < 0;
if (NodeKind != Other.NodeKind)
return NodeKind < Other.NodeKind;
if (DiffKind != Other.DiffKind)
return DiffKind < Other.DiffKind;
if (auto ChildCompare = ChildIndex.compare(Other.ChildIndex))
return ChildCompare < 0;
return false;
}
void swift::ide::api::CommonDiffItem::describe(llvm::raw_ostream &os) {
os << "#ifndef " << head() << "\n";
os << "#define " << head() << "(NODE_KIND, DIFF_KIND, CHILD_INDEX, LEFT_USR, "
"RIGHT_USR, LEFT_COMMENT, RIGHT_COMMENT, "
"MODULENAME)\n";
os << "#endif\n";
}
void swift::ide::api::CommonDiffItem::undef(llvm::raw_ostream &os) {
os << "#undef " << head() << "\n";
}
void swift::ide::api::CommonDiffItem::streamDef(llvm::raw_ostream &S) const {
S << head() << "(" << NodeKind << ", " << DiffKind << ", \"" << ChildIndex
<< "\", \"" << LeftUsr << "\", \"" << RightUsr << "\", \""
<< LeftComment << "\", \"" << RightComment
<< "\", \"" << ModuleName << "\")";
}
StringRef swift::ide::api::TypeMemberDiffItem::head() {
return "SDK_CHANGE_TYPE_MEMBER";
}
TypeMemberDiffItemSubKind
swift::ide::api::TypeMemberDiffItem::getSubKind() const {
DeclNameViewer OldName = getOldName();
DeclNameViewer NewName = getNewName();
if (!OldName.isFunction()) {
assert(!NewName.isFunction());
if (oldTypeName.empty())
return TypeMemberDiffItemSubKind::SimpleReplacement;
else
return TypeMemberDiffItemSubKind::QualifiedReplacement;
}
assert(OldName.isFunction());
bool ToProperty = !NewName.isFunction();
if (selfIndex) {
if (removedIndex) {
if (ToProperty)
llvm_unreachable("unknown situation");
else {
assert(NewName.argSize() + 2 == OldName.argSize());
return TypeMemberDiffItemSubKind::HoistSelfAndRemoveParam;
}
} else if (ToProperty) {
assert(OldName.argSize() == 1);
return TypeMemberDiffItemSubKind::HoistSelfAndUseProperty;
} else if (oldTypeName.empty()) {
assert(NewName.argSize() + 1 == OldName.argSize());
return TypeMemberDiffItemSubKind::HoistSelfOnly;
} else {
assert(NewName.argSize() == OldName.argSize());
return TypeMemberDiffItemSubKind::QualifiedReplacement;
}
} else if (ToProperty) {
assert(OldName.argSize() == 0);
assert(!removedIndex);
return TypeMemberDiffItemSubKind::GlobalFuncToStaticProperty;
} else if (oldTypeName.empty()) {
// we can handle this as a simple function rename.
assert(NewName.argSize() == OldName.argSize());
return TypeMemberDiffItemSubKind::FuncRename;
} else {
assert(NewName.argSize() == OldName.argSize());
return TypeMemberDiffItemSubKind::QualifiedReplacement;
}
}
void swift::ide::api::TypeMemberDiffItem::describe(llvm::raw_ostream &os) {
os << "#ifndef " << head() << "\n";
os << "#define " << head() << "(USR, NEW_TYPE_NAME, NEW_PRINTED_NAME, "
"SELF_INDEX, OLD_PRINTED_NAME)\n";
os << "#endif\n";
}
void swift::ide::api::TypeMemberDiffItem::undef(llvm::raw_ostream &os) {
os << "#undef " << head() << "\n";
}
void swift::ide::api::TypeMemberDiffItem::streamDef(llvm::raw_ostream &os) const {
std::string IndexContent = selfIndex.hasValue() ?
std::to_string(selfIndex.getValue()) : "";
os << head() << "("
<< "\"" << usr << "\"" << ", "
<< "\"" << newTypeName << "\"" << ", "
<< "\"" << newPrintedName << "\"" << ", "
<< "\"" << IndexContent << "\"" << ", "
<< "\"" << oldPrintedName << "\""
<< ")";
}
bool swift::ide::api::TypeMemberDiffItem::
operator<(TypeMemberDiffItem Other) const {
return usr.compare(Other.usr) < 0;
}
StringRef swift::ide::api::NoEscapeFuncParam::head() {
return "NOESCAPE_FUNC_PARAM";
}
void swift::ide::api::NoEscapeFuncParam::describe(llvm::raw_ostream &os) {
os << "#ifndef " << head() << "\n";
os << "#define " << head() << "(USR, Index)\n";
os << "#endif\n";
}
void swift::ide::api::NoEscapeFuncParam::undef(llvm::raw_ostream &os) {
os << "#undef " << head() << "\n";
}
void swift::ide::api::NoEscapeFuncParam::
streamDef(llvm::raw_ostream &os) const {
os << head() << "(" << "\"" << Usr << "\"" << ", "
<< "\"" << Index << "\"" << ")";
}
bool swift::ide::api::NoEscapeFuncParam::
operator<(NoEscapeFuncParam Other) const {
if (Usr != Other.Usr)
return Usr.compare(Other.Usr) < 0;
return Index < Other.Index;
}
StringRef swift::ide::api::OverloadedFuncInfo::head() {
return "OVERLOAD_FUNC_TRAILING_CLOSURE";
}
void swift::ide::api::OverloadedFuncInfo::describe(llvm::raw_ostream &os) {
os << "#ifndef " << head() << "\n";
os << "#define " << head() << "(USR)\n";
os << "#endif\n";
}
void swift::ide::api::OverloadedFuncInfo::undef(llvm::raw_ostream &os) {
os << "#undef " << head() << "\n";
}
void swift::ide::api::OverloadedFuncInfo::
streamDef(llvm::raw_ostream &os) const {
os << head() << "(" << "\"" << Usr << "\"" << ")";
}
bool swift::ide::api::OverloadedFuncInfo::
operator<(OverloadedFuncInfo Other) const {
return Usr.compare(Other.Usr) < 0;
}
#define DIFF_ITEM_KIND(NAME) \
bool swift::ide::api::NAME::classof(const APIDiffItem *D) { \
return D->getKind() == APIDiffItemKind::ADK_##NAME; \
}
#include "swift/IDE/DigesterEnums.def"
bool APIDiffItem::operator==(const APIDiffItem &Other) const {
if (getKind() != Other.getKind())
return false;
if (getKey() != Other.getKey())
return false;
switch(getKind()) {
case APIDiffItemKind::ADK_CommonDiffItem: {
auto *Left = static_cast<const CommonDiffItem*>(this);
auto *Right = static_cast<const CommonDiffItem*>(&Other);
return
Left->DiffKind == Right->DiffKind &&
Left->ChildIndex == Right->ChildIndex;
}
case APIDiffItemKind::ADK_NoEscapeFuncParam: {
auto *Left = static_cast<const NoEscapeFuncParam*>(this);
auto *Right = static_cast<const NoEscapeFuncParam*>(&Other);
return Left->Index == Right->Index;
}
case APIDiffItemKind::ADK_TypeMemberDiffItem:
case APIDiffItemKind::ADK_OverloadedFuncInfo:
case APIDiffItemKind::ADK_SpecialCaseDiffItem:
return true;
}
llvm_unreachable("unhandled kind");
}
namespace {
enum class DiffItemKeyKind {
#define DIFF_ITEM_KEY_KIND(NAME) KK_##NAME,
#include "swift/IDE/DigesterEnums.def"
};
static const char* getKeyContent(DiffItemKeyKind KK) {
switch (KK) {
#define DIFF_ITEM_KEY_KIND(NAME) case DiffItemKeyKind::KK_##NAME: return #NAME;
#include "swift/IDE/DigesterEnums.def"
}
llvm_unreachable("unhandled kind");
}
static DiffItemKeyKind parseKeyKind(StringRef Content) {
return llvm::StringSwitch<DiffItemKeyKind>(Content)
#define DIFF_ITEM_KEY_KIND(NAME) .Case(#NAME, DiffItemKeyKind::KK_##NAME)
#include "swift/IDE/DigesterEnums.def"
;
}
static APIDiffItemKind parseDiffItemKind(StringRef Content) {
return llvm::StringSwitch<APIDiffItemKind>(Content)
#define DIFF_ITEM_KIND(NAME) .Case(#NAME, APIDiffItemKind::ADK_##NAME)
#include "swift/IDE/DigesterEnums.def"
;
}
static StringRef getScalarString(llvm::yaml::Node *N) {
auto WithQuote = cast<llvm::yaml::ScalarNode>(N)->getRawValue();
return WithQuote.substr(1, WithQuote.size() - 2);
}
static int getScalarInt(llvm::yaml::Node *N) {
return std::stoi(cast<llvm::yaml::ScalarNode>(N)->getRawValue().str());
}
static APIDiffItem*
serializeDiffItem(llvm::BumpPtrAllocator &Alloc,
llvm::yaml::MappingNode* Node) {
#define DIFF_ITEM_KEY_KIND_STRING(NAME) StringRef NAME;
#define DIFF_ITEM_KEY_KIND_INT(NAME) Optional<int> NAME;
#include "swift/IDE/DigesterEnums.def"
for (auto &Pair : *Node) {
switch(parseKeyKind(getScalarString(Pair.getKey()))) {
#define DIFF_ITEM_KEY_KIND_STRING(NAME) \
case DiffItemKeyKind::KK_##NAME: \
NAME = getScalarString(Pair.getValue()); break;
#define DIFF_ITEM_KEY_KIND_INT(NAME) \
case DiffItemKeyKind::KK_##NAME: \
NAME = getScalarInt(Pair.getValue()); break;
#include "swift/IDE/DigesterEnums.def"
}
}
switch (parseDiffItemKind(DiffItemKind)) {
case APIDiffItemKind::ADK_CommonDiffItem: {
return new (Alloc.Allocate<CommonDiffItem>())
CommonDiffItem(*parseSDKNodeKind(NodeKind),
parseSDKNodeAnnotation(NodeAnnotation), ChildIndex,
LeftUsr, RightUsr, LeftComment, RightComment, ModuleName);
}
case APIDiffItemKind::ADK_TypeMemberDiffItem: {
Optional<uint8_t> SelfIndexShort;
Optional<uint8_t> RemovedIndexShort;
if (SelfIndex)
SelfIndexShort = SelfIndex.getValue();
if (RemovedIndex)
RemovedIndexShort = RemovedIndex.getValue();
return new (Alloc.Allocate<TypeMemberDiffItem>())
TypeMemberDiffItem(Usr, NewTypeName, NewPrintedName, SelfIndexShort,
RemovedIndexShort, OldTypeName, OldPrintedName);
}
case APIDiffItemKind::ADK_NoEscapeFuncParam: {
return new (Alloc.Allocate<NoEscapeFuncParam>())
NoEscapeFuncParam(Usr, Index.getValue());
}
case APIDiffItemKind::ADK_OverloadedFuncInfo: {
return new (Alloc.Allocate<OverloadedFuncInfo>()) OverloadedFuncInfo(Usr);
}
case APIDiffItemKind::ADK_SpecialCaseDiffItem: {
return new (Alloc.Allocate<SpecialCaseDiffItem>())
SpecialCaseDiffItem(Usr, SpecialCaseId);
}
}
llvm_unreachable("unhandled kind");
}
} // end anonymous namespace
namespace swift {
namespace json {
template<>
struct ScalarEnumerationTraits<APIDiffItemKind> {
static void enumeration(Output &out, APIDiffItemKind &value) {
#define DIFF_ITEM_KIND(X) out.enumCase(value, #X, APIDiffItemKind::ADK_##X);
#include "swift/IDE/DigesterEnums.def"
}
};
template<>
struct ScalarEnumerationTraits<NodeAnnotation> {
static void enumeration(Output &out, NodeAnnotation &value) {
#define NODE_ANNOTATION(X) out.enumCase(value, #X, NodeAnnotation::X);
#include "swift/IDE/DigesterEnums.def"
}
};
template<>
struct ObjectTraits<APIDiffItem*> {
static void mapping(Output &out, APIDiffItem *&value) {
switch (value->getKind()) {
case APIDiffItemKind::ADK_CommonDiffItem: {
CommonDiffItem *Item = cast<CommonDiffItem>(value);
auto ItemKind = Item->getKind();
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_DiffItemKind), ItemKind);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NodeKind),
Item->NodeKind);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NodeAnnotation),
Item->DiffKind);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_ChildIndex),
Item->ChildIndex);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_LeftUsr),
Item->LeftUsr);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_LeftComment),
Item->LeftComment);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_RightUsr),
Item->RightUsr);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_RightComment),
Item->RightComment);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_ModuleName),
Item->ModuleName);
return;
}
case APIDiffItemKind::ADK_TypeMemberDiffItem: {
TypeMemberDiffItem *Item = cast<TypeMemberDiffItem>(value);
auto ItemKind = Item->getKind();
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_DiffItemKind),
ItemKind);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_Usr), Item->usr);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_OldPrintedName),
Item->oldPrintedName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_OldTypeName),
Item->oldTypeName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NewPrintedName),
Item->newPrintedName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NewTypeName),
Item->newTypeName);
out.mapOptional(getKeyContent(DiffItemKeyKind::KK_SelfIndex),
Item->selfIndex);
return;
}
case APIDiffItemKind::ADK_NoEscapeFuncParam: {
NoEscapeFuncParam *Item = cast<NoEscapeFuncParam>(value);
auto ItemKind = Item->getKind();
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_DiffItemKind), ItemKind);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_Usr), Item->Usr);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_Index), Item->Index);
return;
}
case APIDiffItemKind::ADK_OverloadedFuncInfo: {
OverloadedFuncInfo *Item = cast<OverloadedFuncInfo>(value);
auto ItemKind = Item->getKind();
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_DiffItemKind), ItemKind);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_Usr), Item->Usr);
return;
}
case APIDiffItemKind::ADK_SpecialCaseDiffItem:
llvm_unreachable("This entry should be authored only.");
}
}
};
template<>
struct ArrayTraits<ArrayRef<APIDiffItem*>> {
static size_t size(Output &out, ArrayRef<APIDiffItem *> &seq) {
return seq.size();
}
static APIDiffItem *&element(Output &, ArrayRef<APIDiffItem *> &seq,
size_t index) {
return const_cast<APIDiffItem *&>(seq[index]);
}
};
template<>
struct ObjectTraits<NameCorrectionInfo> {
static void mapping(Output &out, NameCorrectionInfo &value) {
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_OldPrintedName),value.OriginalName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NewPrintedName), value.CorrectedName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_ModuleName), value.ModuleName);
}
};
template<>
struct ArrayTraits<ArrayRef<NameCorrectionInfo>> {
static size_t size(Output &out, ArrayRef<NameCorrectionInfo> &seq) {
return seq.size();
}
static NameCorrectionInfo &element(Output &, ArrayRef<NameCorrectionInfo> &seq,
size_t index) {
return const_cast<NameCorrectionInfo&>(seq[index]);
}
};
} // namespace json
} // namespace swift
void swift::ide::api::APIDiffItemStore::
serialize(llvm::raw_ostream &os, ArrayRef<APIDiffItem*> Items) {
json::Output yout(os);
yout << Items;
}
void swift::ide::api::APIDiffItemStore::
serialize(llvm::raw_ostream &os, ArrayRef<NameCorrectionInfo> Items) {
json::Output yout(os);
yout << Items;
}
struct swift::ide::api::APIDiffItemStore::Implementation {
private:
DiagnosticEngine &Diags;
llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 2> AllBuffer;
llvm::BumpPtrAllocator Allocator;
static bool shouldInclude(APIDiffItem *Item) {
if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
if (CI->rightCommentUnderscored())
return false;
// Ignore constructor's return value rewritten.
if (CI->DiffKind == NodeAnnotation::TypeRewritten &&
CI->NodeKind == SDKNodeKind::DeclConstructor &&
CI->getChildIndices().front() == 0) {
return false;
}
}
return true;
}
public:
Implementation(DiagnosticEngine &Diags): Diags(Diags) {}
llvm::StringMap<std::vector<APIDiffItem*>> Data;
bool PrintUsr;
std::vector<APIDiffItem*> AllItems;
llvm::StringSet<> PrintedUsrs;
void addStorePath(StringRef FileName) {
llvm::MemoryBuffer *pMemBuffer = nullptr;
{
auto FileBufOrErr = llvm::MemoryBuffer::getFileOrSTDIN(FileName);
if (!FileBufOrErr) {
Diags.diagnose(SourceLoc(), diag::cannot_find_migration_script,
FileName);
return;
}
pMemBuffer = FileBufOrErr->get();
AllBuffer.push_back(std::move(FileBufOrErr.get()));
}
assert(pMemBuffer);
StringRef Buffer = pMemBuffer->getBuffer();
llvm::SourceMgr SM;
llvm::yaml::Stream Stream(Buffer, SM);
for (auto DI = Stream.begin(); DI != Stream.end(); ++ DI) {
auto Array = cast<llvm::yaml::SequenceNode>(DI->getRoot());
for (auto It = Array->begin(); It != Array->end(); ++ It) {
APIDiffItem *Item = serializeDiffItem(Allocator,
cast<llvm::yaml::MappingNode>(&*It));
auto &Bag = Data[Item->getKey()];
if (shouldInclude(Item) && std::find_if(Bag.begin(), Bag.end(),
[&](APIDiffItem* I) { return *Item == *I; }) == Bag.end()) {
Bag.push_back(Item);
AllItems.push_back(Item);
}
}
}
}
};
ArrayRef<APIDiffItem*> swift::ide::api::APIDiffItemStore::
getDiffItems(StringRef Key) const {
if (Impl.PrintUsr && !Impl.PrintedUsrs.count(Key)) {
llvm::outs() << Key << "\n";
Impl.PrintedUsrs.insert(Key);
}
return Impl.Data[Key];
}
ArrayRef<APIDiffItem*> swift::ide::api::APIDiffItemStore::
getAllDiffItems() const { return Impl.AllItems; }
swift::ide::api::APIDiffItemStore::APIDiffItemStore(DiagnosticEngine &Diags) :
Impl(*new Implementation(Diags)) {}
swift::ide::api::APIDiffItemStore::~APIDiffItemStore() { delete &Impl; }
void swift::ide::api::APIDiffItemStore::addStorePath(StringRef Path) {
Impl.addStorePath(Path);
}
void swift::ide::api::APIDiffItemStore::printIncomingUsr(bool print) {
Impl.PrintUsr = print;
}