Skip to content

Commit ac28612

Browse files
authored
---
yaml --- r: 348871 b: refs/heads/master c: 64224ca h: refs/heads/master i: 348869: fc03264 348867: 333aaf5 348863: cd5c694
1 parent f0576d0 commit ac28612

File tree

14 files changed

+169
-165
lines changed

14 files changed

+169
-165
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 6e70b397a7fc654b3bfa08f79c90f1cc71b9e719
2+
refs/heads/master: 64224cadcca062fae92e6112ad9a1ab93bf9f83a
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/AST/Decl.h

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ class alignas(1 << DeclAlignInBits) Decl {
388388
SWIFT_INLINE_BITFIELD(SubscriptDecl, VarDecl, 2,
389389
StaticSpelling : 2
390390
);
391-
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+1+1+1+1+1+1+1+1,
391+
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+1+1+1+1+1+1,
392392
/// \see AbstractFunctionDecl::BodyKind
393393
BodyKind : 3,
394394

@@ -404,12 +404,6 @@ class alignas(1 << DeclAlignInBits) Decl {
404404
/// Whether the function body throws.
405405
Throws : 1,
406406

407-
/// Whether this function requires a new vtable entry.
408-
NeedsNewVTableEntry : 1,
409-
410-
/// Whether NeedsNewVTableEntry is valid.
411-
HasComputedNeedsNewVTableEntry : 1,
412-
413407
/// Whether this member was synthesized as part of a derived
414408
/// protocol conformance.
415409
Synthesized : 1,
@@ -5553,6 +5547,8 @@ class ImportAsMemberStatus {
55535547

55545548
/// Base class for function-like declarations.
55555549
class AbstractFunctionDecl : public GenericContext, public ValueDecl {
5550+
friend class NeedsNewVTableEntryRequest;
5551+
55565552
public:
55575553
enum class BodyKind {
55585554
/// The function did not have a body in the source code file.
@@ -5622,6 +5618,11 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
56225618
/// Location of the 'throws' token.
56235619
SourceLoc ThrowsLoc;
56245620

5621+
struct {
5622+
unsigned NeedsNewVTableEntryComputed : 1;
5623+
unsigned NeedsNewVTableEntry : 1;
5624+
} LazySemanticInfo = { };
5625+
56255626
AbstractFunctionDecl(DeclKind Kind, DeclContext *Parent, DeclName Name,
56265627
SourceLoc NameLoc, bool Throws, SourceLoc ThrowsLoc,
56275628
bool HasImplicitSelfDecl,
@@ -5633,8 +5634,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
56335634
Bits.AbstractFunctionDecl.HasImplicitSelfDecl = HasImplicitSelfDecl;
56345635
Bits.AbstractFunctionDecl.Overridden = false;
56355636
Bits.AbstractFunctionDecl.Throws = Throws;
5636-
Bits.AbstractFunctionDecl.NeedsNewVTableEntry = false;
5637-
Bits.AbstractFunctionDecl.HasComputedNeedsNewVTableEntry = false;
56385637
Bits.AbstractFunctionDecl.Synthesized = false;
56395638
Bits.AbstractFunctionDecl.HasSingleExpressionBody = false;
56405639
}
@@ -5804,16 +5803,9 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
58045803
return getBodyKind() == BodyKind::MemberwiseInitializer;
58055804
}
58065805

5807-
void setNeedsNewVTableEntry(bool value) {
5808-
Bits.AbstractFunctionDecl.HasComputedNeedsNewVTableEntry = true;
5809-
Bits.AbstractFunctionDecl.NeedsNewVTableEntry = value;
5810-
}
5811-
5812-
bool needsNewVTableEntry() const {
5813-
if (!Bits.AbstractFunctionDecl.HasComputedNeedsNewVTableEntry)
5814-
const_cast<AbstractFunctionDecl *>(this)->computeNeedsNewVTableEntry();
5815-
return Bits.AbstractFunctionDecl.NeedsNewVTableEntry;
5816-
}
5806+
/// For a method of a class, checks whether it will require a new entry in the
5807+
/// vtable.
5808+
bool needsNewVTableEntry() const;
58175809

58185810
bool isEffectiveLinkageMoreVisibleThan(ValueDecl *other) const {
58195811
return (std::min(getEffectiveAccess(), AccessLevel::Public) >

trunk/include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,27 @@ class IsStaticRequest :
13141314
void cacheResult(bool value) const;
13151315
};
13161316

1317+
class NeedsNewVTableEntryRequest
1318+
: public SimpleRequest<NeedsNewVTableEntryRequest,
1319+
bool(AbstractFunctionDecl *),
1320+
CacheKind::SeparatelyCached> {
1321+
public:
1322+
using SimpleRequest::SimpleRequest;
1323+
1324+
private:
1325+
friend SimpleRequest;
1326+
1327+
// Evaluation.
1328+
llvm::Expected<bool> evaluate(Evaluator &evaluator,
1329+
AbstractFunctionDecl *decl) const;
1330+
1331+
public:
1332+
// Separate caching.
1333+
bool isCached() const { return true; }
1334+
Optional<bool> getCachedResult() const;
1335+
void cacheResult(bool value) const;
1336+
};
1337+
13171338
// Allow AnyValue to compare two Type values, even though Type doesn't
13181339
// support ==.
13191340
template<>

trunk/include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,5 @@ SWIFT_REQUEST(TypeChecker, IsABICompatibleOverrideRequest,
149149
bool(ValueDecl *), Cached, NoLocationInfo)
150150
SWIFT_REQUEST(TypeChecker, IsStaticRequest,
151151
bool(FuncDecl *), SeparatelyCached, NoLocationInfo)
152+
SWIFT_REQUEST(TypeChecker, NeedsNewVTableEntryRequest,
153+
bool(AbstractFunctionDecl *), SeparatelyCached, NoLocationInfo)

trunk/lib/AST/Decl.cpp

Lines changed: 4 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6536,81 +6536,12 @@ bool AbstractFunctionDecl::isObjCInstanceMethod() const {
65366536
return isInstanceMember() || isa<ConstructorDecl>(this);
65376537
}
65386538

6539-
static bool requiresNewVTableEntry(const AbstractFunctionDecl *decl) {
6540-
auto *dc = decl->getDeclContext();
6541-
6542-
if (!isa<ClassDecl>(dc))
6543-
return true;
6544-
6545-
assert(isa<FuncDecl>(decl) || isa<ConstructorDecl>(decl));
6546-
6547-
// Final members are always be called directly.
6548-
// Dynamic methods are always accessed by objc_msgSend().
6549-
if (decl->isFinal() || decl->isObjCDynamic() || decl->hasClangNode())
6550-
return false;
6551-
6552-
auto &ctx = dc->getASTContext();
6553-
6554-
// Initializers are not normally inherited, but required initializers can
6555-
// be overridden for invocation from dynamic types, and convenience initializers
6556-
// are conditionally inherited when all designated initializers are available,
6557-
// working by dynamically invoking the designated initializer implementation
6558-
// from the subclass. Convenience initializers can also override designated
6559-
// initializer implementations from their superclass.
6560-
if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
6561-
if (!ctor->isRequired() && !ctor->isDesignatedInit()) {
6562-
return false;
6563-
}
6564-
}
6565-
6566-
if (auto *accessor = dyn_cast<AccessorDecl>(decl)) {
6567-
// Check to see if it's one of the opaque accessors for the declaration.
6568-
auto storage = accessor->getStorage();
6569-
if (!storage->requiresOpaqueAccessor(accessor->getAccessorKind()))
6570-
return false;
6571-
}
6572-
6573-
auto base = decl->getOverriddenDecl();
6574-
6575-
if (!base || base->hasClangNode() || base->isObjCDynamic())
6576-
return true;
6577-
6578-
// As above, convenience initializers are not formally overridable in Swift
6579-
// vtables, although same-named initializers are modeled as overriding for
6580-
// various QoI and objc interop reasons. Even if we "override" a non-required
6581-
// convenience init, we still need a distinct vtable entry.
6582-
if (auto baseCtor = dyn_cast<ConstructorDecl>(base)) {
6583-
if (!baseCtor->isRequired() && !baseCtor->isDesignatedInit()) {
6584-
return true;
6585-
}
6586-
}
6587-
6588-
// If the base is less visible than the override, we might need a vtable
6589-
// entry since callers of the override might not be able to see the base
6590-
// at all.
6591-
if (decl->isEffectiveLinkageMoreVisibleThan(base))
6592-
return true;
6593-
6594-
using Direction = ASTContext::OverrideGenericSignatureReqCheck;
6595-
if (!ctx.overrideGenericSignatureReqsSatisfied(
6596-
base, decl, Direction::BaseReqSatisfiedByDerived)) {
6597-
return true;
6598-
}
6599-
6600-
// If this method is an ABI compatible override, then we don't need a new
6601-
// vtable entry. Otherwise, if it's not ABI compatible, for example if the
6602-
// base has a more general AST type, then we need a new entry. Note that an
6603-
// abstraction change is OK; we don't want to add a whole new vtable entry
6604-
// just because an @in parameter becomes @owned, or whatever.
6605-
auto isABICompatibleOverride = evaluateOrDefault(
6539+
bool AbstractFunctionDecl::needsNewVTableEntry() const {
6540+
auto &ctx = getASTContext();
6541+
return evaluateOrDefault(
66066542
ctx.evaluator,
6607-
IsABICompatibleOverrideRequest{const_cast<AbstractFunctionDecl *>(decl)},
6543+
NeedsNewVTableEntryRequest{const_cast<AbstractFunctionDecl *>(this)},
66086544
false);
6609-
return !isABICompatibleOverride;
6610-
}
6611-
6612-
void AbstractFunctionDecl::computeNeedsNewVTableEntry() {
6613-
setNeedsNewVTableEntry(requiresNewVTableEntry(this));
66146545
}
66156546

66166547
ParamDecl *AbstractFunctionDecl::getImplicitSelfDecl(bool createIfNeeded) {

trunk/lib/AST/GenericSignatureBuilder.cpp

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -539,66 +539,6 @@ void GenericSignatureBuilder::Implementation::deallocateEquivalenceClass(
539539
FreeEquivalenceClasses.push_back(equivClass);
540540
}
541541

542-
#pragma mark GraphViz visualization
543-
namespace {
544-
/// A node in the equivalence class, used for visualization.
545-
struct EquivalenceClassVizNode {
546-
const EquivalenceClass *first;
547-
Type second;
548-
549-
operator const void *() const { return second.getPointer(); }
550-
};
551-
552-
/// Iterator through the adjacent nodes in an equivalence class, for
553-
/// visualization.
554-
class EquivalenceClassVizIterator {
555-
using BaseIterator = const Constraint<Type> *;
556-
557-
EquivalenceClassVizNode node;
558-
BaseIterator base;
559-
560-
public:
561-
using difference_type = ptrdiff_t;
562-
using value_type = EquivalenceClassVizNode;
563-
using reference = value_type;
564-
using pointer = value_type*;
565-
using iterator_category = std::forward_iterator_tag;
566-
567-
EquivalenceClassVizIterator(EquivalenceClassVizNode node,
568-
BaseIterator base, BaseIterator baseEnd)
569-
: node(node), base(base) {
570-
}
571-
572-
BaseIterator &getBase() { return base; }
573-
const BaseIterator &getBase() const { return base; }
574-
575-
reference operator*() const {
576-
return { node.first, getBase()->value };
577-
}
578-
579-
EquivalenceClassVizIterator& operator++() {
580-
++getBase();
581-
return *this;
582-
}
583-
584-
EquivalenceClassVizIterator operator++(int) {
585-
EquivalenceClassVizIterator result = *this;
586-
++(*this);
587-
return result;
588-
}
589-
590-
friend bool operator==(const EquivalenceClassVizIterator &lhs,
591-
const EquivalenceClassVizIterator &rhs) {
592-
return lhs.getBase() == rhs.getBase();
593-
}
594-
595-
friend bool operator!=(const EquivalenceClassVizIterator &lhs,
596-
const EquivalenceClassVizIterator &rhs) {
597-
return !(lhs == rhs);
598-
}
599-
};
600-
}
601-
602542
namespace {
603543
/// Retrieve the type described by the given unresolved tyoe.
604544
Type getUnresolvedType(GSBUnresolvedType type,

trunk/lib/AST/TypeCheckRequests.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -908,4 +908,21 @@ Optional<bool> IsStaticRequest::getCachedResult() const {
908908
void IsStaticRequest::cacheResult(bool result) const {
909909
auto *FD = std::get<0>(getStorage());
910910
FD->setStatic(result);
911-
}
911+
}
912+
913+
//----------------------------------------------------------------------------//
914+
// NeedsNewVTableEntryRequest computation.
915+
//----------------------------------------------------------------------------//
916+
917+
Optional<bool> NeedsNewVTableEntryRequest::getCachedResult() const {
918+
auto *decl = std::get<0>(getStorage());
919+
if (decl->LazySemanticInfo.NeedsNewVTableEntryComputed)
920+
return decl->LazySemanticInfo.NeedsNewVTableEntry;
921+
return None;
922+
}
923+
924+
void NeedsNewVTableEntryRequest::cacheResult(bool value) const {
925+
auto *decl = std::get<0>(getStorage());
926+
decl->LazySemanticInfo.NeedsNewVTableEntryComputed = true;
927+
decl->LazySemanticInfo.NeedsNewVTableEntry = value;
928+
}

trunk/lib/ClangImporter/ImporterImpl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,8 +1234,6 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
12341234
D->setAccess(access);
12351235
if (auto ASD = dyn_cast<AbstractStorageDecl>(D))
12361236
ASD->setSetterAccess(access);
1237-
if (auto AFD = dyn_cast<AbstractFunctionDecl>(static_cast<Decl *>(D)))
1238-
AFD->setNeedsNewVTableEntry(false);
12391237
return D;
12401238
}
12411239

trunk/lib/IRGen/IRGenModule.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,11 +650,16 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module,
650650
{argTypes.begin(), argTypes.end()},
651651
/*isVararg*/ false);
652652

653-
cache =
654-
cast<llvm::Function>(Module.getOrInsertFunction(functionName.c_str(), fnTy).getCallee());
653+
auto addr = Module.getOrInsertFunction(functionName.c_str(), fnTy).getCallee();
654+
auto fnptr = addr;
655+
// Strip off any bitcast we might have due to this function being declared of
656+
// a different type previously.
657+
if (auto bitcast = dyn_cast<llvm::BitCastInst>(fnptr))
658+
fnptr = cast<llvm::Constant>(bitcast->getOperand(0));
659+
cache = cast<llvm::Constant>(addr);
655660

656661
// Add any function attributes and set the calling convention.
657-
if (auto fn = dyn_cast<llvm::Function>(cache)) {
662+
if (auto fn = dyn_cast<llvm::Function>(fnptr)) {
658663
fn->setCallingConv(cc);
659664

660665
bool IsExternal =

trunk/lib/SILOptimizer/Utils/CFGOptUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ using namespace swift;
2727
///
2828
/// \param branch The terminator to add the argument to.
2929
/// \param dest The destination block of the edge.
30-
/// \param Val The value to the arguments of the branch.
30+
/// \param val The value to the arguments of the branch.
3131
/// \return The created branch. The old branch is deleted.
3232
/// The argument is appended at the end of the argument tuple.
3333
TermInst *swift::addNewEdgeValueToBranch(TermInst *branch, SILBasicBlock *dest,
@@ -268,7 +268,7 @@ replaceSwitchDest(SwitchEnumTy *sTy, SmallVectorImpl<SwitchEnumCaseTy> &cases,
268268

269269
/// Replace a branch target.
270270
///
271-
/// \param T The terminating instruction to modify.
271+
/// \param t The terminating instruction to modify.
272272
/// \param oldDest The successor block that will be replaced.
273273
/// \param newDest The new target block.
274274
/// \param preserveArgs If set, preserve arguments on the replaced edge.

trunk/lib/Sema/CodeSynthesis.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,6 @@ createDesignatedInitOverride(ClassDecl *classDecl,
702702
// Note that this is a stub implementation.
703703
ctor->setStubImplementation(true);
704704

705-
// Stub constructors don't appear in the vtable.
706-
ctor->setNeedsNewVTableEntry(false);
707705
return ctor;
708706
}
709707

0 commit comments

Comments
 (0)