Skip to content

Commit 59afba5

Browse files
committed
Manually merge branch 'main' into rebranch
2 parents b44231b + 71b0ea6 commit 59afba5

File tree

200 files changed

+4093
-792
lines changed

Some content is hidden

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

200 files changed

+4093
-792
lines changed

include/swift/ABI/Executor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class ExecutorRef {
6767
: Identity(identity), Implementation(implementation) {}
6868

6969
public:
70+
7071
/// A generic execution environment. When running in a generic
7172
/// environment, it's presumed to be okay to switch synchronously
7273
/// to an actor. As an executor request, this represents a request

include/swift/ABI/TaskStatus.h

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "swift/ABI/MetadataValues.h"
2424
#include "swift/ABI/Task.h"
25+
#include "swift/ABI/Executor.h"
2526
#include "swift/Runtime/HeapObject.h"
2627

2728
namespace swift {
@@ -61,25 +62,10 @@ class TaskStatusRecord {
6162

6263
TaskStatusRecord *getParent() const { return Parent; }
6364

64-
/// Change the parent of this unregistered status record to the
65-
/// given record.
66-
///
67-
/// This should be used when the record has been previously initialized
68-
/// without knowing what the true parent is. If we decide to cache
69-
/// important information (e.g. the earliest timeout) in the innermost
70-
/// status record, this is the method that should fill that in
71-
/// from the parent.
65+
/// Change the parent of this status record to the given record.
7266
void resetParent(TaskStatusRecord *newParent) {
7367
Parent = newParent;
74-
// TODO: cache
7568
}
76-
77-
/// Splice a record out of the status-record chain.
78-
///
79-
/// Unlike resetParent, this assumes that it's just removing one or
80-
/// more records from the chain and that there's no need to do any
81-
/// extra cache manipulation.
82-
void spliceParent(TaskStatusRecord *newParent) { Parent = newParent; }
8369
};
8470

8571
/// A status record which states that a task has one or
@@ -293,22 +279,23 @@ class EscalationNotificationStatusRecord : public TaskStatusRecord {
293279
// This record is allocated for a task to record what it is dependent on before
294280
// the task can make progress again.
295281
class TaskDependencyStatusRecord : public TaskStatusRecord {
296-
// A word sized storage which references what this task is suspended waiting
297-
// for. Note that this is different from the waitQueue in the future fragment
298-
// of a task since that denotes all the tasks which this specific task, will
299-
// unblock.
282+
// A word sized storage which references what this task is waiting for. Note
283+
// that this is different from the waitQueue in the future fragment of a task
284+
// since that denotes all the tasks which this specific task, will unblock.
300285
//
301286
// This field is only really pointing to something valid when the
302-
// ActiveTaskStatus specifies that the task is suspended. It can be accessed
303-
// asynchronous to the task during escalation which will therefore require the
304-
// task status record lock for synchronization.
287+
// ActiveTaskStatus specifies that the task is suspended or enqueued. It can
288+
// be accessed asynchronous to the task during escalation which will therefore
289+
// require the task status record lock for synchronization.
305290
//
306291
// When a task has TaskDependencyStatusRecord in the status record list, it
307292
// must be the innermost status record, barring the status record lock which
308293
// could be taken while this record is present.
309294
//
310295
// The type of thing we are waiting on, is specified in the enum below
311-
union {
296+
union Dependent {
297+
constexpr Dependent() {}
298+
312299
// This task is suspended waiting on another task. This could be an async
313300
// let child task or it could be another unstructured task.
314301
AsyncTask *Task;
@@ -325,40 +312,68 @@ class TaskDependencyStatusRecord : public TaskStatusRecord {
325312
// the duration of the wait. We do not need to take an additional +1 on this
326313
// task group in this dependency record.
327314
TaskGroup *TaskGroup;
328-
} WaitingOn;
315+
316+
// The task is enqueued waiting on an executor. It could be any kind of
317+
// executor - the generic executor, the default actor's executor, or an
318+
// actor with a custom executor.
319+
//
320+
// This information is helpful to know *where* a task is enqueued into
321+
// (potentially intrusively), so that the appropriate escalation effect
322+
// (which may be different for each type of executor) can happen if a task
323+
// is escalated while enqueued.
324+
ExecutorRef Executor;
325+
} DependentOn;
329326

330327
// Enum specifying the type of dependency this task has
331328
enum DependencyKind {
332329
WaitingOnTask = 1,
333330
WaitingOnContinuation,
334331
WaitingOnTaskGroup,
332+
333+
EnqueuedOnExecutor,
335334
} DependencyKind;
336335

336+
// The task that has this task status record - ie a backpointer from the
337+
// record to the task with the record. This is not its own +1, we rely on the
338+
// fact that since this status record is linked into a task, the task is
339+
// already alive and maintained by someone and we can safely borrow the
340+
// reference.
341+
AsyncTask *WaitingTask;
342+
337343
public:
338-
TaskDependencyStatusRecord(AsyncTask *task) :
344+
TaskDependencyStatusRecord(AsyncTask *waitingTask, AsyncTask *task) :
339345
TaskStatusRecord(TaskStatusRecordKind::TaskDependency),
340-
DependencyKind(WaitingOnTask) {
341-
WaitingOn.Task = task;
346+
DependencyKind(WaitingOnTask), WaitingTask(waitingTask) {
347+
DependentOn.Task = task;
342348
}
343349

344-
TaskDependencyStatusRecord(ContinuationAsyncContext *context) :
350+
TaskDependencyStatusRecord(AsyncTask *waitingTask, ContinuationAsyncContext *context) :
345351
TaskStatusRecord(TaskStatusRecordKind::TaskDependency),
346-
DependencyKind(WaitingOnContinuation) {
347-
WaitingOn.Continuation = context;
352+
DependencyKind(WaitingOnContinuation), WaitingTask(waitingTask) {
353+
DependentOn.Continuation = context;
348354
}
349355

350-
TaskDependencyStatusRecord(TaskGroup *taskGroup) :
356+
TaskDependencyStatusRecord(AsyncTask *waitingTask, TaskGroup *taskGroup) :
351357
TaskStatusRecord(TaskStatusRecordKind::TaskDependency),
352-
DependencyKind(WaitingOnTaskGroup) {
353-
WaitingOn.TaskGroup = taskGroup;
358+
DependencyKind(WaitingOnTaskGroup), WaitingTask(waitingTask){
359+
DependentOn.TaskGroup = taskGroup;
354360
}
355361

356-
void destroy() { }
362+
TaskDependencyStatusRecord(AsyncTask *waitingTask, ExecutorRef executor) :
363+
TaskStatusRecord(TaskStatusRecordKind::TaskDependency),
364+
DependencyKind(EnqueuedOnExecutor), WaitingTask(waitingTask) {
365+
DependentOn.Executor = executor;
366+
}
357367

358368
static bool classof(const TaskStatusRecord *record) {
359369
return record->getKind() == TaskStatusRecordKind::TaskDependency;
360370
}
361371

372+
void updateDependencyToEnqueuedOn(ExecutorRef executor) {
373+
DependencyKind = EnqueuedOnExecutor;
374+
DependentOn.Executor = executor;
375+
}
376+
362377
void performEscalationAction(JobPriority newPriority);
363378
};
364379

include/swift/AST/ASTSynthesis.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,9 @@ template <class S>
239239
struct SpecifiedParamSynthesizer { ParamSpecifier specifier; S sub; };
240240
template <class G>
241241
constexpr SpecifiedParamSynthesizer<G> _owned(G sub) {
242-
return {ParamSpecifier::Owned, sub};
242+
// TODO: We should probably synthesize decls to use the standard `consuming`
243+
// modifier, once we're certain doing so won't break anything.
244+
return {ParamSpecifier::LegacyOwned, sub};
243245
}
244246
template <class G>
245247
constexpr SpecifiedParamSynthesizer<G> _inout(G sub) {
@@ -257,10 +259,8 @@ FunctionType::Param synthesizeParamType(SynthesisContext &SC,
257259
const SpecifiedParamSynthesizer<S> &s) {
258260
auto param = synthesizeParamType(SC, s.sub);
259261
auto flags = param.getParameterFlags();
260-
if (s.specifier == ParamSpecifier::Owned)
261-
flags = flags.withOwned(true);
262-
if (s.specifier == ParamSpecifier::InOut)
263-
flags = flags.withInOut(true);
262+
if (s.specifier != ParamSpecifier::Default)
263+
flags = flags.withValueOwnership(s.specifier);
264264
return param.withFlags(flags);
265265
}
266266

include/swift/AST/ASTWalker.h

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ enum class LazyInitializerWalking {
7979
InAccessor
8080
};
8181

82+
/// Specifies the behavior for walking a macro expansion, whether we want to
83+
/// see the macro arguments, the expansion, or both.
84+
enum class MacroWalking {
85+
/// Walk into the expansion of the macro, to see the semantic effect of
86+
/// the macro expansion.
87+
Expansion,
88+
89+
/// Walk into the arguments of the macro as written in the source code.
90+
///
91+
/// The actual arguments walked may not make it into the program itself,
92+
/// because they can be translated by the macro in arbitrary ways.
93+
Arguments,
94+
95+
/// Walk into both the arguments of the macro as written in the source code
96+
/// and also the macro expansion.
97+
ArgumentsAndExpansion
98+
};
99+
82100
/// An abstract class used to traverse an AST.
83101
class ASTWalker {
84102
public:
@@ -504,6 +522,26 @@ class ASTWalker {
504522
return LazyInitializerWalking::InPatternBinding;
505523
}
506524

525+
/// This method configures how the walker should walk into uses of macros.
526+
virtual MacroWalking getMacroWalkingBehavior() const {
527+
return MacroWalking::ArgumentsAndExpansion;
528+
}
529+
530+
/// Determine whether we should walk macro arguments (as they appear in
531+
/// source) and the expansion (which is semantically part of the program).
532+
std::pair<bool, bool> shouldWalkMacroArgumentsAndExpansion() const {
533+
switch (getMacroWalkingBehavior()) {
534+
case MacroWalking::Expansion:
535+
return std::make_pair(false, true);
536+
537+
case MacroWalking::Arguments:
538+
return std::make_pair(true, false);
539+
540+
case MacroWalking::ArgumentsAndExpansion:
541+
return std::make_pair(true, true);
542+
}
543+
}
544+
507545
/// This method configures whether the walker should visit the body of a
508546
/// closure that was checked separately from its enclosing expression.
509547
///
@@ -541,10 +579,6 @@ class ASTWalker {
541579
/// TODO: Consider changing this to false by default.
542580
virtual bool shouldWalkSerializedTopLevelInternalDecls() { return true; }
543581

544-
/// Whether we should walk into expanded macros, whether it be from a
545-
/// \c MacroExpansionExpr or declarations created by attached macros.
546-
virtual bool shouldWalkMacroExpansions() { return true; }
547-
548582
/// walkToParameterListPre - This method is called when first visiting a
549583
/// ParameterList, before walking into its parameters.
550584
///

include/swift/AST/Decl.h

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -410,12 +410,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
410410
);
411411

412412
SWIFT_INLINE_BITFIELD(ParamDecl, VarDecl, 1+2+NumDefaultArgumentKindBits,
413-
/// Whether we've computed the specifier yet.
414-
SpecifierComputed : 1,
415-
416-
/// The specifier associated with this parameter. This determines
417-
/// the storage semantics of the value e.g. mutability.
418-
Specifier : 2,
413+
/// The specifier associated with this parameter + 1, or zero if the
414+
/// specifier has not been computed yet. This determines
415+
/// the ownership semantics of the parameter.
416+
OwnershipSpecifier : 3,
419417

420418
/// Information about a symbolic default argument, like #file.
421419
defaultArgumentKind : NumDefaultArgumentKindBits
@@ -5983,11 +5981,27 @@ class VarDecl : public AbstractStorageDecl {
59835981
}
59845982
};
59855983

5984+
/// The various spellings of ownership modifier that can be used in source.
59865985
enum class ParamSpecifier : uint8_t {
5986+
/// No explicit ownership specifier was provided. The parameter will use the
5987+
/// default ownership convention for the declaration.
59875988
Default = 0,
5989+
5990+
/// `inout`, indicating exclusive mutable access to the argument for the
5991+
/// duration of a call.
59885992
InOut = 1,
5989-
Shared = 2,
5990-
Owned = 3,
5993+
5994+
/// `borrowing`, indicating nonexclusive access to the argument for the
5995+
/// duration of a call.
5996+
Borrowing = 2,
5997+
/// `consuming`, indicating ownership transfer of the argument from caller
5998+
/// to callee.
5999+
Consuming = 3,
6000+
6001+
/// `__shared`, a legacy spelling of `borrowing`.
6002+
LegacyShared = 4,
6003+
/// `__owned`, a legacy spelling of `consuming`.
6004+
LegacyOwned = 5,
59916005
};
59926006

59936007
/// A function parameter declaration.
@@ -6276,8 +6290,8 @@ class ParamDecl : public VarDecl {
62766290
using Specifier = ParamSpecifier;
62776291

62786292
Optional<Specifier> getCachedSpecifier() const {
6279-
if (Bits.ParamDecl.SpecifierComputed)
6280-
return Specifier(Bits.ParamDecl.Specifier);
6293+
if (Bits.ParamDecl.OwnershipSpecifier != 0)
6294+
return Specifier(Bits.ParamDecl.OwnershipSpecifier - 1);
62816295

62826296
return None;
62836297
}
@@ -6288,20 +6302,18 @@ class ParamDecl : public VarDecl {
62886302

62896303
/// Is the type of this parameter 'inout'?
62906304
bool isInOut() const { return getSpecifier() == Specifier::InOut; }
6291-
/// Is this an immutable 'shared' property?
6292-
bool isShared() const { return getSpecifier() == Specifier::Shared; }
6293-
/// Is this an immutable 'owned' property?
6294-
bool isOwned() const { return getSpecifier() == Specifier::Owned; }
62956305

6296-
bool isImmutable() const {
6297-
return isImmutableSpecifier(getSpecifier());
6306+
bool isImmutableInFunctionBody() const {
6307+
return isSpecifierImmutableInFunctionBody(getSpecifier());
62986308
}
6299-
static bool isImmutableSpecifier(Specifier sp) {
6309+
static bool isSpecifierImmutableInFunctionBody(Specifier sp) {
63006310
switch (sp) {
63016311
case Specifier::Default:
6302-
case Specifier::Shared:
6303-
case Specifier::Owned:
6312+
case Specifier::Borrowing:
6313+
case Specifier::LegacyShared:
6314+
case Specifier::LegacyOwned:
63046315
return true;
6316+
case Specifier::Consuming:
63056317
case Specifier::InOut:
63066318
return false;
63076319
}
@@ -6314,29 +6326,32 @@ class ParamDecl : public VarDecl {
63146326

63156327
static ValueOwnership getValueOwnershipForSpecifier(Specifier specifier) {
63166328
switch (specifier) {
6317-
case Specifier::Default:
6318-
return ValueOwnership::Default;
6319-
case Specifier::InOut:
6329+
case ParamSpecifier::InOut:
63206330
return ValueOwnership::InOut;
6321-
case Specifier::Shared:
6331+
case ParamSpecifier::Borrowing:
6332+
case ParamSpecifier::LegacyShared:
63226333
return ValueOwnership::Shared;
6323-
case Specifier::Owned:
6334+
case ParamSpecifier::Consuming:
6335+
case ParamSpecifier::LegacyOwned:
63246336
return ValueOwnership::Owned;
6337+
case ParamSpecifier::Default:
6338+
return ValueOwnership::Default;
63256339
}
6326-
llvm_unreachable("unhandled specifier");
6340+
llvm_unreachable("invalid ParamSpecifier");
63276341
}
63286342

63296343
static Specifier
63306344
getParameterSpecifierForValueOwnership(ValueOwnership ownership) {
6345+
// TODO: switch over to consuming/borrowing once they're fully supported
63316346
switch (ownership) {
63326347
case ValueOwnership::Default:
63336348
return Specifier::Default;
63346349
case ValueOwnership::Shared:
6335-
return Specifier::Shared;
6350+
return Specifier::LegacyShared; // should become Borrowing
63366351
case ValueOwnership::InOut:
63376352
return Specifier::InOut;
63386353
case ValueOwnership::Owned:
6339-
return Specifier::Owned;
6354+
return Specifier::LegacyOwned; // should become Consuming
63406355
}
63416356
llvm_unreachable("unhandled ownership");
63426357
}
@@ -6349,6 +6364,9 @@ class ParamDecl : public VarDecl {
63496364
static bool classof(const Decl *D) {
63506365
return D->getKind() == DeclKind::Param;
63516366
}
6367+
6368+
/// Get the source code spelling of a parameter specifier value as a string.
6369+
static StringRef getSpecifierSpelling(Specifier spec);
63526370
};
63536371

63546372
/// Describes the kind of subscripting used in Objective-C.

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ ERROR(error_mode_requires_one_sil_multi_sib,none,
221221
"this mode requires .sil for primary-file and only .sib for other inputs",
222222
())
223223

224+
ERROR(error_clang_validate_once_requires_session_file,none,
225+
"'-validate-clang-modules-once' also requires a '-clang-build-session-file' argument",
226+
())
227+
224228
ERROR(error_no_output_filename_specified,none,
225229
"an %0 filename was not specified for a mode which requires an "
226230
"%0 filename", (StringRef))

0 commit comments

Comments
 (0)