[swift] master: swift-api-digester: teach the tool to keep track of ownership attributes. (4475b07)


(Kenny Leung) #1

Just curious - what is the swift-api-digester?

-Kenny

···

On Oct 27, 2016, at 11:55 AM, Xi Ge via swift-commits <swift-commits@swift.org> wrote:

Repository : github.com/apple/swift
On branch : master
Link : github.com/apple/swift/commit/4475b0761337b3a379d0a88561a659c9c6d946db

---------------------------------------------------------------

commit 4475b0761337b3a379d0a88561a659c9c6d946db
Author: Xi Ge <xi_ge@apple.com>
Date: Thu Oct 27 11:55:17 2016 -0700

   swift-api-digester: teach the tool to keep track of ownership attributes.

---------------------------------------------------------------

4475b0761337b3a379d0a88561a659c9c6d946db
test/api-digester/Inputs/cake.swift | 2 +
test/api-digester/Outputs/cake.json | 142 +++++++++++++++++++++++
tools/swift-api-digester/DigesterEnums.def | 1 +
tools/swift-api-digester/swift-api-digester.cpp | 39 +++++--
4 files changed, 176 insertions(+), 8 deletions(-)

diff --git a/test/api-digester/Inputs/cake.swift b/test/api-digester/Inputs/cake.swift
index 80f6d23..a61ac20 100644
--- a/test/api-digester/Inputs/cake.swift
+++ b/test/api-digester/Inputs/cake.swift
@@ -8,4 +8,6 @@ public struct S1 {

public class C1 {
  open class func foo1() {}
+ public weak var Ins : C1?
+ public unowned var Ins2 : C1 = C1()
}
\ No newline at end of file
diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index c29c338..e783b94 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -91,6 +91,148 @@
          ]
        },
        {
+ "kind": "Var",
+ "name": "Ins",
+ "printedName": "Ins",
+ "declKind": "Var",
+ "usr": "s:vC4cake2C13InsXwGSqS0__",
+ "location": "",
+ "moduleName": "cake",
+ "ownership": 1,
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "WeakStorage",
+ "printedName": "C1?"
+ },
+ {
+ "kind": "Getter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Func",
+ "usr": "s:FC4cake2C1g3InsXwGSqS0__",
+ "location": "",
+ "moduleName": "cake",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Optional",
+ "printedName": "C1?",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ },
+ {
+ "kind": "Setter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Func",
+ "usr": "s:FC4cake2C1s3InsXwGSqS0__",
+ "location": "",
+ "moduleName": "cake",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Void",
+ "printedName": "()"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Optional",
+ "printedName": "C1?",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "kind": "Var",
+ "name": "Ins2",
+ "printedName": "Ins2",
+ "declKind": "Var",
+ "usr": "s:vC4cake2C14Ins2XoS0_",
+ "location": "",
+ "moduleName": "cake",
+ "ownership": 2,
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "UnownedStorage",
+ "printedName": "C1"
+ },
+ {
+ "kind": "Getter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Func",
+ "usr": "s:FC4cake2C1g4Ins2XoS0_",
+ "location": "",
+ "moduleName": "cake",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ },
+ {
+ "kind": "Setter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Func",
+ "usr": "s:FC4cake2C1s4Ins2XoS0_",
+ "location": "",
+ "moduleName": "cake",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Void",
+ "printedName": "()"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ }
+ ]
+ },
+ {
          "kind": "Constructor",
          "name": "init",
          "printedName": "init()",
diff --git a/tools/swift-api-digester/DigesterEnums.def b/tools/swift-api-digester/DigesterEnums.def
index b123d2f..2e8ef29 100644
--- a/tools/swift-api-digester/DigesterEnums.def
+++ b/tools/swift-api-digester/DigesterEnums.def
@@ -73,6 +73,7 @@ KEY(static)
KEY(typeAttributes)
KEY(declAttributes)
KEY(declKind)
+KEY(ownership)

KNOWN_TYPE(Optional)
KNOWN_TYPE(ImplicitlyUnwrappedOptional)
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index c067945..eefef8f 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -228,23 +228,23 @@ static StringRef getKeyContent(KeyKind Kind) {
}

// 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"
};
@@ -283,6 +283,7 @@ struct SDKNodeInitInfo {
  bool IsMutating = false;
  bool IsStatic = false;
  Optional<uint8_t> SelfIndex;
+ Ownership Ownership = Ownership::Strong;
  std::vector<SDKDeclAttrKind> DeclAttrs;
  std::vector<TypeAttrKind> TypeAttrs;
  SDKNodeInitInfo() = default;
@@ -344,13 +345,14 @@ class SDKNodeDecl : public SDKNode {
  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),
- IsStatic(Info.IsStatic) {}
+ IsStatic(Info.IsStatic), Ownership(uint8_t(Info.Ownership)) {}

public:
  StringRef getUsr() const { return Usr; }
@@ -358,6 +360,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; }
@@ -762,6 +765,10 @@ 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;
@@ -778,8 +785,7 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) {
      Info.Name = GetScalarString(Pair.getValue());
      break;
    case KeyKind::KK_selfIndex:
- Info.SelfIndex = std::stoi(cast<llvm::yaml::ScalarNode>(Pair.getValue())->
- getRawValue());
+ Info.SelfIndex = getAsInt(Pair.getValue());
      break;
    case KeyKind::KK_usr:
      Info.USR = GetScalarString(Pair.getValue());
@@ -808,6 +814,10 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) {
    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());
