Skip to content

Commit 3ff4080

Browse files
authored
Merge pull request swiftlang#270 from swiftwasm/master
[pull] swiftwasm from master
2 parents 99efcc9 + b860356 commit 3ff4080

File tree

69 files changed

+4453
-478
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+4453
-478
lines changed

docs/CppInteroperabilityManifesto.md

Lines changed: 3403 additions & 0 deletions
Large diffs are not rendered by default.

include/swift/AST/Decl.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -665,9 +665,10 @@ class alignas(1 << DeclAlignInBits) Decl {
665665
SourceLoc Loc;
666666
SourceLoc StartLoc;
667667
SourceLoc EndLoc;
668+
SmallVector<CharSourceRange, 4> DocRanges;
668669
};
669-
mutable CachedExternalSourceLocs const *CachedLocs = nullptr;
670-
const CachedExternalSourceLocs *calculateSerializedLocs() const;
670+
mutable CachedExternalSourceLocs const *CachedSerializedLocs = nullptr;
671+
const CachedExternalSourceLocs *getSerializedLocs() const;
671672
protected:
672673

673674
Decl(DeclKind kind, llvm::PointerUnion<DeclContext *, ASTContext *> context)
@@ -828,7 +829,7 @@ class alignas(1 << DeclAlignInBits) Decl {
828829
}
829830

830831
/// \returns the unparsed comment attached to this declaration.
831-
RawComment getRawComment() const;
832+
RawComment getRawComment(bool SerializedOK = false) const;
832833

833834
Optional<StringRef> getGroupName() const;
834835

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3285,14 +3285,16 @@ ERROR(partial_application_of_function_invalid,none,
32853285
"partial application of %select{"
32863286
"'mutating' method|"
32873287
"'super.init' initializer chain|"
3288-
"'self.init' initializer delegation"
3288+
"'self.init' initializer delegation|"
3289+
"'super' instance method with metatype base"
32893290
"}0 is not allowed",
32903291
(unsigned))
32913292
WARNING(partial_application_of_function_invalid_swift4,none,
32923293
"partial application of %select{"
32933294
"'mutating' method|"
32943295
"'super.init' initializer chain|"
3295-
"'self.init' initializer delegation"
3296+
"'self.init' initializer delegation|"
3297+
"'super' instance method with metatype base"
32963298
"}0 is not allowed; calling the function has undefined behavior and will "
32973299
"be an error in future Swift versions",
32983300
(unsigned))

include/swift/AST/Expr.h

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,10 @@ class alignas(8) Expr {
284284
Discriminator : 16
285285
);
286286

287-
SWIFT_INLINE_BITFIELD(AutoClosureExpr, AbstractClosureExpr, 1,
288-
/// True if this autoclosure was built for a function conversion, and
289-
/// not an actual @autoclosure parameter.
290-
IsThunk : 1
287+
SWIFT_INLINE_BITFIELD(AutoClosureExpr, AbstractClosureExpr, 2,
288+
/// If the autoclosure was built for a curry thunk, the thunk kind is
289+
/// stored here.
290+
Kind : 2
291291
);
292292

293293
SWIFT_INLINE_BITFIELD(ClosureExpr, AbstractClosureExpr, 1,
@@ -3790,22 +3790,36 @@ class AutoClosureExpr : public AbstractClosureExpr {
37903790
BraceStmt *Body;
37913791

37923792
public:
3793+
enum class Kind : uint8_t {
3794+
// An autoclosure with type () -> Result. Formed from type checking an
3795+
// @autoclosure argument in a function call.
3796+
None = 0,
3797+
3798+
// An autoclosure with type (Args...) -> Result. Formed from type checking a
3799+
// partial application.
3800+
SingleCurryThunk = 1,
3801+
3802+
// An autoclosure with type (Self) -> (Args...) -> Result. Formed from type
3803+
// checking a partial application.
3804+
DoubleCurryThunk = 2
3805+
};
3806+
37933807
AutoClosureExpr(Expr *Body, Type ResultTy, unsigned Discriminator,
37943808
DeclContext *Parent)
37953809
: AbstractClosureExpr(ExprKind::AutoClosure, ResultTy, /*Implicit=*/true,
37963810
Discriminator, Parent) {
37973811
if (Body != nullptr)
37983812
setBody(Body);
37993813

3800-
Bits.AutoClosureExpr.IsThunk = false;
3814+
Bits.AutoClosureExpr.Kind = 0;
38013815
}
38023816

3803-
bool isThunk() const {
3804-
return Bits.AutoClosureExpr.IsThunk;
3817+
Kind getThunkKind() const {
3818+
return Kind(Bits.AutoClosureExpr.Kind);
38053819
}
38063820

3807-
void setIsThunk(bool isThunk) {
3808-
Bits.AutoClosureExpr.IsThunk = isThunk;
3821+
void setThunkKind(Kind K) {
3822+
Bits.AutoClosureExpr.Kind = uint8_t(K);
38093823
}
38103824

38113825
SourceRange getSourceRange() const;
@@ -3824,6 +3838,16 @@ class AutoClosureExpr : public AbstractClosureExpr {
38243838
/// The body of an autoclosure always consists of a single expression.
38253839
Expr *getSingleExpressionBody() const;
38263840

3841+
/// Unwraps a curry thunk. Basically, this gives you what the old AST looked
3842+
/// like, before Sema started building curry thunks. This is really only
3843+
/// meant for legacy usages.
3844+
///
3845+
/// The behavior is as follows, based on the kind:
3846+
/// - for double curry thunks, returns the original DeclRefExpr.
3847+
/// - for single curry thunks, returns the ApplyExpr for the self call.
3848+
/// - otherwise, returns nullptr for convenience.
3849+
Expr *getUnwrappedCurryThunkExpr() const;
3850+
38273851
// Implement isa/cast/dyncast/etc.
38283852
static bool classof(const Expr *E) {
38293853
return E->getKind() == ExprKind::AutoClosure;

include/swift/AST/RawComment.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ struct LineColumn {
8686

8787
struct BasicDeclLocs {
8888
StringRef SourceFilePath;
89+
SmallVector<std::pair<LineColumn, uint32_t>, 4> DocRanges;
8990
LineColumn Loc;
9091
LineColumn StartLoc;
9192
LineColumn EndLoc;

include/swift/Basic/OptionSet.h

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,45 +50,46 @@ class OptionSet {
5050

5151
public:
5252
/// Create an empty option set.
53-
OptionSet() : Storage() { }
53+
constexpr OptionSet() : Storage() {}
5454

5555
/// Create an empty option set.
56-
OptionSet(llvm::NoneType) : Storage() { }
56+
constexpr OptionSet(llvm::NoneType) : Storage() {}
5757

5858
/// Create an option set with only the given option set.
59-
OptionSet(Flags flag) : Storage(static_cast<StorageType>(flag)) { }
59+
constexpr OptionSet(Flags flag) : Storage(static_cast<StorageType>(flag)) {}
6060

6161
/// Create an option set from raw storage.
62-
explicit OptionSet(StorageType storage) : Storage(storage) { }
62+
explicit constexpr OptionSet(StorageType storage) : Storage(storage) {}
6363

6464
/// Check whether an option set is non-empty.
65-
explicit operator bool() const { return Storage != 0; }
65+
explicit constexpr operator bool() const { return Storage != 0; }
6666

6767
/// Explicitly convert an option set to its underlying storage.
68-
explicit operator StorageType() const { return Storage; }
68+
explicit constexpr operator StorageType() const { return Storage; }
6969

7070
/// Explicitly convert an option set to intptr_t, for use in
7171
/// llvm::PointerIntPair.
7272
///
7373
/// This member is not present if the underlying type is bigger than
7474
/// a pointer.
7575
template <typename T = std::intptr_t>
76-
explicit operator typename std::enable_if<sizeof(StorageType) <= sizeof(T),
77-
std::intptr_t>::type () const {
76+
explicit constexpr
77+
operator typename std::enable_if<sizeof(StorageType) <= sizeof(T),
78+
std::intptr_t>::type() const {
7879
return static_cast<intptr_t>(Storage);
7980
}
8081

8182
/// Retrieve the "raw" representation of this option set.
8283
StorageType toRaw() const { return Storage; }
83-
84+
8485
/// Determine whether this option set contains all of the options in the
8586
/// given set.
86-
bool contains(OptionSet set) const {
87+
constexpr bool contains(OptionSet set) const {
8788
return !static_cast<bool>(set - *this);
8889
}
8990

9091
/// Check if this option set contains the exact same options as the given set.
91-
bool containsOnly(OptionSet set) const {
92+
constexpr bool containsOnly(OptionSet set) const {
9293
return Storage == set.Storage;
9394
}
9495

@@ -97,34 +98,34 @@ class OptionSet {
9798
// want '==' behavior, use 'containsOnly'.
9899

99100
/// Produce the union of two option sets.
100-
friend OptionSet operator|(OptionSet lhs, OptionSet rhs) {
101+
friend constexpr OptionSet operator|(OptionSet lhs, OptionSet rhs) {
101102
return OptionSet(lhs.Storage | rhs.Storage);
102103
}
103104

104105
/// Produce the union of two option sets.
105-
friend OptionSet &operator|=(OptionSet &lhs, OptionSet rhs) {
106+
friend constexpr OptionSet &operator|=(OptionSet &lhs, OptionSet rhs) {
106107
lhs.Storage |= rhs.Storage;
107108
return lhs;
108-
}
109+
}
109110

110111
/// Produce the intersection of two option sets.
111-
friend OptionSet operator&(OptionSet lhs, OptionSet rhs) {
112+
friend constexpr OptionSet operator&(OptionSet lhs, OptionSet rhs) {
112113
return OptionSet(lhs.Storage & rhs.Storage);
113114
}
114115

115116
/// Produce the intersection of two option sets.
116-
friend OptionSet &operator&=(OptionSet &lhs, OptionSet rhs) {
117+
friend constexpr OptionSet &operator&=(OptionSet &lhs, OptionSet rhs) {
117118
lhs.Storage &= rhs.Storage;
118119
return lhs;
119120
}
120121

121122
/// Produce the difference of two option sets.
122-
friend OptionSet operator-(OptionSet lhs, OptionSet rhs) {
123+
friend constexpr OptionSet operator-(OptionSet lhs, OptionSet rhs) {
123124
return OptionSet(lhs.Storage & ~rhs.Storage);
124125
}
125126

126127
/// Produce the difference of two option sets.
127-
friend OptionSet &operator-=(OptionSet &lhs, OptionSet rhs) {
128+
friend constexpr OptionSet &operator-=(OptionSet &lhs, OptionSet rhs) {
128129
lhs.Storage &= ~rhs.Storage;
129130
return lhs;
130131
}

include/swift/SIL/SILFunctionBuilder.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,16 @@ class SILFunctionBuilder {
8080
SubclassScope subclassScope = SubclassScope::NotApplicable);
8181

8282
/// Return the declaration of a function, or create it if it doesn't exist.
83-
SILFunction *
84-
getOrCreateFunction(SILLocation loc, SILDeclRef constant,
85-
ForDefinition_t forDefinition,
86-
ProfileCounter entryCount = ProfileCounter());
83+
/// Creating a function that references another function (a dynamic
84+
/// replacement) requires getting/creating a SIL function for this reference.
85+
/// In this case the function will call the \p getOrCreateDeclaration
86+
/// callback.
87+
SILFunction *getOrCreateFunction(
88+
SILLocation loc, SILDeclRef constant, ForDefinition_t forDefinition,
89+
llvm::function_ref<SILFunction *(SILLocation loc, SILDeclRef constant)>
90+
getOrCreateDeclaration = [](SILLocation loc, SILDeclRef constant)
91+
-> SILFunction * { return nullptr; },
92+
ProfileCounter entryCount = ProfileCounter());
8793

8894
/// Create a function declaration.
8995
///
@@ -104,8 +110,11 @@ class SILFunctionBuilder {
104110
SILFunction *InsertBefore = nullptr,
105111
const SILDebugScope *DebugScope = nullptr);
106112

107-
void addFunctionAttributes(SILFunction *F, DeclAttributes &Attrs,
108-
SILModule &M, SILDeclRef constant = SILDeclRef());
113+
void addFunctionAttributes(
114+
SILFunction *F, DeclAttributes &Attrs, SILModule &M,
115+
llvm::function_ref<SILFunction *(SILLocation loc, SILDeclRef constant)>
116+
getOrCreateDeclaration,
117+
SILDeclRef constant = SILDeclRef());
109118

110119
/// We do not expose this to everyone, instead we allow for our users to opt
111120
/// into this if they need to. Please do not do this in general! We only want

lib/AST/AbstractSourceFileDepGraphFactory.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ void AbstractSourceFileDepGraphFactory::addAUsedDecl(
7979
const DependencyKey &defKey, const DependencyKey &useKey) {
8080
auto *defNode =
8181
g.findExistingNodeOrCreateIfNew(defKey, None, false /* = !isProvides */);
82+
// If the depended-upon node is defined in this file, then don't
83+
// create an arc to the user, when the user is the whole file.
84+
// Otherwise, if the defNode's type-body fingerprint changes,
85+
// the whole file will be marked as dirty, losing the benefit of the
86+
// fingerprint.
87+
if (defNode->getIsProvides() &&
88+
useKey.getKind() == NodeKind::sourceFileProvide)
89+
return;
8290
auto nullableUse = g.findExistingNode(useKey);
8391
assert(nullableUse.isNonNull() && "Use must be an already-added provides");
8492
auto *useNode = nullableUse.get();

lib/AST/Decl.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,10 @@ case DeclKind::ID: return cast<ID##Decl>(this)->getLocFromSource();
569569
llvm_unreachable("Unknown decl kind");
570570
}
571571

572-
const Decl::CachedExternalSourceLocs *Decl::calculateSerializedLocs() const {
572+
const Decl::CachedExternalSourceLocs *Decl::getSerializedLocs() const {
573+
if (CachedSerializedLocs) {
574+
return CachedSerializedLocs;
575+
}
573576
auto *File = cast<FileUnit>(getDeclContext()->getModuleScopeContext());
574577
auto Locs = File->getBasicLocsForDecl(this);
575578
if (!Locs.hasValue()) {
@@ -585,6 +588,14 @@ Result->X = SM.getLocFromExternalSource(Locs->SourceFilePath, Locs->X.Line, \
585588
CASE(StartLoc)
586589
CASE(EndLoc)
587590
#undef CASE
591+
592+
for (const auto &LineColumnAndLength : Locs->DocRanges) {
593+
auto Start = SM.getLocFromExternalSource(Locs->SourceFilePath,
594+
LineColumnAndLength.first.Line,
595+
LineColumnAndLength.first.Column);
596+
Result->DocRanges.push_back({ Start, LineColumnAndLength.second });
597+
}
598+
588599
return Result;
589600
}
590601

@@ -625,10 +636,7 @@ static_assert(sizeof(checkSourceLocType(&ID##Decl::getLoc)) == 2, \
625636
case FileUnitKind::SerializedAST: {
626637
if (!SerializedOK)
627638
return SourceLoc();
628-
if (!CachedLocs) {
629-
CachedLocs = calculateSerializedLocs();
630-
}
631-
return CachedLocs->Loc;
639+
return getSerializedLocs()->Loc;
632640
}
633641
case FileUnitKind::Builtin:
634642
case FileUnitKind::ClangModule:

lib/AST/DocComment.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/ASTContext.h"
2020
#include "swift/AST/Comment.h"
2121
#include "swift/AST/Decl.h"
22+
#include "swift/AST/FileUnit.h"
2223
#include "swift/AST/Types.h"
2324
#include "swift/AST/PrettyStackTrace.h"
2425
#include "swift/AST/RawComment.h"
@@ -502,14 +503,23 @@ StringRef Decl::getBriefComment() const {
502503
if (!this->canHaveComment())
503504
return StringRef();
504505

505-
// Ensure the serialized doc is populated to ASTContext.
506-
auto RC = getRawComment();
507-
508506
// Check the cache in ASTContext.
509507
auto &Context = getASTContext();
510508
if (Optional<StringRef> Comment = Context.getBriefComment(this))
511509
return Comment.getValue();
512510

511+
// Check if the serialized module may have the brief comment available.
512+
if (auto *Unit =
513+
dyn_cast<FileUnit>(this->getDeclContext()->getModuleScopeContext())) {
514+
if (Optional<CommentInfo> C = Unit->getCommentForDecl(this)) {
515+
Context.setBriefComment(this, C->Brief);
516+
return C->Brief;
517+
}
518+
}
519+
520+
// Otherwise, parse the brief from the raw comment itself.
521+
auto RC = getRawComment();
522+
513523
StringRef Result;
514524
if (RC.isEmpty())
515525
if (auto *docD = getDocCommentProvidingDecl(this))

lib/AST/Expr.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,46 @@ Expr *AutoClosureExpr::getSingleExpressionBody() const {
18431843
return cast<ReturnStmt>(Body->getFirstElement().get<Stmt *>())->getResult();
18441844
}
18451845

1846+
Expr *AutoClosureExpr::getUnwrappedCurryThunkExpr() const {
1847+
switch (getThunkKind()) {
1848+
case AutoClosureExpr::Kind::None:
1849+
break;
1850+
1851+
case AutoClosureExpr::Kind::SingleCurryThunk: {
1852+
auto *body = getSingleExpressionBody();
1853+
body = body->getSemanticsProvidingExpr();
1854+
if (auto *outerCall = dyn_cast<ApplyExpr>(body)) {
1855+
return outerCall->getFn();
1856+
}
1857+
1858+
assert(false && "Malformed curry thunk?");
1859+
break;
1860+
}
1861+
1862+
case AutoClosureExpr::Kind::DoubleCurryThunk: {
1863+
auto *body = getSingleExpressionBody();
1864+
if (auto *innerClosure = dyn_cast<AutoClosureExpr>(body)) {
1865+
assert(innerClosure->getThunkKind() ==
1866+
AutoClosureExpr::Kind::SingleCurryThunk);
1867+
auto *innerBody = innerClosure->getSingleExpressionBody();
1868+
innerBody = innerBody->getSemanticsProvidingExpr();
1869+
if (auto *outerCall = dyn_cast<ApplyExpr>(innerBody)) {
1870+
if (auto *innerCall = dyn_cast<ApplyExpr>(outerCall->getFn())) {
1871+
if (auto *declRef = dyn_cast<DeclRefExpr>(innerCall->getFn())) {
1872+
return declRef;
1873+
}
1874+
}
1875+
}
1876+
}
1877+
1878+
assert(false && "Malformed curry thunk?");
1879+
break;
1880+
}
1881+
}
1882+
1883+
return nullptr;
1884+
}
1885+
18461886
FORWARD_SOURCE_LOCS_TO(UnresolvedPatternExpr, subPattern)
18471887

18481888
TypeExpr::TypeExpr(TypeLoc TyLoc)

0 commit comments

Comments
 (0)