Merge pull request #13211 from compnerd/COFF-registration
diff --git a/benchmark/single-source/LazyFilter.swift b/benchmark/single-source/LazyFilter.swift
index 652fe00..2cfdfc8 100644
--- a/benchmark/single-source/LazyFilter.swift
+++ b/benchmark/single-source/LazyFilter.swift
@@ -47,7 +47,7 @@
CheckResults(res == 123)
}
-fileprivate var multiplesOfThree: LazyFilterBidirectionalCollection<Array<Int>>?
+fileprivate var multiplesOfThree: LazyFilterCollection<Array<Int>>?
fileprivate func setup_LazilyFilteredArrayContains() {
multiplesOfThree = Array(1..<5_000).lazy.filter { $0 % 3 == 0 }
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 9fd1b87..78c574e 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -55,6 +55,7 @@
global ::= type 'ML' // type metadata lazy cache variable
global ::= nominal-type 'Mm' // class metaclass
global ::= nominal-type 'Mn' // nominal type descriptor
+ global ::= nominal-type 'Mo' // class metadata immediate member base offset
global ::= protocol 'Mp' // protocol descriptor
global ::= type 'MF' // metadata for remote mirrors: field descriptor
global ::= type 'MB' // metadata for remote mirrors: builtin type descriptor
diff --git a/docs/DebuggingTheCompiler.rst b/docs/DebuggingTheCompiler.rst
index 9d75f29..d0736e0 100644
--- a/docs/DebuggingTheCompiler.rst
+++ b/docs/DebuggingTheCompiler.rst
@@ -2,6 +2,7 @@
.. highlight:: none
+============================
Debugging the Swift Compiler
============================
@@ -67,12 +68,85 @@
The output of all these dump options (except ``-dump-ast``) can be redirected
with an additional ``-o <file>`` option.
+Debugging the Type Checker
+--------------------------
+
+Enabling Logging
+~~~~~~~~~~~~~~~~
+
+To enable logging in the type checker, use the following argument: ``-Xfrontend -debug-constraints``.
+This will cause the typechecker to log its internal state as it solves
+constraints and present the final type checked solution, e.g.::
+
+ ---Constraint solving for the expression at [test.swift:3:10 - line:3:10]---
+ ---Initial constraints for the given expression---
+ (integer_literal_expr type='$T0' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] value=0)
+ Score: 0 0 0 0 0 0 0 0 0 0 0 0 0
+ Contextual Type: Int
+ Type Variables:
+ #0 = $T0 [inout allowed]
+
+ Active Constraints:
+
+ Inactive Constraints:
+ $T0 literal conforms to ExpressibleByIntegerLiteral [[locator@0x7ffa3a865a00 [IntegerLiteral@test.swift:3:10]]];
+ $T0 conv Int [[locator@0x7ffa3a865a00 [IntegerLiteral@test.swift:3:10]]];
+ ($T0 literal=3 bindings=(subtypes of) (default from ExpressibleByIntegerLiteral) Int)
+ Active bindings: $T0 := Int
+ (trying $T0 := Int
+ (found solution 0 0 0 0 0 0 0 0 0 0 0 0 0)
+ )
+ ---Solution---
+ Fixed score: 0 0 0 0 0 0 0 0 0 0 0 0 0
+ Type variables:
+ $T0 as Int
+
+ Overload choices:
+
+ Constraint restrictions:
+
+ Disjunction choices:
+
+ Conformances:
+ At locator@0x7ffa3a865a00 [IntegerLiteral@test.swift:3:10]
+ (normal_conformance type=Int protocol=ExpressibleByIntegerLiteral lazy
+ (normal_conformance type=Int protocol=_ExpressibleByBuiltinIntegerLiteral lazy))
+ (found solution 0 0 0 0 0 0 0 0 0 0 0 0 0)
+ ---Type-checked expression---
+ (call_expr implicit type='Int' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] arg_labels=_builtinIntegerLiteral:
+ (constructor_ref_call_expr implicit type='(_MaxBuiltinIntegerType) -> Int' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10]
+ (declref_expr implicit type='(Int.Type) -> (_MaxBuiltinIntegerType) -> Int' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] decl=Swift.(file).Int.init(_builtinIntegerLiteral:) function_ref=single)
+ (type_expr implicit type='Int.Type' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] typerepr='Int'))
+ (tuple_expr implicit type='(_builtinIntegerLiteral: Int2048)' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] names=_builtinIntegerLiteral
+ (integer_literal_expr type='Int2048' location=test.swift:3:10 range=[test.swift:3:10 - line:3:10] value=0)))
+
+When using the integrated swift-repl, one can dump the same output for each
+expression as one evaluates the expression by enabling constraints debugging by
+typing ``:constraints debug on``::
+
+ $ swift -frontend -repl -enable-objc-interop -module-name REPL
+ *** You are running Swift's integrated REPL, ***
+ *** intended for compiler and stdlib ***
+ *** development and testing purposes only. ***
+ *** The full REPL is built as part of LLDB. ***
+ *** Type ':help' for assistance. ***
+ (swift) :constraints debug on
+
+Asserting on First Error
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When changing the typechecker, one can cause a series of cascading errors. Since
+Swift doesn't assert on such errors, one has to know more about the typechecker
+to know where to stop in the debugger. Rather than doing that, one can use the
+option ``-Xllvm -swift-diagnostics-assert-on-error=1`` to cause the
+DiagnosticsEngine to assert upon the first error, providing the signal that the
+debugger needs to know that it should attach.
Debugging on SIL Level
-~~~~~~~~~~~~~~~~~~~~~~
+----------------------
Options for Dumping the SIL
-```````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
Often it is not sufficient to dump the SIL at the beginning or end of the
optimization pipeline.
@@ -92,7 +166,7 @@
For details see ``PassManager.cpp``.
Dumping the SIL and other Data in LLDB
-``````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When debugging the Swift compiler with LLDB (or Xcode, of course), there is
even a more powerful way to examine the data in the compiler, e.g. the SIL.
@@ -125,7 +199,7 @@
environment setting contains the path to the dot tool.
Debugging and Profiling on SIL level
-````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The compiler provides a way to debug and profile on SIL level. To enable SIL
debugging add the front-end option -gsil together with -g. Example::
@@ -141,7 +215,7 @@
the build-script-impl option ``--build-sil-debugging-stdlib``.
ViewCFG: Regex based CFG Printer
-````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ViewCFG (``./utils/viewcfg``) is a script that parses a textual CFG (e.g. a llvm
or sil function) and displays a .dot file of the CFG. Since the parsing is done
@@ -178,7 +252,7 @@
**NOTE** Since we use open, .dot files should be associated with the Graphviz app for viewcfg to work.
Using Breakpoints
-`````````````````
+~~~~~~~~~~~~~~~~~
LLDB has very powerful breakpoints, which can be utilized in many ways to debug
the compiler and Swift executables. The examples in this section show the LLDB
@@ -255,7 +329,7 @@
(lldb) br set -i 84 -n GlobalARCOpts::run
LLDB Scripts
-````````````
+~~~~~~~~~~~~
LLDB has powerful capabilities of scripting in Python among other languages. An
often overlooked, but very useful technique is the -s command to lldb. This
@@ -294,7 +368,7 @@
needing to retype the various commands perfectly every time.
Reducing SIL test cases using bug_reducer
-`````````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There is functionality provided in ./swift/utils/bug_reducer/bug_reducer.py for
reducing SIL test cases by:
diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def
index 4bb7035..d2aabf3 100644
--- a/include/swift/Demangling/DemangleNodes.def
+++ b/include/swift/Demangling/DemangleNodes.def
@@ -37,6 +37,7 @@
NODE(BuiltinTypeName)
NODE(CFunctionPointer)
CONTEXT_NODE(Class)
+NODE(ClassMetadataBaseOffset)
CONTEXT_NODE(Constructor)
CONTEXT_NODE(Deallocator)
NODE(DeclContext)
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index 31e028f..c230ca1 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -110,6 +110,14 @@
/// A swift metaclass-stub reference. The pointer is a ClassDecl*.
SwiftMetaclassStub,
+ /// A class metadata base offset global variable. This stores the offset
+ /// of the immediate members of a class (generic parameters, field offsets,
+ /// vtable offsets) in the class's metadata. The immediate members begin
+ /// immediately after the superclass members end.
+ ///
+ /// The pointer is a ClassDecl*.
+ ClassMetadataBaseOffset,
+
/// The nominal type descriptor for a nominal type.
/// The pointer is a NominalTypeDecl*.
NominalTypeDescriptor,
@@ -416,6 +424,12 @@
return entity;
}
+ static LinkEntity forClassMetadataBaseOffset(ClassDecl *decl) {
+ LinkEntity entity;
+ entity.setForDecl(Kind::ClassMetadataBaseOffset, decl);
+ return entity;
+ }
+
static LinkEntity forNominalTypeDescriptor(NominalTypeDecl *decl) {
LinkEntity entity;
entity.setForDecl(Kind::NominalTypeDescriptor, decl);
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index 7558967..ef8f0dc 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -2206,7 +2206,7 @@
(TargetGenericMetadata<Runtime> *pattern, const void *arguments);
/// The size of the template in bytes.
- uint32_t MetadataSize;
+ uint32_t TemplateSize;
/// The number of generic arguments that we need to unique on,
/// in words. The first 'NumArguments * sizeof(void*)' bytes of
@@ -2223,7 +2223,7 @@
PrivateData[swift::NumGenericMetadataPrivateDataWords];
// Here there is a variably-sized field:
- // char alignas(void*) MetadataTemplate[MetadataSize];
+ // char alignas(void*) MetadataTemplate[TemplateSize];
/// Return the starting address of the metadata template data.
TargetPointer<Runtime, const void> getMetadataTemplate() const {
@@ -2602,8 +2602,9 @@
/// if (metadata = getExistingMetadata(&header.PrivateData,
/// arguments[0..header.NumArguments]))
/// return metadata
-/// metadata = malloc(header.MetadataSize)
-/// memcpy(metadata, header.MetadataTemplate, header.MetadataSize)
+/// metadata = malloc(superclass.MetadataSize +
+/// numImmediateMembers * sizeof(void *))
+/// memcpy(metadata, header.MetadataTemplate, header.TemplateSize)
/// for (i in 0..header.NumFillInstructions)
/// metadata[header.FillInstructions[i].ToIndex]
/// = arguments[header.FillInstructions[i].FromIndex]
@@ -2623,7 +2624,8 @@
ClassMetadata *
swift_allocateGenericClassMetadata(GenericMetadata *pattern,
const void *arguments,
- ClassMetadata *superclass);
+ ClassMetadata *superclass,
+ size_t numImmediateMembers);
// Callback to allocate a generic struct/enum metadata object.
SWIFT_RUNTIME_EXPORT
@@ -2867,6 +2869,16 @@
size_t *fieldOffsets,
ValueWitnessTable *vwtable);
+/// Relocate the metadata for a class and copy fields from the given template.
+/// The final size of the metadata is calculated at runtime from the size of
+/// the superclass metadata together with the given number of immediate
+/// members.
+SWIFT_RUNTIME_EXPORT
+ClassMetadata *
+swift_relocateClassMetadata(ClassMetadata *self,
+ size_t templateSize,
+ size_t numImmediateMembers);
+
/// Initialize the field offset vector for a dependent-layout class, using the
/// "Universal" layout strategy.
SWIFT_RUNTIME_EXPORT
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index 28f0c73..86b0ce9 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -854,10 +854,11 @@
// Metadata *swift_allocateGenericClassMetadata(GenericMetadata *pattern,
// const void * const *arguments,
-// objc_class *superclass);
+// objc_class *superclass,
+// size_t numImmediateMembers);
FUNCTION(AllocateGenericClassMetadata, swift_allocateGenericClassMetadata,
DefaultCC, RETURNS(TypeMetadataPtrTy),
- ARGS(TypeMetadataPatternPtrTy, Int8PtrPtrTy, ObjCClassPtrTy),
+ ARGS(TypeMetadataPatternPtrTy, Int8PtrPtrTy, ObjCClassPtrTy, SizeTy),
ATTRS(NoUnwind))
// Metadata *swift_allocateGenericValueMetadata(GenericMetadata *pattern,
@@ -945,6 +946,15 @@
ProtocolDescriptorPtrTy->getPointerTo()),
ATTRS(NoUnwind, ReadOnly))
+// Metadata *swift_relocateClassMetadata(Metadata *self,
+// size_t templateSize,
+// size_t numImmediateMembers);
+FUNCTION(RelocateClassMetadata,
+ swift_relocateClassMetadata, DefaultCC,
+ RETURNS(TypeMetadataPtrTy),
+ ARGS(TypeMetadataPtrTy, SizeTy, SizeTy),
+ ATTRS(NoUnwind))
+
// struct FieldInfo { size_t Size; size_t AlignMask; };
// void swift_initClassMetadata_UniversalStrategy(Metadata *self,
// size_t numFields,
diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp
index 11362ef..1aaf6ca 100644
--- a/lib/AST/DiagnosticEngine.cpp
+++ b/lib/AST/DiagnosticEngine.cpp
@@ -24,12 +24,13 @@
#include "swift/AST/PrintOptions.h"
#include "swift/AST/TypeRepr.h"
#include "swift/Basic/SourceManager.h"
-#include "swift/Parse/Lexer.h" // bad dependency
#include "swift/Config.h"
+#include "swift/Parse/Lexer.h" // bad dependency
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
using namespace swift;
@@ -588,6 +589,11 @@
llvm_unreachable("Unhandled DiagnosticKind in switch.");
}
+/// A special option only for compiler writers that causes Diagnostics to assert
+/// when a failure diagnostic is emitted. Intended for use in the debugger.
+llvm::cl::opt<bool> AssertOnError("swift-diagnostics-assert-on-error",
+ llvm::cl::init(false));
+
DiagnosticState::Behavior DiagnosticState::determineBehavior(DiagID id) {
auto set = [this](DiagnosticState::Behavior lvl) {
if (lvl == Behavior::Fatal) {
@@ -597,6 +603,7 @@
anyErrorOccurred = true;
}
+ assert((!AssertOnError || !anyErrorOccurred) && "We emitted an error?!");
previousBehavior = lvl;
return lvl;
};
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index 313c908..7624cfa 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -1089,6 +1089,8 @@
return createWithPoppedType(Node::Kind::Metaclass);
case 'n':
return createWithPoppedType(Node::Kind::NominalTypeDescriptor);
+ case 'o':
+ return createWithPoppedType(Node::Kind::ClassMetadataBaseOffset);
case 'p':
return createWithChild(Node::Kind::ProtocolDescriptor, popProtocol());
case 'B':
diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp
index 0c4c0fb..fb82c18 100644
--- a/lib/Demangling/NodePrinter.cpp
+++ b/lib/Demangling/NodePrinter.cpp
@@ -291,6 +291,7 @@
case Node::Kind::AssociatedTypeMetadataAccessor:
case Node::Kind::AssociatedTypeWitnessTableAccessor:
case Node::Kind::AutoClosureType:
+ case Node::Kind::ClassMetadataBaseOffset:
case Node::Kind::CFunctionPointer:
case Node::Kind::Constructor:
case Node::Kind::CurryThunk:
@@ -1372,6 +1373,10 @@
Printer << " in ";
print(Node->getChild(0));
return nullptr;
+ case Node::Kind::ClassMetadataBaseOffset:
+ Printer << "class metadata base offset for ";
+ print(Node->getChild(0));
+ return nullptr;
case Node::Kind::NominalTypeDescriptor:
Printer << "nominal type descriptor for ";
print(Node->getChild(0));
diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp
index 7d3097e..3cb1315 100644
--- a/lib/Demangling/OldRemangler.cpp
+++ b/lib/Demangling/OldRemangler.cpp
@@ -625,6 +625,11 @@
mangleSingleChildNode(node); // type
}
+void Remangler::mangleClassMetadataBaseOffset(Node *node) {
+ Out << "Mo";
+ mangleSingleChildNode(node); // type
+}
+
void Remangler::mangleNominalTypeDescriptor(Node *node) {
Out << "Mn";
mangleSingleChildNode(node); // type
diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp
index a0a9b75..8a03e3a 100644
--- a/lib/Demangling/Remangler.cpp
+++ b/lib/Demangling/Remangler.cpp
@@ -1354,6 +1354,11 @@
mangleAbstractStorage(node->getFirstChild(), "aP");
}
+void Remangler::mangleClassMetadataBaseOffset(Node *node) {
+ mangleSingleChildNode(node);
+ Buffer << "Mo";
+}
+
void Remangler::mangleNominalTypeDescriptor(Node *node) {
mangleSingleChildNode(node);
Buffer << "Mn";
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 340e18c..7be0a1c 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -1258,6 +1258,7 @@
case Kind::SwiftMetaclassStub:
case Kind::FieldOffset:
case Kind::NominalTypeDescriptor:
+ case Kind::ClassMetadataBaseOffset:
case Kind::ProtocolDescriptor:
return getSILLinkage(getDeclLinkage(getDecl()), forDefinition);
@@ -1344,6 +1345,7 @@
return true;
case Kind::SwiftMetaclassStub:
+ case Kind::ClassMetadataBaseOffset:
case Kind::NominalTypeDescriptor:
case Kind::ProtocolDescriptor:
return ::isAvailableExternally(IGM, getDecl());
@@ -2819,6 +2821,15 @@
return addr;
}
+/// Returns the address of a class metadata base offset.
+llvm::Constant *
+IRGenModule::getAddrOfClassMetadataBaseOffset(ClassDecl *D,
+ ForDefinition_t forDefinition) {
+ LinkEntity entity = LinkEntity::forClassMetadataBaseOffset(D);
+ return getAddrOfLLVMVariable(entity, getPointerAlignment(), forDefinition,
+ SizeTy, DebugTypeInfo());
+}
+
/// Return the address of a nominal type descriptor. Right now, this
/// must always be for purposes of defining it.
llvm::Constant *IRGenModule::getAddrOfNominalTypeDescriptor(NominalTypeDecl *D,
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 0bfc425..62bf20f 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -2926,7 +2926,7 @@
// Metadata *(*CreateFunction)(GenericMetadata *, const void*);
B.fillPlaceholder(createFunctionField, emitCreateFunction());
- // uint32_t MetadataSize;
+ // uint32_t TemplateSize;
// We compute this assuming that every entry in the metadata table
// is a pointer in size.
Size size = getNextOffsetFromTemplateHeader();
@@ -3141,7 +3141,6 @@
/// size is not known at compile time.
class ResilientClassMemberBuilder {
IRGenModule &IGM;
- ConstantStructBuilder &B;
SILVTable *VTable;
struct MethodOverride {
@@ -3156,23 +3155,13 @@
ConstantStructBuilder &builder,
const StructLayout &layout,
const ClassLayout &fieldLayout)
- : IGM(IGM), B(builder) {
+ : IGM(IGM) {
VTable = IGM.getSILModule().lookUpVTable(theClass);
}
- void addFieldOffset(VarDecl *var) {
- B.addInt(IGM.SizeTy, 0);
- }
+ void addFieldOffset(VarDecl *var) {}
- void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) {
- for (unsigned i = 0,
- e = placeholder->getNumberOfFieldOffsetVectorEntries();
- i < e; ++i) {
- // Emit placeholder values for some number of stored properties we
- // know exist but aren't able to reference directly.
- B.addInt(IGM.SizeTy, 0);
- }
- }
+ void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) {}
void addMethod(SILDeclRef fn) {
// Find the vtable entry.
@@ -3192,8 +3181,6 @@
// Record the override so that we can fill it in later.
Overrides.push_back({offset, entry->Implementation});
}
-
- B.addNullPointer(IGM.FunctionPtrTy);
}
// Update vtable entries for method overrides. The runtime copies in
@@ -3223,14 +3210,10 @@
// FIXME
}
- void addGenericArgument(CanType argTy, ClassDecl *forClass) {
- B.addNullPointer(IGM.TypeMetadataPtrTy);
- }
+ void addGenericArgument(CanType argTy, ClassDecl *forClass) {}
void addGenericWitnessTable(CanType argTy, ProtocolConformanceRef conf,
- ClassDecl *forClass) {
- B.addNullPointer(IGM.WitnessTablePtrTy);
- }
+ ClassDecl *forClass) {}
};
/// Base class for laying out class metadata.
@@ -3399,6 +3382,7 @@
}
void addClassAddressPoint() {
+ // FIXME: Wrong
auto size = IGM.getMetadataLayout(Target).getSize();
B.addInt32(size.AddressPoint.getValue());
}
@@ -3720,10 +3704,21 @@
Address superField =
emitAddressOfSuperclassRefInClassMetadata(IGF, metadata);
superField = IGF.Builder.CreateElementBitCast(superField,
- IGF.IGM.TypeMetadataPtrTy);
+ IGM.TypeMetadataPtrTy);
IGF.Builder.CreateStore(superclassMetadata, superField);
}
+ // Relocate the metadata if it has a superclass that is resilient
+ // to us.
+ if (doesClassMetadataRequireDynamicInitialization(IGM, Target)) {
+ auto templateSize = IGM.getSize(Size(B.getNextOffsetFromGlobal()));
+ auto numImmediateMembers = IGM.getSize(
+ Size(IGM.getMetadataLayout(Target).getNumImmediateMembers()));
+ metadata = IGF.Builder.CreateCall(IGF.IGM.getRelocateClassMetadataFn(),
+ {metadata, templateSize,
+ numImmediateMembers});
+ }
+
return emitFinishInitializationOfClassMetadata(IGF, metadata);
}
};
@@ -3804,11 +3799,15 @@
IGM.getObjCRuntimeBaseForSwiftRootClass(Target));
} else {
superMetadata
- = llvm::ConstantPointerNull::get(IGF.IGM.ObjCClassPtrTy);
+ = llvm::ConstantPointerNull::get(IGM.ObjCClassPtrTy);
}
+ auto numImmediateMembers =
+ IGM.getSize(Size(IGM.getMetadataLayout(Target).getNumImmediateMembers()));
+
return IGF.Builder.CreateCall(IGM.getAllocateGenericClassMetadataFn(),
- {metadataPattern, arguments, superMetadata});
+ {metadataPattern, arguments, superMetadata,
+ numImmediateMembers});
}
void addMetadataFlags() {
diff --git a/lib/IRGen/IRGenMangler.h b/lib/IRGen/IRGenMangler.h
index 57a9e12..e6a031c 100644
--- a/lib/IRGen/IRGenMangler.h
+++ b/lib/IRGen/IRGenMangler.h
@@ -52,6 +52,10 @@
return mangleNominalTypeSymbol(Decl, "Mm");
}
+ std::string mangleClassMetadataBaseOffset(const ClassDecl *Decl) {
+ return mangleNominalTypeSymbol(Decl, "Mo");
+ }
+
std::string mangleNominalTypeDescriptor(const NominalTypeDecl *Decl) {
return mangleNominalTypeSymbol(Decl, "Mn");
}
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 71f52c5..808b3e7 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -1055,6 +1055,8 @@
llvm::Constant *getAddrOfTypeMetadataLazyCacheVariable(CanType type,
ForDefinition_t forDefinition);
llvm::Constant *getAddrOfForeignTypeMetadataCandidate(CanType concreteType);
+ llvm::Constant *getAddrOfClassMetadataBaseOffset(ClassDecl *D,
+ ForDefinition_t forDefinition);
llvm::Constant *getAddrOfNominalTypeDescriptor(NominalTypeDecl *D,
ConstantInitFuture definition);
llvm::Constant *getAddrOfProtocolDescriptor(ProtocolDecl *D,
diff --git a/lib/IRGen/Linking.cpp b/lib/IRGen/Linking.cpp
index b0cdcc6..fbe8201 100644
--- a/lib/IRGen/Linking.cpp
+++ b/lib/IRGen/Linking.cpp
@@ -66,29 +66,20 @@
/// Mangle this entity as a std::string.
std::string LinkEntity::mangleAsString() const {
- // Almost everything below gets the common prefix:
- // mangled-name ::= '_T' global
IRGenMangler mangler;
switch (getKind()) {
- // global ::= 'w' value-witness-kind // value witness
case Kind::ValueWitness:
return mangler.mangleValueWitness(getType(), getValueWitness());
- // global ::= 'WV' type // value witness
case Kind::ValueWitnessTable:
return mangler.mangleValueWitnessTable(getType());
- // global ::= 'Ma' type // type metadata access function
case Kind::TypeMetadataAccessFunction:
return mangler.mangleTypeMetadataAccessFunction(getType());
- // global ::= 'ML' type // type metadata lazy cache variable
case Kind::TypeMetadataLazyCacheVariable:
return mangler.mangleTypeMetadataLazyCacheVariable(getType());
- // global ::= 'Mf' type // 'full' type metadata
- // global ::= 'M' directness type // type metadata
- // global ::= 'MP' directness type // type metadata pattern
case Kind::TypeMetadata:
switch (getMetadataAddress()) {
case TypeMetadataAddress::FullMetadata:
@@ -98,72 +89,58 @@
}
llvm_unreachable("invalid metadata address");
- // global ::= 'M' directness type // type metadata
case Kind::ForeignTypeMetadataCandidate:
return mangler.mangleTypeMetadataFull(getType(), /*isPattern=*/false);
- // global ::= 'Mm' type // class metaclass
case Kind::SwiftMetaclassStub:
return mangler.mangleClassMetaClass(cast<ClassDecl>(getDecl()));
- // global ::= 'Mn' type // nominal type descriptor
+ case Kind::ClassMetadataBaseOffset: // class metadata base offset
+ return mangler.mangleClassMetadataBaseOffset(cast<ClassDecl>(getDecl()));
+
case Kind::NominalTypeDescriptor:
return mangler.mangleNominalTypeDescriptor(
cast<NominalTypeDecl>(getDecl()));
- // global ::= 'Mp' type // protocol descriptor
case Kind::ProtocolDescriptor:
return mangler.mangleProtocolDescriptor(cast<ProtocolDecl>(getDecl()));
- // global ::= 'Wv' directness entity
case Kind::FieldOffset:
return mangler.mangleFieldOffsetFull(getDecl(), isOffsetIndirect());
- // global ::= 'WP' protocol-conformance
case Kind::DirectProtocolWitnessTable:
return mangler.mangleDirectProtocolWitnessTable(getProtocolConformance());
- // global ::= 'WG' protocol-conformance
case Kind::GenericProtocolWitnessTableCache:
return mangler.mangleGenericProtocolWitnessTableCache(
getProtocolConformance());
- // global ::= 'WI' protocol-conformance
case Kind::GenericProtocolWitnessTableInstantiationFunction:
return mangler.mangleGenericProtocolWitnessTableInstantiationFunction(
getProtocolConformance());
- // global ::= 'Wa' protocol-conformance
case Kind::ProtocolWitnessTableAccessFunction:
return mangler.mangleProtocolWitnessTableAccessFunction(
getProtocolConformance());
- // global ::= 'Wl' type protocol-conformance
case Kind::ProtocolWitnessTableLazyAccessFunction:
return mangler.mangleProtocolWitnessTableLazyAccessFunction(getType(),
getProtocolConformance());
- // global ::= 'WL' type protocol-conformance
case Kind::ProtocolWitnessTableLazyCacheVariable:
return mangler.mangleProtocolWitnessTableLazyCacheVariable(getType(),
getProtocolConformance());
- // global ::= 'Wt' protocol-conformance identifier
case Kind::AssociatedTypeMetadataAccessFunction:
return mangler.mangleAssociatedTypeMetadataAccessFunction(
getProtocolConformance(), getAssociatedType()->getNameStr());
- // global ::= protocol-conformance identifier+ nominal-type 'WT'
case Kind::AssociatedTypeWitnessTableAccessFunction: {
auto assocConf = getAssociatedConformance();
return mangler.mangleAssociatedTypeWitnessTableAccessFunction(
getProtocolConformance(), assocConf.first, assocConf.second);
}
- // For all the following, this rule was imposed above:
- // global ::= local-marker? entity // some identifiable thing
-
- // entity ::= declaration // other declaration
case Kind::Function:
// As a special case, functions can have manually mangled names.
if (auto AsmA = getDecl()->getAttrs().getAttribute<SILGenNameAttr>())
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index 8837d4f..ad96156 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -158,6 +158,10 @@
// Trivial case: empty parameter list.
if (Tok.is(tok::r_paren)) {
+ {
+ SyntaxParsingContext EmptyPLContext(SyntaxContext,
+ SyntaxKind::FunctionParameterList);
+ }
rightParenLoc = consumeToken(tok::r_paren);
return ParserStatus();
}
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 0625e61..ac9a650 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -321,6 +321,85 @@
return true;
}
+/// Determine whether the given type refers to a non-final class (or
+/// dynamic self of one).
+static bool isNonFinalClass(Type type) {
+ if (auto dynamicSelf = type->getAs<DynamicSelfType>())
+ type = dynamicSelf->getSelfType();
+
+ if (auto classDecl = type->getClassOrBoundGenericClass())
+ return !classDecl->isFinal();
+
+ if (auto archetype = type->getAs<ArchetypeType>())
+ if (auto super = archetype->getSuperclass())
+ return isNonFinalClass(super);
+
+ return false;
+}
+
+// Non-required constructors may not be not inherited. Therefore when
+// constructing a class object, either the metatype must be statically
+// derived (rather than an arbitrary value of metatype type) or the referenced
+// constructor must be required.
+static bool
+diagnoseInvalidDynamicConstructorReferences(ConstraintSystem &cs,
+ Expr *base,
+ DeclNameLoc memberRefLoc,
+ ConstructorDecl *ctorDecl,
+ bool SuppressDiagnostics) {
+ auto &tc = cs.getTypeChecker();
+ auto baseTy = cs.getType(base)->getRValueType();
+ auto instanceTy = baseTy->getRValueInstanceType();
+
+ bool isStaticallyDerived =
+ base->isStaticallyDerivedMetatype(
+ [&](const Expr *expr) -> Type {
+ return cs.getType(expr);
+ });
+
+ // 'super.' is always OK
+ if (isa<SuperRefExpr>(base))
+ return true;
+
+ // 'self.' reference with concrete type is OK
+ if (isa<DeclRefExpr>(base) &&
+ cast<DeclRefExpr>(base)->getDecl()->getBaseName() == tc.Context.Id_self &&
+ !baseTy->is<ArchetypeType>())
+ return true;
+
+ // FIXME: The "hasClangNode" check here is a complete hack.
+ if (isNonFinalClass(instanceTy) &&
+ !isStaticallyDerived &&
+ !ctorDecl->hasClangNode() &&
+ !(ctorDecl->isRequired() ||
+ ctorDecl->getDeclContext()->getAsProtocolOrProtocolExtensionContext())) {
+ if (SuppressDiagnostics)
+ return false;
+
+ tc.diagnose(memberRefLoc, diag::dynamic_construct_class, instanceTy)
+ .highlight(base->getSourceRange());
+ auto ctor = cast<ConstructorDecl>(ctorDecl);
+ tc.diagnose(ctorDecl, diag::note_nonrequired_initializer,
+ ctor->isImplicit(), ctor->getFullName());
+ // Constructors cannot be called on a protocol metatype, because there is no
+ // metatype to witness it.
+ } else if (isa<ConstructorDecl>(ctorDecl) &&
+ baseTy->is<MetatypeType>() &&
+ instanceTy->isExistentialType()) {
+ if (SuppressDiagnostics)
+ return false;
+
+ if (isStaticallyDerived) {
+ tc.diagnose(memberRefLoc, diag::construct_protocol_by_name, instanceTy)
+ .highlight(base->getSourceRange());
+ } else {
+ tc.diagnose(memberRefLoc, diag::construct_protocol_value, baseTy)
+ .highlight(base->getSourceRange());
+ }
+ }
+ return true;
+}
+
namespace {
/// \brief Rewrites an expression by applying the solution of a constraint
@@ -825,12 +904,12 @@
if (auto baseMeta = baseTy->getAs<AnyMetatypeType>()) {
baseIsInstance = false;
baseTy = baseMeta->getInstanceType();
+
// If the member is a constructor, verify that it can be legally
// referenced from this base.
if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
- cs.setExprTypes(base);
- if (!tc.diagnoseInvalidDynamicConstructorReferences(base, memberLoc,
- baseMeta, ctor, SuppressDiagnostics))
+ if (!diagnoseInvalidDynamicConstructorReferences(cs, base, memberLoc,
+ ctor, SuppressDiagnostics))
return nullptr;
}
}
@@ -2466,6 +2545,13 @@
ConstructorDecl *ctor,
FunctionRefKind functionRefKind,
Type openedType) {
+
+ // If the member is a constructor, verify that it can be legally
+ // referenced from this base.
+ if (!diagnoseInvalidDynamicConstructorReferences(cs, base, nameLoc,
+ ctor, SuppressDiagnostics))
+ return nullptr;
+
// If the subexpression is a metatype, build a direct reference to the
// constructor.
if (cs.getType(base)->is<AnyMetatypeType>()) {
@@ -6805,67 +6891,6 @@
return literal;
}
-/// Determine whether the given type refers to a non-final class (or
-/// dynamic self of one).
-static bool isNonFinalClass(Type type) {
- if (auto dynamicSelf = type->getAs<DynamicSelfType>())
- type = dynamicSelf->getSelfType();
-
- if (auto classDecl = type->getClassOrBoundGenericClass())
- return !classDecl->isFinal();
-
- if (auto archetype = type->getAs<ArchetypeType>())
- if (auto super = archetype->getSuperclass())
- return isNonFinalClass(super);
-
- return false;
-}
-
-// Non-required constructors may not be not inherited. Therefore when
-// constructing a class object, either the metatype must be statically
-// derived (rather than an arbitrary value of metatype type) or the referenced
-// constructor must be required.
-bool
-TypeChecker::diagnoseInvalidDynamicConstructorReferences(Expr *base,
- DeclNameLoc memberRefLoc,
- AnyMetatypeType *metaTy,
- ConstructorDecl *ctorDecl,
- bool SuppressDiagnostics) {
- auto ty = metaTy->getInstanceType();
-
- // FIXME: The "hasClangNode" check here is a complete hack.
- if (isNonFinalClass(ty) &&
- !base->isStaticallyDerivedMetatype() &&
- !ctorDecl->hasClangNode() &&
- !(ctorDecl->isRequired() ||
- ctorDecl->getDeclContext()->getAsProtocolOrProtocolExtensionContext())) {
- if (SuppressDiagnostics)
- return false;
-
- diagnose(memberRefLoc, diag::dynamic_construct_class, ty)
- .highlight(base->getSourceRange());
- auto ctor = cast<ConstructorDecl>(ctorDecl);
- diagnose(ctorDecl, diag::note_nonrequired_initializer,
- ctor->isImplicit(), ctor->getFullName());
- // Constructors cannot be called on a protocol metatype, because there is no
- // metatype to witness it.
- } else if (isa<ConstructorDecl>(ctorDecl) &&
- isa<MetatypeType>(metaTy) &&
- ty->isExistentialType()) {
- if (SuppressDiagnostics)
- return false;
-
- if (base->isStaticallyDerivedMetatype()) {
- diagnose(memberRefLoc, diag::construct_protocol_by_name, ty)
- .highlight(base->getSourceRange());
- } else {
- diagnose(memberRefLoc, diag::construct_protocol_value, metaTy)
- .highlight(base->getSourceRange());
- }
- }
- return true;
-}
-
Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
ConstraintLocatorBuilder locator) {
TypeChecker &tc = cs.getTypeChecker();
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 83f5354..9bab480 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -2468,15 +2468,6 @@
/// Diagnose assigning variable to itself.
bool diagnoseSelfAssignment(const Expr *E);
- /// When referencing a class initializer, check that the base expression is
- /// either a static metatype or that the initializer is 'required'.
- bool
- diagnoseInvalidDynamicConstructorReferences(Expr *base,
- DeclNameLoc memberRefLoc,
- AnyMetatypeType *metaTy,
- ConstructorDecl *ctorDecl,
- bool SuppressDiagnostics);
-
/// Builds a string representing a "default" generic argument list for
/// \p typeDecl. In general, this means taking the bound of each generic
/// parameter. The \p getPreferredType callback can be used to provide a
diff --git a/stdlib/private/StdlibCollectionUnittest/CheckCollectionType.swift.gyb b/stdlib/private/StdlibCollectionUnittest/CheckCollectionType.swift.gyb
index 7e597d6..00843b0 100644
--- a/stdlib/private/StdlibCollectionUnittest/CheckCollectionType.swift.gyb
+++ b/stdlib/private/StdlibCollectionUnittest/CheckCollectionType.swift.gyb
@@ -1584,11 +1584,6 @@
.forEach(in: distanceFromToTests) {
test in
let c = toCollection(0..<20)
- let backwards = (test.startOffset > test.endOffset)
- if backwards && !collectionIsBidirectional {
- expectCrashLater()
- }
-
let d = c.distance(
from: c.nthIndex(test.startOffset), to: c.nthIndex(test.endOffset))
expectEqual(
diff --git a/stdlib/private/StdlibCollectionUnittest/MinimalCollections.swift.gyb b/stdlib/private/StdlibCollectionUnittest/MinimalCollections.swift.gyb
index ee364bf..ae11f3c 100644
--- a/stdlib/private/StdlibCollectionUnittest/MinimalCollections.swift.gyb
+++ b/stdlib/private/StdlibCollectionUnittest/MinimalCollections.swift.gyb
@@ -657,8 +657,6 @@
public func distance(from start: ${Index}, to end: ${Index})
-> Int {
% if Traversal == 'Forward':
- _precondition(start <= end,
- "Only BidirectionalCollections can have end come before start")
% end
// FIXME: swift-3-indexing-model: perform a range check properly.
if start != endIndex {
diff --git a/stdlib/public/SDK/CoreImage/CoreImage.swift b/stdlib/public/SDK/CoreImage/CoreImage.swift
index 624a770..794b49d 100644
--- a/stdlib/public/SDK/CoreImage/CoreImage.swift
+++ b/stdlib/public/SDK/CoreImage/CoreImage.swift
@@ -14,7 +14,7 @@
@_exported import CoreImage // Clang module
extension CIFilter {
-#if os(OSX)
+#if os(macOS)
// - (CIImage *)apply:(CIKernel *)k, ...
// @objc(apply:arguments:options:)
// func apply(_ k: CIKernel,
@@ -42,7 +42,7 @@
}
}
-#if os(OSX)
+#if os(macOS)
extension CISampler {
// - (id)initWithImage:(CIImage *)im keysAndValues:key0, ...;
convenience init(im: CIImage, elements: (String, Any)...) {
diff --git a/stdlib/public/SDK/Metal/Metal.swift b/stdlib/public/SDK/Metal/Metal.swift
index d1e260f..1f9eebb 100644
--- a/stdlib/public/SDK/Metal/Metal.swift
+++ b/stdlib/public/SDK/Metal/Metal.swift
@@ -25,7 +25,7 @@
@available(macOS 10.11, iOS 8.0, tvOS 8.0, *)
extension MTLBuffer {
-#if os(OSX)
+#if os(macOS)
@available(macOS, introduced: 10.11)
public func didModifyRange(_ range: Range<Int>) {
__didModifyRange(NSRange(location: range.lowerBound, length: range.count))
@@ -81,7 +81,7 @@
}
}
-#if os(OSX)
+#if os(macOS)
@available(swift 4)
@available(macOS 10.13, *)
public func MTLCopyAllDevicesWithObserver(handler: @escaping MTLDeviceNotificationHandler) -> (devices:[MTLDevice], observer:NSObject) {
@@ -133,7 +133,7 @@
__use(heaps, count: heaps.count)
}
-#if os(OSX)
+#if os(macOS)
@available(macOS 10.13, *)
public func setViewports(_ viewports: [MTLViewport]) {
__setViewports(viewports, count: viewports.count)
diff --git a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift
index b2cd7cd..dbf43f1 100644
--- a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift
+++ b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift
@@ -25,7 +25,7 @@
/// ObjCBool.
@_fixed_layout
public struct ObjCBool : ExpressibleByBooleanLiteral {
-#if os(OSX) || (os(iOS) && (arch(i386) || arch(arm)))
+#if os(macOS) || (os(iOS) && (arch(i386) || arch(arm)))
// On OS X and 32-bit iOS, Objective-C's BOOL type is a "signed char".
var _value: Int8
@@ -48,7 +48,7 @@
/// The value of `self`, expressed as a `Bool`.
public var boolValue: Bool {
-#if os(OSX) || (os(iOS) && (arch(i386) || arch(arm)))
+#if os(macOS) || (os(iOS) && (arch(i386) || arch(arm)))
return _value != 0
#else
return _value
diff --git a/stdlib/public/SDK/SafariServices/SafariServices.swift b/stdlib/public/SDK/SafariServices/SafariServices.swift
index f59d59f..6f04fa3 100644
--- a/stdlib/public/SDK/SafariServices/SafariServices.swift
+++ b/stdlib/public/SDK/SafariServices/SafariServices.swift
@@ -13,7 +13,7 @@
@_exported import SafariServices // Clang module
import _SwiftSafariServicesOverlayShims
-#if os(OSX)
+#if os(macOS)
@available(OSX, introduced: 10.11)
public func SFSafariServicesAvailable(_ version: SFSafariServicesVersion = SFSafariServicesVersion.version10_0) -> Bool {
diff --git a/stdlib/public/SDK/SceneKit/SceneKit.swift.gyb b/stdlib/public/SDK/SceneKit/SceneKit.swift.gyb
index 21e8405..1581b39 100644
--- a/stdlib/public/SDK/SceneKit/SceneKit.swift.gyb
+++ b/stdlib/public/SDK/SceneKit/SceneKit.swift.gyb
@@ -22,7 +22,7 @@
// MARK: Exposing SCNFloat
-#if os(OSX)
+#if os(macOS)
public typealias SCNFloat = CGFloat
#elseif os(iOS) || os(tvOS) || os(watchOS)
public typealias SCNFloat = Float
diff --git a/stdlib/public/SDK/SpriteKit/SpriteKit.swift b/stdlib/public/SDK/SpriteKit/SpriteKit.swift
index aecd66a..947b33c 100644
--- a/stdlib/public/SDK/SpriteKit/SpriteKit.swift
+++ b/stdlib/public/SDK/SpriteKit/SpriteKit.swift
@@ -15,7 +15,7 @@
// SpriteKit defines SKColor using a macro.
-#if os(OSX)
+#if os(macOS)
public typealias SKColor = NSColor
#elseif os(iOS) || os(tvOS) || os(watchOS)
public typealias SKColor = UIColor
diff --git a/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb b/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb
index 746a0f1..0cd4431 100644
--- a/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb
+++ b/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb
@@ -21,7 +21,7 @@
// we could send a Raw, but I don't want to make a copy of the
// bytes for no good reason make an NSImage out of them and
// send that
-#if os(OSX)
+#if os(macOS)
let image = data.flatMap(NSImage.init(data:)) ?? NSImage()
#elseif os(iOS) || os(watchOS) || os(tvOS)
let image = data.flatMap(UIImage.init(data:)) ?? UIImage()
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index b5371f1..e91c0b9 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -54,7 +54,7 @@
Equatable.swift
ErrorType.swift
Existential.swift
- Filter.swift.gyb
+ Filter.swift
FixedArray.swift.gyb
FlatMap.swift
Flatten.swift.gyb
@@ -82,7 +82,7 @@
LazySequence.swift
LifetimeManager.swift
ManagedBuffer.swift
- Map.swift.gyb
+ Map.swift
MemoryLayout.swift
UnicodeScalar.swift # ORDER DEPENDENCY: Must precede Mirrors.swift
Mirrors.swift.gyb
diff --git a/stdlib/public/core/Collection.swift b/stdlib/public/core/Collection.swift
index ea210d2..abd0980 100644
--- a/stdlib/public/core/Collection.swift
+++ b/stdlib/public/core/Collection.swift
@@ -701,16 +701,11 @@
/// Returns the distance between two indices.
///
- /// Unless the collection conforms to the `BidirectionalCollection` protocol,
- /// `start` must be less than or equal to `end`.
- ///
/// - Parameters:
/// - start: A valid index of the collection.
/// - end: Another valid index of the collection. If `end` is equal to
/// `start`, the result is zero.
- /// - Returns: The distance between `start` and `end`. The result can be
- /// negative only if the collection conforms to the
- /// `BidirectionalCollection` protocol.
+ /// - Returns: The distance between `start` and `end`.
///
/// - Complexity: O(1) if the collection conforms to
/// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the
@@ -962,30 +957,34 @@
/// Returns the distance between two indices.
///
- /// Unless the collection conforms to the `BidirectionalCollection` protocol,
- /// `start` must be less than or equal to `end`.
- ///
/// - Parameters:
/// - start: A valid index of the collection.
/// - end: Another valid index of the collection. If `end` is equal to
/// `start`, the result is zero.
- /// - Returns: The distance between `start` and `end`. The result can be
- /// negative only if the collection conforms to the
- /// `BidirectionalCollection` protocol.
+ /// - Returns: The distance between `start` and `end`.
///
/// - Complexity: O(1) if the collection conforms to
/// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the
/// resulting distance.
@_inlineable
public func distance(from start: Index, to end: Index) -> Int {
- _precondition(start <= end,
- "Only BidirectionalCollections can have end come before start")
-
- var start = start
+ var _start: Index
+ let _end: Index
+ let step: Int
+ if start > end {
+ _start = end
+ _end = start
+ step = -1
+ }
+ else {
+ _start = start
+ _end = end
+ step = 1
+ }
var count = 0
- while start != end {
- count = count + 1
- formIndex(after: &start)
+ while _start != _end {
+ count += step
+ formIndex(after: &_start)
}
return count
}
diff --git a/stdlib/public/core/Filter.swift.gyb b/stdlib/public/core/Filter.swift
similarity index 75%
rename from stdlib/public/core/Filter.swift.gyb
rename to stdlib/public/core/Filter.swift
index 86d5d94..668311c 100644
--- a/stdlib/public/core/Filter.swift.gyb
+++ b/stdlib/public/core/Filter.swift
@@ -1,4 +1,4 @@
-//===--- Filter.swift.gyb -------------------------------------*- swift -*-===//
+//===--- Filter.swift -----------------------------------------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
@@ -10,12 +10,6 @@
//
//===----------------------------------------------------------------------===//
-%{
-from gyb_stdlib_support import (
- collectionForTraversal
-)
-}%
-
/// An iterator over the elements traversed by some base iterator that also
/// satisfy a given predicate.
///
@@ -122,14 +116,6 @@
@available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Use Base.Index")
public typealias LazyFilterIndex<Base : Collection> = Base.Index
-// FIXME(ABI)#27 (Conditional Conformance): `LazyFilter*Collection` types should be
-// collapsed into one `LazyFilterCollection` using conditional conformances.
-// Maybe even combined with `LazyFilterSequence`.
-// rdar://problem/17144340
-
-% for Traversal in ['Forward', 'Bidirectional']:
-% Self = "LazyFilter" + collectionForTraversal(Traversal)
-
/// A lazy `Collection` wrapper that includes the elements of an
/// underlying collection that satisfy a predicate.
///
@@ -140,17 +126,11 @@
/// general operations on `LazyFilterCollection` instances may not have the
/// documented complexity.
@_fixed_layout // FIXME(sil-serialize-all)
-public struct ${Self}<
- Base : ${collectionForTraversal(Traversal)}
-> : LazyCollectionProtocol, ${collectionForTraversal(Traversal)}
-{
-
- /// A type that represents a valid position in the collection.
- ///
- /// Valid indices consist of the position of every element and a
- /// "past the end" position that's not valid for use as a subscript.
- public typealias Index = Base.Index
-
+public struct LazyFilterCollection<Base : Collection> {
+ @_versioned // FIXME(sil-serialize-all)
+ internal var _base: Base
+ @_versioned // FIXME(sil-serialize-all)
+ internal let _predicate: (Base.Element) -> Bool
/// Creates an instance containing the elements of `base` that
/// satisfy `isIncluded`.
@@ -163,6 +143,38 @@
self._base = _base
self._predicate = isIncluded
}
+}
+
+extension LazyFilterCollection : Sequence {
+ public typealias SubSequence = LazyFilterCollection<Base.SubSequence>
+ public typealias Element = Base.Element
+
+ // Any estimate of the number of elements that pass `_predicate` requires
+ // iterating the collection and evaluating each element, which can be costly,
+ // is unexpected, and usually doesn't pay for itself in saving time through
+ // preventing intermediate reallocations. (SR-4164)
+ @_inlineable // FIXME(sil-serialize-all)
+ public var underestimatedCount: Int { return 0 }
+
+ @_inlineable // FIXME(sil-serialize-all)
+ public func _copyToContiguousArray()
+ -> ContiguousArray<Base.Iterator.Element> {
+
+ // The default implementation of `_copyToContiguousArray` queries the
+ // `count` property, which evaluates `_predicate` for every element --
+ // see the note above `underestimatedCount`. Here we treat `self` as a
+ // sequence and only rely on underestimated count.
+ return _copySequenceToContiguousArray(self)
+ }
+
+ /// Returns an iterator over the elements of this sequence.
+ ///
+ /// - Complexity: O(1).
+ @_inlineable // FIXME(sil-serialize-all)
+ public func makeIterator() -> LazyFilterIterator<Base.Iterator> {
+ return LazyFilterIterator(
+ _base: _base.makeIterator(), _predicate)
+ }
@_inlineable
public func _customContainsEquatableElement(
@@ -176,6 +188,14 @@
}
return nil
}
+}
+
+extension LazyFilterCollection : LazyCollectionProtocol, Collection {
+ /// A type that represents a valid position in the collection.
+ ///
+ /// Valid indices consist of the position of every element and a
+ /// "past the end" position that's not valid for use as a subscript.
+ public typealias Index = Base.Index
/// The position of the first element in a non-empty collection.
///
@@ -221,7 +241,98 @@
i = index
}
-% if Traversal == 'Bidirectional':
+ @inline(__always)
+ @_inlineable // FIXME(sil-serialize-all)
+ @_versioned // FIXME(sil-serialize-all)
+ internal func _advanceIndex(_ i: inout Index, step: Int) {
+ repeat {
+ _base.formIndex(&i, offsetBy: step)
+ } while i != _base.endIndex && !_predicate(_base[i])
+ }
+
+ @inline(__always)
+ @_inlineable // FIXME(sil-serialize-all)
+ @_versioned // FIXME(sil-serialize-all)
+ internal func _ensureBidirectional(step: Int) {
+ // FIXME: This seems to be the best way of checking whether _base is
+ // forward only without adding an extra protocol requirement.
+ // index(_:offsetBy:limitedBy:) is chosen becuase it is supposed to return
+ // nil when the resulting index lands outside the collection boundaries,
+ // and therefore likely does not trap in these cases.
+ if step < 0 {
+ _ = _base.index(
+ _base.endIndex, offsetBy: step, limitedBy: _base.startIndex)
+ }
+ }
+
+ @_inlineable // FIXME(sil-serialize-all)
+ public func index(_ i: Index, offsetBy n: Int) -> Index {
+ var i = i
+ let step = n.signum()
+ // The following line makes sure that index(_:offsetBy:) is invoked on the
+ // _base at least once, to trigger a _precondition in forward only
+ // collections.
+ _ensureBidirectional(step: step)
+ for _ in 0 ..< abs(numericCast(n)) {
+ _advanceIndex(&i, step: step)
+ }
+ return i
+ }
+
+ @_inlineable // FIXME(sil-serialize-all)
+ public func formIndex(_ i: inout Index, offsetBy n: Int) {
+ i = index(i, offsetBy: n)
+ }
+
+ @_inlineable // FIXME(sil-serialize-all)
+ public func index(
+ _ i: Index, offsetBy n: Int, limitedBy limit: Index
+ ) -> Index? {
+ var i = i
+ let step = n.signum()
+ // The following line makes sure that index(_:offsetBy:limitedBy:) is
+ // invoked on the _base at least once, to trigger a _precondition in
+ // forward only collections.
+ _ensureBidirectional(step: step)
+ for _ in 0 ..< abs(numericCast(n)) {
+ if i == limit {
+ return nil
+ }
+ _advanceIndex(&i, step: step)
+ }
+ return i
+ }
+
+ @_inlineable // FIXME(sil-serialize-all)
+ public func formIndex(
+ _ i: inout Index, offsetBy n: Int, limitedBy limit: Index
+ ) -> Bool {
+ if let advancedIndex = index(i, offsetBy: n, limitedBy: limit) {
+ i = advancedIndex
+ return true
+ }
+ i = limit
+ return false
+ }
+
+ /// Accesses the element at `position`.
+ ///
+ /// - Precondition: `position` is a valid position in `self` and
+ /// `position != endIndex`.
+ @_inlineable // FIXME(sil-serialize-all)
+ public subscript(position: Index) -> Base.Element {
+ return _base[position]
+ }
+
+ @_inlineable // FIXME(sil-serialize-all)
+ public subscript(bounds: Range<Index>) -> SubSequence {
+ return SubSequence(_base: _base[bounds], _predicate)
+ }
+}
+
+extension LazyFilterCollection : BidirectionalCollection
+ where Base : BidirectionalCollection {
+
@_inlineable // FIXME(sil-serialize-all)
public func index(before i: Index) -> Index {
var i = i
@@ -239,59 +350,8 @@
} while !_predicate(_base[index])
i = index
}
-% end
-
- /// Accesses the element at `position`.
- ///
- /// - Precondition: `position` is a valid position in `self` and
- /// `position != endIndex`.
- @_inlineable // FIXME(sil-serialize-all)
- public subscript(position: Index) -> Base.Element {
- return _base[position]
- }
-
- public typealias SubSequence = ${Self}<Base.SubSequence>
-
- @_inlineable // FIXME(sil-serialize-all)
- public subscript(bounds: Range<Index>) -> SubSequence {
- return SubSequence(_base: _base[bounds], _predicate)
- }
-
- // Any estimate of the number of elements that pass `_predicate` requires
- // iterating the collection and evaluating each element, which can be costly,
- // is unexpected, and usually doesn't pay for itself in saving time through
- // preventing intermediate reallocations. (SR-4164)
- @_inlineable // FIXME(sil-serialize-all)
- public var underestimatedCount: Int { return 0 }
-
- @_inlineable // FIXME(sil-serialize-all)
- public func _copyToContiguousArray()
- -> ContiguousArray<Base.Iterator.Element> {
-
- // The default implementation of `_copyToContiguousArray` queries the
- // `count` property, which evaluates `_predicate` for every element --
- // see the note above `underestimatedCount`. Here we treat `self` as a
- // sequence and only rely on underestimated count.
- return _copySequenceToContiguousArray(self)
- }
-
- /// Returns an iterator over the elements of this sequence.
- ///
- /// - Complexity: O(1).
- @_inlineable // FIXME(sil-serialize-all)
- public func makeIterator() -> LazyFilterIterator<Base.Iterator> {
- return LazyFilterIterator(
- _base: _base.makeIterator(), _predicate)
- }
-
- @_versioned // FIXME(sil-serialize-all)
- internal var _base: Base
- @_versioned // FIXME(sil-serialize-all)
- internal let _predicate: (Base.Element) -> Bool
}
-% end
-
extension LazySequenceProtocol {
/// Returns the elements of `self` that satisfy `isIncluded`.
///
@@ -303,20 +363,11 @@
public func filter(
_ isIncluded: @escaping (Elements.Element) -> Bool
) -> LazyFilterSequence<Self.Elements> {
- return LazyFilterSequence(
- _base: self.elements, isIncluded)
+ return LazyFilterSequence(_base: self.elements, isIncluded)
}
}
-% for Traversal in ['Forward', 'Bidirectional']:
-
-extension LazyCollectionProtocol
-% if Traversal != 'Forward':
- where
- Self : ${collectionForTraversal(Traversal)},
- Elements : ${collectionForTraversal(Traversal)}
-% end
-{
+extension LazyCollectionProtocol {
/// Returns the elements of `self` that satisfy `predicate`.
///
/// - Note: The elements of the result are computed on-demand, as
@@ -326,14 +377,10 @@
@_inlineable // FIXME(sil-serialize-all)
public func filter(
_ isIncluded: @escaping (Elements.Element) -> Bool
- ) -> LazyFilter${collectionForTraversal(Traversal)}<Self.Elements> {
- return LazyFilter${collectionForTraversal(Traversal)}(
- _base: self.elements, isIncluded)
+ ) -> LazyFilterCollection<Self.Elements> {
+ return LazyFilterCollection(_base: self.elements, isIncluded)
}
}
-% end
-
-// ${'Local Variables'}:
-// eval: (read-only-mode 1)
-// End:
+@available(*, deprecated, renamed: "LazyFilterCollection")
+public typealias LazyFilterBidirectionalCollection<T> = LazyFilterCollection<T> where T : BidirectionalCollection
diff --git a/stdlib/public/core/FlatMap.swift b/stdlib/public/core/FlatMap.swift
index 61e6483..33b2757 100644
--- a/stdlib/public/core/FlatMap.swift
+++ b/stdlib/public/core/FlatMap.swift
@@ -95,8 +95,7 @@
extension LazyCollectionProtocol
where
Self : BidirectionalCollection,
- Elements : BidirectionalCollection
-{
+ Elements : BidirectionalCollection {
/// Returns the concatenated results of mapping the given transformation over
/// this collection.
///
@@ -111,7 +110,7 @@
_ transform: @escaping (Elements.Element) -> SegmentOfResult
) -> LazyCollection<
FlattenBidirectionalCollection<
- LazyMapBidirectionalCollection<Elements, SegmentOfResult>>> {
+ LazyMapCollection<Elements, SegmentOfResult>>> {
return self.map(transform).joined()
}
@@ -128,9 +127,9 @@
@_inlineable // FIXME(sil-serialize-all)
public func flatMap<ElementOfResult>(
_ transform: @escaping (Elements.Element) -> ElementOfResult?
- ) -> LazyMapBidirectionalCollection<
- LazyFilterBidirectionalCollection<
- LazyMapBidirectionalCollection<Elements, ElementOfResult?>>,
+ ) -> LazyMapCollection<
+ LazyFilterCollection<
+ LazyMapCollection<Elements, ElementOfResult?>>,
ElementOfResult
> {
return self.map(transform).filter { $0 != nil }.map { $0! }
diff --git a/stdlib/public/core/LazyCollection.swift.gyb b/stdlib/public/core/LazyCollection.swift.gyb
index 2ea4e0c..c50d741 100644
--- a/stdlib/public/core/LazyCollection.swift.gyb
+++ b/stdlib/public/core/LazyCollection.swift.gyb
@@ -38,18 +38,13 @@
public var elements: Self { return self }
}
-% for Traversal in TRAVERSALS:
-% TraversalCollection = collectionForTraversal(Traversal)
-% Self = 'Lazy' + TraversalCollection
-% Slice = TraversalCollection.replace('Collection', 'Slice')
-
/// A collection containing the same elements as a `Base` collection,
/// but on which some operations such as `map` and `filter` are
/// implemented lazily.
///
/// - See also: `LazySequenceProtocol`, `LazyCollection`
@_fixed_layout
-public struct ${Self}<Base : ${TraversalCollection}> : LazyCollectionProtocol {
+public struct LazyCollection<Base : Collection> : LazyCollectionProtocol {
/// The type of the underlying collection.
public typealias Elements = Base
@@ -78,7 +73,7 @@
/// Forward implementations to the base collection, to pick up any
/// optimizations it might implement.
-extension ${Self} : Sequence {
+extension LazyCollection : Sequence {
public typealias Iterator = Base.Iterator
@@ -118,7 +113,7 @@
}
}
-extension ${Self} : ${TraversalCollection} {
+extension LazyCollection : Collection {
/// The position of the first element in a non-empty collection.
///
/// In an empty collection, `startIndex == endIndex`.
@@ -162,7 +157,7 @@
///
/// - Complexity: O(1)
@_inlineable
- public subscript(bounds: Range<Index>) -> Slice<${Self}<Base>> {
+ public subscript(bounds: Range<Index>) -> Slice<LazyCollection<Base>> {
return Slice(base: self, bounds: bounds)
}
@@ -226,8 +221,10 @@
return _base.distance(from:start, to: end)
}
-% if Traversal != 'Forward':
+}
+extension LazyCollection : BidirectionalCollection
+ where Base : BidirectionalCollection {
@_inlineable
public func index(before i: Base.Index) -> Base.Index {
return _base.index(before: i)
@@ -237,11 +234,13 @@
public var last: Base.Element? {
return _base.last
}
-% end
}
+extension LazyCollection : RandomAccessCollection
+ where Base : RandomAccessCollection {}
+
/// Augment `self` with lazy methods such as `map`, `filter`, etc.
-extension ${TraversalCollection} {
+extension Collection {
/// A view onto this collection that provides lazy implementations of
/// normally eager operations, such as `map` and `filter`.
///
@@ -249,11 +248,13 @@
/// intermediate operations from allocating storage, or when you only
/// need a part of the final collection to avoid unnecessary computation.
@_inlineable
- public var lazy: ${Self}<Self> {
- return ${Self}(_base: self)
+ public var lazy: LazyCollection<Self> {
+ return LazyCollection(_base: self)
}
}
+% for Traversal in TRAVERSALS:
+% TraversalCollection = collectionForTraversal(Traversal)
// Without this specific overload the non-re-wrapping extension on
// LazyCollectionProtocol (below) is not selected for some reason.
extension ${TraversalCollection} where Self : LazyCollectionProtocol {
@@ -263,12 +264,15 @@
return self
}
}
-
% end
extension Slice: LazySequenceProtocol where Base: LazySequenceProtocol { }
extension Slice: LazyCollectionProtocol where Base: LazyCollectionProtocol { }
+@available(*, deprecated, renamed: "LazyCollection")
+public typealias LazyBidirectionalCollection<T> = LazyCollection<T> where T : BidirectionalCollection
+@available(*, deprecated, renamed: "LazyCollection")
+public typealias LazyRandomAccessCollection<T> = LazyCollection<T> where T : RandomAccessCollection
// ${'Local Variables'}:
// eval: (read-only-mode 1)
// End:
diff --git a/stdlib/public/core/Map.swift.gyb b/stdlib/public/core/Map.swift
similarity index 85%
rename from stdlib/public/core/Map.swift.gyb
rename to stdlib/public/core/Map.swift
index 1a73442..a8a0d90 100644
--- a/stdlib/public/core/Map.swift.gyb
+++ b/stdlib/public/core/Map.swift
@@ -1,4 +1,4 @@
-//===--- Map.swift.gyb - Lazily map over a Sequence -----------*- swift -*-===//
+//===--- Map.swift - Lazily map over a Sequence ---------------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
@@ -10,13 +10,6 @@
//
//===----------------------------------------------------------------------===//
-%{
-from gyb_stdlib_support import (
- TRAVERSALS,
- collectionForTraversal
-)
-}%
-
/// The `IteratorProtocol` used by `MapSequence` and `MapCollection`.
/// Produces each element by passing the output of the `Base`
/// `IteratorProtocol` through a transform function returning `Element`.
@@ -96,22 +89,14 @@
//===--- Collections ------------------------------------------------------===//
-// FIXME(ABI)#45 (Conditional Conformance): `LazyMap*Collection` types should be
-// collapsed into one `LazyMapCollection` using conditional conformances.
-// Maybe even combined with `LazyMapSequence`.
-// rdar://problem/17144340
-
-% for Traversal in TRAVERSALS:
-% Self = "LazyMap" + collectionForTraversal(Traversal)
-
/// A `Collection` whose elements consist of those in a `Base`
/// `Collection` passed through a transform function returning `Element`.
/// These elements are computed lazily, each time they're read, by
/// calling the transform function on a base element.
@_fixed_layout
-public struct ${Self}<
- Base : ${collectionForTraversal(Traversal)}, Element
-> : LazyCollectionProtocol, ${collectionForTraversal(Traversal)} {
+public struct LazyMapCollection<
+ Base : Collection, Element
+> : LazyCollectionProtocol, Collection {
// FIXME(compiler limitation): should be inferable.
public typealias Index = Base.Index
@@ -129,16 +114,6 @@
_base.formIndex(after: &i)
}
-% if Traversal in ['Bidirectional', 'RandomAccess']:
- @_inlineable
- public func index(before i: Index) -> Index { return _base.index(before: i) }
-
- @_inlineable
- public func formIndex(before i: inout Index) {
- _base.formIndex(before: &i)
- }
-% end
-
/// Accesses the element at `position`.
///
/// - Precondition: `position` is a valid position in `self` and
@@ -148,7 +123,7 @@
return _transform(_base[position])
}
- public typealias SubSequence = ${Self}<Base.SubSequence, Element>
+ public typealias SubSequence = LazyMapCollection<Base.SubSequence, Element>
@_inlineable
public subscript(bounds: Range<Base.Index>) -> SubSequence {
@@ -183,11 +158,6 @@
@_inlineable
public var first: Element? { return _base.first.map(_transform) }
-% if Traversal in ['Bidirectional', 'RandomAccess']:
- @_inlineable
- public var last: Element? { return _base.last.map(_transform) }
-% end
-
@_inlineable
public func index(_ i: Index, offsetBy n: Int) -> Index {
return _base.index(i, offsetBy: n)
@@ -233,7 +203,24 @@
internal let _transform: (Base.Element) -> Element
}
-% end
+extension LazyMapCollection : BidirectionalCollection
+ where Base : BidirectionalCollection {
+
+ @_inlineable
+ public func index(before i: Index) -> Index { return _base.index(before: i) }
+
+ @_inlineable
+ public func formIndex(before i: inout Index) {
+ _base.formIndex(before: &i)
+ }
+
+ @_inlineable
+ public var last: Element? { return _base.last.map(_transform) }
+}
+
+extension LazyMapCollection : RandomAccessCollection
+ where Base : RandomAccessCollection {}
+
//===--- Support for s.lazy -----------------------------------------------===//
@@ -249,30 +236,18 @@
}
}
-% for Traversal in TRAVERSALS:
-
-extension LazyCollectionProtocol
-% if Traversal != 'Forward':
- where
- Self : ${collectionForTraversal(Traversal)},
- Elements : ${collectionForTraversal(Traversal)}
-% end
-{
+extension LazyCollectionProtocol {
/// Returns a `LazyMapCollection` over this `Collection`. The elements of
/// the result are computed lazily, each time they are read, by
/// calling `transform` function on a base element.
@_inlineable
public func map<U>(
_ transform: @escaping (Elements.Element) -> U
- ) -> LazyMap${collectionForTraversal(Traversal)}<Self.Elements, U> {
- return LazyMap${collectionForTraversal(Traversal)}(
- _base: self.elements,
- transform: transform)
+ ) -> LazyMapCollection<Self.Elements, U> {
+ return LazyMapCollection(_base: self.elements, transform: transform)
}
}
-% end
-
extension LazyMapCollection {
// This overload is needed to re-enable Swift 3 source compatibility related
// to a bugfix in ranking behavior of the constraint solver.
@@ -289,6 +264,7 @@
}
}
-// ${'Local Variables'}:
-// eval: (read-only-mode 1)
-// End:
+@available(*, deprecated, renamed: "LazyMapCollection")
+public typealias LazyMapBidirectionalCollection<T, E> = LazyMapCollection<T, E> where T : BidirectionalCollection
+@available(*, deprecated, renamed: "LazyMapCollection")
+public typealias LazyMapRandomAccessCollection<T, E> = LazyMapCollection<T, E> where T : RandomAccessCollection
diff --git a/stdlib/public/core/Reverse.swift b/stdlib/public/core/Reverse.swift
index f9303ad..da7c0c9 100644
--- a/stdlib/public/core/Reverse.swift
+++ b/stdlib/public/core/Reverse.swift
@@ -312,25 +312,7 @@
///
/// - Complexity: O(1)
@_inlineable
- public func reversed() -> LazyBidirectionalCollection<
- ReversedCollection<Elements>
- > {
- return ReversedCollection(_base: elements).lazy
- }
-}
-
-extension LazyCollectionProtocol
- where
- Self : RandomAccessCollection,
- Elements : RandomAccessCollection {
-
- /// Returns the elements of the collection in reverse order.
- ///
- /// - Complexity: O(1)
- @_inlineable
- public func reversed() -> LazyRandomAccessCollection<
- ReversedCollection<Elements>
- > {
+ public func reversed() -> LazyCollection<ReversedCollection<Elements>> {
return ReversedCollection(_base: elements).lazy
}
}
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 4ef9cd2..cff3ad2 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -137,13 +137,23 @@
ClassMetadata *
swift::swift_allocateGenericClassMetadata(GenericMetadata *pattern,
const void *arguments,
- ClassMetadata *superclass) {
+ ClassMetadata *superclass,
+ size_t numImmediateMembers) {
void * const *argumentsAsArray = reinterpret_cast<void * const *>(arguments);
size_t numGenericArguments = pattern->NumKeyArguments;
- size_t metadataSize = pattern->MetadataSize;
+ size_t metadataSize;
if (superclass && superclass->isTypeMetadata()) {
assert(superclass->getClassAddressPoint() <= pattern->AddressPoint);
+
+ metadataSize = (superclass->getClassSize() -
+ superclass->getClassAddressPoint() +
+ pattern->AddressPoint +
+ numImmediateMembers * sizeof(void *));
+ assert(pattern->TemplateSize <= metadataSize);
+ } else {
+ metadataSize = (pattern->TemplateSize +
+ numImmediateMembers * sizeof(void *));
}
char *bytes = GenericCacheEntry::allocate(
@@ -153,7 +163,11 @@
metadataSize)->getData<char>();
// Copy in the metadata template.
- memcpy(bytes, pattern->getMetadataTemplate(), pattern->MetadataSize);
+ memcpy(bytes, pattern->getMetadataTemplate(), pattern->TemplateSize);
+
+ // Zero out the rest of the metadata.
+ memset(bytes + pattern->TemplateSize, 0,
+ metadataSize - pattern->TemplateSize);
// Okay, move to the address point.
bytes += pattern->AddressPoint;
@@ -188,10 +202,10 @@
GenericCacheEntry::allocate(
unsafeGetInitializedCache(pattern).getAllocator(),
argumentsAsArray, numGenericArguments,
- pattern->MetadataSize)->getData<char>();
+ pattern->TemplateSize)->getData<char>();
// Copy in the metadata template.
- memcpy(bytes, pattern->getMetadataTemplate(), pattern->MetadataSize);
+ memcpy(bytes, pattern->getMetadataTemplate(), pattern->TemplateSize);
// Okay, move to the address point.
bytes += pattern->AddressPoint;
@@ -1465,6 +1479,42 @@
}
#endif
+ClassMetadata *
+swift::swift_relocateClassMetadata(ClassMetadata *self,
+ size_t templateSize,
+ size_t numImmediateMembers) {
+ const ClassMetadata *superclass = self->SuperClass;
+
+ size_t metadataSize;
+ if (superclass && superclass->isTypeMetadata()) {
+ metadataSize = (superclass->getClassSize() -
+ superclass->getClassAddressPoint() +
+ self->getClassAddressPoint() +
+ numImmediateMembers * sizeof(void *));
+ } else {
+ metadataSize = (templateSize +
+ numImmediateMembers * sizeof(void *));
+ }
+
+ if (templateSize < metadataSize) {
+ auto rawNewClass = (char*) malloc(metadataSize);
+ auto rawOldClass = (const char*) self;
+ rawOldClass -= self->getClassAddressPoint();
+
+ memcpy(rawNewClass, rawOldClass, templateSize);
+ memset(rawNewClass + templateSize, 0,
+ metadataSize - templateSize);
+
+ rawNewClass += self->getClassAddressPoint();
+ auto *newClass = (ClassMetadata *) rawNewClass;
+ assert(newClass->isTypeMetadata());
+
+ return newClass;
+ }
+
+ return self;
+}
+
/// Initialize the field offset vector for a dependent-layout class, using the
/// "Universal" layout strategy.
void
diff --git a/test/Compatibility/tuple_arguments.swift b/test/Compatibility/tuple_arguments.swift
index 531669d..957e1b5 100644
--- a/test/Compatibility/tuple_arguments.swift
+++ b/test/Compatibility/tuple_arguments.swift
@@ -1493,3 +1493,17 @@
func bar() -> ((()) -> Void)? { return nil }
foo(bar()) // OK in Swift 3 mode
}
+
+// https://bugs.swift.org/browse/SR-6509
+public extension Optional {
+ public func apply<Result>(_ transform: ((Wrapped) -> Result)?) -> Result? {
+ return self.flatMap { value in
+ transform.map { $0(value) }
+ }
+ }
+
+ public func apply<Value, Result>(_ value: Value?) -> Result?
+ where Wrapped == (Value) -> Result {
+ return value.apply(self)
+ }
+}
diff --git a/test/Constraints/tuple_arguments.swift b/test/Constraints/tuple_arguments.swift
index d6336bb..48c5e10 100644
--- a/test/Constraints/tuple_arguments.swift
+++ b/test/Constraints/tuple_arguments.swift
@@ -1628,3 +1628,17 @@
func bar() -> ((()) -> Void)? { return nil }
foo(bar()) // expected-error {{cannot convert value of type '((()) -> Void)?' to expected argument type '(() -> Void)?'}}
}
+
+// https://bugs.swift.org/browse/SR-6509
+public extension Optional {
+ public func apply<Result>(_ transform: ((Wrapped) -> Result)?) -> Result? {
+ return self.flatMap { value in
+ transform.map { $0(value) }
+ }
+ }
+
+ public func apply<Value, Result>(_ value: Value?) -> Result?
+ where Wrapped == (Value) -> Result {
+ return value.apply(self)
+ }
+}
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index e1a3c3a..1c8aa3b 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -241,29 +241,33 @@
// CHECK-LABEL: define{{( protected)?}} private void @initialize_metadata_ClassWithResilientProperty
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata({{.*}}, [[INT]] {{60|96}}, [[INT]] 4)
// CHECK: [[SIZE_METADATA:%.*]] = call %swift.type* @_T016resilient_struct4SizeVMa()
-// CHECK: call void @swift_initClassMetadata_UniversalStrategy(
-// CHECK-native: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* {{.*}}, [[INT]] {{12|15}}
+// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], [[INT]] 3, {{.*}})
+// CHECK-native: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to [[INT]]*
+// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_PTR]], [[INT]] {{12|15}}
// CHECK-native-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]]
// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @_T016class_resilience26ClassWithResilientPropertyC1s16resilient_struct4SizeVvWvd
-// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* {{.*}}, [[INT]] {{13|16}}
+// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_PTR]], [[INT]] {{13|16}}
// CHECK-native-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]]
// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @_T016class_resilience26ClassWithResilientPropertyC5colors5Int32VvWvd
-// CHECK: store atomic %swift.type* {{.*}}, %swift.type** @_T016class_resilience26ClassWithResilientPropertyCML release,
+// CHECK: store atomic %swift.type* [[METADATA]], %swift.type** @_T016class_resilience26ClassWithResilientPropertyCML release,
// CHECK: ret void
// ClassWithResilientlySizedProperty metadata initialization function
// CHECK-LABEL: define{{( protected)?}} private void @initialize_metadata_ClassWithResilientlySizedProperty
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata({{.*}}, [[INT]] {{60|96}}, [[INT]] 3)
// CHECK: [[RECTANGLE_METADATA:%.*]] = call %swift.type* @_T016resilient_struct9RectangleVMa()
-// CHECK: call void @swift_initClassMetadata_UniversalStrategy(
-// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* {{.*}}, [[INT]] {{11|14}}
+// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], [[INT]] 2, {{.*}})
+// CHECK-native: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to [[INT]]*
+// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_PTR]], [[INT]] {{11|14}}
// CHECK-native-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]]
// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @_T016class_resilience33ClassWithResilientlySizedPropertyC1r16resilient_struct9RectangleVvWvd
-// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* {{.*}}, [[INT]] {{12|15}}
+// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_PTR]], [[INT]] {{12|15}}
// CHECK-native-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]]
// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @_T016class_resilience33ClassWithResilientlySizedPropertyC5colors5Int32VvWvd
-// CHECK: store atomic %swift.type* {{.*}}, %swift.type** @_T016class_resilience33ClassWithResilientlySizedPropertyCML release,
+// CHECK: store atomic %swift.type* [[METADATA]], %swift.type** @_T016class_resilience33ClassWithResilientlySizedPropertyCML release,
// CHECK: ret void
diff --git a/test/IRGen/concrete_inherits_generic_base.swift b/test/IRGen/concrete_inherits_generic_base.swift
index 24d521d..ab2be08 100644
--- a/test/IRGen/concrete_inherits_generic_base.swift
+++ b/test/IRGen/concrete_inherits_generic_base.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -module-name foo -emit-ir %s | %FileCheck %s
+// RUN: %target-swift-frontend -module-name foo -emit-ir %s | %FileCheck %s
// CHECK: %swift.type = type { [[INT:i32|i64]] }
@@ -74,6 +74,7 @@
// CHECK-LABEL: define{{( protected)?}} private void @initialize_metadata_SuperDerived(i8*)
// CHECK: [[TMP:%.*]] = call %swift.type* @_T03foo7DerivedCMa()
// CHECK-NEXT: store %swift.type* [[TMP]], %swift.type** getelementptr inbounds ({{.*}} @_T03foo12SuperDerivedCMf{{.*}}, i32 1), align
-// CHECK: call void @swift_initClassMetadata_UniversalStrategy(
-// CHECK: store atomic %swift.type* {{.*}}, %swift.type** @_T03foo12SuperDerivedCML release,
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata({{.*}}, [[INT]] {{60|96}}, [[INT]] 0)
+// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], [[INT]] 0, {{.*}})
+// CHECK: store atomic %swift.type* [[METADATA]], %swift.type** @_T03foo12SuperDerivedCML release,
// CHECK: ret void
diff --git a/test/IRGen/field_type_vectors.sil b/test/IRGen/field_type_vectors.sil
index cef0685..82b7638 100644
--- a/test/IRGen/field_type_vectors.sil
+++ b/test/IRGen/field_type_vectors.sil
@@ -36,7 +36,7 @@
// CHECK-LABEL: @_T018field_type_vectors3ZimCMP = internal global
// -- There should be 1 word between the field type vector slot, with type %swift.type**,
// and the address point
-// CHECK: %swift.type**, i8*, i8**, i64, %swift.type*, %swift.opaque*, %swift.opaque*, i64, i32, i32, i32, i16, i16, i32, i32, <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i32, i32, i32, %swift.method_descriptor }>*, i8*, %swift.type*, %swift.type*, i8*, i64, i64, i64
+// CHECK: %swift.type**, i8*, i8**, i64, %swift.type*, %swift.opaque*, %swift.opaque*, i64, i32, i32, i32, i16, i16, i32, i32, <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i32, i32, i32, %swift.method_descriptor }>*, i8*
class Zim<T, U> {
var foo: Foo?
var bar: Bar<T>?
@@ -51,7 +51,7 @@
// CHECK-LABEL: @_T018field_type_vectors4ZangCMP = internal global
// -- There should be 1 word between the field type vector slot, with type %swift.type**,
// and the address point
-// CHECK: %swift.type**, i8*, i8**, i64, %swift.type*, %swift.opaque*, %swift.opaque*, i64, i32, i32, i32, i16, i16, i32, i32, <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i32 }>*, i8*, %swift.type*, %swift.type*, i8*, i64, i64, i64, %swift.type*, i64
+// CHECK: %swift.type**, i8*, i8**, i64, %swift.type*, %swift.opaque*, %swift.opaque*, i64, i32, i32, i32, i16, i16, i32, i32, <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i32 }>*, i8*
class Zang<V>: Zim<V, V> {
var zung: Int = 0
}
diff --git a/test/IRGen/generic_classes.sil b/test/IRGen/generic_classes.sil
index 33a83e7..20aa1e4 100644
--- a/test/IRGen/generic_classes.sil
+++ b/test/IRGen/generic_classes.sil
@@ -12,7 +12,9 @@
// FIXME: Strings should be unnamed_addr. rdar://problem/22674524
// CHECK: [[ROOTGENERIC_NAME:@.*]] = private constant [32 x i8] c"15generic_classes11RootGenericC\00"
// CHECK: [[ROOTGENERIC_FIELDS:@.*]] = private constant [7 x i8] c"x\00y\00z\00\00"
-// CHECK: @_T015generic_classes11RootGenericCMn = hidden constant <{ {{.*}} %swift.method_descriptor }> <{
+
+// CHECK-LABEL: @_T015generic_classes11RootGenericCMn =
+// CHECK-SAME: hidden constant <{ {{.*}} %swift.method_descriptor }> <{
// -- name
// CHECK-SAME: [32 x i8]* [[ROOTGENERIC_NAME]]
// -- num fields
@@ -38,17 +40,14 @@
// -- vtable size
// CHECK-SAME: i32 4
// CHECK-SAME: }
-// CHECK: @_T015generic_classes11RootGenericCMP = internal global
+
+// CHECK-LABEL: @_T015generic_classes11RootGenericCMP = internal global
// -- template fill function
// CHECK-SAME: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_RootGeneric
// -- nominal type descriptor
// CHECK-SAME: @_T015generic_classes11RootGenericCMn
-// -- vtable
-// CHECK-SAME: i8* null,
-// CHECK-SAME: i8* null,
-// CHECK-SAME: i8* null,
-// -- field offset placeholders
-// CHECK-SAME: i64 0, i64 0, i64 0
+// -- ivar destroyer
+// CHECK-SAME: i8* null
// CHECK-SAME: }>
// -- Check that offset vars are emitted for fixed-layout generics
@@ -98,18 +97,10 @@
// CHECK: @_T015generic_classes015GenericInheritsC0CMP = internal global
// -- template fill function
// CHECK-SAME: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_GenericInheritsGeneric
-// -- RootGeneric vtable
-// CHECK-SAME: i8* null,
-// CHECK-SAME: i8* null,
-// CHECK-SAME: i8* null,
-// -- RootGeneric field offset placeholders
-// CHECK-SAME: i64 0, i64 0, i64 0
-// -- GenericInheritsGeneric vtable
-// CHECK-SAME: i8* null,
-// CHECK-SAME: i8* null,
-// CHECK-SAME: i8* null,
-// -- GenericInheritsGeneric field offset placeholder
-// CHECK-SAME: i64 0
+// -- nominal type descriptor
+// CHECK-SAME: @_T015generic_classes015GenericInheritsC0CMn,
+// -- ivar destroyer
+// CHECK-SAME: i8* null
// CHECK-SAME: }
// CHECK: @_T015generic_classes018GenericInheritsNonC0CMP
@@ -311,12 +302,14 @@
*/
// CHECK: define{{( protected)?}} private %swift.type* @create_generic_metadata_RootGeneric(%swift.type_pattern*, i8**) {{.*}} {
+// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, {{.*}}, i64 8)
// -- initialize the dependent field offsets
-// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* {{%.*}}, i64 3, i8*** {{%.*}}, i64* {{%.*}})
+// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}})
// CHECK: }
// CHECK: define{{( protected)?}} private %swift.type* @create_generic_metadata_RootGenericFixedLayout(%swift.type_pattern*, i8**) {{.*}} {
-// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* {{%.*}}, i64 3, i8*** {{%.*}}, i64* {{%.*}})
+// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, {{.*}}, i64 5)
+// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}})
// CHECK: }
// CHECK: define{{( protected)?}} private %swift.type* @create_generic_metadata_GenericInheritsGeneric(%swift.type_pattern*, i8**) {{.*}} {
@@ -328,7 +321,7 @@
// Construct the superclass.
// CHECK: [[SUPER:%.*]] = call %swift.type* @_T015generic_classes11RootGenericCMa(%swift.type* %A)
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[SUPER]] to %objc_class*
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[T0]])
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[T0]], i64 6)
// CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
// Put the generic arguments in their correct positions.
// CHECK: [[A_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i32 18
diff --git a/test/IRGen/generic_types.swift b/test/IRGen/generic_types.swift
index 1ea2737..bf3eb6f 100644
--- a/test/IRGen/generic_types.swift
+++ b/test/IRGen/generic_types.swift
@@ -10,8 +10,8 @@
// CHECK-LABEL: @_T013generic_types1ACMP = internal global
// CHECK: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_A,
-// CHECK-native-SAME: i32 160,
-// CHECK-objc-SAME: i32 344,
+// CHECK-native-SAME: i32 104,
+// CHECK-objc-SAME: i32 288,
// CHECK-SAME: i16 1,
// CHECK-native-SAME: i16 24,
// CHECK-objc-SAME: i16 208,
@@ -31,14 +31,16 @@
// CHECK-SAME: i16 0,
// CHECK-SAME: i32 152,
// CHECK-SAME: i32 16,
-// CHECK-SAME: i8* null,
-// CHECK-SAME: i8* null,
+// -- nominal type descriptor
+// CHECK-SAME: @_T013generic_types1ACMn,
+// -- ivar destroyer
// CHECK-SAME: i8* null
// CHECK-SAME: }
+
// CHECK-LABEL: @_T013generic_types1BCMP = internal global
// CHECK-SAME: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_B,
-// CHECK-native-SAME: i32 152,
-// CHECK-objc-SAME: i32 336,
+// CHECK-native-SAME: i32 104,
+// CHECK-objc-SAME: i32 288,
// CHECK-SAME: i16 1,
// CHECK-native-SAME: i16 24,
// CHECK-objc-SAME: i16 208,
@@ -58,8 +60,12 @@
// CHECK-SAME: i16 0,
// CHECK-SAME: i32 144,
// CHECK-SAME: i32 16,
-// CHECK-SAME: %swift.type* null
+// -- nominal type descriptor
+// CHECK-SAME: @_T013generic_types1BCMn,
+// -- ivar destroyer
+// CHECK-SAME: i8* null
// CHECK-SAME: }
+
// CHECK-LABEL: @_T013generic_types1CCMP = internal global
// CHECK-SAME: void ([[C]]*)* @_T013generic_types1CCfD,
// CHECK-SAME: i8** @_T0BoWV,
@@ -69,7 +75,19 @@
// CHECK-objc-SAME: %swift.opaque* @_objc_empty_cache,
// CHECK-SAME: %swift.opaque* null,
// CHECK-SAME: i64 1,
+// CHECK-SAME: i32 3,
+// CHECK-SAME: i32 0,
+// CHECK-SAME: i32 24,
+// CHECK-SAME: i16 7,
+// CHECK-SAME: i16 0,
+// CHECK-SAME: i32 160,
+// CHECK-SAME: i32 16,
+// -- nominal type descriptor
+// CHECK-SAME: @_T013generic_types1CCMn,
+// -- ivar destroyer
+// CHECK-SAME: i8* null
// CHECK-SAME: }
+
// CHECK-LABEL: @_T013generic_types1DCMP = internal global
// CHECK-SAME: void ([[D]]*)* @_T013generic_types1DCfD,
// CHECK-SAME: i8** @_T0BoWV,
@@ -79,15 +97,26 @@
// CHECK-objc-SAME: %swift.opaque* @_objc_empty_cache,
// CHECK-SAME: %swift.opaque* null,
// CHECK-SAME: i64 1,
+// CHECK-SAME: i32 3,
+// CHECK-SAME: i32 0,
+// CHECK-SAME: i32 24,
+// CHECK-SAME: i16 7,
+// CHECK-SAME: i16 0,
+// CHECK-SAME: i32 160,
+// CHECK-SAME: i32 16,
+// -- nominal type descriptor
+// CHECK-SAME: @_T013generic_types1DCMn,
+// -- ivar destroyer
+// CHECK-SAME: i8* null
// CHECK-SAME: }
// CHECK-LABEL: define{{( protected)?}} private %swift.type* @create_generic_metadata_A(%swift.type_pattern*, i8**) {{.*}} {
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: %T = load %swift.type*, %swift.type** [[T0]],
-// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* null)
+// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* null, i64 7)
// CHECK-objc: [[T0:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_SwiftObject"
// CHECK-objc: [[SUPER:%.*]] = call %objc_class* @swift_rt_swift_getInitializedObjCClass(%objc_class* [[T0]])
-// CHECK-objc: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER]])
+// CHECK-objc: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER]], i64 7)
// CHECK: [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
// CHECK: [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 10
// CHECK: [[T0:%.*]] = bitcast %swift.type* %T to i8*
@@ -98,10 +127,10 @@
// CHECK-LABEL: define{{( protected)?}} private %swift.type* @create_generic_metadata_B(%swift.type_pattern*, i8**) {{.*}} {
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: %T = load %swift.type*, %swift.type** [[T0]],
-// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* null)
+// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* null, i64 6)
// CHECK-objc: [[T0:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_SwiftObject"
// CHECK-objc: [[SUPER:%.*]] = call %objc_class* @swift_rt_swift_getInitializedObjCClass(%objc_class* [[T0]])
-// CHECK-objc: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER]])
+// CHECK-objc: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER]], i64 6)
// CHECK: [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
// CHECK: [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 10
// CHECK: [[T0:%.*]] = bitcast %swift.type* %T to i8*
diff --git a/test/IRGen/generic_vtable.swift b/test/IRGen/generic_vtable.swift
index 026dcef..70758b1 100644
--- a/test/IRGen/generic_vtable.swift
+++ b/test/IRGen/generic_vtable.swift
@@ -68,17 +68,13 @@
//// Type metadata pattern for 'Derived' has an empty vtable, filled in at
//// instantiation time.
-// CHECK-LABEL: @_T014generic_vtable7DerivedCMP = internal global
-// -- vtable entry for 'm1()'
-// CHECK-SAME: i8* null,
-// -- vtable entry for 'm2()'
-// CHECK-SAME: i8* null,
-// -- vtable entry for 'init()'
-// CHECK-SAME: i8* null,
-// -- vtable entry for 'm3()'
+// CHECK-LABEL: @_T014generic_vtable7DerivedCMP = internal global <{{.*}}> <{
+// -- nominal type descriptor
+// CHECK-SAME: @_T014generic_vtable7DerivedCMn,
+// -- ivar destroyer
// CHECK-SAME: i8* null
// --
-// CHECK-SAME: , align 8
+// CHECK-SAME: }>, align 8
//// Nominal type descriptor for 'Concrete' has method descriptors.
@@ -99,37 +95,39 @@
// --
// CHECK-SAME: section "{{.*}}", align 8
-//// Type metadata for 'Concrete' has an empty vtable, filled in at
-//// initialization time.
+//// Type metadata for 'Concrete' does not have any vtable entries; the vtable is
+//// filled in at initialization time.
-// CHECK-LABEL: @_T014generic_vtable8ConcreteCMf = internal global
-// -- vtable entry for 'm1()'
-// CHECK-SAME: i8* null,
-// -- vtable entry for 'm2()'
-// CHECK-SAME: i8* null,
-// -- vtable entry for 'init()'
-// CHECK-SAME: i8* null,
-// -- vtable entry for 'm3()'
-// CHECK-SAME: i8* null,
-// -- vtable entry for 'm4()'
+// CHECK-LABEL: @_T014generic_vtable8ConcreteCMf = internal global <{{.*}}> <{
+// -- nominal type descriptor
+// CHECK-SAME: @_T014generic_vtable8ConcreteCMn,
+// -- ivar destroyer
// CHECK-SAME: i8* null
// --
-// CHECK-SAME: , align 8
+// CHECK-SAME: }>, align 8
//// Metadata initialization function for 'Derived' copies superclass vtable
//// and installs overrides for 'm2()' and 'init()'.
// CHECK-LABEL: define private %swift.type* @create_generic_metadata_Derived(%swift.type_pattern*, i8**)
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata({{.*}})
-// CHECK: call void @swift_initClassMetadata_UniversalStrategy({{.*}})
+
+// - 2 immediate members:
+// - type metadata for generic parameter T,
+// - and vtable entry for 'm3()'
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, {{.*}}, i64 2)
+
+// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 0, {{.*}})
+
// -- method override for 'm2()'
// CHECK: [[WORDS:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
// CHECK: [[VTABLE0:%.*]] = getelementptr inbounds i8*, i8** [[WORDS]], i32 11
// CHECK: store i8* bitcast (void (%T14generic_vtable7DerivedC*)* @_T014generic_vtable7DerivedC2m2yyF to i8*), i8** [[VTABLE0]], align 8
+
// -- method override for 'init()'
// CHECK: [[VTABLE1:%.*]] = getelementptr inbounds i8*, i8** [[WORDS]], i32 12
// CHECK: store i8* bitcast (%T14generic_vtable7DerivedC* (%T14generic_vtable7DerivedC*)* @_T014generic_vtable7DerivedCACyxGycfc to i8*), i8** [[VTABLE1]], align 8
+
// CHECK: ret %swift.type* [[METADATA]]
@@ -139,9 +137,14 @@
// CHECK-LABEL: define private void @initialize_metadata_Concrete(i8*)
// CHECK: [[SUPERCLASS:%.*]] = call %swift.type* @_T014generic_vtable7DerivedCySiGMa()
// CHECK: store %swift.type* [[SUPERCLASS]], %swift.type** getelementptr inbounds {{.*}} @_T014generic_vtable8ConcreteCMf
-// CHECK: call void @swift_initClassMetadata_UniversalStrategy({{.*}})
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata({{.*}}, i64 96, i64 1)
+// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 0, {{.*}})
+
// -- method override for 'init()'
// CHECK: store i8* bitcast (%T14generic_vtable8ConcreteC* (%T14generic_vtable8ConcreteC*)* @_T014generic_vtable8ConcreteCACycfc to i8*), i8**
+
// -- method override for 'm3()'
// CHECK: store i8* bitcast (void (%T14generic_vtable8ConcreteC*)* @_T014generic_vtable8ConcreteC2m3yyF to i8*), i8**
+
+// CHECK: store atomic %swift.type* [[METADATA]], %swift.type** @_T014generic_vtable8ConcreteCML release, align 8
// CHECK: ret void
diff --git a/test/SILGen/protocol_extensions.swift b/test/SILGen/protocol_extensions.swift
index 37d1fbc..6920b92 100644
--- a/test/SILGen/protocol_extensions.swift
+++ b/test/SILGen/protocol_extensions.swift
@@ -813,7 +813,7 @@
// rdar://problem/21370992 - delegation from an initializer in a
// protocol extension to an @objc initializer in a class.
class ObjCInitClass {
- @objc init() { }
+ @objc required init() { }
}
protocol ProtoDelegatesToObjC { }
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 6c33bd8..b3790df 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -8,8 +8,8 @@
func bar1<FunctionSignature>(<FunctionParameter>_ a: <SimpleTypeIdentifier>Float</SimpleTypeIdentifier></FunctionParameter>) -> <SimpleTypeIdentifier>Float </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{ <ReturnStmt>return <SequenceExpr><PrefixOperatorExpr>-<FloatLiteralExpr>0.6 </FloatLiteralExpr></PrefixOperatorExpr><BinaryOperatorExpr>+ </BinaryOperatorExpr><FloatLiteralExpr>0.1 </FloatLiteralExpr><BinaryOperatorExpr>- </BinaryOperatorExpr><FloatLiteralExpr>0.3 </FloatLiteralExpr></SequenceExpr></ReturnStmt>}</CodeBlock></FunctionDecl><FunctionDecl>
func bar2<FunctionSignature>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>, </FunctionParameter><FunctionParameter>b: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>, </FunctionParameter><FunctionParameter>c:<SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) -> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></FunctionDecl><FunctionDecl>
func bar3<FunctionSignature>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) -> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></FunctionDecl><FunctionDecl>
- func bar4<FunctionSignature>(<FunctionParameter>_ a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) -> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></FunctionDecl>
- func foo() <CodeBlock>{
+ func bar4<FunctionSignature>(<FunctionParameter>_ a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) -> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></FunctionDecl><FunctionDecl>
+ func foo<FunctionSignature>() </FunctionSignature><CodeBlock>{
var a = <StringLiteralExpr>/*comment*/"ab\(x)c"</StringLiteralExpr>/*comment*/
var b = <PrefixOperatorExpr>/*comment*/+<IntegerLiteralExpr>2</IntegerLiteralExpr></PrefixOperatorExpr><IdentifierExpr>/*comment*/
bar</IdentifierExpr>(<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)<IdentifierExpr>
@@ -19,9 +19,9 @@
bar1</IdentifierExpr>(<FunctionCallArgument><FloatLiteralExpr>1.1</FloatLiteralExpr></FunctionCallArgument>)
var f = <PrefixOperatorExpr>/*comments*/+<FloatLiteralExpr>0.1</FloatLiteralExpr></PrefixOperatorExpr><IdentifierExpr>/*comments*/
foo</IdentifierExpr>()
- }</CodeBlock>
+ }</CodeBlock></FunctionDecl><FunctionDecl>
- func foo1() <CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
+ func foo1<FunctionSignature>() </FunctionSignature><CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>bar2</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>b:<IntegerLiteralExpr>2</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>c:<IntegerLiteralExpr>2</IntegerLiteralExpr></FunctionCallArgument>)</SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>bar2</IdentifierExpr>(<FunctionCallArgument>a:<SequenceExpr><IntegerLiteralExpr>1 </IntegerLiteralExpr><BinaryOperatorExpr>+ </BinaryOperatorExpr><IntegerLiteralExpr>1</IntegerLiteralExpr></SequenceExpr>, </FunctionCallArgument><FunctionCallArgument>b:<SequenceExpr><IntegerLiteralExpr>2 </IntegerLiteralExpr><BinaryOperatorExpr>* </BinaryOperatorExpr><IntegerLiteralExpr>2 </IntegerLiteralExpr><BinaryOperatorExpr>+ </BinaryOperatorExpr><IntegerLiteralExpr>2</IntegerLiteralExpr></SequenceExpr>, </FunctionCallArgument><FunctionCallArgument>c:<SequenceExpr><IntegerLiteralExpr>2 </IntegerLiteralExpr><BinaryOperatorExpr>+ </BinaryOperatorExpr><IntegerLiteralExpr>2</IntegerLiteralExpr></SequenceExpr></FunctionCallArgument>)</SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>bar2</IdentifierExpr>(<FunctionCallArgument>a : <IdentifierExpr>bar2</IdentifierExpr>(<FunctionCallArgument>a: <IntegerLiteralExpr>1</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>b: <IntegerLiteralExpr>2</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>c: <IntegerLiteralExpr>3</IntegerLiteralExpr></FunctionCallArgument>), </FunctionCallArgument><FunctionCallArgument>b: <IntegerLiteralExpr>2</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>c: <IntegerLiteralExpr>3</IntegerLiteralExpr></FunctionCallArgument>)</SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
@@ -32,11 +32,11 @@
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ArrayExpr>[<ArrayElement><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>), </ArrayElement><ArrayElement><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>), </ArrayElement><ArrayElement><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>), </ArrayElement><ArrayElement><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</ArrayElement>]</ArrayExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><DictionaryExpr>[<DictionaryElement><StringLiteralExpr>"a"</StringLiteralExpr>: <IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>), </DictionaryElement><DictionaryElement><StringLiteralExpr>"b"</StringLiteralExpr>: <IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>), </DictionaryElement><DictionaryElement><StringLiteralExpr>"c"</StringLiteralExpr>: <IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>), </DictionaryElement><DictionaryElement><StringLiteralExpr>"d"</StringLiteralExpr>: <IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</DictionaryElement>]</DictionaryExpr></SequenceExpr><IdentifierExpr>
foo</IdentifierExpr>(<FunctionCallArgument><NilLiteralExpr>nil</NilLiteralExpr>, </FunctionCallArgument><FunctionCallArgument><NilLiteralExpr>nil</NilLiteralExpr>, </FunctionCallArgument><FunctionCallArgument><NilLiteralExpr>nil</NilLiteralExpr></FunctionCallArgument>)
- }</CodeBlock>
- func boolAnd() -> <SimpleTypeIdentifier>Bool </SimpleTypeIdentifier><CodeBlock>{ <ReturnStmt>return <SequenceExpr><BooleanLiteralExpr>true </BooleanLiteralExpr><BinaryOperatorExpr>&& </BinaryOperatorExpr><BooleanLiteralExpr>false </BooleanLiteralExpr></SequenceExpr></ReturnStmt>}</CodeBlock>
- func boolOr() -> <SimpleTypeIdentifier>Bool </SimpleTypeIdentifier><CodeBlock>{ <ReturnStmt>return <SequenceExpr><BooleanLiteralExpr>true </BooleanLiteralExpr><BinaryOperatorExpr>|| </BinaryOperatorExpr><BooleanLiteralExpr>false </BooleanLiteralExpr></SequenceExpr></ReturnStmt>}</CodeBlock>
+ }</CodeBlock></FunctionDecl><FunctionDecl>
+ func boolAnd<FunctionSignature>() -> <SimpleTypeIdentifier>Bool </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{ <ReturnStmt>return <SequenceExpr><BooleanLiteralExpr>true </BooleanLiteralExpr><BinaryOperatorExpr>&& </BinaryOperatorExpr><BooleanLiteralExpr>false </BooleanLiteralExpr></SequenceExpr></ReturnStmt>}</CodeBlock></FunctionDecl><FunctionDecl>
+ func boolOr<FunctionSignature>() -> <SimpleTypeIdentifier>Bool </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{ <ReturnStmt>return <SequenceExpr><BooleanLiteralExpr>true </BooleanLiteralExpr><BinaryOperatorExpr>|| </BinaryOperatorExpr><BooleanLiteralExpr>false </BooleanLiteralExpr></SequenceExpr></ReturnStmt>}</CodeBlock></FunctionDecl><FunctionDecl>
- func foo2() <CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
+ func foo2<FunctionSignature>() </FunctionSignature><CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><TernaryExpr><BooleanLiteralExpr>true </BooleanLiteralExpr>? <IntegerLiteralExpr>1 </IntegerLiteralExpr>: <IntegerLiteralExpr>0</IntegerLiteralExpr></TernaryExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><TernaryExpr><TupleExpr>(<TupleElement><SequenceExpr><TernaryExpr><BooleanLiteralExpr>true </BooleanLiteralExpr>? <IntegerLiteralExpr>1 </IntegerLiteralExpr>: <IntegerLiteralExpr>0</IntegerLiteralExpr></TernaryExpr></SequenceExpr></TupleElement>) </TupleExpr>? <TupleExpr>(<TupleElement><SequenceExpr><TernaryExpr><BooleanLiteralExpr>true </BooleanLiteralExpr>? <IntegerLiteralExpr>1 </IntegerLiteralExpr>: <IntegerLiteralExpr>0</IntegerLiteralExpr></TernaryExpr></SequenceExpr></TupleElement>) </TupleExpr>: <TupleExpr>(<TupleElement><SequenceExpr><TernaryExpr><BooleanLiteralExpr>true </BooleanLiteralExpr>? <IntegerLiteralExpr>1 </IntegerLiteralExpr>: <IntegerLiteralExpr>0</IntegerLiteralExpr></TernaryExpr></SequenceExpr></TupleElement>)</TupleExpr></TernaryExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><TupleExpr>(<TupleElement><IntegerLiteralExpr>1</IntegerLiteralExpr>, </TupleElement><TupleElement><IntegerLiteralExpr>2</IntegerLiteralExpr></TupleElement>)</TupleExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
@@ -46,9 +46,9 @@
if <PrefixOperatorExpr>!<BooleanLiteralExpr>true </BooleanLiteralExpr></PrefixOperatorExpr><CodeBlock>{<ReturnStmt>
return</ReturnStmt>
}</CodeBlock>
- }</CodeBlock>
+ }</CodeBlock></FunctionDecl><FunctionDecl>
- func foo3() <CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
+ func foo3<FunctionSignature>() </FunctionSignature><CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ArrayExpr>[<ArrayElement><TypeExpr><SimpleTypeIdentifier>Any</SimpleTypeIdentifier></TypeExpr></ArrayElement>]</ArrayExpr>()</SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><MemberAccessExpr><IdentifierExpr>a</IdentifierExpr>.a</MemberAccessExpr>.a</MemberAccessExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><IdentifierExpr>a</IdentifierExpr>.b</MemberAccessExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
@@ -56,7 +56,7 @@
(<TupleElement><SequenceExpr><IntegerLiteralExpr>1 </IntegerLiteralExpr><BinaryOperatorExpr>+ </BinaryOperatorExpr><IntegerLiteralExpr>1</IntegerLiteralExpr></SequenceExpr></TupleElement>)</TupleExpr>.a</MemberAccessExpr>.b</MemberAccessExpr>.foo</MemberAccessExpr><SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>a </IdentifierExpr><AsExpr>as <SimpleTypeIdentifier>Bool </SimpleTypeIdentifier></AsExpr><BinaryOperatorExpr>|| </BinaryOperatorExpr><IdentifierExpr>a </IdentifierExpr><AsExpr>as! <SimpleTypeIdentifier>Bool </SimpleTypeIdentifier></AsExpr><BinaryOperatorExpr>|| </BinaryOperatorExpr><IdentifierExpr>a </IdentifierExpr><AsExpr>as? <SimpleTypeIdentifier>Bool</SimpleTypeIdentifier></AsExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>a </IdentifierExpr><IsExpr>is <SimpleTypeIdentifier>Bool</SimpleTypeIdentifier></IsExpr></SequenceExpr>
- }</CodeBlock>
+ }</CodeBlock></FunctionDecl>
}
typealias A = <SimpleTypeIdentifier>Any</SimpleTypeIdentifier>
@@ -68,9 +68,9 @@
struct foo <MemberDeclBlock>{<StructDecl>
struct foo <MemberDeclBlock>{<StructDecl>
- struct foo <MemberDeclBlock>{
- func foo() <CodeBlock>{
- }</CodeBlock>
+ struct foo <MemberDeclBlock>{<FunctionDecl>
+ func foo<FunctionSignature>() </FunctionSignature><CodeBlock>{
+ }</CodeBlock></FunctionDecl>
}</MemberDeclBlock></StructDecl>
}</MemberDeclBlock></StructDecl><StructDecl>
struct foo <MemberDeclBlock>{}</MemberDeclBlock></StructDecl>
@@ -79,10 +79,10 @@
struct foo <MemberDeclBlock>{<StructDecl><Attribute>
@available(*, unavailable)</Attribute>
struct foo <MemberDeclBlock>{}</MemberDeclBlock></StructDecl><DeclModifier>
- public </DeclModifier>class foo {<Attribute>
+ public </DeclModifier>class foo {<FunctionDecl><Attribute>
@available(*, unavailable)</Attribute><Attribute>
@objc(fooObjc)</Attribute><DeclModifier>
- private </DeclModifier><DeclModifier>static </DeclModifier>func foo() <CodeBlock>{}</CodeBlock>
+ private </DeclModifier><DeclModifier>static </DeclModifier>func foo<FunctionSignature>() </FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl>
}
}</MemberDeclBlock></StructDecl><StructDecl>
@@ -108,5 +108,8 @@
struct C <MemberDeclBlock>{<FunctionDecl><Attribute>
@objc</Attribute><Attribute>
@available(*, unavailable)</Attribute><DeclModifier>
-private </DeclModifier><DeclModifier>static </DeclModifier><DeclModifier>override </DeclModifier>func foo<GenericParameterClause><<GenericParameter>a, </GenericParameter><GenericParameter>b, </GenericParameter><GenericParameter>c</GenericParameter>></GenericParameterClause><FunctionSignature>(<FunctionParameter>a b: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>, </FunctionParameter><FunctionParameter>c: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) throws -> <ArrayType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>] </ArrayType></FunctionSignature><GenericWhereClause>where <SameTypeRequirement><SimpleTypeIdentifier>a</SimpleTypeIdentifier>==<SimpleTypeIdentifier>p1</SimpleTypeIdentifier>, </SameTypeRequirement><ConformanceRequirement><SimpleTypeIdentifier>b</SimpleTypeIdentifier>:<SimpleTypeIdentifier>p2 </SimpleTypeIdentifier></ConformanceRequirement></GenericWhereClause><CodeBlock>{ <IdentifierExpr>ddd </IdentifierExpr>}</CodeBlock></FunctionDecl>
+private </DeclModifier><DeclModifier>static </DeclModifier><DeclModifier>override </DeclModifier>func foo<GenericParameterClause><<GenericParameter>a, </GenericParameter><GenericParameter>b, </GenericParameter><GenericParameter>c</GenericParameter>></GenericParameterClause><FunctionSignature>(<FunctionParameter>a b: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>, </FunctionParameter><FunctionParameter>c: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) throws -> <ArrayType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>] </ArrayType></FunctionSignature><GenericWhereClause>where <SameTypeRequirement><SimpleTypeIdentifier>a</SimpleTypeIdentifier>==<SimpleTypeIdentifier>p1</SimpleTypeIdentifier>, </SameTypeRequirement><ConformanceRequirement><SimpleTypeIdentifier>b</SimpleTypeIdentifier>:<SimpleTypeIdentifier>p2 </SimpleTypeIdentifier></ConformanceRequirement></GenericWhereClause><CodeBlock>{ <IdentifierExpr>ddd </IdentifierExpr>}</CodeBlock></FunctionDecl><FunctionDecl>
+func rootView<FunctionSignature>() -> <SimpleTypeIdentifier>Label </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><FunctionDecl><DeclModifier>
+static </DeclModifier>func ==<FunctionSignature>() -> <SimpleTypeIdentifier>bool </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><FunctionDecl><DeclModifier>
+static </DeclModifier>func !=<GenericParameterClause><<GenericParameter>a, </GenericParameter><GenericParameter>b, </GenericParameter><GenericParameter>c</GenericParameter>></GenericParameterClause><FunctionSignature>() -> <SimpleTypeIdentifier>bool </SimpleTypeIdentifier></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl>
}</MemberDeclBlock></StructDecl>
\ No newline at end of file
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index 48b999c..0decabe 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -109,4 +109,7 @@
@objc
@available(*, unavailable)
private static override func foo<a, b, c>(a b: Int, c: Int) throws -> [Int] where a==p1, b:p2 { ddd }
+func rootView() -> Label {}
+static func ==() -> bool {}
+static func !=<a, b, c>() -> bool {}
}
\ No newline at end of file
diff --git a/test/decl/ext/protocol.swift b/test/decl/ext/protocol.swift
index 36af2df..1425c51 100644
--- a/test/decl/ext/protocol.swift
+++ b/test/decl/ext/protocol.swift
@@ -267,6 +267,22 @@
func f4(x: NestedNominal) {}
}
+// rdar://problem/21991470 & https://bugs.swift.org/browse/SR-5022
+class NonPolymorphicInit {
+ init() { } // expected-note {{selected non-required initializer 'init()'}}
+}
+
+protocol EmptyProtocol { }
+
+// The diagnostic is not very accurate, but at least we reject this.
+
+extension EmptyProtocol where Self : NonPolymorphicInit {
+ init(string: String) {
+ self.init()
+ // expected-error@-1 {{constructing an object of class type 'Self' with a metatype value must use a 'required' initializer}}
+ }
+}
+
// ----------------------------------------------------------------------------
// Using protocol extensions to satisfy requirements
// ----------------------------------------------------------------------------
diff --git a/unittests/runtime/Metadata.cpp b/unittests/runtime/Metadata.cpp
index d272285..83ee516 100644
--- a/unittests/runtime/Metadata.cpp
+++ b/unittests/runtime/Metadata.cpp
@@ -631,7 +631,7 @@
[](GenericMetadata *pattern, const void *args) -> Metadata* {
auto metadata =
swift_allocateGenericClassMetadata(pattern, args,
- SuperclassWithPrefix_AddressPoint);
+ SuperclassWithPrefix_AddressPoint, 0);
char *bytes = (char*) metadata + sizeof(ClassMetadata);
auto metadataWords = reinterpret_cast<const void**>(bytes);
auto argsWords = reinterpret_cast<const void* const *>(args);
diff --git a/utils/gyb_syntax_support/DeclNodes.py b/utils/gyb_syntax_support/DeclNodes.py
index 45c0af7..29ca15a 100644
--- a/utils/gyb_syntax_support/DeclNodes.py
+++ b/utils/gyb_syntax_support/DeclNodes.py
@@ -207,7 +207,15 @@
Child('Modifiers', kind='ModifierList',
is_optional=True),
Child('FuncKeyword', kind='FuncToken'),
- Child('Identifier', kind='IdentifierToken'),
+ Child('Identifier', kind='Token',
+ token_choices=[
+ 'IdentifierToken',
+ 'OperatorToken',
+ 'UnspacedBinaryOperatorToken',
+ 'SpacedBinaryOperatorToken',
+ 'PrefixOperatorToken',
+ 'PostfixOperatorToken',
+ ]),
Child('GenericParameterClause', kind='GenericParameterClause',
is_optional=True),
Child('Signature', kind='FunctionSignature'),
diff --git a/validation-test/stdlib/Collection/LazyFilterCollection.swift.gyb b/validation-test/stdlib/Collection/LazyFilterCollection.swift.gyb
index ff3513f..0aa6967 100644
--- a/validation-test/stdlib/Collection/LazyFilterCollection.swift.gyb
+++ b/validation-test/stdlib/Collection/LazyFilterCollection.swift.gyb
@@ -15,12 +15,12 @@
// Test collections using value types as elements.
% for (traversal, kind) in variations:
CollectionTests.add${traversal}${kind}Tests(
- make${kind}: { (elements: [OpaqueValue<Int>]) -> LazyFilter${traversal}${kind}<Minimal${traversal}${kind}<OpaqueValue<Int>>> in
+ make${kind}: { (elements: [OpaqueValue<Int>]) -> LazyFilter${kind}<Minimal${traversal}${kind}<OpaqueValue<Int>>> in
Minimal${traversal}${kind}(elements: elements).lazy.filter { _ in return true }
},
wrapValue: identity,
extractValue: identity,
- make${kind}OfEquatable: { (elements: [MinimalEquatableValue]) -> LazyFilter${traversal}${kind}<Minimal${traversal}${kind}<MinimalEquatableValue>> in
+ make${kind}OfEquatable: { (elements: [MinimalEquatableValue]) -> LazyFilter${kind}<Minimal${traversal}${kind}<MinimalEquatableValue>> in
Minimal${traversal}${kind}(elements: elements).lazy.filter { _ in return true }
},
wrapValueIntoEquatable: identityEq,
@@ -31,7 +31,7 @@
// Test collections using reference types as elements.
% for (traversal, kind) in variations:
CollectionTests.add${traversal}${kind}Tests(
- make${kind}: { (elements: [LifetimeTracked]) -> LazyFilter${traversal}${kind}<Minimal${traversal}${kind}<LifetimeTracked>> in
+ make${kind}: { (elements: [LifetimeTracked]) -> LazyFilter${kind}<Minimal${traversal}${kind}<LifetimeTracked>> in
// FIXME: create a better sequence and filter
Minimal${traversal}${kind}(elements: elements).lazy.filter { _ in return true }
},
@@ -41,7 +41,7 @@
extractValue: { (element: LifetimeTracked) in
OpaqueValue(element.value, identity: element.identity)
},
- make${kind}OfEquatable: { (elements: [LifetimeTracked]) -> LazyFilter${traversal}${kind}<Minimal${traversal}${kind}<LifetimeTracked>> in
+ make${kind}OfEquatable: { (elements: [LifetimeTracked]) -> LazyFilter${kind}<Minimal${traversal}${kind}<LifetimeTracked>> in
// FIXME: create a better sequence and filter
Minimal${traversal}${kind}(elements: elements).lazy.filter { _ in return true }
},
diff --git a/validation-test/stdlib/Collection/LazyMapBidirectionalCollection.swift b/validation-test/stdlib/Collection/LazyMapBidirectionalCollection.swift
index de4162b..38acd9b 100644
--- a/validation-test/stdlib/Collection/LazyMapBidirectionalCollection.swift
+++ b/validation-test/stdlib/Collection/LazyMapBidirectionalCollection.swift
@@ -15,12 +15,12 @@
// Test collections using value types as elements.
CollectionTests.addBidirectionalCollectionTests(
- makeCollection: { (elements: [OpaqueValue<Int>]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<OpaqueValue<Int>>, OpaqueValue<Int>> in
+ makeCollection: { (elements: [OpaqueValue<Int>]) -> LazyMapCollection<MinimalBidirectionalCollection<OpaqueValue<Int>>, OpaqueValue<Int>> in
MinimalBidirectionalCollection(elements: elements).lazy.map(identity)
},
wrapValue: identity,
extractValue: identity,
- makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<MinimalEquatableValue>, MinimalEquatableValue> in
+ makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) -> LazyMapCollection<MinimalBidirectionalCollection<MinimalEquatableValue>, MinimalEquatableValue> in
MinimalBidirectionalCollection(elements: elements).lazy.map(identityEq)
},
wrapValueIntoEquatable: identityEq,
@@ -29,7 +29,7 @@
// Test collections using reference types as elements.
CollectionTests.addBidirectionalCollectionTests(
- makeCollection: { (elements: [LifetimeTracked]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
+ makeCollection: { (elements: [LifetimeTracked]) -> LazyMapCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
MinimalBidirectionalCollection(elements: elements).lazy.map { $0 }
},
wrapValue: { (element: OpaqueValue<Int>) in
@@ -38,7 +38,7 @@
extractValue: { (element: LifetimeTracked) in
OpaqueValue(element.value, identity: element.identity)
},
- makeCollectionOfEquatable: { (elements: [LifetimeTracked]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
+ makeCollectionOfEquatable: { (elements: [LifetimeTracked]) -> LazyMapCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
MinimalBidirectionalCollection(elements: elements).lazy.map { $0 }
},
wrapValueIntoEquatable: { (element: MinimalEquatableValue) in
diff --git a/validation-test/stdlib/Lazy.swift.gyb b/validation-test/stdlib/Lazy.swift.gyb
index 58b6e57..22e4a79 100644
--- a/validation-test/stdlib/Lazy.swift.gyb
+++ b/validation-test/stdlib/Lazy.swift.gyb
@@ -507,7 +507,7 @@
OpaqueValue(Int32(input.value))
}
expectType(
- LazyMap${TraversalCollection}<
+ LazyMapCollection<
Minimal${TraversalCollection}<OpaqueValue<Int>>, OpaqueValue<Int32>
>.self,
&lazyMap)
@@ -810,7 +810,7 @@
expectEqual(0, calls)
expectType(
- LazyMap${TraversalCollection}<
+ LazyMapCollection<
Minimal${TraversalCollection}<OpaqueValue<Int>>,
OpaqueValue<Double>>.self,
&mapped)
@@ -880,22 +880,22 @@
tests.test("LazyMapBidirectionalCollection/AssociatedTypes") {
typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
- typealias Subject = LazyMapBidirectionalCollection<Base, OpaqueValue<Int32>>
+ typealias Subject = LazyMapCollection<Base, OpaqueValue<Int32>>
expectBidirectionalCollectionAssociatedTypes(
collectionType: Subject.self,
iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
- subSequenceType: LazyMapBidirectionalCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
+ subSequenceType: LazyMapCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
indexType: Base.Index.self,
indicesType: Base.Indices.self)
}
tests.test("LazyMapRandomAccessCollection/AssociatedTypes") {
typealias Base = MinimalRandomAccessCollection<OpaqueValue<Int>>
- typealias Subject = LazyMapRandomAccessCollection<Base, OpaqueValue<Int32>>
+ typealias Subject = LazyMapCollection<Base, OpaqueValue<Int32>>
expectRandomAccessCollectionAssociatedTypes(
collectionType: Subject.self,
iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
- subSequenceType: LazyMapRandomAccessCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
+ subSequenceType: LazyMapCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
indexType: Base.Index.self,
indicesType: Base.Indices.self)
}
@@ -926,7 +926,7 @@
var mapped = MinimalBidirectionalCollection(elements: baseArray)
.lazy.map { _ in OpaqueValue<Int8>(0) }
expectType(
- LazyMapBidirectionalCollection<
+ LazyMapCollection<
MinimalBidirectionalCollection<OpaqueValue<Int>>,
OpaqueValue<Int8>
>.self,
@@ -936,7 +936,7 @@
var mapped = MinimalRandomAccessCollection(elements: baseArray)
.lazy.map { _ in OpaqueValue<Int8>(0) }
expectType(
- LazyMapRandomAccessCollection<
+ LazyMapCollection<
MinimalRandomAccessCollection<OpaqueValue<Int>>,
OpaqueValue<Int8>
>.self,
@@ -960,14 +960,14 @@
}
checkBidirectionalCollection(
- "raboof".characters,
- "foobar".characters.reversed())
+ "raboof",
+ "foobar".reversed())
// Check that the reverse collection is still eager
do {
var calls = 0
- _ = "foobar".characters.reversed().map { _ in calls += 1 }
- expectEqual("foobar".characters.count, calls)
+ _ = "foobar".reversed().map { _ in calls += 1 }
+ expectEqual("foobar".count, calls)
}
}
@@ -985,11 +985,10 @@
let base = Array(stride(from: 11, through: 0, by: -1)).lazy.map { $0 }
- typealias Base = LazyMapRandomAccessCollection<[Int], Int>
+ typealias Base = LazyMapCollection<[Int], Int>
ExpectType<Base>.test(base)
- typealias LazyReversedBase = LazyRandomAccessCollection<
- ReversedCollection<Base>>
+ typealias LazyReversedBase = LazyCollection<ReversedCollection<Base>>
let reversed = base.reversed()
ExpectType<LazyReversedBase>.test(reversed)
@@ -1002,17 +1001,11 @@
}
do {
- typealias Expected = LazyBidirectionalCollection<
- ReversedCollection<String.CharacterView>
- >
-
- let base = "foobar".characters.lazy.map { $0 }
- typealias Base = LazyMapBidirectionalCollection<
- String.CharacterView, Character>
+ let base = "foobar".lazy.map { $0 }
+ typealias Base = LazyMapCollection<String, Character>
ExpectType<Base>.test(base)
- typealias LazyReversedBase = LazyBidirectionalCollection<
- ReversedCollection<Base>>
+ typealias LazyReversedBase = LazyCollection<ReversedCollection<Base>>
let reversed = base.reversed()
ExpectType<LazyReversedBase>.test(reversed)
@@ -1020,7 +1013,7 @@
var calls = 0
let reversedAndMapped = reversed.map { (x) -> Character in calls += 1; return x }
expectEqual(0, calls)
- checkBidirectionalCollection("raboof".characters, reversedAndMapped)
+ checkBidirectionalCollection("raboof", reversedAndMapped)
expectNotEqual(0, calls)
}
}
@@ -1161,18 +1154,18 @@
collectionType: Subject.self,
iteratorType: LazyFilterIterator<Base.Iterator>.self,
subSequenceType: LazyFilterCollection<Base.SubSequence>.self,
- indexType: LazyFilterIndex<Base>.self,
+ indexType: Base.Index.self,
indicesType: DefaultIndices<Subject>.self)
}
tests.test("LazyFilterBidirectionalCollection/AssociatedTypes") {
typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
- typealias Subject = LazyFilterBidirectionalCollection<Base>
+ typealias Subject = LazyFilterCollection<Base>
expectBidirectionalCollectionAssociatedTypes(
collectionType: Subject.self,
iteratorType: LazyFilterIterator<Base.Iterator>.self,
- subSequenceType: LazyFilterBidirectionalCollection<Base.SubSequence>.self,
- indexType: LazyFilterIndex<Base>.self,
+ subSequenceType: LazyFilterCollection<Base.SubSequence>.self,
+ indexType: Base.Index.self,
indicesType: DefaultBidirectionalIndices<Subject>.self)
}
@@ -1196,7 +1189,7 @@
var filtered = MinimalBidirectionalCollection(elements: baseArray)
.lazy.filter { _ in true }
expectType(
- LazyFilterBidirectionalCollection<
+ LazyFilterCollection<
MinimalBidirectionalCollection<OpaqueValue<Int>>
>.self,
&filtered)
@@ -1205,7 +1198,7 @@
var filtered = MinimalRandomAccessCollection(elements: baseArray)
.lazy.filter { _ in true }
expectType(
- LazyFilterBidirectionalCollection<
+ LazyFilterCollection<
MinimalRandomAccessCollection<OpaqueValue<Int>>
>.self,
&filtered)
diff --git a/validation-test/stdlib/Range.swift.gyb b/validation-test/stdlib/Range.swift.gyb
index d94930d..a9675e2 100644
--- a/validation-test/stdlib/Range.swift.gyb
+++ b/validation-test/stdlib/Range.swift.gyb
@@ -784,7 +784,7 @@
MiscTestSuite.test("reversed()") {
var result = (0..<10).lazy.reversed()
- typealias Expected = LazyRandomAccessCollection<
+ typealias Expected = LazyCollection<
ReversedRandomAccessCollection<CountableRange<Int>>>
expectType(Expected.self, &result)
expectEqualSequence(