Merge remote-tracking branch 'origin/master' into master-next

This commit is contained in:
Bob Wilson
2016-10-27 22:28:28 -07:00
377 changed files with 10818 additions and 6806 deletions

View File

@@ -207,27 +207,43 @@ struct NodeMatcher {
virtual ~NodeMatcher() = default;
};
#define KEY(NAME) static const char* Key_##NAME = #NAME;
enum class KeyKind {
#define KEY(NAME) KK_##NAME,
#include "DigesterEnums.def"
};
static KeyKind parseKeyKind(StringRef Content) {
return llvm::StringSwitch<KeyKind>(Content)
#define KEY(NAME) .Case(#NAME, KeyKind::KK_##NAME)
#include "DigesterEnums.def"
;
}
static StringRef getKeyContent(KeyKind Kind) {
switch (Kind) {
#define KEY(NAME) case KeyKind::KK_##NAME: return InsertToBuffer(#NAME);
#include "DigesterEnums.def"
}
}
// The node kind appearing in the tree that describes the content of the SDK
enum class SDKNodeKind {
enum class SDKNodeKind: uint8_t {
#define NODE_KIND(NAME) NAME,
#include "DigesterEnums.def"
};
enum class NodeAnnotation {
enum class NodeAnnotation: uint8_t{
#define NODE_ANNOTATION(NAME) NAME,
#include "DigesterEnums.def"
};
enum class KnownTypeKind {
enum class KnownTypeKind: uint8_t {
#define KNOWN_TYPE(NAME) NAME,
#include "DigesterEnums.def"
Unknown,
};
enum class SDKDeclAttrKind {
enum class SDKDeclAttrKind: uint8_t {
#define DECL_ATTR(Name) DAK_##Name,
#include "DigesterEnums.def"
};
@@ -264,7 +280,9 @@ struct SDKNodeInitInfo {
StringRef ModuleName;
bool IsThrowing = false;
bool IsMutating = false;
bool IsStatic = false;
Optional<uint8_t> SelfIndex;
Ownership Ownership = Ownership::Strong;
std::vector<SDKDeclAttrKind> DeclAttrs;
std::vector<TypeAttrKind> TypeAttrs;
SDKNodeInitInfo() = default;
@@ -325,12 +343,15 @@ class SDKNodeDecl : public SDKNode {
StringRef Location;
StringRef ModuleName;
std::vector<SDKDeclAttrKind> DeclAttributes;
bool IsStatic;
uint8_t Ownership;
bool hasDeclAttribute(SDKDeclAttrKind DAKind) const;
protected:
SDKNodeDecl(SDKNodeInitInfo Info, SDKNodeKind Kind) : SDKNode(Info, Kind),
DKind(Info.DKind), Usr(Info.USR), Location(Info.Location),
ModuleName(Info.ModuleName), DeclAttributes(Info.DeclAttrs) {}
DKind(Info.DKind), Usr(Info.USR), Location(Info.Location),
ModuleName(Info.ModuleName), DeclAttributes(Info.DeclAttrs),
IsStatic(Info.IsStatic), Ownership(uint8_t(Info.Ownership)) {}
public:
StringRef getUsr() const { return Usr; }
@@ -338,6 +359,7 @@ public:
StringRef getModuleName() const {return ModuleName;}
void addDeclAttribute(SDKDeclAttrKind DAKind);
ArrayRef<SDKDeclAttrKind> getDeclAttributes() const;
swift::Ownership getOwnership() const { return swift::Ownership(Ownership); }
bool isObjc() const { return Usr.startswith("c:"); }
static bool classof(const SDKNode *N);
DeclKind getDeclKind() const { return DKind; }
@@ -345,6 +367,7 @@ public:
StringRef getFullyQualifiedName();
bool isSDKPrivate();
bool isDeprecated();
bool isStatic() const { return IsStatic; };
};
class SDKNodeType : public SDKNode {
@@ -667,6 +690,7 @@ public:
Optional<uint8_t> getSelfIndexOptional() const { return SelfIndex; }
bool hasSelfIndex() const { return SelfIndex.hasValue(); }
static bool classof(const SDKNode *N);
static StringRef getTypeRoleDescription(unsigned Index);
};
bool SDKNodeAbstractFunc::classof(const SDKNode *N) {
@@ -688,10 +712,9 @@ public:
SDKNodeKind::Function) {}
SDKNode *getReturnType() { return (*getChildBegin()).get(); }
static bool classof(const SDKNode *N);
static StringRef getTypeRoleDescription(unsigned Index);
};
StringRef SDKNodeFunction::getTypeRoleDescription(unsigned Index) {
StringRef SDKNodeAbstractFunc::getTypeRoleDescription(unsigned Index) {
if (Index == 0) {
return InsertToBuffer("return");
} else if (Index == 1) {
@@ -741,39 +764,61 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) {
auto WithQuote = cast<llvm::yaml::ScalarNode>(N)->getRawValue();
return WithQuote.substr(1, WithQuote.size() - 2);
};
static auto getAsInt = [&](llvm::yaml::Node *N) -> int {
return std::stoi(cast<llvm::yaml::ScalarNode>(N)->getRawValue());
};
SDKNodeKind Kind;
SDKNodeInitInfo Info;
NodeOwnedVector Children;
for (auto Pair : *Node) {
auto Key = GetScalarString(Pair.getKey());
if (Key == Key_kind) {
switch(parseKeyKind(GetScalarString(Pair.getKey()))) {
case KeyKind::KK_kind:
Kind = llvm::StringSwitch<SDKNodeKind>(GetScalarString(Pair.getValue()))
#define NODE_KIND(NAME) .Case(#NAME, SDKNodeKind::NAME)
#include "DigesterEnums.def"
;
} else if (Key == Key_name) {
break;
case KeyKind::KK_name:
Info.Name = GetScalarString(Pair.getValue());
} else if (Key == Key_selfIndex) {
Info.SelfIndex = std::stoi(cast<llvm::yaml::ScalarNode>(Pair.getValue())->
getRawValue());
} else if (Key == Key_usr) {
break;
case KeyKind::KK_selfIndex:
Info.SelfIndex = getAsInt(Pair.getValue());
break;
case KeyKind::KK_usr:
Info.USR = GetScalarString(Pair.getValue());
} else if (Key == Key_location) {
break;
case KeyKind::KK_location:
Info.Location = GetScalarString(Pair.getValue());
} else if (Key == Key_children) {
break;
case KeyKind::KK_children:
for (auto &Mapping : *cast<llvm::yaml::SequenceNode>(Pair.getValue())) {
Children.push_back(constructSDKNode(cast<llvm::yaml::MappingNode>(&Mapping)));
}
} else if (Key == Key_printedName) {
break;
case KeyKind::KK_printedName:
Info.PrintedName = GetScalarString(Pair.getValue());
} else if (Key == Key_moduleName) {
break;
case KeyKind::KK_moduleName:
Info.ModuleName = GetScalarString(Pair.getValue());
} else if (Key == Key_throwing) {
break;
case KeyKind::KK_throwing:
Info.IsThrowing = true;
} else if (Key == Key_mutating) {
break;
case KeyKind::KK_mutating:
Info.IsMutating = true;
} else if (Key == Key_typeAttributes) {
break;
case KeyKind::KK_static:
Info.IsStatic = true;
break;
case KeyKind::KK_ownership:
Info.Ownership = swift::Ownership(getAsInt(Pair.getValue()));
assert(Info.Ownership != swift::Ownership::Strong && "Stong is implied.");
break;
case KeyKind::KK_typeAttributes: {
auto *Seq = cast<llvm::yaml::SequenceNode>(Pair.getValue());
for (auto It = Seq->begin(); It != Seq->end(); ++ It) {
Info.TypeAttrs.push_back(
@@ -782,7 +827,9 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) {
#include "swift/AST/Attr.def"
.Case("Count", TypeAttrKind::TAK_Count));
}
} else if (Key == Key_declAttributes) {
break;
}
case KeyKind::KK_declAttributes: {
auto *Seq = cast<llvm::yaml::SequenceNode>(Pair.getValue());
for (auto It = Seq->begin(); It != Seq->end(); ++ It) {
Info.DeclAttrs.push_back(
@@ -791,13 +838,14 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) {
#include "DigesterEnums.def"
);
}
} else if (Key == Key_declKind) {
break;
}
case KeyKind::KK_declKind:
Info.DKind = llvm::StringSwitch<DeclKind>(GetScalarString(Pair.getValue()))
#define DECL(X, PARENT) .Case(#X, DeclKind::X)
#include "swift/AST/DeclNodes.def"
;
} else {
llvm_unreachable("Cannot parse key.");
break;
}
};
NodeUniquePtr Result = Info.createSDKNode(Kind);
@@ -807,45 +855,17 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) {
return Result;
}
/// This is for caching the comparison results between two SDKNodes.
class SDKNodeEqualContext {
using NodePtrAndEqual = llvm::DenseMap<const SDKNode*, bool>;
llvm::DenseMap<const SDKNode*, llvm::DenseMap<const SDKNode*, bool>> Data;
public:
Optional<bool> getEquality(const SDKNode* Left, const SDKNode* Right) {
auto &Map = Data.insert({Left, NodePtrAndEqual()}).first->getSecond();
if (Map.count(Right))
return Map[Right];
return None;
}
void addEquality(const SDKNode* Left, const SDKNode* Right, const bool Value) {
Data.insert(std::make_pair(Left, NodePtrAndEqual())).first->getSecond().
insert({Right, Value});
}
};
bool SDKNode::operator==(const SDKNode &Other) const {
static SDKNodeEqualContext EqualCache;
if (auto Cached = EqualCache.getEquality(this, &Other)) {
return Cached.getValue();
}
auto Exit = [&](const bool Result) {
EqualCache.addEquality(this, &Other, Result);
return Result;
};
if (getKind() != Other.getKind())
return Exit(false);
return false;
switch(getKind()) {
case SDKNodeKind::TypeNominal:
case SDKNodeKind::TypeFunc: {
auto Left = this->getAs<SDKNodeType>();
auto Right = (&Other)->getAs<SDKNodeType>();
return Exit(Left->getTypeAttributes().equals(Right->getTypeAttributes())
&& Left->getPrintedName() == Right->getPrintedName());
return Left->getTypeAttributes().equals(Right->getTypeAttributes())
&& Left->getPrintedName() == Right->getPrintedName();
}
case SDKNodeKind::Function:
@@ -855,25 +875,31 @@ bool SDKNode::operator==(const SDKNode &Other) const {
auto Left = this->getAs<SDKNodeAbstractFunc>();
auto Right = (&Other)->getAs<SDKNodeAbstractFunc>();
if (Left->isMutating() ^ Right->isMutating())
return Exit(false);
return false;
if (Left->isThrowing() ^ Right->isThrowing())
return Exit(false);
return false;
SWIFT_FALLTHROUGH;
}
case SDKNodeKind::TypeDecl:
case SDKNodeKind::Var:
case SDKNodeKind::TypeAlias:
case SDKNodeKind::TypeAlias: {
auto Left = this->getAs<SDKNodeDecl>();
auto Right = (&Other)->getAs<SDKNodeDecl>();
if (Left->isStatic() ^ Right->isStatic())
return false;
SWIFT_FALLTHROUGH;
}
case SDKNodeKind::Root:
case SDKNodeKind::Nil: {
if (getPrintedName() == Other.getPrintedName() &&
Children.size() == Other.Children.size()) {
for (unsigned I = 0; I < Children.size(); ++ I) {
if (*Children[I] != *Other.Children[I])
return Exit(false);
return false;
}
return Exit(true);
return true;
}
return Exit(false);
return false;
}
}
}
@@ -996,6 +1022,13 @@ static Optional<uint8_t> getSelfIndex(ValueDecl *VD) {
return None;
}
static Ownership getOwnership(ValueDecl *VD) {
if (auto OA = VD->getAttrs().getAttribute<OwnershipAttr>()) {
return OA->get();
}
return Ownership::Strong;
}
SDKNodeInitInfo::SDKNodeInitInfo(Type Ty) : Name(getTypeName(Ty)),
PrintedName(getPrintedName(Ty)) {
if (isFunctionTypeNoEscape(Ty))
@@ -1008,7 +1041,8 @@ SDKNodeInitInfo::SDKNodeInitInfo(ValueDecl *VD) :
USR(calculateUsr(VD)), Location(calculateLocation(VD)),
ModuleName(VD->getModuleContext()->getName().str()),
IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)),
SelfIndex(getSelfIndex(VD)) {
IsStatic(VD->isStatic()), SelfIndex(getSelfIndex(VD)),
Ownership(getOwnership(VD)) {
if (VD->getAttrs().getDeprecated(VD->getASTContext()))
DeclAttrs.push_back(SDKDeclAttrKind::DAK_deprecated);
}
@@ -1111,6 +1145,15 @@ static bool shouldIgnore(Decl *D) {
return true;
if (VD->getName().empty())
return true;
switch (VD->getFormalAccess()) {
case Accessibility::Internal:
case Accessibility::Private:
case Accessibility::FilePrivate:
return true;
case Accessibility::Public:
case Accessibility::Open:
break;
}
}
if (auto *ClangD = D->getClangDecl()) {
@@ -1321,9 +1364,10 @@ namespace swift {
auto Name = value->getName();
auto PrintedName = value->getPrintedName();
out.mapRequired(Key_kind, Kind);
out.mapRequired(Key_name, Name);
out.mapRequired(Key_printedName, PrintedName);
out.mapRequired(getKeyContent(KeyKind::KK_kind).data(), Kind);
out.mapRequired(getKeyContent(KeyKind::KK_name).data(), Name);
out.mapRequired(getKeyContent(KeyKind::KK_printedName).data(),
PrintedName);
if (auto D = dyn_cast<SDKNodeDecl>(value.get())) {
DeclKind DK = D->getDeclKind();
@@ -1331,32 +1375,45 @@ namespace swift {
StringRef Location = D->getLocation();
StringRef ModuleName = D->getModuleName();
out.mapRequired(Key_declKind, DK);
out.mapRequired(Key_usr, Usr);
out.mapRequired(Key_location, Location);
out.mapRequired(Key_moduleName, ModuleName);
out.mapRequired(getKeyContent(KeyKind::KK_declKind).data(), DK);
out.mapRequired(getKeyContent(KeyKind::KK_usr).data(), Usr);
out.mapRequired(getKeyContent(KeyKind::KK_location).data(), Location);
out.mapRequired(getKeyContent(KeyKind::KK_moduleName).data(),
ModuleName);
if (auto isStatic = D->isStatic())
out.mapRequired(getKeyContent(KeyKind::KK_static).data(), isStatic);
if (auto F = dyn_cast<SDKNodeAbstractFunc>(value.get())) {
if (bool isThrowing = F->isThrowing())
out.mapRequired(Key_throwing, isThrowing);
out.mapRequired(getKeyContent(KeyKind::KK_throwing).data(),
isThrowing);
if (bool isMutating = F->isMutating())
out.mapRequired(Key_mutating, isMutating);
out.mapRequired(getKeyContent(KeyKind::KK_mutating).data(),
isMutating);
if (F->hasSelfIndex()) {
auto Index = F->getSelfIndex();
out.mapRequired(Key_selfIndex, Index);
out.mapRequired(getKeyContent(KeyKind::KK_selfIndex).data(),
Index);
}
}
auto Attributes = D->getDeclAttributes();
if (!Attributes.empty())
out.mapRequired(Key_declAttributes, Attributes);
out.mapRequired(getKeyContent(KeyKind::KK_declAttributes).data(),
Attributes);
// Strong reference is implied, no need for serialization.
if (D->getOwnership() != Ownership::Strong) {
uint8_t Raw = uint8_t(D->getOwnership());
out.mapRequired(getKeyContent(KeyKind::KK_ownership).data(), Raw);
}
} else if (auto T = dyn_cast<SDKNodeType>(value.get())) {
auto Attributes = T->getTypeAttributes();
if (!Attributes.empty())
out.mapRequired(Key_typeAttributes, Attributes);
out.mapRequired(getKeyContent(KeyKind::KK_typeAttributes).data(),
Attributes);
}
if (!value->isLeaf()) {
ArrayRef<NodeUniquePtr> Children = value->getChildren();
out.mapRequired(Key_children, Children);
out.mapRequired(getKeyContent(KeyKind::KK_children).data(), Children);
}
}
};
@@ -1886,7 +1943,7 @@ public:
}
};
void detectThrowing(NodePtr L, NodePtr R) {
static void detectThrowing(NodePtr L, NodePtr R) {
assert(L->getKind() == R->getKind());
if (auto LF = dyn_cast<SDKNodeAbstractFunc>(L)) {
auto RF = R->getAs<SDKNodeAbstractFunc>();
@@ -1896,7 +1953,7 @@ void detectThrowing(NodePtr L, NodePtr R) {
}
}
void detectMutating(NodePtr L, NodePtr R) {
static void detectMutating(NodePtr L, NodePtr R) {
assert(L->getKind() == R->getKind());
if (auto LF = dyn_cast<SDKNodeAbstractFunc>(L)) {
auto RF = R->getAs<SDKNodeAbstractFunc>();
@@ -1917,6 +1974,15 @@ static void detectRename(NodePtr L, NodePtr R) {
}
}
static void detectStaticUpdate(NodePtr L, NodePtr R) {
assert(L->getKind() == R->getKind());
if (auto LD = dyn_cast<SDKNodeDecl>(L)) {
if (LD->isStatic() ^ R->getAs<SDKNodeDecl>()->isStatic()) {
L->annotate(NodeAnnotation::StaticChange);
}
}
}
// This is first pass on two given SDKNode trees. This pass removes the common part
// of two versions of SDK, leaving only the changed part.
class PrunePass : public MatchedNodeListener, public SDKTreeDiffPass {
@@ -1957,19 +2023,26 @@ public:
}
virtual void foundMatch(NodePtr Left, NodePtr Right) override {
Left->annotate(NodeAnnotation::Updated);
Right->annotate(NodeAnnotation::Updated);
// Push the updated node to the map for future reference.
UpdateMap->foundMatch(Left, Right);
if (Left->getKind() != Right->getKind()) {
assert(isa<SDKNodeType>(Left) && isa<SDKNodeType>(Right) &&
"only type nodes can match across kinds.");
return;
}
assert(Left->getKind() == Right->getKind());
SDKNodeKind Kind = Left->getKind();
assert(Left->getKind() != SDKNodeKind::Nil &&
Right->getKind() != SDKNodeKind::Nil);
assert(Kind == SDKNodeKind::Root || *Left != *Right);
Left->annotate(NodeAnnotation::Updated);
Right->annotate(NodeAnnotation::Updated);
// Push the updated node to the map for future reference.
UpdateMap->foundMatch(Left, Right);
detectRename(Left, Right);
detectThrowing(Left, Right);
detectMutating(Left, Right);
detectStaticUpdate(Left, Right);
switch(Kind) {
case SDKNodeKind::Root:
@@ -2813,7 +2886,7 @@ bool DiagnosisEmitter::DeclAttrDiag::operator<(DeclAttrDiag Other) const {
}
void DiagnosisEmitter::DeclAttrDiag::output() const {
llvm::outs() << Kind << "" << printName(DeclName) << " is now " <<
llvm::outs() << Kind << " " << printName(DeclName) << " is now " <<
printDiagKeyword(AttrName) << "\n";
}
@@ -2856,6 +2929,11 @@ void DiagnosisEmitter::visitDecl(SDKNodeDecl *Node) {
Node->getFullyQualifiedName(),
InsertToBuffer("throwing"));
}
if (Node->isAnnotatedAs(NodeAnnotation::StaticChange)) {
AttrChangedDecls.Diags.emplace_back(Node->getDeclKind(),
Node->getFullyQualifiedName(),
InsertToBuffer(Node->isStatic() ? "not static" : "static"));
}
}
void DiagnosisEmitter::visitType(SDKNodeType *Node) {
auto *Parent = Node->getParent()->getAs<SDKNodeDecl>();
@@ -2866,10 +2944,11 @@ void DiagnosisEmitter::visitType(SDKNodeType *Node) {
auto *Count = UpdateMap.findUpdateCounterpart(Node)->getAs<SDKNodeType>();
StringRef Descriptor;
switch (Parent->getKind()) {
case SDKNodeKind::Constructor:
case SDKNodeKind::Function:
case SDKNodeKind::Var:
Descriptor = Parent->getKind() == SDKNodeKind::Function ?
SDKNodeFunction::getTypeRoleDescription(Parent->getChildIndex(Node)) :
Descriptor = isa<SDKNodeAbstractFunc>(Parent) ?
SDKNodeAbstractFunc::getTypeRoleDescription(Parent->getChildIndex(Node)) :
InsertToBuffer("declared");
TypeChangedDecls.Diags.emplace_back(Parent->getDeclKind(),
Parent->getFullyQualifiedName(),