@@ -1013,6 +1023,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))
@@ -1025,7 +1042,8 @@ SDKNodeInitInfo::SDKNodeInitInfo(ValueDecl *VD) :
    USR(calculateUsr(VD)), Location(calculateLocation(VD)),
    ModuleName(VD->getModuleContext()->getName().str()),
    IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)),
- IsStatic(VD->isStatic()), SelfIndex(getSelfIndex(VD)) {
+ IsStatic(VD->isStatic()), SelfIndex(getSelfIndex(VD)),
+ Ownership(getOwnership(VD)) {
  if (VD->getAttrs().getDeprecated(VD->getASTContext()))
    DeclAttrs.push_back(SDKDeclAttrKind::DAK_deprecated);
}
@@ -1383,6 +1401,11 @@ namespace swift {
          if (!Attributes.empty())
            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())


(Xi Ge) #2

Just curious - what is the swift-api-digester?

swift-api-digester is a test utility to detect source-breaking API changes during the evolution of a Swift-compatible module. The tool works on two phases:
(1) dumping module content as a JSON file, and (2) comparing two JSON files textually to report source-breaking changes.

···

On Oct 31, 2016, at 12:00 PM, Kenny Leung via swift-dev <swift-dev@swift.org> wrote:

-Kenny

On Oct 27, 2016, at 11:55 AM, Xi Ge via swift-commits <swift-commits@swift.org> wrote:

Repository : github.com/apple/swift
On branch : master
Link : github.com/apple/swift/commit/4475b0761337b3a379d0a88561a659c9c6d946db

---------------------------------------------------------------

commit 4475b0761337b3a379d0a88561a659c9c6d946db
Author: Xi Ge <xi_ge@apple.com>
Date: Thu Oct 27 11:55:17 2016 -0700

  swift-api-digester: teach the tool to keep track of ownership attributes.

---------------------------------------------------------------

4475b0761337b3a379d0a88561a659c9c6d946db
test/api-digester/Inputs/cake.swift | 2 +
test/api-digester/Outputs/cake.json | 142 +++++++++++++++++++++++
tools/swift-api-digester/DigesterEnums.def | 1 +
tools/swift-api-digester/swift-api-digester.cpp | 39 +++++--
4 files changed, 176 insertions(+), 8 deletions(-)

diff --git a/test/api-digester/Inputs/cake.swift b/test/api-digester/Inputs/cake.swift
index 80f6d23..a61ac20 100644
--- a/test/api-digester/Inputs/cake.swift
+++ b/test/api-digester/Inputs/cake.swift
@@ -8,4 +8,6 @@ public struct S1 {

public class C1 {
  open class func foo1() {}
+ public weak var Ins : C1?
+ public unowned var Ins2 : C1 = C1()
}
\ No newline at end of file
diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index c29c338..e783b94 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -91,6 +91,148 @@
         ]
       },
       {
+ "kind": "Var",
+ "name": "Ins",
+ "printedName": "Ins",
+ "declKind": "Var",
+ "usr": "s:vC4cake2C13InsXwGSqS0__",
+ "location": "",
+ "moduleName": "cake",
+ "ownership": 1,
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "WeakStorage",
+ "printedName": "C1?"
+ },
+ {
+ "kind": "Getter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Func",
+ "usr": "s:FC4cake2C1g3InsXwGSqS0__",
+ "location": "",
+ "moduleName": "cake",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Optional",
+ "printedName": "C1?",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ },
+ {
+ "kind": "Setter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Func",
+ "usr": "s:FC4cake2C1s3InsXwGSqS0__",
+ "location": "",
+ "moduleName": "cake",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Void",
+ "printedName": "()"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "Optional",
+ "printedName": "C1?",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "kind": "Var",
+ "name": "Ins2",
+ "printedName": "Ins2",
+ "declKind": "Var",
+ "usr": "s:vC4cake2C14Ins2XoS0_",
+ "location": "",
+ "moduleName": "cake",
+ "ownership": 2,
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "UnownedStorage",
+ "printedName": "C1"
+ },
+ {
+ "kind": "Getter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Func",
+ "usr": "s:FC4cake2C1g4Ins2XoS0_",
+ "location": "",
+ "moduleName": "cake",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ },
+ {
+ "kind": "Setter",
+ "name": "_",
+ "printedName": "_()",
+ "declKind": "Func",
+ "usr": "s:FC4cake2C1s4Ins2XoS0_",
+ "location": "",
+ "moduleName": "cake",
+ "children": [
+ {
+ "kind": "TypeNominal",
+ "name": "Void",
+ "printedName": "()"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ },
+ {
+ "kind": "TypeNominal",
+ "name": "C1",
+ "printedName": "C1"
+ }
+ ]
+ }
+ ]
+ },
+ {
         "kind": "Constructor",
         "name": "init",
         "printedName": "init()",
diff --git a/tools/swift-api-digester/DigesterEnums.def b/tools/swift-api-digester/DigesterEnums.def
index b123d2f..2e8ef29 100644
--- a/tools/swift-api-digester/DigesterEnums.def
+++ b/tools/swift-api-digester/DigesterEnums.def
@@ -73,6 +73,7 @@ KEY(static)
KEY(typeAttributes)
KEY(declAttributes)
KEY(declKind)
+KEY(ownership)

KNOWN_TYPE(Optional)
KNOWN_TYPE(ImplicitlyUnwrappedOptional)
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index c067945..eefef8f 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -228,23 +228,23 @@ static StringRef getKeyContent(KeyKind Kind) {
}

// 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"
};
@@ -283,6 +283,7 @@ struct SDKNodeInitInfo {
bool IsMutating = false;
bool IsStatic = false;
Optional<uint8_t> SelfIndex;
+ Ownership Ownership = Ownership::Strong;
std::vector<SDKDeclAttrKind> DeclAttrs;
std::vector<TypeAttrKind> TypeAttrs;
SDKNodeInitInfo() = default;
@@ -344,13 +345,14 @@ class SDKNodeDecl : public SDKNode {
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),
- IsStatic(Info.IsStatic) {}
+ IsStatic(Info.IsStatic), Ownership(uint8_t(Info.Ownership)) {}

public:
StringRef getUsr() const { return Usr; }
@@ -358,6 +360,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; }
@@ -762,6 +765,10 @@ 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;
@@ -778,8 +785,7 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) {
     Info.Name = GetScalarString(Pair.getValue());
     break;
   case KeyKind::KK_selfIndex:
- Info.SelfIndex = std::stoi(cast<llvm::yaml::ScalarNode>(Pair.getValue())->
- getRawValue());
+ Info.SelfIndex = getAsInt(Pair.getValue());
     break;
   case KeyKind::KK_usr:
     Info.USR = GetScalarString(Pair.getValue());
@@ -808,6 +814,10 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) {
   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());
@@ -1013,6 +1023,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))
@@ -1025,7 +1042,8 @@ SDKNodeInitInfo::SDKNodeInitInfo(ValueDecl *VD) :
   USR(calculateUsr(VD)), Location(calculateLocation(VD)),
   ModuleName(VD->getModuleContext()->getName().str()),
   IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)),
- IsStatic(VD->isStatic()), SelfIndex(getSelfIndex(VD)) {
+ IsStatic(VD->isStatic()), SelfIndex(getSelfIndex(VD)),
+ Ownership(getOwnership(VD)) {
if (VD->getAttrs().getDeprecated(VD->getASTContext()))
   DeclAttrs.push_back(SDKDeclAttrKind::DAK_deprecated);
}
@@ -1383,6 +1401,11 @@ namespace swift {
         if (!Attributes.empty())
           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())

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev