Skip to content

Commit b223ccb

Browse files
swift-cibeccadax
authored andcommitted
Merge pull request #22605 from brentdax/all-in-the-family
1 parent 8997c70 commit b223ccb

File tree

4 files changed

+97
-73
lines changed

4 files changed

+97
-73
lines changed

include/swift/AST/Identifier.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,12 @@ class DeclName {
592592
"only for use within the debugger");
593593
};
594594

595+
enum class ObjCSelectorFamily : unsigned {
596+
None,
597+
#define OBJC_SELECTOR_FAMILY(LABEL, PREFIX) LABEL,
598+
#include "swift/AST/ObjCSelectorFamily.def"
599+
};
600+
595601
/// Represents an Objective-C selector.
596602
class ObjCSelector {
597603
/// The storage for an Objective-C selector.
@@ -656,6 +662,8 @@ class ObjCSelector {
656662
/// \param scratch Scratch space to use.
657663
StringRef getString(llvm::SmallVectorImpl<char> &scratch) const;
658664

665+
ObjCSelectorFamily getSelectorFamily() const;
666+
659667
void *getOpaqueValue() const { return Storage.getOpaqueValue(); }
660668
static ObjCSelector getFromOpaqueValue(void *p) {
661669
return ObjCSelector(DeclName::getFromOpaqueValue(p));
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===--- ObjCSelectorFamily.def - Objective-C Selector Families - C++ ---*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines macros used for macro-metaprogramming with Objective-C
14+
// selector families, categories of Objective-C methods with special ARC
15+
// semantics.
16+
//
17+
//===----------------------------------------------------------------------===//
18+
19+
#ifndef OBJC_SELECTOR_FAMILY
20+
#define OBJC_SELECTOR_FAMILY(LABEL, PREFIX)
21+
#endif
22+
23+
OBJC_SELECTOR_FAMILY(Alloc, "alloc")
24+
OBJC_SELECTOR_FAMILY(Copy, "copy")
25+
OBJC_SELECTOR_FAMILY(Init, "init")
26+
OBJC_SELECTOR_FAMILY(MutableCopy, "mutableCopy")
27+
OBJC_SELECTOR_FAMILY(New, "new")
28+
29+
#undef OBJC_SELECTOR_FAMILY

lib/AST/Identifier.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/ADT/StringExtras.h"
1919
#include "llvm/Support/raw_ostream.h"
2020
#include "llvm/Support/ConvertUTF.h"
21+
#include "clang/Basic/CharInfo.h"
2122
using namespace swift;
2223

2324
void *DeclBaseName::SubscriptIdentifierData =
@@ -199,6 +200,30 @@ ObjCSelector::ObjCSelector(ASTContext &ctx, unsigned numArgs,
199200
Storage = DeclName(ctx, Identifier(), pieces);
200201
}
201202

203+
ObjCSelectorFamily ObjCSelector::getSelectorFamily() const {
204+
StringRef text = getSelectorPieces().front().get();
205+
while (!text.empty() && text[0] == '_') text = text.substr(1);
206+
207+
// Does the given selector start with the given string as a prefix, in the
208+
// sense of the selector naming conventions?
209+
// This implementation matches the one used by
210+
// clang::Selector::getMethodFamily, to make sure we behave the same as
211+
// Clang ARC. We're not just calling that method here because it means
212+
// allocating a clang::IdentifierInfo, which requires a Clang ASTContext.
213+
auto hasPrefix = [](StringRef text, StringRef prefix) {
214+
if (!text.startswith(prefix)) return false;
215+
if (text.size() == prefix.size()) return true;
216+
assert(text.size() > prefix.size());
217+
return !clang::isLowercase(text[prefix.size()]);
218+
};
219+
220+
if (false) /*for #define purposes*/;
221+
#define OBJC_SELECTOR_FAMILY(LABEL, PREFIX) \
222+
else if (hasPrefix(text, PREFIX)) return ObjCSelectorFamily::LABEL;
223+
#include "swift/AST/ObjCSelectorFamily.def"
224+
else return ObjCSelectorFamily::None;
225+
}
226+
202227
StringRef ObjCSelector::getString(llvm::SmallVectorImpl<char> &scratch) const {
203228
// Fast path for zero-argument selectors.
204229
if (getNumArgs() == 0) {

lib/SIL/SILFunctionType.cpp

Lines changed: 35 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
#include "clang/AST/Attr.h"
3030
#include "clang/AST/DeclObjC.h"
3131
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
32-
#include "clang/Basic/CharInfo.h"
3332
#include "llvm/Support/CommandLine.h"
3433
#include "llvm/Support/Compiler.h"
3534
#include "llvm/Support/Debug.h"
@@ -221,7 +220,7 @@ enum class ConventionsKind : uint8_t {
221220
ObjCMethod = 2,
222221
CFunctionType = 3,
223222
CFunction = 4,
224-
SelectorFamily = 5,
223+
ObjCSelectorFamily = 5,
225224
Deallocator = 6,
226225
Capture = 7,
227226
};
@@ -1710,64 +1709,27 @@ static const clang::Decl *findClangMethod(ValueDecl *method) {
17101709
// Selector Family SILFunctionTypes
17111710
//===----------------------------------------------------------------------===//
17121711

1713-
/// Apply a macro FAMILY(Name, Prefix) to all ObjC selector families.
1714-
#define FOREACH_FAMILY(FAMILY) \
1715-
FAMILY(Alloc, "alloc") \
1716-
FAMILY(Copy, "copy") \
1717-
FAMILY(Init, "init") \
1718-
FAMILY(MutableCopy, "mutableCopy") \
1719-
FAMILY(New, "new")
1720-
1721-
namespace {
1722-
enum class SelectorFamily : unsigned {
1723-
None,
1724-
#define GET_LABEL(LABEL, PREFIX) LABEL,
1725-
FOREACH_FAMILY(GET_LABEL)
1726-
#undef GET_LABEL
1727-
};
1728-
} // end anonymous namespace
1729-
17301712
/// Derive the ObjC selector family from an identifier.
17311713
///
17321714
/// Note that this will never derive the Init family, which is too dangerous
17331715
/// to leave to chance. Swift functions starting with "init" are always
17341716
/// emitted as if they are part of the "none" family.
1735-
static SelectorFamily getSelectorFamily(Identifier name) {
1736-
StringRef text = name.get();
1737-
while (!text.empty() && text[0] == '_') text = text.substr(1);
1738-
1739-
// Does the given selector start with the given string as a prefix, in the
1740-
// sense of the selector naming conventions?
1741-
// This implementation matches the one used by
1742-
// clang::Selector::getMethodFamily, to make sure we behave the same as Clang
1743-
// ARC. We're not just calling that method here because it means allocating a
1744-
// clang::IdentifierInfo, which requires a Clang ASTContext.
1745-
auto hasPrefix = [](StringRef text, StringRef prefix) {
1746-
if (!text.startswith(prefix)) return false;
1747-
if (text.size() == prefix.size()) return true;
1748-
assert(text.size() > prefix.size());
1749-
return !clang::isLowercase(text[prefix.size()]);
1750-
};
1751-
1752-
auto result = SelectorFamily::None;
1753-
if (false) /*for #define purposes*/;
1754-
#define CHECK_PREFIX(LABEL, PREFIX) \
1755-
else if (hasPrefix(text, PREFIX)) result = SelectorFamily::LABEL;
1756-
FOREACH_FAMILY(CHECK_PREFIX)
1757-
#undef CHECK_PREFIX
1758-
1759-
if (result == SelectorFamily::Init)
1760-
return SelectorFamily::None;
1717+
static ObjCSelectorFamily getObjCSelectorFamily(ObjCSelector name) {
1718+
auto result = name.getSelectorFamily();
1719+
1720+
if (result == ObjCSelectorFamily::Init)
1721+
return ObjCSelectorFamily::None;
1722+
17611723
return result;
17621724
}
17631725

17641726
/// Get the ObjC selector family a foreign SILDeclRef belongs to.
1765-
static SelectorFamily getSelectorFamily(SILDeclRef c) {
1727+
static ObjCSelectorFamily getObjCSelectorFamily(SILDeclRef c) {
17661728
assert(c.isForeign);
17671729
switch (c.kind) {
17681730
case SILDeclRef::Kind::Func: {
17691731
if (!c.hasDecl())
1770-
return SelectorFamily::None;
1732+
return ObjCSelectorFamily::None;
17711733

17721734
auto *FD = cast<FuncDecl>(c.getDecl());
17731735
if (auto accessor = dyn_cast<AccessorDecl>(FD)) {
@@ -1783,11 +1745,11 @@ static SelectorFamily getSelectorFamily(SILDeclRef c) {
17831745
}
17841746
}
17851747

1786-
return getSelectorFamily(FD->getObjCSelector().getSelectorPieces().front());
1748+
return getObjCSelectorFamily(FD->getObjCSelector());
17871749
}
17881750
case SILDeclRef::Kind::Initializer:
17891751
case SILDeclRef::Kind::IVarInitializer:
1790-
return SelectorFamily::Init;
1752+
return ObjCSelectorFamily::Init;
17911753

17921754
/// Currently IRGen wraps alloc/init methods into Swift constructors
17931755
/// with Swift conventions.
@@ -1796,7 +1758,7 @@ static SelectorFamily getSelectorFamily(SILDeclRef c) {
17961758
case SILDeclRef::Kind::Destroyer:
17971759
case SILDeclRef::Kind::Deallocator:
17981760
case SILDeclRef::Kind::IVarDestroyer:
1799-
return SelectorFamily::None;
1761+
return ObjCSelectorFamily::None;
18001762

18011763
case SILDeclRef::Kind::EnumElement:
18021764
case SILDeclRef::Kind::GlobalAccessor:
@@ -1810,12 +1772,12 @@ static SelectorFamily getSelectorFamily(SILDeclRef c) {
18101772

18111773
namespace {
18121774

1813-
class SelectorFamilyConventions : public Conventions {
1814-
SelectorFamily Family;
1775+
class ObjCSelectorFamilyConventions : public Conventions {
1776+
ObjCSelectorFamily Family;
18151777

18161778
public:
1817-
SelectorFamilyConventions(SelectorFamily family)
1818-
: Conventions(ConventionsKind::SelectorFamily), Family(family) {}
1779+
ObjCSelectorFamilyConventions(ObjCSelectorFamily family)
1780+
: Conventions(ConventionsKind::ObjCSelectorFamily), Family(family) {}
18191781

18201782
ParameterConvention getIndirectParameter(unsigned index,
18211783
const AbstractionPattern &type,
@@ -1836,14 +1798,14 @@ class SelectorFamilyConventions : public Conventions {
18361798

18371799
ResultConvention getResult(const TypeLowering &tl) const override {
18381800
switch (Family) {
1839-
case SelectorFamily::Alloc:
1840-
case SelectorFamily::Copy:
1841-
case SelectorFamily::Init:
1842-
case SelectorFamily::MutableCopy:
1843-
case SelectorFamily::New:
1801+
case ObjCSelectorFamily::Alloc:
1802+
case ObjCSelectorFamily::Copy:
1803+
case ObjCSelectorFamily::Init:
1804+
case ObjCSelectorFamily::MutableCopy:
1805+
case ObjCSelectorFamily::New:
18441806
return ResultConvention::Owned;
18451807

1846-
case SelectorFamily::None:
1808+
case ObjCSelectorFamily::None:
18471809
// Defaults below.
18481810
break;
18491811
}
@@ -1860,7 +1822,7 @@ class SelectorFamilyConventions : public Conventions {
18601822

18611823
ParameterConvention
18621824
getDirectSelfParameter(const AbstractionPattern &type) const override {
1863-
if (Family == SelectorFamily::Init)
1825+
if (Family == ObjCSelectorFamily::Init)
18641826
return ParameterConvention::Direct_Owned;
18651827
return ObjCSelfConvention;
18661828
}
@@ -1872,21 +1834,21 @@ class SelectorFamilyConventions : public Conventions {
18721834
}
18731835

18741836
static bool classof(const Conventions *C) {
1875-
return C->getKind() == ConventionsKind::SelectorFamily;
1837+
return C->getKind() == ConventionsKind::ObjCSelectorFamily;
18761838
}
18771839
};
18781840

18791841
} // end anonymous namespace
18801842

18811843
static CanSILFunctionType
1882-
getSILFunctionTypeForSelectorFamily(SILModule &M, SelectorFamily family,
1883-
CanAnyFunctionType origType,
1884-
CanAnyFunctionType substInterfaceType,
1885-
AnyFunctionType::ExtInfo extInfo,
1886-
const ForeignInfo &foreignInfo,
1887-
Optional<SILDeclRef> constant) {
1844+
getSILFunctionTypeForObjCSelectorFamily(SILModule &M, ObjCSelectorFamily family,
1845+
CanAnyFunctionType origType,
1846+
CanAnyFunctionType substInterfaceType,
1847+
AnyFunctionType::ExtInfo extInfo,
1848+
const ForeignInfo &foreignInfo,
1849+
Optional<SILDeclRef> constant) {
18881850
return getSILFunctionType(M, AbstractionPattern(origType), substInterfaceType,
1889-
extInfo, SelectorFamilyConventions(family),
1851+
extInfo, ObjCSelectorFamilyConventions(family),
18901852
foreignInfo, constant, constant,
18911853
/*requirement subs*/None,
18921854
/*witnessMethodConformance=*/None);
@@ -1967,10 +1929,10 @@ getUncachedSILFunctionTypeForConstant(SILModule &M,
19671929

19681930
// If the decl belongs to an ObjC method family, use that family's
19691931
// ownership conventions.
1970-
return getSILFunctionTypeForSelectorFamily(M, getSelectorFamily(constant),
1971-
origLoweredInterfaceType,
1972-
origLoweredInterfaceType,
1973-
extInfo, foreignInfo, constant);
1932+
return getSILFunctionTypeForObjCSelectorFamily(
1933+
M, getObjCSelectorFamily(constant),
1934+
origLoweredInterfaceType, origLoweredInterfaceType,
1935+
extInfo, foreignInfo, constant);
19741936
}
19751937

19761938
CanSILFunctionType TypeConverter::

0 commit comments

Comments
 (0)