Merge pull request #16829 from shajrawi/fix_dynamic_cast
diff --git a/.mailmap b/.mailmap
index 16508c2..34c3d73 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,6 +1,7 @@
Adrian-Constantin Popescu <epsilon.gamma@gmail.com> <adrian-constantin.popescu@outlook.com>
Alex Blewitt <alblue@apple.com> <alex.blewitt@gmail.com>
Alex Hoppen <alex@alexhoppen.de> <alex@ateamer.de>
+Alex Hoppen <alex@alexhoppen.de> <ahoppen@apple.com>>
Alexis Beingessner <abeingessner@apple.com> <a.beingessner@gmail.com>
Alper Çugun <github@alper.nl> <alper@users.noreply.github.com>
Amr Aboelela <amraboelela@gmail.com> <amraboelela@users.noreply.github.com>
@@ -55,10 +56,12 @@
GauravDS <er.gauravds@gmail.com> <gaurav.sharma@punchh.com>
Graydon Hoare <ghoare@apple.com> <graydon@users.noreply.github.com>
Greg Parker <gparker@apple.com> <gparker-github@sealiesoftware.com>
+Greg Titus <gregomni@gmail.com>
Guillaume Lessard <dhtnstff@gmail.com> <glessard@users.noreply.github.com>
Hamish <hamish2knight@gmail.com>
Han Sangjin <tinysun@jssolution.co.kr> <tinysun.net@gmail.com>
Harlan Haskins <harlan@apple.com> <harlan@harlanhaskins.com>
+Harlan Haskins <harlan@apple.com> <hbh@google.com>
Hitster GTD <hitstergtd@users.noreply.github.com>
Huon Wilson <huon@apple.com> <dbau.pp+github@gmail.com>
Ingmar Stein <IngmarStein@users.noreply.github.com>
@@ -102,6 +105,7 @@
Mike Ash <mikeash@apple.com> <mike@mikeash.com>
Mike Ferris <mferris@apple.com> <mike@lorax.com>
Mishal Awadah <mawadah@apple.com>
+Mishal Shah <mishal_shah@apple.com>
Mishal Shah <mishal_shah@apple.com> <shahmishal@users.noreply.github.com>
Nadav Rotem <nrotem@apple.com> <nadavrot@users.noreply.github.com>
Nate Cook <natecook@apple.com> <nate@Nates-MacBook-Pro.local>
diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake
index 48243be..f544d5b 100644
--- a/cmake/modules/SwiftSharedCMakeConfig.cmake
+++ b/cmake/modules/SwiftSharedCMakeConfig.cmake
@@ -90,6 +90,7 @@
# selectively add it to the per-target link flags; this is currently done
# in add_swift_library within AddSwift.cmake.
string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+ string(REGEX REPLACE "-Wl,-z,nodelete" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.[0-9]+)?" "\\1" PACKAGE_VERSION_MAJOR
diff --git a/docs/SIL.rst b/docs/SIL.rst
index 589b0c2..5450b8b 100644
--- a/docs/SIL.rst
+++ b/docs/SIL.rst
@@ -4767,6 +4767,24 @@
returning two bits: the first indicates whether the object is an Objective-C
object, the second indicates whether it is an Objective-C tagged pointer value.
+value_to_bridge_object
+``````````````````````
+::
+
+ sil-instruction ::= 'value_to_bridge_object' sil-operand
+
+ %1 = value_to_bridge_object %0 : $T
+ // %1 will be of type Builtin.BridgeObject
+
+Sets the BridgeObject to a tagged pointer representation holding its operands
+by tagging and shifting the operand if needed::
+
+ value_to_bridge_object %x ===
+ (x << _swift_abi_ObjCReservedLowBits) | _swift_BridgeObject_TaggedPointerBits
+
+``%x`` thus must not be using any high bits shifted away or the tag bits post-shift.
+ARC operations on such tagged values are NOPs.
+
ref_to_bridge_object
````````````````````
::
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index 433e958..0a82e16 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -138,6 +138,8 @@
}
/// True if the type requires out-of-line allocation of its storage.
+ /// This can be the case because the value requires more storage or if it is
+ /// not bitwise takable.
bool isInlineStorage() const { return !(Data & IsNonInline); }
constexpr TargetValueWitnessFlags withInlineStorage(bool isInline) const {
return TargetValueWitnessFlags((Data & ~IsNonInline) |
diff --git a/include/swift/ABI/ValueWitness.def b/include/swift/ABI/ValueWitness.def
index b50da3e..52df0c1 100644
--- a/include/swift/ABI/ValueWitness.def
+++ b/include/swift/ABI/ValueWitness.def
@@ -172,14 +172,6 @@
MUTABLE_VALUE_TYPE,
(MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE))
-/// T *(*initializeBufferWithTakeOfBuffer)(B *dest, B *src, M *self);
-/// Given an invalid buffer, initialize it by taking the value out of
-/// the source buffer.
-FUNCTION_VALUE_WITNESS(initializeBufferWithTakeOfBuffer,
- InitializeBufferWithTakeOfBuffer,
- MUTABLE_VALUE_TYPE,
- (MUTABLE_BUFFER_TYPE, MUTABLE_BUFFER_TYPE, TYPE_TYPE))
-
/// unsigned (*getEnumTagSinglePayload)(const T* enum, UINT_TYPE emptyCases)
/// Given an instance of valid single payload enum with a payload of this
/// witness table's type (e.g Optional<ThisType>) , get the tag of the enum.
@@ -228,7 +220,7 @@
/// The ValueWitnessIsNonPOD bit is set if the type is not POD.
///
/// The ValueWitnessIsNonInline bit is set if the type cannot be
-/// represented in a fixed-size buffer.
+/// represented in a fixed-size buffer or if it is not bitwise takable.
///
/// The Enum_HasExtraInhabitants bit is set if the type's binary
/// representation has "extra inhabitants" that do not form valid values of
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 5fc411e..69b9169 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -122,7 +122,8 @@
PrecedenceGroup,
TypeAlias,
GenericTypeParam,
- AssociatedType,
+ AssociatedType,
+ Type,
Enum,
Struct,
Class,
@@ -130,6 +131,7 @@
GenericEnum,
GenericStruct,
GenericClass,
+ GenericType,
Subscript,
Constructor,
Destructor,
@@ -149,6 +151,7 @@
EnumElement,
Module,
MissingMember,
+ Requirement,
};
/// Keeps track of stage of circularity checking for the given protocol.
diff --git a/include/swift/AST/DiagnosticsDriver.def b/include/swift/AST/DiagnosticsDriver.def
index 0b2b9b3..90b0ae6 100644
--- a/include/swift/AST/DiagnosticsDriver.def
+++ b/include/swift/AST/DiagnosticsDriver.def
@@ -155,6 +155,10 @@
"the option '-driver-use-filelists' is deprecated; use "
"'-driver-filelist-threshold=0' instead", ())
+WARNING(warn_emit_public_type_metadata_accessors_deprecated, none,
+ "the option '-emit-public-type-metadata-accessors' is no longer "
+ "needed and is deprecated; consider removing it", ())
+
REMARK(remark_using_batch_mode,none, "using batch mode", ())
#ifndef DIAG_NO_UNDEF
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 7ce915b..e081ec0 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -37,11 +37,16 @@
DIAG(NOTE,ID,Options,Text,Signature)
#endif
-
-NOTE(type_declared_here,none,
- "type declared here", ())
+NOTE(kind_declname_declared_here,none,
+ "%0 %1 declared here", (DescriptiveDeclKind, DeclName))
+NOTE(kind_identifier_declared_here,none,
+ "%0 %1 declared here", (DescriptiveDeclKind, Identifier))
NOTE(decl_declared_here,none,
"%0 declared here", (DeclName))
+NOTE(identifier_declared_here,none,
+ "%0 declared here", (Identifier))
+NOTE(kind_declared_here,none,
+ "%0 declared here", (DescriptiveDeclKind))
NOTE(implicit_member_declared_here,none,
"%1 '%0' is implicitly declared", (StringRef, StringRef))
NOTE(extended_type_declared_here,none,
@@ -75,6 +80,11 @@
"type %0 has no member %1; did you mean %2?",
(Type, DeclName, DeclName))
+ERROR(could_not_find_subscript_member_did_you_mean,none,
+ "value of type %0 has no property or method named 'subscript'; "
+ "did you mean to use the subscript operator?",
+ (Type))
+
ERROR(could_not_find_enum_case,none,
"enum type %0 has no case %1; did you mean %2", (Type, DeclName, DeclName))
@@ -759,8 +769,6 @@
"precedence group cannot be given lower precedence than group in same"
" module; make the other precedence group higher than this one instead",
())
-NOTE(precedence_group_declared_here,none,"precedence group declared here",
- ())
ERROR(precedence_group_redeclared,none,
"precedence group redeclared", ())
NOTE(previous_precedence_group_decl,none,
@@ -1682,8 +1690,6 @@
"possibly intended match %0 does not "
"%select{inherit from|conform to}2 %1", (Type, Type, bool))
-NOTE(protocol_requirement_here,none,
- "requirement %0 declared here", (DeclName))
NOTE(protocol_conformance_here,none,
"%select{|class }0%1 declares conformance to protocol %2 here",
(bool, DeclName, DeclName))
@@ -1746,8 +1752,6 @@
ERROR(circular_protocol_def,none,
"circular protocol inheritance %0", (StringRef))
-NOTE(protocol_here,none,
- "protocol %0 declared here", (Identifier))
ERROR(objc_protocol_inherits_non_objc_protocol,none,
"@objc protocol %0 cannot refine non-@objc protocol %1", (Type, Type))
WARNING(protocol_composition_with_postfix,none,
@@ -2065,8 +2069,6 @@
"superclass %0 of open class must be open", (Type))
ERROR(circular_class_inheritance,none,
"circular class inheritance %0", (StringRef))
-NOTE(class_here,none,
- "class %0 declared here", (Identifier))
ERROR(inheritance_from_final_class,none,
"inheritance from a final class %0", (Identifier))
ERROR(inheritance_from_unspecialized_objc_generic_class,none,
@@ -2134,8 +2136,6 @@
"%select{a private|a fileprivate|an internal|%error|%error}2 type",
(bool, AccessLevel, AccessLevel, bool))
-NOTE(enum_here,none,
- "enum %0 declared here", (Identifier))
ERROR(empty_enum_raw_type,none,
"an enum with no cases cannot declare a raw type", ())
ERROR(enum_raw_value_without_raw_type,none,
@@ -2240,8 +2240,6 @@
"property behavior name must refer to a protocol", ())
ERROR(property_behavior_protocol_reqt_ambiguous,none,
"property behavior protocol has ambiguous %0 member", (Identifier))
-NOTE(property_behavior_protocol_reqt_here,none,
- "%0 declared here", (Identifier))
ERROR(property_behavior_protocol_no_value,none,
"property behavior protocol does not have a 'value' property", ())
ERROR(property_behavior_protocol_no_initStorage,none,
@@ -2678,8 +2676,6 @@
(Identifier, unsigned, unsigned, bool))
ERROR(generic_type_requires_arguments,none,
"reference to generic type %0 requires arguments in <...>", (Type))
-NOTE(generic_type_declared_here,none,
- "generic type %0 declared here", (Identifier))
NOTE(descriptive_generic_type_declared_here,none,
"%0 declared here", (StringRef))
diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h
index c4fb037..d49f6b9 100644
--- a/include/swift/AST/Expr.h
+++ b/include/swift/AST/Expr.h
@@ -549,6 +549,10 @@
/// a builtin operator.
bool isInfixOperator() const;
+ /// Returns true if this is a reference to the implicit self of function.
+ bool isSelfExprOf(const AbstractFunctionDecl *AFD,
+ bool sameBase = false) const;
+
/// Produce a mapping from each subexpression to its parent
/// expression, with the provided expression serving as the root of
/// the parent map.
diff --git a/include/swift/AST/Initializer.h b/include/swift/AST/Initializer.h
index 053cb8a..c3ce60d 100644
--- a/include/swift/AST/Initializer.h
+++ b/include/swift/AST/Initializer.h
@@ -162,7 +162,7 @@
/// Change the parent of this context. This is necessary because
/// the function signature is parsed before the function
/// declaration/expression itself is built.
- void changeFunction(DeclContext *parent, MutableArrayRef<ParameterList *> paramLists);
+ void changeFunction(DeclContext *parent, ArrayRef<ParameterList *> paramLists);
static bool classof(const DeclContext *DC) {
if (auto init = dyn_cast<Initializer>(DC))
diff --git a/include/swift/AST/Stmt.h b/include/swift/AST/Stmt.h
index 6f3b473..c6ea9c8 100644
--- a/include/swift/AST/Stmt.h
+++ b/include/swift/AST/Stmt.h
@@ -128,7 +128,7 @@
LLVM_ATTRIBUTE_DEPRECATED(
void dump() const LLVM_ATTRIBUTE_USED,
"only for use within the debugger");
- void print(raw_ostream &OS, unsigned Indent = 0) const;
+ void print(raw_ostream &OS, const ASTContext *Ctx = nullptr, unsigned Indent = 0) const;
// Only allow allocation of Exprs using the allocator in ASTContext
// or by doing a placement new.
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index f31121c..f14fbd2 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -3059,12 +3059,6 @@
/// function type and return the resulting non-generic type.
FunctionType *substGenericArgs(SubstitutionMap subs);
- /// Substitute the given generic arguments into this generic
- /// function type using the given substitution and conformance lookup
- /// callbacks.
- FunctionType *substGenericArgs(TypeSubstitutionFn subs,
- LookupConformanceFn conformances);
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getGenericSignature(), getInput(), getResult(),
getExtInfo());
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index 5ef1aae..2f56591 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -223,9 +223,6 @@
/// Enables key path resilience.
bool EnableKeyPathResilience = false;
- /// Enables public emission of private metadata accessors.
- bool EmitPublicTypeMetadataAccessors = false;
-
/// If set to true, the diagnosis engine can assume the emitted diagnostics
/// will be used in editor. This usually leads to more aggressive fixit.
bool DiagnosticsEditorMode = false;
diff --git a/include/swift/IDE/DigesterEnums.def b/include/swift/IDE/DigesterEnums.def
index 0a21aaf..26fb0cb 100644
--- a/include/swift/IDE/DigesterEnums.def
+++ b/include/swift/IDE/DigesterEnums.def
@@ -79,6 +79,7 @@
NODE_ANNOTATION_CHANGE_KIND(OptionalArrayMemberUpdate)
NODE_ANNOTATION_CHANGE_KIND(SimpleStringRepresentableUpdate)
NODE_ANNOTATION_CHANGE_KIND(SimpleOptionalStringRepresentableUpdate)
+NODE_ANNOTATION_CHANGE_KIND(TypeAliasDeclToRawRepresentable)
NODE_ANNOTATION_CHANGE_KIND(RevertDictionaryKeyUpdate)
NODE_ANNOTATION_CHANGE_KIND(RevertOptionalDictionaryKeyUpdate)
diff --git a/include/swift/IDE/RefactoringKinds.def b/include/swift/IDE/RefactoringKinds.def
index cbb0e1e..3764fdf 100644
--- a/include/swift/IDE/RefactoringKinds.def
+++ b/include/swift/IDE/RefactoringKinds.def
@@ -44,7 +44,7 @@
CURSOR_REFACTORING(SimplifyNumberLiteral, "Simplify Long Number Literal", simplify.long.number.literal)
-CURSOR_REFACTORING(CollapseNestedIfExpr, "Collapse Nested If Expression", collapse.nested.if.expr)
+CURSOR_REFACTORING(CollapseNestedIfStmt, "Collapse Nested If Statements", collapse.nested.ifstmt)
CURSOR_REFACTORING(ConvertToDoCatch, "Convert To Do/Catch", convert.do.catch)
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index 36563c9..3fb1be9 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -880,6 +880,9 @@
llvm::GlobalValue::VisibilityTypes Visibility,
llvm::GlobalValue::DLLStorageClassTypes DLLStorage);
};
+
+StringRef encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
+ StringRef name);
}
}
@@ -910,5 +913,4 @@
LHS.SecondaryPointer == RHS.SecondaryPointer && LHS.Data == RHS.Data;
}
};
-
#endif
diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td
index 6d3edf2..dfbf752 100644
--- a/include/swift/Option/Options.td
+++ b/include/swift/Option/Options.td
@@ -358,7 +358,7 @@
def emit_public_type_metadata_accessors :
Flag<["-"], "emit-public-type-metadata-accessors">,
Flags<[FrontendOption]>,
- HelpText<"Emit all type metadata accessors as public">;
+ HelpText<"Emit all type metadata accessors as public (deprecated: now does nothing)">;
def Rpass_EQ : Joined<["-"], "Rpass=">,
Flags<[FrontendOption]>,
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index a805082..46d0091 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -466,6 +466,16 @@
return consumeToken();
}
+ SourceLoc consumeArgumentLabel(Identifier &Result) {
+ assert(Tok.canBeArgumentLabel());
+ assert(Result.empty());
+ if (!Tok.is(tok::kw__)) {
+ Tok.setKind(tok::identifier);
+ Result = Context.getIdentifier(Tok.getText());
+ }
+ return consumeToken();
+ }
+
/// \brief Retrieve the location just past the end of the previous
/// source location.
SourceLoc getEndOfPreviousLoc();
@@ -1015,7 +1025,7 @@
/// Set the parsed context for all the initializers to the given
/// function.
- void setFunctionContext(DeclContext *DC, MutableArrayRef<ParameterList *> paramList);
+ void setFunctionContext(DeclContext *DC, ArrayRef<ParameterList *> paramList);
DefaultArgumentInfo(bool inTypeContext) {
NextIndex = inTypeContext ? 1 : 0;
diff --git a/include/swift/Reflection/ReflectionContext.h b/include/swift/Reflection/ReflectionContext.h
index a88e8bc..a58d9e6 100644
--- a/include/swift/Reflection/ReflectionContext.h
+++ b/include/swift/Reflection/ReflectionContext.h
@@ -148,14 +148,14 @@
// The docs say "not all sections may be present." We'll succeed if ANY of
// them are present. Not sure if that's the right thing to do.
- auto FieldMd = findSection<FieldSection>(Header, "__swift4_fieldmd");
+ auto FieldMd = findSection<FieldSection>(Header, "__swift5_fieldmd");
auto AssocTyMd =
- findSection<AssociatedTypeSection>(Header, "__swift4_assocty");
+ findSection<AssociatedTypeSection>(Header, "__swift5_assocty");
auto BuiltinTyMd =
- findSection<BuiltinTypeSection>(Header, "__swift4_builtin");
- auto CaptureMd = findSection<CaptureSection>(Header, "__swift4_capture");
- auto TyperefMd = findSection<GenericSection>(Header, "__swift4_typeref");
- auto ReflStrMd = findSection<GenericSection>(Header, "__swift4_reflstr");
+ findSection<BuiltinTypeSection>(Header, "__swift5_builtin");
+ auto CaptureMd = findSection<CaptureSection>(Header, "__swift5_capture");
+ auto TyperefMd = findSection<GenericSection>(Header, "__swift5_typeref");
+ auto ReflStrMd = findSection<GenericSection>(Header, "__swift5_reflstr");
bool success = FieldMd.second || AssocTyMd.second || BuiltinTyMd.second ||
CaptureMd.second || TyperefMd.second || ReflStrMd.second;
diff --git a/include/swift/Runtime/Concurrent.h b/include/swift/Runtime/Concurrent.h
index 274d221..003088c 100644
--- a/include/swift/Runtime/Concurrent.h
+++ b/include/swift/Runtime/Concurrent.h
@@ -451,7 +451,44 @@
Mutex WriterLock;
std::vector<Storage *> FreeList;
+ void incrementReaders() {
+ ReaderCount.fetch_add(1, std::memory_order_acquire);
+ }
+
+ void decrementReaders() {
+ ReaderCount.fetch_sub(1, std::memory_order_release);
+ }
+
+ void deallocateFreeList() {
+ for (Storage *storage : FreeList)
+ storage->deallocate();
+ FreeList.clear();
+ FreeList.shrink_to_fit();
+ }
+
public:
+ struct Snapshot {
+ ConcurrentReadableArray *Array;
+ const ElemTy *Start;
+ size_t Count;
+
+ Snapshot(ConcurrentReadableArray *array, const ElemTy *start, size_t count)
+ : Array(array), Start(start), Count(count) {}
+
+ Snapshot(const Snapshot &other)
+ : Array(other.Array), Start(other.Start), Count(other.Count) {
+ Array->incrementReaders();
+ }
+
+ ~Snapshot() {
+ Array->decrementReaders();
+ }
+
+ const ElemTy *begin() { return Start; }
+ const ElemTy *end() { return Start + Count; }
+ size_t count() { return Count; }
+ };
+
// This type cannot be safely copied, moved, or deleted.
ConcurrentReadableArray(const ConcurrentReadableArray &) = delete;
ConcurrentReadableArray(ConcurrentReadableArray &&) = delete;
@@ -459,6 +496,12 @@
ConcurrentReadableArray() : Capacity(0), ReaderCount(0), Elements(nullptr) {}
+ ~ConcurrentReadableArray() {
+ assert(ReaderCount.load(std::memory_order_acquire) == 0 &&
+ "deallocating ConcurrentReadableArray with outstanding snapshots");
+ deallocateFreeList();
+ }
+
void push_back(const ElemTy &elem) {
ScopedLock guard(WriterLock);
@@ -482,32 +525,19 @@
storage->Count.store(count + 1, std::memory_order_release);
if (ReaderCount.load(std::memory_order_acquire) == 0)
- for (Storage *storage : FreeList)
- storage->deallocate();
+ deallocateFreeList();
}
- /// Read the contents of the array. The parameter `f` is called with
- /// two parameters: a pointer to the elements in the array, and the
- /// count. This represents a snapshot of the contents at the time
- /// `read` was called. The pointer becomes invalid after `f` returns.
- template <class F> auto read(F f) -> decltype(f(nullptr, 0)) {
- ReaderCount.fetch_add(1, std::memory_order_acquire);
+ Snapshot snapshot() {
+ incrementReaders();
auto *storage = Elements.load(SWIFT_MEMORY_ORDER_CONSUME);
+ if (storage == nullptr) {
+ return Snapshot(this, nullptr, 0);
+ }
+
auto count = storage->Count.load(std::memory_order_acquire);
const auto *ptr = storage->data();
-
- decltype(f(nullptr, 0)) result = f(ptr, count);
-
- ReaderCount.fetch_sub(1, std::memory_order_release);
-
- return result;
- }
-
- /// Get the current count. It's just a snapshot and may be obsolete immediately.
- size_t count() {
- return read([](const ElemTy *ptr, size_t count) -> size_t {
- return count;
- });
+ return Snapshot(this, ptr, count);
}
};
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index 3d4e384..897f2b6 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -278,13 +278,15 @@
using ValueBuffer = TargetValueBuffer<InProcess>;
/// Can a value with the given size and alignment be allocated inline?
-constexpr inline bool canBeInline(size_t size, size_t alignment) {
- return size <= sizeof(ValueBuffer) && alignment <= alignof(ValueBuffer);
+constexpr inline bool canBeInline(bool isBitwiseTakable, size_t size,
+ size_t alignment) {
+ return isBitwiseTakable && size <= sizeof(ValueBuffer) &&
+ alignment <= alignof(ValueBuffer);
}
template <class T>
-constexpr inline bool canBeInline() {
- return canBeInline(sizeof(T), alignof(T));
+constexpr inline bool canBeInline(bool isBitwiseTakable) {
+ return canBeInline(isBitwiseTakable, sizeof(T), alignof(T));
}
struct ValueWitnessTable;
@@ -345,8 +347,8 @@
/// Would values of a type with the given layout requirements be
/// allocated inline?
- static bool isValueInline(size_t size, size_t alignment) {
- return (size <= sizeof(ValueBuffer) &&
+ static bool isValueInline(bool isBitwiseTakable, size_t size, size_t alignment) {
+ return (isBitwiseTakable && size <= sizeof(ValueBuffer) &&
alignment <= alignof(ValueBuffer));
}
diff --git a/include/swift/SIL/MemAccessUtils.h b/include/swift/SIL/MemAccessUtils.h
index 8eb5145..562f5d8 100644
--- a/include/swift/SIL/MemAccessUtils.h
+++ b/include/swift/SIL/MemAccessUtils.h
@@ -53,17 +53,17 @@
}
};
-/// Represents the identity of a storage location being accessed.
+/// Represents the identity of a storage object being accessed.
///
/// AccessedStorage may be one of several kinds of "identified" storage
-/// locations, or may be valid, but Unidentified storage. An identified location
+/// objects, or may be valid, but Unidentified storage. An identified object
/// is known to identify the base of the accessed storage, whether that is a
/// SILValue that produces the base address, or a variable
/// declaration. "Uniquely identified" storage refers to identified storage that
/// cannot be aliased. For example, local allocations are uniquely identified,
/// while global variables and class properties are not. Unidentified storage is
/// associated with a SILValue that produces the accessed address but has not
-/// been determined to be the base of a storage location. It may, for example,
+/// been determined to be the base of a storage object. It may, for example,
/// be a SILPHIArgument.
///
/// An invalid AccessedStorage object is marked Unidentified and contains an
@@ -72,19 +72,19 @@
/// SILVerification could allow the optimizer to aggressively assert that
/// AccessedStorage is always valid.
///
-/// Note that the SILValue that represents a storage location is not
+/// Note that the SILValue that represents a storage object is not
/// necessarilly an address type. It may instead be a SILBoxType.
///
-/// AccessedStorage hashing and comparison is used to determine when two
-/// 'begin_access' instructions access the same or disjoint underlying
-/// locations.
+/// AccessedStorage hashing and comparison (via DenseMapInfo) is used to
+/// determine when two 'begin_access' instructions access the same or disjoint
+/// underlying objects.
///
-/// Equality guarantees that two AccessStorage values refer to the same
-/// memory if both values are valid.
+/// `DenseMapInfo::isEqual()` guarantees that two AccessStorage values refer to
+/// the same memory if both values are valid.
///
-/// Inequality does not guarantee that two identified AccessStorage values
-/// distinct. Inequality does guarantee that two *uniquely* identified
-/// AccessStorage values are distinct.
+/// `!DenseMapInfo::isEqual()` does not guarantee that two identified
+/// AccessStorage values are distinct. Inequality does, however, guarantee that
+/// two *uniquely* identified AccessStorage values are distinct.
class AccessedStorage {
public:
/// Enumerate over all valid begin_access bases. Clients can use a covered
@@ -111,26 +111,42 @@
// with the fields used within this class as a common prefix.
//
// This allows passes to embed analysis flags, and reserves enough space to
- // embed a unique access index.
+ // embed a unique index.
+ //
+ // AccessedStorageAnalysis defines an StorageAccessInfo object that maps each
+ // storage object within a function to its unique storage index and summary
+ // information of that storage object.
+ //
+ // AccessEnforcementOpts defines an AccessEnforcementOptsInfo object that maps
+ // each begin_access to its storage object, unique access index, and summary
+ // info for that access.
union {
uint64_t OpaqueBits;
- SWIFT_INLINE_BITFIELD_BASE(AccessedStorage, bitmax(NumKindBits, 8), Kind
- : bitmax(NumKindBits, 8));
+ SWIFT_INLINE_BITFIELD_BASE(AccessedStorage, bitmax(NumKindBits, 8),
+ Kind : bitmax(NumKindBits, 8));
- // Define bits for use in the AccessEnforcementOpts pass. Reserve the high
- // bit for a seenNestedConflict flag, which is the result of pass-specific
- // analysis. The remaning bits are sufficient to index all
+ // Define bits for use in AccessedStorageAnalysis. Each identified storage
+ // object is mapped to one instance of this subclass.
+ SWIFT_INLINE_BITFIELD_FULL(StorageAccessInfo, AccessedStorage,
+ 64 - NumAccessedStorageBits,
+ accessKind : NumSILAccessKindBits,
+ noNestedConflict : 1,
+ storageIndex : 64 - (NumAccessedStorageBits
+ + NumSILAccessKindBits
+ + 1));
+
+ // Define bits for use in the AccessEnforcementOpts pass. Each begin_access
+ // in the function is mapped to one instance of this subclass. Reserve a
+ // bit for a seenNestedConflict flag, which is the per-begin-access result
+ // of pass-specific analysis. The remaning bits are sufficient to index all
// begin_[unpaired_]access instructions.
//
- // `AccessEnforcementOpts` does not need to be a defined class. This macro
- // simply defines the pass-specific name "AccessEnforcementOptsBitfield".
- //
- // `AccessedStorage` identifies the AccessedStoredBitfield defined above,
+ // `AccessedStorage` refers to the AccessedStorageBitfield defined above,
// setting aside enough bits for common data.
SWIFT_INLINE_BITFIELD_FULL(AccessEnforcementOptsInfo, AccessedStorage,
64 - NumAccessedStorageBits,
- beginAccessIndex : 63 - NumAccessedStorageBits,
- seenNestedConflict : 1);
+ seenNestedConflict : 1,
+ beginAccessIndex : 63 - NumAccessedStorageBits);
} Bits;
private:
@@ -156,7 +172,7 @@
initKind(Class);
}
- // Return true if this is a valid storage location.
+ // Return true if this is a valid storage object.
operator bool() const { return getKind() != Unidentified || value; }
Kind getKind() const { return static_cast<Kind>(Bits.AccessedStorage.Kind); }
@@ -205,6 +221,20 @@
}
}
+ bool isLocal() const {
+ switch (getKind()) {
+ case Box:
+ case Stack:
+ return true;
+ case Global:
+ case Class:
+ case Argument:
+ case Nested:
+ case Unidentified:
+ return false;
+ }
+ }
+
bool isUniquelyIdentified() const {
switch (getKind()) {
case Box:
@@ -231,6 +261,13 @@
void print(raw_ostream &os) const;
void dump() const;
+
+private:
+ // Disable direct comparison because we allow subclassing with bitfields.
+ // Currently, we use DenseMapInfo to unique storage, which defines key
+ // equalilty only in terms of the base AccessedStorage class bits.
+ bool operator==(const AccessedStorage &) const = delete;
+ bool operator!=(const AccessedStorage &) const = delete;
};
} // end namespace swift
@@ -300,9 +337,9 @@
/// memory, return an AccessedStorage object that identifies the formal access.
///
/// The returned AccessedStorage represents the best attempt to find the base of
-/// the storage location being accessed at `sourceAddr`. This may be a fully
+/// the storage object being accessed at `sourceAddr`. This may be a fully
/// identified storage base of known kind, or a valid but Unidentified storage
-/// location, such as a SILPHIArgument.
+/// object, such as a SILPHIArgument.
///
/// This may return an invalid storage object if the address producer is not
/// recognized by a whitelist of recognizable access patterns. The result must
@@ -347,6 +384,14 @@
void visitAccessedAddress(SILInstruction *I,
llvm::function_ref<void(Operand *)> visitor);
+/// Perform a RAUW operation on begin_access with it's own source operand.
+/// Then erase the begin_access and all associated end_access instructions.
+/// Return an iterator to the following instruction.
+///
+/// The caller should use this iterator rather than assuming that the
+/// instruction following this begin_access was not also erased.
+SILBasicBlock::iterator removeBeginAccess(BeginAccessInst *beginAccess);
+
} // end namespace swift
#endif
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index cb3830b..0fe4591 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -3184,8 +3184,10 @@
Deinit,
// This enum is encoded.
- Last = Deinit
+ Last = Deinit,
};
+enum { NumSILAccessKindBits = 2 };
+
StringRef getSILAccessKindName(SILAccessKind kind);
/// Different kinds of exclusivity enforcement for accesses.
diff --git a/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h b/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h
index b4d1024..b0e6af4 100644
--- a/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h
@@ -15,10 +15,10 @@
// used by AccessEnforcementOpts to locally fold access scopes and remove
// dynamic checks based on whole module analysis.
//
-// Note: This can be easily augmented to simultaneously compute
-// FunctionSideEffects by adding FunctionSideEffects as a member of
-// FunctionAccessedStorage. However, currently, the only use of
-// FunctionAccessedStorage is local to summarizeFunction().
+// Note: This interprocedural analysis can be easily augmented to simultaneously
+// compute FunctionSideEffects, without using a separate analysis, by adding
+// FunctionSideEffects as a member of FunctionAccessedStorage. However, passes
+// that use AccessedStorageAnalysis do not currently need SideEffectAnalysis.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ACCESSED_STORAGE_ANALYSIS_H_
@@ -33,48 +33,139 @@
/// Information about a formal access within a function pertaining to a
/// particular AccessedStorage location.
-struct StorageAccessInfo {
- SILAccessKind accessKind;
- bool noNestedConflict = false;
+class StorageAccessInfo : public AccessedStorage {
+public:
+ StorageAccessInfo(AccessedStorage storage, SILAccessKind accessKind,
+ bool noNestedConflict)
+ : AccessedStorage(storage) {
+ Bits.StorageAccessInfo.accessKind = unsigned(accessKind);
+ Bits.StorageAccessInfo.noNestedConflict = noNestedConflict;
+ Bits.StorageAccessInfo.storageIndex = 0;
+ }
- StorageAccessInfo() {}
+ // Initialize AccessedStorage from the given storage argument and fill in
+ // subclass fields from otherStorageInfo.
+ StorageAccessInfo(AccessedStorage storage, StorageAccessInfo otherStorageInfo)
+ : StorageAccessInfo(storage, otherStorageInfo.getAccessKind(),
+ otherStorageInfo.hasNoNestedConflict()) {}
template <typename B>
- explicit StorageAccessInfo(B *beginAccess)
- : accessKind(beginAccess->getAccessKind()),
- noNestedConflict(beginAccess->hasNoNestedConflict()) {
+ StorageAccessInfo(AccessedStorage storage, B *beginAccess)
+ : StorageAccessInfo(storage, beginAccess->getAccessKind(),
+ beginAccess->hasNoNestedConflict()) {
// Currently limited to dynamic Read/Modify access.
assert(beginAccess->getEnforcement() == SILAccessEnforcement::Dynamic);
}
+ /// Get the merged access kind of all accesses on this storage. If any access
+ /// is a Modify, the return Modify, otherwise return Read.
+ SILAccessKind getAccessKind() const {
+ return SILAccessKind(Bits.StorageAccessInfo.accessKind);
+ }
+
+ void setAccessKind(SILAccessKind accessKind) {
+ Bits.StorageAccessInfo.accessKind = unsigned(accessKind);
+ }
+
+ /// Get a unique index for this accessed storage within a function.
+ unsigned getStorageIndex() const {
+ return Bits.StorageAccessInfo.storageIndex;
+ }
+
+ void setStorageIndex(unsigned index) {
+ Bits.StorageAccessInfo.storageIndex = index;
+ assert(unsigned(Bits.StorageAccessInfo.storageIndex) == index);
+ }
+
+ /// Return true if all accesses of this storage within a function have the
+ /// [no_nested_conflict] flag set.
+ bool hasNoNestedConflict() const {
+ return Bits.StorageAccessInfo.noNestedConflict;
+ }
+
+ void setNoNestedConflict(bool val) {
+ Bits.StorageAccessInfo.noNestedConflict = val;
+ }
+
bool mergeFrom(const StorageAccessInfo &RHS);
+
+ void print(raw_ostream &os) const;
+ void dump() const;
+};
+} // namespace swift
+
+// Use the same DenseMapInfo for StorageAccessInfo as for AccessedStorage. None
+// of the subclass bitfields participate in the Key.
+template <> struct llvm::DenseMapInfo<swift::StorageAccessInfo> {
+ static swift::StorageAccessInfo getEmptyKey() {
+ auto key = DenseMapInfo<swift::AccessedStorage>::getEmptyKey();
+ return static_cast<swift::StorageAccessInfo &>(key);
+ }
+
+ static swift::StorageAccessInfo getTombstoneKey() {
+ auto key = DenseMapInfo<swift::AccessedStorage>::getTombstoneKey();
+ return static_cast<swift::StorageAccessInfo &>(key);
+ }
+ static unsigned getHashValue(swift::StorageAccessInfo storage) {
+ return DenseMapInfo<swift::AccessedStorage>::getHashValue(storage);
+ }
+ static bool isEqual(swift::StorageAccessInfo LHS,
+ swift::StorageAccessInfo RHS) {
+ return DenseMapInfo<swift::AccessedStorage>::isEqual(LHS, RHS);
+ }
};
+namespace swift {
/// The per-function result of AccessedStorageAnalysis.
///
-/// Maps each unique AccessedStorage location to StorageAccessInfo.
+/// Records each unique AccessedStorage in a set of StorageAccessInfo
+/// objects. Hashing and equality only sees the AccesedStorage data. The
+/// additional StorageAccessInfo bits are recorded as results of this analysis.
///
/// Any unidentified accesses are summarized as a single unidentifiedAccess
/// property.
class FunctionAccessedStorage {
- using AccessedStorageMap =
- llvm::SmallDenseMap<AccessedStorage, StorageAccessInfo, 8>;
+ using AccessedStorageSet = llvm::SmallDenseSet<StorageAccessInfo, 8>;
- AccessedStorageMap storageAccessMap;
+ AccessedStorageSet storageAccessSet;
Optional<SILAccessKind> unidentifiedAccess;
public:
FunctionAccessedStorage() {}
+ // ---------------------------------------------------------------------------
+ // Accessing the results.
+
+ bool hasUnidentifiedAccess() const { return unidentifiedAccess != None; }
+
+ /// Return true if the analysis has determined all accesses of otherStorage
+ /// have the [no_nested_conflict] flag set.
+ ///
+ /// Only call this if there is no unidentifiedAccess in the function and the
+ /// given storage is uniquely identified.
+ bool hasNoNestedConflict(const AccessedStorage &otherStorage) const;
+
+ /// Does any of the accesses represented by this FunctionAccessedStorage
+ /// object conflict with the given access kind and storage.
+ bool mayConflictWith(SILAccessKind otherAccessKind,
+ const AccessedStorage &otherStorage) const;
+
+ /// Raw access to the result for a given AccessedStorage location.
+ StorageAccessInfo
+ getStorageAccessInfo(const AccessedStorage &otherStorage) const;
+
+ // ---------------------------------------------------------------------------
+ // Constructing the results.
+
void clear() {
- storageAccessMap.clear();
+ storageAccessSet.clear();
unidentifiedAccess = None;
}
/// Sets the most conservative effects, if we don't know anything about the
/// function.
void setWorstEffects() {
- storageAccessMap.clear();
+ storageAccessSet.clear();
unidentifiedAccess = SILAccessKind::Modify;
}
@@ -98,7 +189,7 @@
///
/// TODO: Summarize ArraySemanticsCall accesses.
bool summarizeCall(FullApplySite fullApply) {
- assert(storageAccessMap.empty() && "expected uninitialized results.");
+ assert(storageAccessSet.empty() && "expected uninitialized results.");
return false;
}
@@ -121,20 +212,22 @@
/// reaches MaxRecursionDepth.
void analyzeInstruction(SILInstruction *I);
- /// Does any of the accesses represented by this FunctionAccessedStorage
- /// object conflict with the given access kind and storage.
- bool mayConflictWith(SILAccessKind otherAccessKind,
- const AccessedStorage &otherStorage);
-
void print(raw_ostream &os) const;
void dump() const;
protected:
+ std::pair<AccessedStorageSet::iterator, bool>
+ insertStorageAccess(StorageAccessInfo storageAccess) {
+ storageAccess.setStorageIndex(storageAccessSet.size());
+ return storageAccessSet.insert(storageAccess);
+ }
+
bool updateUnidentifiedAccess(SILAccessKind accessKind);
bool mergeAccesses(
- const FunctionAccessedStorage &RHS,
- std::function<AccessedStorage(const AccessedStorage &)> transformStorage);
+ const FunctionAccessedStorage &other,
+ std::function<StorageAccessInfo(const StorageAccessInfo &)>
+ transformStorage);
template <typename B> void visitBeginAccess(B *beginAccess);
};
@@ -149,6 +242,10 @@
/// marked as potentially executing unidentified reads or writes. An incomplete
/// function, without a known callee set, is considered to have unidentified
/// writes.
+///
+/// Use the GenericFunctionEffectAnalysis API to get the results of the analysis:
+/// - geEffects(SILFunction*)
+/// - getCallSiteEffects(FunctionEffects &callEffects, FullApplySite fullApply)
class AccessedStorageAnalysis
: public GenericFunctionEffectAnalysis<FunctionAccessedStorage> {
public:
diff --git a/include/swift/SILOptimizer/PassManager/Passes.def b/include/swift/SILOptimizer/PassManager/Passes.def
index 2732582..8d9cab9 100644
--- a/include/swift/SILOptimizer/PassManager/Passes.def
+++ b/include/swift/SILOptimizer/PassManager/Passes.def
@@ -236,6 +236,8 @@
"Deserialize all referenced SIL functions that are shared or transparent")
PASS(PerformanceSILLinker, "performance-linker",
"Deserialize all referenced SIL functions")
+PASS(RawSILInstLowering, "raw-sil-inst-lowering",
+ "Lower all raw SIL instructions to canonical equivalents.")
PASS(RemovePins, "remove-pins",
"Remove SIL pin/unpin pairs")
PASS(TempRValueOpt, "temp-rvalue-opt",
diff --git a/include/swift/TBDGen/TBDGen.h b/include/swift/TBDGen/TBDGen.h
index ba9121c..eca9386 100644
--- a/include/swift/TBDGen/TBDGen.h
+++ b/include/swift/TBDGen/TBDGen.h
@@ -23,13 +23,23 @@
class FileUnit;
class ModuleDecl;
-void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,
- bool hasMultipleIGMs);
-void enumeratePublicSymbols(ModuleDecl *module, llvm::StringSet<> &symbols,
- bool hasMultipleIGMs);
+/// \brief Options for controlling the exact set of symbols included in the TBD
+/// output.
+struct TBDGenOptions {
+ /// \brief Whether this compilation has multiple IRGen instances.
+ bool HasMultipleIGMs;
+ /// \brief The install-name used for the compilation.
+ llvm::StringRef InstallName;
+ /// \brief The module link name (for force loading).
+ llvm::StringRef ModuleLinkName;
+};
-void writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os, bool hasMultipleIGMs,
- llvm::StringRef installName);
+void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,
+ TBDGenOptions &opts);
+void enumeratePublicSymbols(ModuleDecl *module, llvm::StringSet<> &symbols,
+ TBDGenOptions &opts);
+
+void writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os, TBDGenOptions &opts);
} // end namespace swift
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 6a1ac4c..387f2aa 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2837,8 +2837,8 @@
true,
classDecl->getFullName(),
protocolName);
- Diags.diagnose(req, diag::protocol_requirement_here,
- reqDiagInfo.second);
+ Diags.diagnose(req, diag::kind_declname_declared_here,
+ DescriptiveDeclKind::Requirement, reqDiagInfo.second);
anyDiagnosed = true;
}
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 2bddd96..3d01c3e 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -425,7 +425,7 @@
void printRec(Decl *D) { D->dump(OS, Indent + 2); }
void printRec(Expr *E) { E->print(OS, Indent + 2); }
- void printRec(Stmt *S) { S->print(OS, Indent + 2); }
+ void printRec(Stmt *S, const ASTContext &Ctx) { S->print(OS, &Ctx, Indent + 2); }
void printRec(TypeRepr *T);
void printRec(const Pattern *P) {
PrintPattern(OS, Indent+2).visit(const_cast<Pattern *>(P));
@@ -553,7 +553,7 @@
void printRec(Decl *D) { PrintDecl(OS, Indent + 2).visit(D); }
void printRec(Expr *E) { E->print(OS, Indent+2); }
- void printRec(Stmt *S) { S->print(OS, Indent+2); }
+ void printRec(Stmt *S, const ASTContext &Ctx) { S->print(OS, &Ctx, Indent+2); }
void printRec(Pattern *P) { PrintPattern(OS, Indent+2).visit(P); }
void printRec(TypeRepr *T);
@@ -575,6 +575,13 @@
if (D->isImplicit())
PrintWithColorRAII(OS, DeclModifierColor) << " implicit";
+ auto R = D->getSourceRange();
+ if (R.isValid()) {
+ PrintWithColorRAII(OS, RangeColor) << " range=";
+ R.print(PrintWithColorRAII(OS, RangeColor).getOS(),
+ D->getASTContext().SourceMgr, /*PrintText=*/false);
+ }
+
if (D->TrailingSemiLoc.isValid())
PrintWithColorRAII(OS, DeclModifierColor) << " trailing_semi";
}
@@ -984,7 +991,7 @@
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
- void printParameterList(const ParameterList *params) {
+ void printParameterList(const ParameterList *params, const ASTContext *ctx = nullptr) {
OS.indent(Indent);
PrintWithColorRAII(OS, ParenthesisColor) << '(';
PrintWithColorRAII(OS, ParameterColor) << "parameter_list";
@@ -993,6 +1000,19 @@
OS << '\n';
printParameter(P);
}
+
+ if (!ctx && params->size() != 0 && params->get(0))
+ ctx = ¶ms->get(0)->getASTContext();
+
+ if (ctx) {
+ auto R = params->getSourceRange();
+ if (R.isValid()) {
+ PrintWithColorRAII(OS, RangeColor) << " range=";
+ R.print(PrintWithColorRAII(OS, RangeColor).getOS(),
+ ctx->SourceMgr, /*PrintText=*/false);
+ }
+ }
+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
Indent -= 2;
}
@@ -1001,7 +1021,7 @@
for (auto pl : D->getParameterLists()) {
OS << '\n';
Indent += 2;
- printParameterList(pl);
+ printParameterList(pl, &D->getASTContext());
Indent -= 2;
}
if (auto FD = dyn_cast<FuncDecl>(D)) {
@@ -1018,7 +1038,7 @@
}
if (auto Body = D->getBody(/*canSynthesize=*/false)) {
OS << '\n';
- printRec(Body);
+ printRec(Body, D->getASTContext());
}
}
@@ -1065,12 +1085,12 @@
printCommon(TLCD, "top_level_code_decl");
if (TLCD->getBody()) {
OS << "\n";
- printRec(TLCD->getBody());
+ printRec(TLCD->getBody(), static_cast<Decl *>(TLCD)->getASTContext());
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
- void printASTNodes(const ArrayRef<ASTNode> &Elements, StringRef Name) {
+ void printASTNodes(const ArrayRef<ASTNode> &Elements, const ASTContext &Ctx, StringRef Name) {
OS.indent(Indent);
PrintWithColorRAII(OS, ParenthesisColor) << "(";
PrintWithColorRAII(OS, ASTNodeColor) << Name;
@@ -1079,7 +1099,7 @@
if (auto *SubExpr = Elt.dyn_cast<Expr*>())
printRec(SubExpr);
else if (auto *SubStmt = Elt.dyn_cast<Stmt*>())
- printRec(SubStmt);
+ printRec(SubStmt, Ctx);
else
printRec(Elt.get<Decl*>());
}
@@ -1102,7 +1122,7 @@
OS << '\n';
Indent += 2;
- printASTNodes(Clause.Elements, "elements");
+ printASTNodes(Clause.Elements, ICD->getASTContext(), "elements");
Indent -= 2;
}
@@ -1349,9 +1369,11 @@
class PrintStmt : public StmtVisitor<PrintStmt> {
public:
raw_ostream &OS;
+ const ASTContext *Ctx;
unsigned Indent;
- PrintStmt(raw_ostream &os, unsigned indent) : OS(os), Indent(indent) {
+ PrintStmt(raw_ostream &os, const ASTContext *ctx, unsigned indent)
+ : OS(os), Ctx(ctx), Indent(indent) {
}
void printRec(Stmt *S) {
@@ -1418,6 +1440,15 @@
if (S->isImplicit())
OS << " implicit";
+ if (Ctx) {
+ auto R = S->getSourceRange();
+ if (R.isValid()) {
+ PrintWithColorRAII(OS, RangeColor) << " range=";
+ R.print(PrintWithColorRAII(OS, RangeColor).getOS(),
+ Ctx->SourceMgr, /*PrintText=*/false);
+ }
+ }
+
if (S->TrailingSemiLoc.isValid())
OS << " trailing_semi";
@@ -1425,13 +1456,12 @@
}
void visitBraceStmt(BraceStmt *S) {
- printASTNodes(S->getElements(), "brace_stmt");
+ printCommon(S, "brace_stmt");
+ printASTNodes(S->getElements());
+ PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
- void printASTNodes(const ArrayRef<ASTNode> &Elements, StringRef Name) {
- OS.indent(Indent);
- PrintWithColorRAII(OS, ParenthesisColor) << "(";
- PrintWithColorRAII(OS, ASTNodeColor) << Name;
+ void printASTNodes(const ArrayRef<ASTNode> &Elements) {
for (auto Elt : Elements) {
OS << '\n';
if (auto *SubExpr = Elt.dyn_cast<Expr*>())
@@ -1441,7 +1471,6 @@
else
printRec(Elt.get<Decl*>());
}
- PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitReturnStmt(ReturnStmt *S) {
@@ -1625,8 +1654,8 @@
llvm::errs() << '\n';
}
-void Stmt::print(raw_ostream &OS, unsigned Indent) const {
- PrintStmt(OS, Indent).visit(const_cast<Stmt*>(this));
+void Stmt::print(raw_ostream &OS, const ASTContext *Ctx, unsigned Indent) const {
+ PrintStmt(OS, Ctx, Indent).visit(const_cast<Stmt*>(this));
}
//===----------------------------------------------------------------------===//
@@ -1662,6 +1691,7 @@
Indent += 2;
OS.indent(Indent);
PrintWithColorRAII(OS, ParenthesisColor) << '(';
+ PrintWithColorRAII(OS, ExprColor) << label;
OS << '\n';
printRec(E);
PrintWithColorRAII(OS, ParenthesisColor) << ')';
@@ -1671,7 +1701,7 @@
/// FIXME: This should use ExprWalker to print children.
void printRec(Decl *D) { D->dump(OS, Indent + 2); }
- void printRec(Stmt *S) { S->print(OS, Indent + 2); }
+ void printRec(Stmt *S, const ASTContext &Ctx) { S->print(OS, &Ctx, Indent + 2); }
void printRec(const Pattern *P) {
PrintPattern(OS, Indent+2).visit(const_cast<Pattern *>(P));
}
@@ -1720,6 +1750,15 @@
return OS;
}
+
+ void printSemanticExpr(Expr * semanticExpr) {
+ if (semanticExpr == nullptr) {
+ return;
+ }
+
+ OS << '\n';
+ printRecLabeled(semanticExpr, "semantic_expr");
+ }
void visitErrorExpr(ErrorExpr *E) {
printCommon(E, "error_expr");
@@ -1780,6 +1819,7 @@
OS << '\n';
printRec(Segment);
}
+ printSemanticExpr(E->getSemanticExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E) {
@@ -1803,6 +1843,8 @@
printArgumentLabels(E->getArgumentLabels());
OS << "\n";
printRec(E->getArg());
+ printSemanticExpr(E->getSemanticExpr());
+ PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitDiscardAssignmentExpr(DiscardAssignmentExpr *E) {
@@ -1954,20 +1996,16 @@
OS << '\n';
printRec(elt);
}
+ printSemanticExpr(E->getSemanticExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitDictionaryExpr(DictionaryExpr *E) {
printCommon(E, "dictionary_expr");
- if (auto semaE = E->getSemanticExpr()) {
- OS << '\n';
- printRec(semaE);
- PrintWithColorRAII(OS, ParenthesisColor) << ')';
- return;
- }
for (auto elt : E->getElements()) {
OS << '\n';
printRec(elt);
}
+ printSemanticExpr(E->getSemanticExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitSubscriptExpr(SubscriptExpr *E) {
@@ -2274,14 +2312,14 @@
if (E->getParameters()) {
OS << '\n';
- PrintDecl(OS, Indent+2).printParameterList(E->getParameters());
+ PrintDecl(OS, Indent+2).printParameterList(E->getParameters(), &E->getASTContext());
}
OS << '\n';
if (E->hasSingleExpressionBody()) {
printRec(E->getSingleExpressionBody());
} else {
- printRec(E->getBody());
+ printRec(E->getBody(), E->getASTContext());
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
@@ -2290,7 +2328,7 @@
if (E->getParameters()) {
OS << '\n';
- PrintDecl(OS, Indent+2).printParameterList(E->getParameters());
+ PrintDecl(OS, Indent+2).printParameterList(E->getParameters(), &E->getASTContext());
}
OS << '\n';
@@ -2467,6 +2505,7 @@
OS << '\n';
printRec(ExpTyR);
}
+ printSemanticExpr(E->getSemanticExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitObjCSelectorExpr(ObjCSelectorExpr *E) {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index c324cd6..70041fa 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -252,6 +252,7 @@
ENTRY(TypeAlias, "type alias");
ENTRY(GenericTypeParam, "generic parameter");
ENTRY(AssociatedType, "associated type");
+ ENTRY(Type, "type");
ENTRY(Enum, "enum");
ENTRY(Struct, "struct");
ENTRY(Class, "class");
@@ -259,6 +260,7 @@
ENTRY(GenericEnum, "generic enum");
ENTRY(GenericStruct, "generic struct");
ENTRY(GenericClass, "generic class");
+ ENTRY(GenericType, "generic type");
ENTRY(Subscript, "subscript");
ENTRY(Constructor, "initializer");
ENTRY(Destructor, "deinitializer");
@@ -278,6 +280,7 @@
ENTRY(EnumElement, "enum element");
ENTRY(Module, "module");
ENTRY(MissingMember, "missing member placeholder");
+ ENTRY(Requirement, "requirement");
}
#undef ENTRY
llvm_unreachable("bad DescriptiveDeclKind");
@@ -4551,7 +4554,7 @@
}
void DefaultArgumentInitializer::changeFunction(
- DeclContext *parent, MutableArrayRef<ParameterList *> paramLists) {
+ DeclContext *parent, ArrayRef<ParameterList *> paramLists) {
if (parent->isLocalContext()) {
setParent(parent);
}
@@ -5465,21 +5468,6 @@
DiagnosticEngine *diags)
: Decl(decl), Diags(diags) { }
- bool isSelfExpr(Expr *E) {
- E = E->getSemanticsProvidingExpr();
-
- if (auto ATSE = dyn_cast<ArchetypeToSuperExpr>(E))
- E = ATSE->getSubExpr();
- if (auto IOE = dyn_cast<InOutExpr>(E))
- E = IOE->getSubExpr();
- if (auto LE = dyn_cast<LoadExpr>(E))
- E = LE->getSubExpr();
- if (auto DRE = dyn_cast<DeclRefExpr>(E))
- return DRE->getDecl() == Decl->getImplicitSelfDecl();
-
- return false;
- }
-
bool walkToDeclPre(class Decl *D) override {
// Don't walk into further nominal decls.
return !isa<NominalTypeDecl>(D);
@@ -5517,7 +5505,7 @@
BodyInitKind myKind;
if (arg->isSuperExpr())
myKind = BodyInitKind::Chained;
- else if (isSelfExpr(arg))
+ else if (arg->isSelfExprOf(Decl, /*sameBase*/true))
myKind = BodyInitKind::Delegating;
else {
// We're constructing something else.
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 10a2a73..f9f60dd 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2174,6 +2174,23 @@
return Res;
}
+bool Expr::isSelfExprOf(const AbstractFunctionDecl *AFD, bool sameBase) const {
+ auto *E = getSemanticsProvidingExpr();
+
+ if (auto IOE = dyn_cast<InOutExpr>(E))
+ E = IOE->getSubExpr();
+
+ while (auto ICE = dyn_cast<ImplicitConversionExpr>(E)) {
+ if (sameBase && isa<DerivedToBaseExpr>(ICE))
+ return false;
+ E = ICE->getSubExpr();
+ }
+
+ if (auto DRE = dyn_cast<DeclRefExpr>(E))
+ return DRE->getDecl() == AFD->getImplicitSelfDecl();
+
+ return false;
+}
ArchetypeType *OpenExistentialExpr::getOpenedArchetype() const {
auto type = getOpaqueValue()->getType()->getRValueType();
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 9334571..d1146f3 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -6988,17 +6988,24 @@
void GenericSignatureBuilder::checkConcreteTypeConstraints(
TypeArrayView<GenericTypeParamType> genericParams,
EquivalenceClass *equivClass) {
+ // Resolve any thus-far-unresolved dependent types.
+ Type resolvedConcreteType =
+ resolveDependentMemberTypes(*this, equivClass->concreteType);
+
checkConstraintList<Type>(
genericParams, equivClass->concreteTypeConstraints,
[&](const ConcreteConstraint &constraint) {
- return constraint.value->isEqual(equivClass->concreteType);
+ if (constraint.value->isEqual(resolvedConcreteType))
+ return true;
+
+ auto resolvedType =
+ resolveDependentMemberTypes(*this, constraint.value);
+ return resolvedType->isEqual(resolvedConcreteType);
},
[&](const Constraint<Type> &constraint) {
Type concreteType = constraint.value;
// If the concrete type is equivalent, the constraint is redundant.
- // FIXME: Should check this constraint after substituting in the
- // archetype anchors for each dependent type.
if (concreteType->isEqual(equivClass->concreteType))
return ConstraintRelation::Redundant;
@@ -7013,9 +7020,7 @@
diag::redundant_same_type_to_concrete,
diag::same_type_redundancy_here);
- // Resolve any thus-far-unresolved dependent types.
- equivClass->concreteType =
- resolveDependentMemberTypes(*this, equivClass->concreteType);
+ equivClass->concreteType = resolvedConcreteType;
}
void GenericSignatureBuilder::checkSuperclassConstraints(
@@ -7023,23 +7028,20 @@
EquivalenceClass *equivClass) {
assert(equivClass->superclass && "No superclass constraint?");
- // FIXME: We should be substituting in the canonical type in context so
- // we can resolve superclass requirements, e.g., if you had:
- //
- // class Foo<T>
- // class Bar: Foo<Int>
- //
- // func foo<T, U where U: Bar, U: Foo<T>>(...) { ... }
- //
- // then the second `U: Foo<T>` constraint introduces a `T == Int`
- // constraint, and we will need to perform that substitution for this final
- // check.
+ // Resolve any this-far-unresolved dependent types.
+ Type resolvedSuperclass =
+ resolveDependentMemberTypes(*this, equivClass->superclass);
auto representativeConstraint =
checkConstraintList<Type>(
genericParams, equivClass->superclassConstraints,
[&](const ConcreteConstraint &constraint) {
- return constraint.value->isEqual(equivClass->superclass);
+ if (constraint.value->isEqual(resolvedSuperclass))
+ return true;
+
+ Type resolvedType =
+ resolveDependentMemberTypes(*this, constraint.value);
+ return resolvedType->isEqual(equivClass->superclass);
},
[&](const Constraint<Type> &constraint) {
Type superclass = constraint.value;
@@ -7056,15 +7058,16 @@
diag::superclass_redundancy_here);
// Resolve any this-far-unresolved dependent types.
- equivClass->superclass =
- resolveDependentMemberTypes(*this, equivClass->superclass);
+ equivClass->superclass = resolvedSuperclass;
// If we have a concrete type, check it.
// FIXME: Substitute into the concrete type.
if (equivClass->concreteType) {
+ Type resolvedConcreteType =
+ resolveDependentMemberTypes(*this, equivClass->concreteType);
auto existing = equivClass->findAnyConcreteConstraintAsWritten();
// Make sure the concrete type fulfills the superclass requirement.
- if (!equivClass->superclass->isExactSuperclassOf(equivClass->concreteType)){
+ if (!equivClass->superclass->isExactSuperclassOf(resolvedConcreteType)){
Impl->HadAnyError = true;
if (existing) {
Diags.diagnose(existing->source->getLoc(), diag::type_does_not_inherit,
@@ -7084,7 +7087,7 @@
diag::type_does_not_inherit,
representativeConstraint.getSubjectDependentType(
genericParams),
- equivClass->concreteType, equivClass->superclass);
+ resolvedConcreteType, equivClass->superclass);
}
} else if (representativeConstraint.source->shouldDiagnoseRedundancy(true)
&& existing &&
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index ddf5a00..cdb536c 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -275,6 +275,11 @@
// Substitute into the replacement type.
replacementType = concreteType.subst(*this);
+
+ // If the generic signature is canonical, canonicalize the replacement type.
+ if (getGenericSignature()->isCanonical())
+ replacementType = replacementType->getCanonicalType();
+
return replacementType;
}
@@ -290,6 +295,11 @@
replacementType = ErrorType::get(type);
replacementType = lookupSubstitution(cast<SubstitutableType>(canonicalType));
+
+ // If the generic signature is canonical, canonicalize the replacement type.
+ if (getGenericSignature()->isCanonical())
+ replacementType = replacementType->getCanonicalType();
+
return replacementType;
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index f2391a5..308b536 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2768,14 +2768,6 @@
return FunctionType::get(input, result, getExtInfo());
}
-FunctionType *
-GenericFunctionType::substGenericArgs(TypeSubstitutionFn subs,
- LookupConformanceFn conformances) {
- Type input = getInput().subst(subs, conformances);
- Type result = getResult().subst(subs, conformances);
- return FunctionType::get(input, result, getExtInfo());
-}
-
static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
Type origBase,
Type substBase,
diff --git a/lib/ClangImporter/ClangDiagnosticConsumer.cpp b/lib/ClangImporter/ClangDiagnosticConsumer.cpp
index e5f088f..bff677a 100644
--- a/lib/ClangImporter/ClangDiagnosticConsumer.cpp
+++ b/lib/ClangImporter/ClangDiagnosticConsumer.cpp
@@ -66,8 +66,18 @@
StringRef Message,
ArrayRef<clang::CharSourceRange> Ranges,
clang::DiagOrStoredDiag Info) override {
- if (shouldSuppressDiagInSwiftBuffers(Info) && isInSwiftBuffers(Loc))
- return;
+ if (isInSwiftBuffers(Loc)) {
+ // FIXME: Ideally, we'd report non-suppressed diagnostics on synthetic
+ // buffers, printing their names (eg. <swift-imported-modules>:...) but
+ // this risks printing _excerpts_ of those buffers to stderr too; at
+ // present the synthetic buffers are "large blocks of null bytes" which
+ // we definitely don't want to print out. So until we have some clever
+ // way to print the name but suppress printing excerpts, we just replace
+ // the Loc with an invalid one here, which suppresses both.
+ Loc = clang::FullSourceLoc();
+ if (shouldSuppressDiagInSwiftBuffers(Info))
+ return;
+ }
callback(Loc, Level, Message);
}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 3fe2c0f..66cfd26 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -244,6 +244,10 @@
validateDebugInfoArgs(diags, args);
validateCompilationConditionArgs(diags, args);
validateAutolinkingArgs(diags, args);
+
+ if (args.hasArg(options::OPT_emit_public_type_metadata_accessors))
+ diags.diagnose(SourceLoc(),
+ diag::warn_emit_public_type_metadata_accessors_deprecated);
}
std::unique_ptr<ToolChain>
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 5caeb5e..d7adb87 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -183,8 +183,6 @@
options::OPT_warn_swift3_objc_inference_minimal,
options::OPT_warn_swift3_objc_inference_complete);
inputArgs.AddLastArg(arguments, options::OPT_typo_correction_limit);
- inputArgs.AddLastArg(arguments,
- options::OPT_emit_public_type_metadata_accessors);
inputArgs.AddLastArg(arguments, options::OPT_enable_app_extension);
inputArgs.AddLastArg(arguments, options::OPT_enable_testing);
inputArgs.AddLastArg(arguments, options::OPT_g_Group);
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index fc1bad9..333a091 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -309,9 +309,6 @@
}
}
- Opts.EmitPublicTypeMetadataAccessors =
- Args.hasArg(OPT_emit_public_type_metadata_accessors);
-
Opts.EnableNSKeyedArchiverDiagnostics =
Args.hasFlag(OPT_enable_nskeyedarchiver_diagnostics,
OPT_disable_nskeyedarchiver_diagnostics,
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index e6904d6..20603e0 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -61,6 +61,7 @@
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/Syntax/Serialization/SyntaxSerialization.h"
#include "swift/Syntax/SyntaxNodes.h"
+#include "swift/TBDGen/TBDGen.h"
// FIXME: We're just using CompilerInstance::createOutputFile.
// This API should be sunk down to LLVM.
@@ -764,20 +765,24 @@
static bool writeTBDIfNeeded(CompilerInvocation &Invocation,
CompilerInstance &Instance) {
- if (!Invocation.getFrontendOptions().InputsAndOutputs.hasTBDPath())
+ const auto &frontendOpts = Invocation.getFrontendOptions();
+ if (!frontendOpts.InputsAndOutputs.hasTBDPath())
return false;
const std::string &TBDPath = Invocation.getTBDPathForWholeModule();
assert(!TBDPath.empty() &&
"If not WMO, getTBDPathForWholeModule should have failed");
- auto installName = Invocation.getFrontendOptions().TBDInstallName.empty()
+ auto installName = frontendOpts.TBDInstallName.empty()
? "lib" + Invocation.getModuleName().str() + ".dylib"
- : Invocation.getFrontendOptions().TBDInstallName;
+ : frontendOpts.TBDInstallName;
- return writeTBD(Instance.getMainModule(),
- Invocation.getSILOptions().hasMultipleIGMs(), TBDPath,
- installName);
+ TBDGenOptions opts;
+ opts.InstallName = installName;
+ opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
+ opts.ModuleLinkName = frontendOpts.ModuleLinkName;
+
+ return writeTBD(Instance.getMainModule(), TBDPath, opts);
}
static std::deque<PostSILGenInputs>
@@ -1138,7 +1143,8 @@
!inputFileKindCanHaveTBDValidated(Invocation.getInputKind()))
return false;
- const auto mode = Invocation.getFrontendOptions().ValidateTBDAgainstIR;
+ const auto &frontendOpts = Invocation.getFrontendOptions();
+ const auto mode = frontendOpts.ValidateTBDAgainstIR;
// Ensure all cases are covered by using a switch here.
switch (mode) {
case FrontendOptions::TBDValidationMode::None:
@@ -1147,12 +1153,14 @@
case FrontendOptions::TBDValidationMode::MissingFromTBD:
break;
}
- const auto hasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
+ TBDGenOptions opts;
+ opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
+ opts.ModuleLinkName = frontendOpts.ModuleLinkName;
+
const bool allSymbols = mode == FrontendOptions::TBDValidationMode::All;
- return MSF.is<SourceFile *>() ? validateTBD(MSF.get<SourceFile *>(), IRModule,
- hasMultipleIGMs, allSymbols)
- : validateTBD(MSF.get<ModuleDecl *>(), IRModule,
- hasMultipleIGMs, allSymbols);
+ return MSF.is<SourceFile *>()
+ ? validateTBD(MSF.get<SourceFile *>(), IRModule, opts, allSymbols)
+ : validateTBD(MSF.get<ModuleDecl *>(), IRModule, opts, allSymbols);
}
static bool generateCode(CompilerInvocation &Invocation,
diff --git a/lib/FrontendTool/TBD.cpp b/lib/FrontendTool/TBD.cpp
index 2c93389..0a634be 100644
--- a/lib/FrontendTool/TBD.cpp
+++ b/lib/FrontendTool/TBD.cpp
@@ -38,8 +38,8 @@
return sorted;
}
-bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIGMs,
- StringRef OutputFilename, StringRef installName) {
+bool swift::writeTBD(ModuleDecl *M, StringRef OutputFilename,
+ TBDGenOptions &Opts) {
std::error_code EC;
llvm::raw_fd_ostream OS(OutputFilename, EC, llvm::sys::fs::F_None);
if (EC) {
@@ -48,7 +48,7 @@
return true;
}
- writeTBDFile(M, OS, hasMultipleIGMs, installName);
+ writeTBDFile(M, OS, Opts);
return false;
}
@@ -117,18 +117,18 @@
}
bool swift::validateTBD(ModuleDecl *M, llvm::Module &IRModule,
- bool hasMultipleIGMs, bool diagnoseExtraSymbolsInTBD) {
+ TBDGenOptions &opts, bool diagnoseExtraSymbolsInTBD) {
llvm::StringSet<> symbols;
- enumeratePublicSymbols(M, symbols, hasMultipleIGMs);
+ enumeratePublicSymbols(M, symbols, opts);
return validateSymbolSet(M->getASTContext().Diags, symbols, IRModule,
diagnoseExtraSymbolsInTBD);
}
bool swift::validateTBD(FileUnit *file, llvm::Module &IRModule,
- bool hasMultipleIGMs, bool diagnoseExtraSymbolsInTBD) {
+ TBDGenOptions &opts, bool diagnoseExtraSymbolsInTBD) {
llvm::StringSet<> symbols;
- enumeratePublicSymbols(file, symbols, hasMultipleIGMs);
+ enumeratePublicSymbols(file, symbols, opts);
return validateSymbolSet(file->getParentModule()->getASTContext().Diags,
symbols, IRModule, diagnoseExtraSymbolsInTBD);
diff --git a/lib/FrontendTool/TBD.h b/lib/FrontendTool/TBD.h
index bda0922..c6e8610 100644
--- a/lib/FrontendTool/TBD.h
+++ b/lib/FrontendTool/TBD.h
@@ -23,13 +23,13 @@
class ModuleDecl;
class FileUnit;
class FrontendOptions;
+struct TBDGenOptions;
-bool writeTBD(ModuleDecl *M, bool hasMultipleIGMs, StringRef OutputFilename,
- llvm::StringRef installName);
+bool writeTBD(ModuleDecl *M, StringRef OutputFilename, TBDGenOptions &Opts);
bool inputFileKindCanHaveTBDValidated(InputFileKind kind);
-bool validateTBD(ModuleDecl *M, llvm::Module &IRModule, bool hasMultipleIGMs,
+bool validateTBD(ModuleDecl *M, llvm::Module &IRModule, TBDGenOptions &opts,
bool diagnoseExtraSymbolsInTBD);
-bool validateTBD(FileUnit *M, llvm::Module &IRModule, bool hasMultipleIGMs,
+bool validateTBD(FileUnit *M, llvm::Module &IRModule, TBDGenOptions &opts,
bool diagnoseExtraSymbolsInTBD);
}
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index 01dd514..1c8e110 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -1318,7 +1318,7 @@
if (!DC)
return;
auto *CD = DC->getAsClassOrClassExtensionContext();
- if (CD == nullptr)
+ if (!CD)
return;
Type ST = CD->getSuperclass();
if (ST.isNull() || ST->is<ErrorType>())
@@ -2838,23 +2838,29 @@
}
void addKeyword(StringRef Name, Type TypeAnnotation,
- SemanticContextKind SK = SemanticContextKind::None) {
+ SemanticContextKind SK = SemanticContextKind::None,
+ CodeCompletionKeywordKind KeyKind
+ = CodeCompletionKeywordKind::None) {
CodeCompletionResultBuilder Builder(
Sink,
CodeCompletionResult::ResultKind::Keyword, SK, ExpectedTypes);
addLeadingDot(Builder);
Builder.addTextChunk(Name);
+ Builder.setKeywordKind(KeyKind);
if (!TypeAnnotation.isNull())
addTypeAnnotation(Builder, TypeAnnotation);
}
- void addKeyword(StringRef Name, StringRef TypeAnnotation) {
+ void addKeyword(StringRef Name, StringRef TypeAnnotation,
+ CodeCompletionKeywordKind KeyKind
+ = CodeCompletionKeywordKind::None) {
CodeCompletionResultBuilder Builder(
Sink,
CodeCompletionResult::ResultKind::Keyword,
SemanticContextKind::None, ExpectedTypes);
addLeadingDot(Builder);
Builder.addTextChunk(Name);
+ Builder.setKeywordKind(KeyKind);
if (!TypeAnnotation.empty())
Builder.addTypeAnnotation(TypeAnnotation);
}
@@ -3259,14 +3265,13 @@
ExprType = ExprType->getRValueType();
this->ExprType = ExprType;
if (ExprType->hasTypeParameter()) {
- DeclContext *DC;
- if (VD) {
+ DeclContext *DC = nullptr;
+ if (VD)
DC = VD->getInnermostDeclContext();
- this->ExprType = DC->mapTypeIntoContext(ExprType);
- } else if (auto NTD = ExprType->getRValueInstanceType()->getAnyNominal()) {
+ else if (auto NTD = ExprType->getRValueInstanceType()->getAnyNominal())
DC = NTD;
- this->ExprType = DC->mapTypeIntoContext(ExprType);
- }
+ if (DC)
+ ExprType = DC->mapTypeIntoContext(ExprType);
}
// Handle special cases
@@ -5316,6 +5321,11 @@
if (isDynamicLookup(*ExprType))
Lookup.setIsDynamicLookup();
+ if (!ExprType.getValue()->getAs<ModuleType>())
+ Lookup.addKeyword("self", (*ExprType)->getRValueType(),
+ SemanticContextKind::CurrentNominal,
+ CodeCompletionKeywordKind::kw_self);
+
if (isa<BindOptionalExpr>(ParsedExpr) || isa<ForceValueExpr>(ParsedExpr))
Lookup.setIsUnwrappedOptional(true);
@@ -5364,6 +5374,11 @@
Lookup.setIsDynamicLookup();
Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
Lookup.getOperatorCompletions(ParsedExpr, leadingSequenceExprs);
+
+ if (!ExprType.getValue()->getAs<ModuleType>())
+ Lookup.addKeyword("self", (*ExprType)->getRValueType(),
+ SemanticContextKind::CurrentNominal,
+ CodeCompletionKeywordKind::kw_self);
break;
}
diff --git a/lib/IDE/Refactoring.cpp b/lib/IDE/Refactoring.cpp
index 9d3974d..88a382e 100644
--- a/lib/IDE/Refactoring.cpp
+++ b/lib/IDE/Refactoring.cpp
@@ -908,6 +908,15 @@
return ExtractCheckResult();
}
+ // Disallow extracting certain kinds of statements.
+ if (RangeInfo.Kind == RangeKind::SingleStatement) {
+ Stmt *S = RangeInfo.ContainedNodes[0].get<Stmt *>();
+
+ // These aren't independent statement.
+ if (isa<BraceStmt>(S) || isa<CatchStmt>(S) || isa<CaseStmt>(S))
+ return ExtractCheckResult();
+ }
+
// Disallow extracting literals.
if (RangeInfo.Kind == RangeKind::SingleExpression) {
Expr *E = RangeInfo.ContainedNodes[0].get<Expr*>();
@@ -1659,109 +1668,70 @@
return false;
}
-struct CollapsibleNestedIfInfo {
- IfStmt *OuterIf;
- IfStmt *InnerIf;
- bool FinishedOuterIf;
- bool FoundNonCollapsibleItem;
- CollapsibleNestedIfInfo():
- OuterIf(nullptr), InnerIf(nullptr),
- FinishedOuterIf(false), FoundNonCollapsibleItem(false) {}
- bool isValid() {
- return OuterIf && InnerIf && FinishedOuterIf && !FoundNonCollapsibleItem;
- }
-};
-
-static CollapsibleNestedIfInfo findCollapseNestedIfTarget(ResolvedCursorInfo CursorInfo) {
+static std::pair<IfStmt *, IfStmt *>
+findCollapseNestedIfTarget(ResolvedCursorInfo CursorInfo) {
if (CursorInfo.Kind != CursorInfoKind::StmtStart)
- return CollapsibleNestedIfInfo();
- struct IfStmtFinder: public SourceEntityWalker {
- SourceLoc StartLoc;
- CollapsibleNestedIfInfo IfInfo;
- IfStmtFinder(SourceLoc StartLoc): StartLoc(StartLoc), IfInfo() {}
- bool finishedInnerIfButNotFinishedOuterIf() {
- return IfInfo.InnerIf && !IfInfo.FinishedOuterIf;
- }
- bool walkToStmtPre(Stmt *S) {
- if (finishedInnerIfButNotFinishedOuterIf()) {
- IfInfo.FoundNonCollapsibleItem = true;
- return false;
- }
+ return {};
- bool StmtIsOuterIfBrace =
- IfInfo.OuterIf && !IfInfo.InnerIf && S->getKind() == StmtKind::Brace;
- if (StmtIsOuterIfBrace) {
- return true;
- }
+ // Ensure the statement is 'if' statement. It must not have 'else' clause.
+ IfStmt *OuterIf = dyn_cast<IfStmt>(CursorInfo.TrailingStmt);
+ if (!OuterIf)
+ return {};
+ if (OuterIf->getElseStmt())
+ return {};
- auto *IFS = dyn_cast<IfStmt>(S);
- if (!IFS) {
- return false;
- }
- if (!IfInfo.OuterIf) {
- IfInfo.OuterIf = IFS;
- return true;
- } else {
- IfInfo.InnerIf = IFS;
- return false;
- }
- }
- bool walkToStmtPost(Stmt *S) {
- assert(S != IfInfo.InnerIf && "Should not traverse inner if statement");
- if (S == IfInfo.OuterIf) {
- IfInfo.FinishedOuterIf = true;
- }
- return true;
- }
- bool walkToDeclPre(Decl *D, CharSourceRange Range) {
- if (finishedInnerIfButNotFinishedOuterIf()) {
- IfInfo.FoundNonCollapsibleItem = true;
- return false;
- }
- return true;
- }
- bool walkToExprPre(Expr *E) {
- if (finishedInnerIfButNotFinishedOuterIf()) {
- IfInfo.FoundNonCollapsibleItem = true;
- return false;
- }
- return true;
- }
+ // The body must contain a sole inner 'if' statement.
+ auto Body = dyn_cast_or_null<BraceStmt>(OuterIf->getThenStmt());
+ if (!Body || Body->getNumElements() != 1)
+ return {};
- } Walker(CursorInfo.TrailingStmt->getStartLoc());
- Walker.walk(CursorInfo.TrailingStmt);
- return Walker.IfInfo;
+ IfStmt *InnerIf =
+ dyn_cast_or_null<IfStmt>(Body->getElement(0).dyn_cast<Stmt *>());
+ if (!InnerIf)
+ return {};
+
+ // Inner 'if' statement also cannot have 'else' clause.
+ if (InnerIf->getElseStmt())
+ return {};
+
+ return {OuterIf, InnerIf};
}
-bool RefactoringActionCollapseNestedIfExpr::
-isApplicable(ResolvedCursorInfo Tok, DiagnosticEngine &Diag) {
- return findCollapseNestedIfTarget(Tok).isValid();
+bool RefactoringActionCollapseNestedIfStmt::
+isApplicable(ResolvedCursorInfo CursorInfo, DiagnosticEngine &Diag) {
+ return findCollapseNestedIfTarget(CursorInfo).first;
}
-bool RefactoringActionCollapseNestedIfExpr::performChange() {
+bool RefactoringActionCollapseNestedIfStmt::performChange() {
auto Target = findCollapseNestedIfTarget(CursorInfo);
- if (!Target.isValid())
+ if (!Target.first)
return true;
- auto OuterIfConds = Target.OuterIf->getCond().vec();
- auto InnerIfConds = Target.InnerIf->getCond().vec();
+ auto OuterIf = Target.first;
+ auto InnerIf = Target.second;
- EditorConsumerInsertStream OS(EditConsumer, SM,
- Lexer::getCharSourceRangeFromSourceRange(
- SM, Target.OuterIf->getSourceRange()));
+ EditorConsumerInsertStream OS(
+ EditConsumer, SM,
+ Lexer::getCharSourceRangeFromSourceRange(SM, OuterIf->getSourceRange()));
- OS << tok::kw_if << " ";
- for (auto CI = OuterIfConds.begin(); CI != OuterIfConds.end(); ++CI) {
- OS << (CI != OuterIfConds.begin() ? ", " : "");
- OS << Lexer::getCharSourceRangeFromSourceRange(
- SM, CI->getSourceRange()).str();
+ OS << tok::kw_if << " ";
+
+ // Emit conditions.
+ bool first = true;
+ for (auto &C : llvm::concat<StmtConditionElement>(OuterIf->getCond(),
+ InnerIf->getCond())) {
+ if (first)
+ first = false;
+ else
+ OS << ", ";
+ OS << Lexer::getCharSourceRangeFromSourceRange(SM, C.getSourceRange())
+ .str();
}
- for (auto CI = InnerIfConds.begin(); CI != InnerIfConds.end(); ++CI) {
- OS << ", " << Lexer::getCharSourceRangeFromSourceRange(
- SM, CI->getSourceRange()).str();
- }
- auto ThenStatementText = Lexer::getCharSourceRangeFromSourceRange(
- SM, Target.InnerIf->getThenStmt()->getSourceRange()).str();
- OS << " " << ThenStatementText;
+
+ // Emit body.
+ OS << " ";
+ OS << Lexer::getCharSourceRangeFromSourceRange(
+ SM, InnerIf->getThenStmt()->getSourceRange())
+ .str();
return false;
}
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 9176495..6f2520e 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2751,10 +2751,10 @@
StringRef sectionName;
switch (TargetInfo.OutputObjectFormat) {
case llvm::Triple::MachO:
- sectionName = "__TEXT, __swift4_protos, regular, no_dead_strip";
+ sectionName = "__TEXT, __swift5_protos, regular, no_dead_strip";
break;
case llvm::Triple::ELF:
- sectionName = "swift4_protocols";
+ sectionName = "swift5_protocols";
break;
case llvm::Triple::COFF:
sectionName = ".sw5prt$B";
@@ -2941,10 +2941,10 @@
StringRef sectionName;
switch (TargetInfo.OutputObjectFormat) {
case llvm::Triple::MachO:
- sectionName = "__TEXT, __swift4_proto, regular, no_dead_strip";
+ sectionName = "__TEXT, __swift5_proto, regular, no_dead_strip";
break;
case llvm::Triple::ELF:
- sectionName = "swift4_protocol_conformances";
+ sectionName = "swift5_protocol_conformances";
break;
case llvm::Triple::COFF:
sectionName = ".sw5prtc$B";
@@ -2968,10 +2968,10 @@
std::string sectionName;
switch (TargetInfo.OutputObjectFormat) {
case llvm::Triple::MachO:
- sectionName = "__TEXT, __swift4_types, regular, no_dead_strip";
+ sectionName = "__TEXT, __swift5_types, regular, no_dead_strip";
break;
case llvm::Triple::ELF:
- sectionName = "swift4_type_metadata";
+ sectionName = "swift5_type_metadata";
break;
case llvm::Triple::COFF:
sectionName = ".sw5tymd$B";
@@ -3035,13 +3035,13 @@
std::string sectionName;
switch (TargetInfo.OutputObjectFormat) {
case llvm::Triple::MachO:
- sectionName = "__TEXT, __swift4_fieldmd, regular, no_dead_strip";
+ sectionName = "__TEXT, __swift5_fieldmd, regular, no_dead_strip";
break;
case llvm::Triple::ELF:
- sectionName = "swift4_fieldmd";
+ sectionName = "swift5_fieldmd";
break;
case llvm::Triple::COFF:
- sectionName = ".swift4_fieldmd";
+ sectionName = ".swift5_fieldmd";
break;
default:
llvm_unreachable("Don't know how to emit field records table for "
diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp
index eadf01e..e7e5fb5 100644
--- a/lib/IRGen/GenExistential.cpp
+++ b/lib/IRGen/GenExistential.cpp
@@ -280,7 +280,7 @@
llvm::Type *ty, Size size, Alignment align)
: super(protocols, ty, size,
SpareBitVector::getConstant(size.getValueInBits(), false), align,
- IsNotPOD, IsNotBitwiseTakable, IsFixedSize) {}
+ IsNotPOD, IsBitwiseTakable, IsFixedSize) {}
public:
OpaqueExistentialLayout getLayout() const {
@@ -343,16 +343,11 @@
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
SILType T, bool isOutlined) const override {
if (isOutlined) {
- llvm::Value *metadata = copyType(IGF, dest, src);
-
- auto layout = getLayout();
-
- // Project down to the buffers and ask the witnesses to do a
- // take-initialize.
- Address srcBuffer = layout.projectExistentialBuffer(IGF, src);
- Address destBuffer = layout.projectExistentialBuffer(IGF, dest);
- emitInitializeBufferWithTakeOfBufferCall(IGF, metadata, destBuffer,
- srcBuffer);
+ // memcpy the existential container. This is safe because: either the
+ // value is stored inline and is therefore by convention bitwise takable
+ // or the value is stored in a reference counted heap buffer, in which
+ // case a memcpy of the reference is also correct.
+ IGF.emitMemCpy(dest, src, getLayout().getSize(IGF.IGM));
} else {
// Create an outlined function to avoid explosion
OutliningMetadataCollector collector(IGF);
diff --git a/lib/IRGen/GenOpaque.cpp b/lib/IRGen/GenOpaque.cpp
index 536fa32..0c07429 100644
--- a/lib/IRGen/GenOpaque.cpp
+++ b/lib/IRGen/GenOpaque.cpp
@@ -66,9 +66,7 @@
}
// T *(*initializeBufferWithCopyOfBuffer)(B *dest, B *src, M *self);
- // T *(*initializeBufferWithTakeOfBuffer)(B *dest, B *src, M *self);
- case ValueWitness::InitializeBufferWithCopyOfBuffer:
- case ValueWitness::InitializeBufferWithTakeOfBuffer: {
+ case ValueWitness::InitializeBufferWithCopyOfBuffer: {
llvm::Type *bufPtrTy = IGM.getFixedBufferTy()->getPointerTo(0);
llvm::Type *args[] = { bufPtrTy, bufPtrTy, IGM.TypeMetadataPtrTy };
return llvm::FunctionType::get(IGM.OpaquePtrTy, args, /*isVarArg*/ false);
@@ -212,7 +210,6 @@
// These have two arguments and they don't alias each other.
case ValueWitness::AssignWithTake:
case ValueWitness::InitializeBufferWithCopyOfBuffer:
- case ValueWitness::InitializeBufferWithTakeOfBuffer:
case ValueWitness::InitializeWithCopy:
case ValueWitness::InitializeWithTake:
return attrs.addAttribute(ctx, 1, llvm::Attribute::NoAlias)
@@ -259,8 +256,6 @@
return "initializeWithCopy";
case ValueWitness::InitializeWithTake:
return "initializeWithTake";
- case ValueWitness::InitializeBufferWithTakeOfBuffer:
- return "initializeBufferWithTakeOfBuffer";
case ValueWitness::Size:
return "size";
case ValueWitness::Flags:
@@ -417,31 +412,6 @@
return call;
}
-llvm::Value *
-irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
- SILType T,
- Address destBuffer,
- Address srcBuffer) {
- auto metadata = IGF.emitTypeMetadataRefForLayout(T);
- return emitInitializeBufferWithTakeOfBufferCall(IGF, metadata,
- destBuffer, srcBuffer);
-}
-
-/// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
-llvm::Value *
-irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
- llvm::Value *metadata,
- Address destBuffer,
- Address srcBuffer) {
- auto copyFn = emitLoadOfValueWitnessFunctionFromMetadata(IGF, metadata,
- ValueWitness::InitializeBufferWithTakeOfBuffer);
- llvm::CallInst *call =
- IGF.Builder.CreateCall(copyFn,
- {destBuffer.getAddress(), srcBuffer.getAddress(), metadata});
-
- return call;
-}
-
/// Emit a dynamic alloca call to allocate enough memory to hold an object of
/// type 'T' and an optional llvm.stackrestore point if 'isInEntryBlock' is
/// false.
diff --git a/lib/IRGen/GenOpaque.h b/lib/IRGen/GenOpaque.h
index 0afcc4a..622bc59 100644
--- a/lib/IRGen/GenOpaque.h
+++ b/lib/IRGen/GenOpaque.h
@@ -58,18 +58,6 @@
Address destBuffer,
Address srcBuffer);
- /// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
- llvm::Value *emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
- llvm::Value *metadata,
- Address destBuffer,
- Address srcBuffer);
-
- /// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
- llvm::Value *emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
- SILType T,
- Address destBuffer,
- Address srcBuffer);
-
/// Emit a call to do an 'initializeWithCopy' operation.
void emitInitializeWithCopyCall(IRGenFunction &IGF,
SILType T,
diff --git a/lib/IRGen/GenRecord.h b/lib/IRGen/GenRecord.h
index 90b9cfb..66b0e14 100644
--- a/lib/IRGen/GenRecord.h
+++ b/lib/IRGen/GenRecord.h
@@ -323,22 +323,6 @@
public:
using super::getStorageType;
- Address initializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
- Address destBuffer,
- Address srcBuffer,
- SILType type) const override {
- if (auto field = getUniqueNonEmptyField()) {
- auto &fieldTI = field->getTypeInfo();
- Address fieldResult =
- fieldTI.initializeBufferWithTakeOfBuffer(IGF, destBuffer, srcBuffer,
- field->getType(IGF.IGM, type));
- return IGF.Builder.CreateElementBitCast(fieldResult, getStorageType());
- } else {
- return super::initializeBufferWithTakeOfBuffer(IGF, destBuffer,
- srcBuffer, type);
- }
- }
-
Address initializeBufferWithCopyOfBuffer(IRGenFunction &IGF,
Address destBuffer,
Address srcBuffer,
diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp
index d4167d6..876ddb0 100644
--- a/lib/IRGen/GenReflection.cpp
+++ b/lib/IRGen/GenReflection.cpp
@@ -247,7 +247,7 @@
// Others, such as capture descriptors, do not have a name.
} else {
- var = B.finishAndCreateGlobal("\x01l__swift4_reflection_descriptor",
+ var = B.finishAndCreateGlobal("\x01l__swift5_reflection_descriptor",
Alignment(4), /*isConstant*/ true,
llvm::GlobalValue::PrivateLinkage);
}
@@ -766,12 +766,12 @@
OS << ".sw5" << FourCC << "$B";
break;
case llvm::Triple::ELF:
- OS << "swift4_" << LongName;
+ OS << "swift5_" << LongName;
break;
case llvm::Triple::MachO:
assert(LongName.size() <= 7 &&
"Mach-O section name length must be <= 16 characters");
- OS << "__TEXT,__swift4_" << LongName << ", regular, no_dead_strip";
+ OS << "__TEXT,__swift5_" << LongName << ", regular, no_dead_strip";
break;
case llvm::Triple::Wasm:
llvm_unreachable("web assembly object format is not supported.");
diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp
index d8f39d8..16c8fd8 100644
--- a/lib/IRGen/GenValueWitness.cpp
+++ b/lib/IRGen/GenValueWitness.cpp
@@ -56,7 +56,6 @@
CASE(InitializeBufferWithCopyOfBuffer)
CASE(InitializeWithCopy)
CASE(InitializeWithTake)
- CASE(InitializeBufferWithTakeOfBuffer)
CASE(StoreExtraInhabitant)
CASE(GetExtraInhabitantIndex)
CASE(GetEnumTag)
@@ -331,47 +330,6 @@
}
}
-/// Emit an 'initializeBufferWithTakeOfBuffer' operation.
-/// Returns the address of the destination object.
-static Address
-emitDefaultInitializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
- Address destBuffer,
- Address srcBuffer,
- SILType T,
- const TypeInfo &type,
- FixedPacking packing) {
- switch (packing) {
-
- case FixedPacking::Dynamic:
- // Special-case dynamic packing in order to thread the jumps.
- return emitForDynamicPacking(IGF,
- &emitDefaultInitializeBufferWithTakeOfBuffer,
- T, type, destBuffer, srcBuffer);
-
- case FixedPacking::OffsetZero: {
- // Both of these allocations/projections should be no-ops.
- Address destObject =
- emitDefaultAllocateBuffer(IGF, destBuffer, T, type, packing);
- Address srcObject =
- emitDefaultProjectBuffer(IGF, srcBuffer, T, type, packing);
- type.initializeWithTake(IGF, destObject, srcObject, T, true);
- return destObject;
- }
-
- case FixedPacking::Allocate: {
- // Just copy the out-of-line storage pointers.
- srcBuffer = IGF.Builder.CreateBitCast(
- srcBuffer, IGF.IGM.RefCountedPtrTy->getPointerTo());
- llvm::Value *addr = IGF.Builder.CreateLoad(srcBuffer);
- destBuffer = IGF.Builder.CreateBitCast(
- destBuffer, IGF.IGM.RefCountedPtrTy->getPointerTo());
- IGF.Builder.CreateStore(addr, destBuffer);
- return emitDefaultProjectBuffer(IGF, destBuffer, T, type, packing);
- }
- }
- llvm_unreachable("bad fixed packing");
-}
-
// Metaprogram some of the common boilerplate here:
// - the default implementation in TypeInfo
// - the value-witness emitter which tries to avoid some dynamic
@@ -392,8 +350,6 @@
}
DEFINE_BINARY_BUFFER_OP(initializeBufferWithCopyOfBuffer,
InitializeBufferWithCopyOfBuffer)
-DEFINE_BINARY_BUFFER_OP(initializeBufferWithTakeOfBuffer,
- InitializeBufferWithTakeOfBuffer)
#undef DEFINE_BINARY_BUFFER_OP
@@ -532,19 +488,6 @@
return;
}
- case ValueWitness::InitializeBufferWithTakeOfBuffer: {
- Address dest = getArgAsBuffer(IGF, argv, "dest");
- Address src = getArgAsBuffer(IGF, argv, "src");
- getArgAsLocalSelfTypeMetadata(IGF, argv, abstractType);
-
- Address result =
- emitInitializeBufferWithTakeOfBuffer(IGF, dest, src, concreteType,
- type, packing);
- result = IGF.Builder.CreateBitCast(result, IGF.IGM.OpaquePtrTy);
- IGF.Builder.CreateRet(result.getAddress());
- return;
- }
-
case ValueWitness::InitializeWithCopy: {
Address dest = getArgAs(IGF, argv, type, "dest");
Address src = getArgAs(IGF, argv, type, "src");
@@ -805,38 +748,6 @@
});
}
-/// Return a function which takes two buffer arguments, copies
-/// a pointer from the second to the first, and returns the pointer.
-static llvm::Constant *
-getCopyOutOfLineBoxPointerFunction(IRGenModule &IGM,
- const FixedTypeInfo &fixedTI) {
- llvm::Type *argTys[] = { IGM.Int8PtrPtrTy, IGM.Int8PtrPtrTy,
- IGM.TypeMetadataPtrTy };
- llvm::SmallString<40> name;
- {
- llvm::raw_svector_ostream nameStream(name);
- nameStream << "__swift_copy_outline_existential_box_pointer";
- nameStream << fixedTI.getFixedAlignment().getValue();
- }
- return IGM.getOrCreateHelperFunction(
- name, IGM.Int8PtrTy, argTys, [&](IRGenFunction &IGF) {
- auto it = IGF.CurFn->arg_begin();
- Address dest(&*it++, IGM.getPointerAlignment());
- Address src(&*it++, IGM.getPointerAlignment());
- auto *ptr = IGF.Builder.CreateLoad(src);
- IGF.Builder.CreateStore(ptr, dest);
- auto *alignmentMask = fixedTI.getStaticAlignmentMask(IGM);
- auto *heapHeaderSize = llvm::ConstantInt::get(
- IGM.SizeTy, IGM.RefCountedStructSize.getValue());
- auto *startOffset = IGF.Builder.CreateAnd(
- IGF.Builder.CreateAdd(heapHeaderSize, alignmentMask),
- IGF.Builder.CreateNot(alignmentMask));
- auto *objectAddr =
- IGF.emitByteOffsetGEP(ptr, startOffset, IGM.Int8Ty);
- IGF.Builder.CreateRet(objectAddr);
- });
-}
-
/// Find a witness to the fact that a type is a value type.
/// Always adds an i8*.
static void addValueWitness(IRGenModule &IGM,
@@ -870,17 +781,6 @@
}
goto standard;
- case ValueWitness::InitializeBufferWithTakeOfBuffer:
- if (packing == FixedPacking::Allocate) {
- return addFunction(getCopyOutOfLineBoxPointerFunction(
- IGM, cast<FixedTypeInfo>(concreteTI)));
- } else
- if (packing == FixedPacking::OffsetZero &&
- concreteTI.isBitwiseTakable(ResilienceExpansion::Maximal)) {
- return addFunction(getMemCpyFunction(IGM, concreteTI));
- }
- goto standard;
-
case ValueWitness::InitializeWithTake:
if (concreteTI.isBitwiseTakable(ResilienceExpansion::Maximal)) {
return addFunction(getMemCpyFunction(IGM, concreteTI));
@@ -927,13 +827,16 @@
if (auto *fixedTI = dyn_cast<FixedTypeInfo>(&concreteTI)) {
assert(packing == FixedPacking::OffsetZero ||
packing == FixedPacking::Allocate);
+ bool isInline = packing == FixedPacking::OffsetZero;
+ bool isBitwiseTakable =
+ fixedTI->isBitwiseTakable(ResilienceExpansion::Maximal);
+ assert(isBitwiseTakable || !isInline);
flags = flags.withAlignment(fixedTI->getFixedAlignment().getValue())
- .withPOD(fixedTI->isPOD(ResilienceExpansion::Maximal))
- .withInlineStorage(packing == FixedPacking::OffsetZero)
- .withExtraInhabitants(
+ .withPOD(fixedTI->isPOD(ResilienceExpansion::Maximal))
+ .withInlineStorage(isInline)
+ .withExtraInhabitants(
fixedTI->getFixedExtraInhabitantCount(IGM) > 0)
- .withBitwiseTakable(
- fixedTI->isBitwiseTakable(ResilienceExpansion::Maximal));
+ .withBitwiseTakable(isBitwiseTakable);
} else {
flags = flags.withIncomplete(true);
}
@@ -1288,6 +1191,10 @@
if (!fixedTI)
return FixedPacking::Dynamic;
+ // By convention we only store bitwise takable values inline.
+ if (!fixedTI->isBitwiseTakable(ResilienceExpansion::Maximal))
+ return FixedPacking::Allocate;
+
Size bufferSize = getFixedBufferSize(IGM);
Size requiredSize = fixedTI->getFixedSize();
diff --git a/lib/IRGen/IRGenMangler.cpp b/lib/IRGen/IRGenMangler.cpp
index 40e7679..7c74e2b 100644
--- a/lib/IRGen/IRGenMangler.cpp
+++ b/lib/IRGen/IRGenMangler.cpp
@@ -45,7 +45,6 @@
GET_MANGLING(AssignWithCopy) \
GET_MANGLING(InitializeWithTake) \
GET_MANGLING(AssignWithTake) \
- GET_MANGLING(InitializeBufferWithTakeOfBuffer) \
GET_MANGLING(GetEnumTagSinglePayload) \
GET_MANGLING(StoreEnumTagSinglePayload) \
GET_MANGLING(StoreExtraInhabitant) \
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 61b36f5..3bc6000 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -793,8 +793,9 @@
appendEncodedName(os, name);
}
-static StringRef encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
- StringRef name) {
+StringRef
+swift::irgen::encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
+ StringRef name) {
llvm::raw_svector_ostream os{buf};
os << "_swift_FORCE_LOAD_$";
appendEncodedName(os, name);
diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp
index 4fa1812..dd4410a 100644
--- a/lib/IRGen/MetadataRequest.cpp
+++ b/lib/IRGen/MetadataRequest.cpp
@@ -589,17 +589,6 @@
return false;
}
-/// Determine whether we should promote the type metadata access function
-/// for the given nominal type to "public".
-static bool promoteMetadataAccessFunctionToPublic(
- const NominalTypeDecl *nominal) {
- ASTContext &ctx = nominal->getASTContext();
-
- // When -emit-public-type-metadata-accessors is provided, promote all
- // of the metadata access functions to public.
- return ctx.LangOpts.EmitPublicTypeMetadataAccessors;
-}
-
/// Return the standard access strategy for getting a non-dependent
/// type metadata object.
MetadataAccessStrategy irgen::getTypeMetadataAccessStrategy(CanType type) {
@@ -632,12 +621,8 @@
case FormalLinkage::PublicUnique:
return MetadataAccessStrategy::PublicUniqueAccessor;
case FormalLinkage::HiddenUnique:
- if (promoteMetadataAccessFunctionToPublic(nominal))
- return MetadataAccessStrategy::PublicUniqueAccessor;
return MetadataAccessStrategy::HiddenUniqueAccessor;
case FormalLinkage::Private:
- if (promoteMetadataAccessFunctionToPublic(nominal))
- return MetadataAccessStrategy::PublicUniqueAccessor;
return MetadataAccessStrategy::PrivateAccessor;
case FormalLinkage::PublicNonUnique:
diff --git a/lib/IRGen/ResilientTypeInfo.h b/lib/IRGen/ResilientTypeInfo.h
index 1672755..0e49503 100644
--- a/lib/IRGen/ResilientTypeInfo.h
+++ b/lib/IRGen/ResilientTypeInfo.h
@@ -88,13 +88,6 @@
return this->getAddressForPointer(addr);
}
- Address initializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
- Address dest, Address src,
- SILType T) const override {
- auto addr = emitInitializeBufferWithTakeOfBufferCall(IGF, T, dest, src);
- return this->getAddressForPointer(addr);
- }
-
void initializeWithCopy(IRGenFunction &IGF, Address dest, Address src,
SILType T, bool isOutlined) const override {
emitInitializeWithCopyCall(IGF, T, dest, src);
diff --git a/lib/IRGen/TypeInfo.h b/lib/IRGen/TypeInfo.h
index 1092b34..abf1b93 100644
--- a/lib/IRGen/TypeInfo.h
+++ b/lib/IRGen/TypeInfo.h
@@ -370,23 +370,6 @@
Address srcBuffer,
SILType T) const;
- /// Perform a take-initialization from the given fixed-size buffer
- /// into an uninitialized fixed-size buffer, allocating the buffer if
- /// necessary and deallocating the destination buffer. Returns the
- /// address of the value inside the destination buffer.
- ///
- /// This is equivalent to:
- /// auto srcAddress = projectBuffer(IGF, srcBuffer, T);
- /// initializeBufferWithTake(IGF, destBuffer, srcAddress, T);
- /// deallocateBuffer(IGF, srcBuffer, T);
- /// but may be able to re-use the buffer from the source buffer, and may
- /// be more efficient for dynamic types, since it uses a single
- /// value witness call.
- virtual Address initializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
- Address destBuffer,
- Address srcBuffer,
- SILType T) const;
-
/// Take-initialize an address from a parameter explosion.
virtual void initializeFromParams(IRGenFunction &IGF, Explosion ¶ms,
Address src, SILType T,
@@ -452,6 +435,9 @@
SILType T) const = 0;
/// Compute the packing of values of this type into a fixed-size buffer.
+ /// A value might not be stored in the fixed-size buffer because it does not
+ /// fit or because it is not bit-wise takable. Non bit-wise takable values are
+ /// not stored inline by convention.
FixedPacking getFixedPacking(IRGenModule &IGM) const;
/// Index into an array of objects of this type.
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index b23b46d..957ee92 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -260,21 +260,6 @@
SF->getASTContext().SourceMgr, Range).str() == "nil";
}
- bool isDotMember(CharSourceRange Range) {
- auto S = Range.str();
- return S.startswith(".") && S.substr(1).find(".") == StringRef::npos;
- }
-
- bool isDotMember(SourceRange Range) {
- return isDotMember(Lexer::getCharSourceRangeFromSourceRange(
- SF->getASTContext().SourceMgr, Range));
- }
-
- bool isDotMember(Expr *E) {
- auto Range = E->getSourceRange();
- return Range.isValid() && isDotMember(Range);
- }
-
std::vector<APIDiffItem*> getRelatedDiffItems(ValueDecl *VD) {
std::vector<APIDiffItem*> results;
auto addDiffItems = [&](ValueDecl *VD) {
@@ -323,11 +308,11 @@
}
- bool isSimpleReplacement(APIDiffItem *Item, bool isDotMember, std::string &Text) {
+ bool isSimpleReplacement(APIDiffItem *Item, std::string &Text) {
if (auto *MD = dyn_cast<TypeMemberDiffItem>(Item)) {
if (MD->Subkind == TypeMemberDiffItemSubKind::SimpleReplacement) {
- Text = (llvm::Twine(isDotMember ? "" : MD->newTypeName) + "." +
- MD->getNewName().base()).str();
+ Text = (llvm::Twine(MD->newTypeName) + "." + MD->getNewName().base()).
+ str();
return true;
}
}
@@ -390,7 +375,7 @@
Type T, ReferenceMetaData Data) override {
for (auto *Item: getRelatedDiffItems(CtorTyRef ? CtorTyRef: D)) {
std::string RepText;
- if (isSimpleReplacement(Item, isDotMember(Range), RepText)) {
+ if (isSimpleReplacement(Item, RepText)) {
Editor.replace(Range, RepText);
return true;
}
@@ -465,9 +450,8 @@
for (auto *I: getRelatedDiffItems(VD)) {
if (auto *Item = dyn_cast<TypeMemberDiffItem>(I)) {
if (Item->Subkind == TypeMemberDiffItemSubKind::QualifiedReplacement) {
- Editor.replace(ToReplace,
- (llvm::Twine(isDotMember(ToReplace) ? "" : Item->newTypeName) + "." +
- Item->getNewName().base()).str());
+ Editor.replace(ToReplace, (llvm::Twine(Item->newTypeName) + "." +
+ Item->getNewName().base()).str());
return true;
}
}
@@ -741,7 +725,7 @@
StringRef LeftComment;
StringRef RightComment;
for (auto *Item: getRelatedDiffItems(RD)) {
- if (isSimpleReplacement(Item, isDotMember(Reference), Rename)) {
+ if (isSimpleReplacement(Item, Rename)) {
} else if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
if (CI->isStringRepresentableChange() &&
CI->NodeKind == SDKNodeKind::DeclVar) {
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 5ba8140..d8c47bc 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2036,12 +2036,7 @@
.fixItRemoveChars(end.getAdvancedLoc(-1), end);
}
- auto unescapedUnderscore = underscore && !escaped;
- if (!unescapedUnderscore)
- name = Context.getIdentifier(text);
- if (!underscore)
- Tok.setKind(tok::identifier);
- loc = consumeToken();
+ loc = consumeArgumentLabel(name);
consumeToken(tok::colon);
}
}
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index 78e799a..95fea25 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -57,7 +57,7 @@
}
void Parser::DefaultArgumentInfo::setFunctionContext(
- DeclContext *DC, MutableArrayRef<ParameterList *> paramList){
+ DeclContext *DC, ArrayRef<ParameterList *> paramList){
for (auto context : ParsedContexts) {
context->changeFunction(DC, paramList);
}
@@ -240,23 +240,11 @@
if (startsParameterName(*this, isClosure)) {
// identifier-or-none for the first name
- if (Tok.is(tok::kw__)) {
- param.FirstNameLoc = consumeToken();
- } else {
- assert(Tok.canBeArgumentLabel() && "startsParameterName() lied");
- Tok.setKind(tok::identifier);
- param.FirstName = Context.getIdentifier(Tok.getText());
- param.FirstNameLoc = consumeToken();
- }
+ param.FirstNameLoc = consumeArgumentLabel(param.FirstName);
// identifier-or-none? for the second name
- if (Tok.canBeArgumentLabel()) {
- if (!Tok.is(tok::kw__)) {
- param.SecondName = Context.getIdentifier(Tok.getText());
- Tok.setKind(tok::identifier);
- }
- param.SecondNameLoc = consumeToken();
- }
+ if (Tok.canBeArgumentLabel())
+ param.SecondNameLoc = consumeArgumentLabel(param.SecondName);
// Operators, closures, and enum elements cannot have API names.
if ((paramContext == ParameterContextKind::Operator ||
diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp
index 350b17d..ad69d3f 100644
--- a/lib/Parse/ParseType.cpp
+++ b/lib/Parse/ParseType.cpp
@@ -878,16 +878,11 @@
Backtracking->cancelBacktrack();
// Consume a name.
- if (!Tok.is(tok::kw__))
- element.Name = Context.getIdentifier(Tok.getText());
- element.NameLoc = consumeToken();
+ element.NameLoc = consumeArgumentLabel(element.Name);
// If there is a second name, consume it as well.
- if (Tok.canBeArgumentLabel()) {
- if (!Tok.is(tok::kw__))
- element.SecondName = Context.getIdentifier(Tok.getText());
- element.SecondNameLoc = consumeToken();
- }
+ if (Tok.canBeArgumentLabel())
+ element.SecondNameLoc = consumeArgumentLabel(element.SecondName);
// Consume the ':'.
if (!consumeIf(tok::colon, element.ColonLoc))
diff --git a/lib/SIL/MemAccessUtils.cpp b/lib/SIL/MemAccessUtils.cpp
index 5a8cc05..cb58844 100644
--- a/lib/SIL/MemAccessUtils.cpp
+++ b/lib/SIL/MemAccessUtils.cpp
@@ -599,3 +599,19 @@
return;
}
}
+
+SILBasicBlock::iterator swift::removeBeginAccess(BeginAccessInst *beginAccess) {
+ while (!beginAccess->use_empty()) {
+ Operand *op = *beginAccess->use_begin();
+
+ // Delete any associated end_access instructions.
+ if (auto endAccess = dyn_cast<EndAccessInst>(op->getUser())) {
+ endAccess->eraseFromParent();
+
+ // Forward all other uses to the original address.
+ } else {
+ op->set(beginAccess->getSource());
+ }
+ }
+ return beginAccess->getParent()->erase(beginAccess);
+}
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index a16a62a..e8219fc 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -25,6 +25,7 @@
#include "swift/SIL/DebugUtils.h"
#include "swift/SIL/Dominance.h"
#include "swift/SIL/DynamicCasts.h"
+#include "swift/SIL/MemAccessUtils.h"
#include "swift/SIL/PostOrder.h"
#include "swift/SIL/PrettyStackTrace.h"
#include "swift/SIL/SILDebugScope.h"
@@ -1581,8 +1582,8 @@
}
void checkBeginAccessInst(BeginAccessInst *BAI) {
- auto op = BAI->getOperand();
- requireSameType(BAI->getType(), op->getType(),
+ auto sourceOper = BAI->getOperand();
+ requireSameType(BAI->getType(), sourceOper->getType(),
"result must be same type as operand");
require(BAI->getType().isAddress(),
"begin_access operand must have address type");
@@ -1603,6 +1604,11 @@
case SILAccessKind::Modify:
break;
}
+
+ // For dynamic Read/Modify access, AccessEnforcementWMO assumes a valid
+ // AccessedStorage and runs very late in the optimizer pipeline.
+ // TODO: eventually, make this true for any kind of access.
+ findAccessedStorage(sourceOper);
}
void checkEndAccessInst(EndAccessInst *EAI) {
diff --git a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
index 0a98484..c9a3ea2 100644
--- a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
@@ -36,12 +36,14 @@
//===----------------------------------------------------------------------===//
bool swift::isRetainInstruction(SILInstruction *I) {
- return isa<StrongRetainInst>(I) || isa<RetainValueInst>(I);
+ return isa<StrongRetainInst>(I) || isa<RetainValueInst>(I) ||
+ isa<UnownedRetainInst>(I);
}
bool swift::isReleaseInstruction(SILInstruction *I) {
- return isa<StrongReleaseInst>(I) || isa<ReleaseValueInst>(I);
+ return isa<StrongReleaseInst>(I) || isa<ReleaseValueInst>(I) ||
+ isa<UnownedReleaseInst>(I);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/SILOptimizer/Analysis/AccessedStorageAnalysis.cpp b/lib/SILOptimizer/Analysis/AccessedStorageAnalysis.cpp
index aaeefc5..4948288 100644
--- a/lib/SILOptimizer/Analysis/AccessedStorageAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/AccessedStorageAnalysis.cpp
@@ -19,6 +19,52 @@
using namespace swift;
+// -----------------------------------------------------------------------------
+// MARK: Accessing the results.
+// -----------------------------------------------------------------------------
+
+bool FunctionAccessedStorage::hasNoNestedConflict(
+ const AccessedStorage &otherStorage) const {
+ assert(otherStorage.isUniquelyIdentified());
+ assert(!hasUnidentifiedAccess());
+
+ return getStorageAccessInfo(otherStorage).hasNoNestedConflict();
+}
+
+bool FunctionAccessedStorage::mayConflictWith(
+ SILAccessKind otherAccessKind, const AccessedStorage &otherStorage) const {
+ if (hasUnidentifiedAccess()
+ && accessKindMayConflict(otherAccessKind,
+ unidentifiedAccess.getValue())) {
+ return true;
+ }
+ for (auto &storageAccess : storageAccessSet) {
+ assert(storageAccess && "FunctionAccessedStorage mapped invalid storage.");
+
+ if (!accessKindMayConflict(otherAccessKind, storageAccess.getAccessKind()))
+ continue;
+
+ if (!otherStorage.isDistinctFrom(storageAccess))
+ return true;
+ }
+ return false;
+}
+
+StorageAccessInfo FunctionAccessedStorage::getStorageAccessInfo(
+ const AccessedStorage &otherStorage) const {
+ // Construct a fake StorageAccessInfo to do a hash lookup for the real
+ // StorageAccessInfo. The DenseSet key is limited to the AccessedStorage base
+ // class members.
+ StorageAccessInfo storageKey(otherStorage, SILAccessKind::Read, false);
+ auto iter = storageAccessSet.find(storageKey);
+ assert(iter != storageAccessSet.end());
+ return *iter;
+}
+
+// -----------------------------------------------------------------------------
+// MARK: Constructing the results.
+// -----------------------------------------------------------------------------
+
static bool updateAccessKind(SILAccessKind &LHS, SILAccessKind RHS) {
bool changed = false;
// Assume we don't track Init/Deinit.
@@ -42,18 +88,23 @@
}
bool StorageAccessInfo::mergeFrom(const StorageAccessInfo &RHS) {
+ bool changed = false;
+ SILAccessKind accessKind = getAccessKind();
assert(accessKind == SILAccessKind::Read
|| accessKind == SILAccessKind::Modify && "uninitialized info");
- bool changed = updateAccessKind(accessKind, RHS.accessKind);
- if (noNestedConflict && !RHS.noNestedConflict) {
- noNestedConflict = false;
+ if (updateAccessKind(accessKind, RHS.getAccessKind())) {
+ setAccessKind(accessKind);
+ changed = true;
+ }
+ if (hasNoNestedConflict() && !RHS.hasNoNestedConflict()) {
+ setNoNestedConflict(false);
changed = true;
}
return changed;
}
bool FunctionAccessedStorage::summarizeFunction(SILFunction *F) {
- assert(storageAccessMap.empty() && "expected uninitialized results.");
+ assert(storageAccessSet.empty() && "expected uninitialized results.");
if (F->isDefinition())
return false;
@@ -81,7 +132,7 @@
unidentifiedAccess = SILAccessKind::Read;
// If function side effects is "readnone" then this result will have an empty
- // storageAccessMap and unidentifiedAccess == None.
+ // storageAccessSet and unidentifiedAccess == None.
return true;
}
@@ -104,38 +155,43 @@
// propagate and merge in that case in case arguments are recursively dependent.
bool FunctionAccessedStorage::mergeAccesses(
const FunctionAccessedStorage &other,
- std::function<AccessedStorage(const AccessedStorage &)> transformStorage) {
+ std::function<StorageAccessInfo(const StorageAccessInfo &)>
+ transformStorage) {
// Insertion in DenseMap invalidates the iterator in the rare case of
// self-recursion (`this` == `other`) that passes accessed storage though an
// argument. Rather than complicate the code, make a temporary copy of the
// AccessedStorage.
- SmallVector<std::pair<AccessedStorage, StorageAccessInfo>, 8> otherAccesses;
- otherAccesses.reserve(other.storageAccessMap.size());
- otherAccesses.append(other.storageAccessMap.begin(),
- other.storageAccessMap.end());
+ //
+ // Also note that the storageAccessIndex from otherStorage is relative to its
+ // original context and should not be copied into this context.
+ SmallVector<StorageAccessInfo, 8> otherStorageAccesses;
+ otherStorageAccesses.reserve(other.storageAccessSet.size());
+ otherStorageAccesses.append(other.storageAccessSet.begin(),
+ other.storageAccessSet.end());
bool changed = false;
- for (auto &accessEntry : otherAccesses) {
- const AccessedStorage &storage = transformStorage(accessEntry.first);
+ for (auto &rawStorageInfo : otherStorageAccesses) {
+ const StorageAccessInfo &otherStorageInfo =
+ transformStorage(rawStorageInfo);
// transformStorage() returns invalid storage object for local storage
// that should not be merged with the caller.
- if (!storage)
+ if (!otherStorageInfo)
continue;
- if (storage.getKind() == AccessedStorage::Unidentified) {
- changed |= updateUnidentifiedAccess(accessEntry.second.accessKind);
+ if (otherStorageInfo.getKind() == AccessedStorage::Unidentified) {
+ changed |= updateUnidentifiedAccess(otherStorageInfo.getAccessKind());
continue;
}
// Attempt to add identified AccessedStorage to this map.
- auto result = storageAccessMap.try_emplace(storage, accessEntry.second);
+ auto result = insertStorageAccess(otherStorageInfo);
if (result.second) {
// A new AccessedStorage key was added to this map.
changed = true;
continue;
}
// Merge StorageAccessInfo into already-mapped AccessedStorage.
- changed |= result.first->second.mergeFrom(accessEntry.second);
+ changed |= result.first->mergeFrom(otherStorageInfo);
}
if (other.unidentifiedAccess != None)
changed |= updateUnidentifiedAccess(other.unidentifiedAccess.getValue());
@@ -147,7 +203,7 @@
// Merge accesses from other. Both `this` and `other` are either from the same
// function or are both callees of the same call site, so their parameters
// indices coincide. transformStorage is the identity function.
- return mergeAccesses(other, [](const AccessedStorage &s) { return s; });
+ return mergeAccesses(other, [](const StorageAccessInfo &s) { return s; });
}
/// Returns the argument of the full apply or partial apply corresponding to the
@@ -175,13 +231,23 @@
/// Transform AccessedStorage from a callee into the caller context. If this is
/// uniquely identified local storage, then return an invalid storage object.
-static AccessedStorage transformCalleeStorage(const AccessedStorage &storage,
- FullApplySite fullApply) {
+///
+/// For correctness, AccessEnforcementOpts relies on all Argument access to
+/// either be mapped into the caller's context or marked as an unidentified
+/// access at the call site.
+///
+/// Note: This does *not* map the storage index into the caller function's index
+/// range. (When the storage value doesn't need to be remapped, it returns the
+/// original storage value.) It's simpler to set the storage index later when it
+/// is actually added to the function's storageAccessSet.
+static StorageAccessInfo
+transformCalleeStorage(const StorageAccessInfo &storage,
+ FullApplySite fullApply) {
switch (storage.getKind()) {
case AccessedStorage::Box:
case AccessedStorage::Stack:
// Do not merge local storage.
- return AccessedStorage();
+ return StorageAccessInfo(AccessedStorage(), storage);
case AccessedStorage::Global:
// Global accesses is universal.
return storage;
@@ -191,9 +257,11 @@
SILValue obj = storage.getObjectProjection().getObject();
if (auto *arg = dyn_cast<SILFunctionArgument>(obj)) {
SILValue argVal = getCallerArg(fullApply, arg->getIndex());
- if (argVal)
- return AccessedStorage(argVal,
- storage.getObjectProjection().getProjection());
+ if (argVal) {
+ auto &proj = storage.getObjectProjection().getProjection();
+ // Remap the argument source value and inherit the old storage info.
+ return StorageAccessInfo(AccessedStorage(argVal, proj), storage);
+ }
}
// Otherwise, continue to reference the value in the callee because we don't
// have any better placeholder for a callee-defined object.
@@ -202,12 +270,15 @@
case AccessedStorage::Argument: {
// Transitively search for the storage base in the caller.
SILValue argVal = getCallerArg(fullApply, storage.getParamIndex());
- if (argVal)
- return findAccessedStorageNonNested(argVal);
-
+ if (argVal) {
+ // Remap the argument source value and inherit the old storage info.
+ return StorageAccessInfo(findAccessedStorageNonNested(argVal), storage);
+ }
// If the argument can't be transformed, demote it to an unidentified
// access.
- return AccessedStorage(storage.getValue(), AccessedStorage::Unidentified);
+ return StorageAccessInfo(
+ AccessedStorage(storage.getValue(), AccessedStorage::Unidentified),
+ storage);
}
case AccessedStorage::Nested:
llvm_unreachable("Unexpected nested access");
@@ -222,7 +293,7 @@
const FunctionAccessedStorage &calleeAccess, FullApplySite fullApply) {
// Merge accesses from calleeAccess. Transform any Argument type
// AccessedStorage into the caller context to be added to `this` storage map.
- return mergeAccesses(calleeAccess, [&fullApply](const AccessedStorage &s) {
+ return mergeAccesses(calleeAccess, [&fullApply](const StorageAccessInfo &s) {
return transformCalleeStorage(s, fullApply);
});
}
@@ -236,13 +307,14 @@
findAccessedStorageNonNested(beginAccess->getSource());
if (storage.getKind() == AccessedStorage::Unidentified) {
+ // This also catches invalid storage.
updateOptionalAccessKind(unidentifiedAccess, beginAccess->getAccessKind());
return;
}
- StorageAccessInfo accessInfo(beginAccess);
- auto result = storageAccessMap.try_emplace(storage, accessInfo);
+ StorageAccessInfo storageAccess(storage, beginAccess);
+ auto result = insertStorageAccess(storageAccess);
if (!result.second)
- result.first->second.mergeFrom(accessInfo);
+ result.first->mergeFrom(storageAccess);
}
void FunctionAccessedStorage::analyzeInstruction(SILInstruction *I) {
@@ -252,44 +324,26 @@
visitBeginAccess(BUAI);
}
-bool FunctionAccessedStorage::mayConflictWith(
- SILAccessKind otherAccessKind, const AccessedStorage &otherStorage) {
- if (unidentifiedAccess != None
- && accessKindMayConflict(otherAccessKind,
- unidentifiedAccess.getValue())) {
- return true;
- }
- for (auto &accessEntry : storageAccessMap) {
-
- const AccessedStorage &storage = accessEntry.first;
- assert(storage && "FunctionAccessedStorage mapped invalid storage.");
-
- StorageAccessInfo accessInfo = accessEntry.second;
- if (!accessKindMayConflict(otherAccessKind, accessInfo.accessKind))
- continue;
-
- if (!otherStorage.isDistinctFrom(storage))
- return true;
- }
- return false;
+void StorageAccessInfo::print(raw_ostream &os) const {
+ os << " [" << getSILAccessKindName(getAccessKind()) << "] ";
+ if (hasNoNestedConflict())
+ os << "[no_nested_conflict] ";
+ AccessedStorage::print(os);
}
+void StorageAccessInfo::dump() const { print(llvm::dbgs()); }
+
void FunctionAccessedStorage::print(raw_ostream &os) const {
- for (auto &accessEntry : storageAccessMap) {
- const AccessedStorage &storage = accessEntry.first;
- const StorageAccessInfo &info = accessEntry.second;
- os << " [" << getSILAccessKindName(info.accessKind) << "] ";
- if (info.noNestedConflict)
- os << "[no_nested_conflict] ";
- storage.print(os);
- }
+ for (auto &storageAccess : storageAccessSet)
+ storageAccess.print(os);
+
if (unidentifiedAccess != None) {
os << " unidentified accesses: "
<< getSILAccessKindName(unidentifiedAccess.getValue()) << "\n";
}
}
-void FunctionAccessedStorage::dump() const { print(llvm::errs()); }
+void FunctionAccessedStorage::dump() const { print(llvm::dbgs()); }
SILAnalysis *swift::createAccessedStorageAnalysis(SILModule *) {
return new AccessedStorageAnalysis();
diff --git a/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp b/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
index 6f353d3..7f1c121 100644
--- a/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
+++ b/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
@@ -29,6 +29,7 @@
#define DEBUG_TYPE "access-marker-elim"
#include "swift/Basic/Range.h"
+#include "swift/SIL/MemAccessUtils.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "llvm/Support/CommandLine.h"
@@ -56,42 +57,27 @@
AccessMarkerElimination(SILFunction *F)
: Mod(&F->getModule()), F(F) {}
- SILBasicBlock::iterator eraseInst(SILInstruction *inst) {
+ void notifyErased(SILInstruction *inst) {
DEBUG(llvm::dbgs() << "Erasing access marker: " << *inst);
removedAny = true;
+ }
+
+ SILBasicBlock::iterator eraseInst(SILInstruction *inst) {
+ notifyErased(inst);
return inst->getParent()->erase(inst);
};
- void replaceBeginAccessUsers(BeginAccessInst *beginAccess);
-
bool shouldPreserveAccess(SILAccessEnforcement enforcement);
// Check if the instruction is a marker that should be eliminated. If so,
// updated the SIL, short of erasing the marker itself, and return true.
- bool checkAndEliminateMarker(SILInstruction *inst);
+ SILBasicBlock::iterator checkAndEliminateMarker(SILInstruction *inst);
// Entry point called either by the pass by the same name
// or as a utility (e.g. during deserialization).
bool stripMarkers();
};
-void AccessMarkerElimination::replaceBeginAccessUsers(
- BeginAccessInst *beginAccess) {
- // Handle all the uses:
- while (!beginAccess->use_empty()) {
- Operand *op = *beginAccess->use_begin();
-
- // Delete any associated end_access instructions.
- if (auto endAccess = dyn_cast<EndAccessInst>(op->getUser())) {
- endAccess->eraseFromParent();
-
- // Forward all other uses to the original address.
- } else {
- op->set(beginAccess->getSource());
- }
- }
-}
-
bool AccessMarkerElimination::shouldPreserveAccess(
SILAccessEnforcement enforcement) {
if (!EnableOptimizedAccessMarkers)
@@ -107,22 +93,26 @@
}
}
-// Check if the instruction is a marker that should be eliminated. If so,
-// updated the SIL, short of erasing the marker itself, and return true.
-bool AccessMarkerElimination::checkAndEliminateMarker(SILInstruction *inst) {
+// Check if the instruction is a marker that should be eliminated. If so, delete
+// the begin_access along with all associated end_access and a valid instruction
+// iterator pointing to the first remaining instruction following the
+// begin_access. If the marker is not eliminated, return an iterator pointing to
+// the marker.
+SILBasicBlock::iterator
+AccessMarkerElimination::checkAndEliminateMarker(SILInstruction *inst) {
if (auto beginAccess = dyn_cast<BeginAccessInst>(inst)) {
// Builtins used by the standard library must emit markers regardless of the
// current compiler options so that any user code that initiates access via
// the standard library is fully enforced.
if (beginAccess->isFromBuiltin())
- return false;
+ return inst->getIterator();
// Leave dynamic accesses in place, but delete all others.
if (shouldPreserveAccess(beginAccess->getEnforcement()))
- return false;
+ return inst->getIterator();
- replaceBeginAccessUsers(beginAccess);
- return true;
+ notifyErased(beginAccess);
+ return removeBeginAccess(beginAccess);
}
// end_access instructions will be handled when we process the
@@ -134,12 +124,12 @@
// Builtins used by the standard library must emit markers regardless of the
// current compiler options.
if (BUA->isFromBuiltin())
- return false;
+ return inst->getIterator();
if (shouldPreserveAccess(BUA->getEnforcement()))
- return false;
+ return inst->getIterator();
- return true;
+ return eraseInst(BUA);
}
// end_unpaired_access instructions will be directly removed and
// simply replaced with their operand.
@@ -147,14 +137,14 @@
// Builtins used by the standard library must emit markers regardless of the
// current compiler options.
if (EUA->isFromBuiltin())
- return false;
+ return inst->getIterator();
if (shouldPreserveAccess(EUA->getEnforcement()))
- return false;
+ return inst->getIterator();
- return true;
+ return eraseInst(EUA);
}
- return false;
+ return inst->getIterator();
}
// Top-level per-function entry-point.
@@ -166,8 +156,9 @@
// Don't cache the begin iterator since we're reverse iterating.
for (auto II = BB.end(); II != BB.begin();) {
SILInstruction *inst = &*(--II);
- if (checkAndEliminateMarker(inst))
- II = eraseInst(inst);
+ // checkAndEliminateMarker returns the next non-deleted instruction. The
+ // following iteration moves the iterator backward.
+ II = checkAndEliminateMarker(inst);
}
}
return removedAny;
diff --git a/lib/SILOptimizer/Mandatory/CMakeLists.txt b/lib/SILOptimizer/Mandatory/CMakeLists.txt
index b4c29d5..8819fe1 100644
--- a/lib/SILOptimizer/Mandatory/CMakeLists.txt
+++ b/lib/SILOptimizer/Mandatory/CMakeLists.txt
@@ -16,4 +16,6 @@
Mandatory/PredictableMemOpt.cpp
Mandatory/SemanticARCOpts.cpp
Mandatory/ClosureLifetimeFixup.cpp
+ Mandatory/RawSILInstLowering.cpp
+ Mandatory/MandatoryOptUtils.cpp
PARENT_SCOPE)
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
index 2df2d15..c8e83b9 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
@@ -1459,24 +1459,79 @@
}
//===----------------------------------------------------------------------===//
-// DelegatingInitElementUseCollector
+// DelegatingValueTypeInitUseCollector
+//===----------------------------------------------------------------------===//
+
+static void
+collectValueTypeDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
+ DIElementUseInfo &UseInfo,
+ SingleValueInstruction *I) {
+ for (auto *Op : I->getUses()) {
+ auto *User = Op->getUser();
+
+ // destroy_addr is a release of the entire value. This can result from an
+ // early release due to a conditional initializer.
+ if (isa<DestroyAddrInst>(User)) {
+ UseInfo.trackDestroy(User);
+ continue;
+ }
+
+ // For delegating initializers, we only track calls to self.init with
+ // specialized code. All other uses are modeled as escapes.
+ //
+ // *NOTE* This intentionally ignores all stores, which (if they got emitted
+ // as copyaddr or assigns) will eventually get rewritten as assignments (not
+ // initializations), which is the right thing to do.
+ DIUseKind Kind = DIUseKind::Escape;
+
+ // Stores *to* the allocation are writes. If the value being stored is a
+ // call to self.init()... then we have a self.init call.
+ if (auto *AI = dyn_cast<AssignInst>(User)) {
+ if (AI->getDest() == I) {
+ UseInfo.trackStoreToSelf(AI);
+ Kind = DIUseKind::InitOrAssign;
+ }
+ }
+
+ if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
+ if (CAI->getDest() == I) {
+ UseInfo.trackStoreToSelf(CAI);
+ Kind = DIUseKind::InitOrAssign;
+ }
+ }
+
+ // Look through begin_access
+ if (auto *BAI = dyn_cast<BeginAccessInst>(User)) {
+ collectValueTypeDelegatingInitUses(TheMemory, UseInfo, BAI);
+ continue;
+ }
+
+ // Ignore end_access
+ if (isa<EndAccessInst>(User))
+ continue;
+
+ // We can safely handle anything else as an escape. They should all happen
+ // after self.init is invoked.
+ UseInfo.trackUse(DIMemoryUse(User, Kind, 0, 1));
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// DelegatingClassInitElementUseCollector
//===----------------------------------------------------------------------===//
namespace {
-class DelegatingInitElementUseCollector {
+class DelegatingClassInitElementUseCollector {
const DIMemoryObjectInfo &TheMemory;
DIElementUseInfo &UseInfo;
- void collectValueTypeInitSelfUses(SingleValueInstruction *I);
-
public:
- DelegatingInitElementUseCollector(const DIMemoryObjectInfo &TheMemory,
- DIElementUseInfo &UseInfo)
+ DelegatingClassInitElementUseCollector(const DIMemoryObjectInfo &TheMemory,
+ DIElementUseInfo &UseInfo)
: TheMemory(TheMemory), UseInfo(UseInfo) {}
void collectClassInitSelfUses();
- void collectValueTypeInitSelfUses();
// *NOTE* Even though this takes a SILInstruction it actually only accepts
// load_borrow and load instructions. This is enforced via an assert.
@@ -1488,7 +1543,7 @@
/// collectDelegatingClassInitSelfUses - Collect uses of the self argument in a
/// delegating-constructor-for-a-class case.
-void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
+void DelegatingClassInitElementUseCollector::collectClassInitSelfUses() {
// When we're analyzing a delegating constructor, we aren't field sensitive at
// all. Just treat all members of self as uses of the single
// non-field-sensitive value.
@@ -1631,70 +1686,9 @@
}
}
-void DelegatingInitElementUseCollector::collectValueTypeInitSelfUses(
- SingleValueInstruction *I) {
- for (auto Op : I->getUses()) {
- auto *User = Op->getUser();
-
- // destroy_addr is a release of the entire value. This can result from an
- // early release due to a conditional initializer.
- if (isa<DestroyAddrInst>(User)) {
- UseInfo.trackDestroy(User);
- continue;
- }
-
- // For delegating initializers, we only track calls to self.init with
- // specialized code. All other uses are modeled as escapes.
- //
- // *NOTE* This intentionally ignores all stores, which (if they got emitted
- // as copyaddr or assigns) will eventually get rewritten as assignments (not
- // initializations), which is the right thing to do.
- DIUseKind Kind = DIUseKind::Escape;
-
- // Stores *to* the allocation are writes. If the value being stored is a
- // call to self.init()... then we have a self.init call.
- if (auto *AI = dyn_cast<AssignInst>(User)) {
- if (AI->getDest() == I) {
- UseInfo.trackStoreToSelf(AI);
- Kind = DIUseKind::InitOrAssign;
- }
- }
-
- if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
- if (CAI->getDest() == I) {
- UseInfo.trackStoreToSelf(CAI);
- Kind = DIUseKind::InitOrAssign;
- }
- }
-
- // Look through begin_access
- if (auto *BAI = dyn_cast<BeginAccessInst>(User)) {
- collectValueTypeInitSelfUses(BAI);
- continue;
- }
-
- // Ignore end_access
- if (isa<EndAccessInst>(User))
- continue;
-
- // We can safely handle anything else as an escape. They should all happen
- // after self.init is invoked.
- UseInfo.trackUse(DIMemoryUse(User, Kind, 0, 1));
- }
-}
-
-void DelegatingInitElementUseCollector::collectValueTypeInitSelfUses() {
- // When we're analyzing a delegating constructor, we aren't field sensitive at
- // all. Just treat all members of self as uses of the single
- // non-field-sensitive value.
- assert(TheMemory.NumElements == 1 && "delegating inits only have 1 bit");
-
- auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst);
- collectValueTypeInitSelfUses(MUI);
-}
-
-void DelegatingInitElementUseCollector::collectDelegatingClassInitSelfLoadUses(
- MarkUninitializedInst *MUI, SingleValueInstruction *LI) {
+void DelegatingClassInitElementUseCollector::
+collectDelegatingClassInitSelfLoadUses(MarkUninitializedInst *MUI,
+ SingleValueInstruction *LI) {
assert(isa<LoadBorrowInst>(LI) || isa<LoadInst>(LI));
// If we have a load, then this is a use of the box. Look at the uses of
@@ -1775,31 +1769,38 @@
// Top Level Entrypoint
//===----------------------------------------------------------------------===//
+static bool shouldPerformClassInitSelf(const DIMemoryObjectInfo &MemoryInfo) {
+ if (MemoryInfo.isDelegatingInit()) {
+ assert(MemoryInfo.isClassInitSelf());
+ return true;
+ }
+
+ return MemoryInfo.isNonDelegatingInit() &&
+ MemoryInfo.getType()->getClassOrBoundGenericClass() != nullptr &&
+ MemoryInfo.isDerivedClassSelfOnly();
+}
+
/// collectDIElementUsesFrom - Analyze all uses of the specified allocation
/// instruction (alloc_box, alloc_stack or mark_uninitialized), classifying them
/// and storing the information found into the Uses and Releases lists.
void swift::ownership::collectDIElementUsesFrom(
const DIMemoryObjectInfo &MemoryInfo, DIElementUseInfo &UseInfo,
bool isDIFinished, bool TreatAddressToPointerAsInout) {
- // If we have a delegating init, use the delegating init element use
- // collector.
- if (MemoryInfo.isDelegatingInit()) {
- DelegatingInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
- if (MemoryInfo.isClassInitSelf()) {
- UseCollector.collectClassInitSelfUses();
- } else {
- UseCollector.collectValueTypeInitSelfUses();
- }
+ if (MemoryInfo.isDelegatingInit() && !MemoryInfo.isClassInitSelf()) {
+ // When we're analyzing a delegating constructor, we aren't field sensitive
+ // at all. Just treat all members of self as uses of the single
+ // non-field-sensitive value.
+ assert(MemoryInfo.NumElements == 1 && "delegating inits only have 1 bit");
+ auto *MUI = cast<MarkUninitializedInst>(MemoryInfo.MemoryInst);
+ collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo, MUI);
MemoryInfo.collectRetainCountInfo(UseInfo);
return;
}
- if (MemoryInfo.isNonDelegatingInit() &&
- MemoryInfo.getType()->getClassOrBoundGenericClass() != nullptr &&
- MemoryInfo.isDerivedClassSelfOnly()) {
- DelegatingInitElementUseCollector(MemoryInfo, UseInfo)
- .collectClassInitSelfUses();
+ if (shouldPerformClassInitSelf(MemoryInfo)) {
+ DelegatingClassInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
+ UseCollector.collectClassInitSelfUses();
MemoryInfo.collectRetainCountInfo(UseInfo);
return;
}
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index 3402a9e..0ba46bb 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -12,6 +12,7 @@
#define DEBUG_TYPE "definite-init"
#include "DIMemoryUseCollectorOwnership.h"
+#include "MandatoryOptUtils.h"
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/DiagnosticsSIL.h"
#include "swift/AST/Expr.h"
@@ -44,8 +45,6 @@
"Meant for debugging ONLY!"),
llvm::cl::Hidden);
-STATISTIC(NumAssignRewritten, "Number of assigns rewritten");
-
template<typename ...ArgTypes>
static InFlightDiagnostic diagnose(SILModule &M, SILLocation loc,
ArgTypes... args) {
@@ -56,83 +55,6 @@
return diag;
}
-enum class PartialInitializationKind {
- /// The box contains a fully-initialized value.
- IsNotInitialization,
-
- /// The box contains a class instance that we own, but the instance has
- /// not been initialized and should be freed with a special SIL
- /// instruction made for this purpose.
- IsReinitialization,
-
- /// The box contains an undefined value that should be ignored.
- IsInitialization,
-};
-
-/// Emit the sequence that an assign instruction lowers to once we know
-/// if it is an initialization or an assignment. If it is an assignment,
-/// a live-in value can be provided to optimize out the reload.
-static void LowerAssignInstruction(SILBuilderWithScope &B, AssignInst *Inst,
- PartialInitializationKind isInitialization) {
- DEBUG(llvm::dbgs() << " *** Lowering [isInit=" << unsigned(isInitialization)
- << "]: " << *Inst << "\n");
-
- ++NumAssignRewritten;
-
- SILValue Src = Inst->getSrc();
- SILLocation Loc = Inst->getLoc();
-
- if (isInitialization == PartialInitializationKind::IsInitialization ||
- Inst->getDest()->getType().isTrivial(Inst->getModule())) {
-
- // If this is an initialization, or the storage type is trivial, we
- // can just replace the assignment with a store.
- assert(isInitialization != PartialInitializationKind::IsReinitialization);
- B.createTrivialStoreOr(Loc, Src, Inst->getDest(),
- StoreOwnershipQualifier::Init);
- Inst->eraseFromParent();
- return;
- }
-
- if (isInitialization == PartialInitializationKind::IsReinitialization) {
- // We have a case where a convenience initializer on a class
- // delegates to a factory initializer from a protocol extension.
- // Factory initializers give us a whole new instance, so the existing
- // instance, which has not been initialized and never will be, must be
- // freed using dealloc_partial_ref.
- SILValue Pointer =
- B.createLoad(Loc, Inst->getDest(), LoadOwnershipQualifier::Take);
- B.createStore(Loc, Src, Inst->getDest(), StoreOwnershipQualifier::Init);
-
- auto MetatypeTy = CanMetatypeType::get(
- Inst->getDest()->getType().getASTType(),
- MetatypeRepresentation::Thick);
- auto SILMetatypeTy = SILType::getPrimitiveObjectType(MetatypeTy);
- SILValue Metatype = B.createValueMetatype(Loc, SILMetatypeTy, Pointer);
-
- B.createDeallocPartialRef(Loc, Pointer, Metatype);
- Inst->eraseFromParent();
- return;
- }
-
- assert(isInitialization == PartialInitializationKind::IsNotInitialization);
- // Otherwise, we need to replace the assignment with the full
- // load/store/release dance. Note that the new value is already
- // considered to be retained (by the semantics of the storage type),
- // and we're transferring that ownership count into the destination.
-
- // This is basically TypeLowering::emitStoreOfCopy, except that if we have
- // a known incoming value, we can avoid the load.
- SILValue IncomingVal =
- B.createLoad(Loc, Inst->getDest(), LoadOwnershipQualifier::Take);
- B.createStore(Inst->getLoc(), Src, Inst->getDest(),
- StoreOwnershipQualifier::Init);
-
- B.emitDestroyValueOperation(Loc, IncomingVal);
- Inst->eraseFromParent();
-}
-
-
/// Insert a CFG diamond at the position specified by the SILBuilder, with a
/// conditional branch based on "Cond".
///
@@ -1912,7 +1834,7 @@
SmallVector<SILInstruction*, 4> InsertedInsts;
SILBuilderWithScope B(Inst, &InsertedInsts);
- LowerAssignInstruction(B, AI, PartialInitKind);
+ lowerAssignInstruction(B, AI, PartialInitKind);
// If lowering of the assign introduced any new loads or stores, keep track
// of them.
@@ -2899,64 +2821,35 @@
DEBUG(llvm::dbgs() << "*** Definite Init visiting function: "
<< Fn.getName() << "\n");
bool Changed = false;
- for (auto &BB : Fn) {
- for (auto I = BB.begin(), E = BB.end(); I != E; ++I) {
- SILInstruction *Inst = &*I;
- if (auto *MUI = dyn_cast<MarkUninitializedInst>(Inst))
- Changed |= processMemoryObject(MUI);
- }
- }
- return Changed;
-}
-/// lowerRawSILOperations - There are a variety of raw-sil instructions like
-/// 'assign' that are only used by this pass. Now that definite initialization
-/// checking is done, remove them.
-static bool lowerRawSILOperations(SILFunction &Fn) {
- bool Changed = false;
for (auto &BB : Fn) {
- auto I = BB.begin(), E = BB.end();
- while (I != E) {
+ for (auto I = BB.begin(), E = BB.end(); I != E;) {
SILInstruction *Inst = &*I;
+
+ auto *MUI = dyn_cast<MarkUninitializedInst>(Inst);
+ if (!MUI || !processMemoryObject(MUI)) {
+ ++I;
+ continue;
+ }
+
+ // Move off of the MUI only after we have processed memory objects. The
+ // lifetime checker may rewrite instructions, so it is important to not
+ // move onto the next element until after it runs.
++I;
-
- // Unprocessed assigns just lower into assignments, not initializations.
- if (auto *AI = dyn_cast<AssignInst>(Inst)) {
- SILBuilderWithScope B(AI);
- LowerAssignInstruction(B, AI,
- PartialInitializationKind::IsNotInitialization);
- // Assign lowering may split the block. If it did,
- // reset our iteration range to the block after the insertion.
- if (B.getInsertionBB() != &BB)
- I = E;
- Changed = true;
- continue;
- }
-
- // mark_uninitialized just becomes a noop, resolving to its operand.
- if (auto *MUI = dyn_cast<MarkUninitializedInst>(Inst)) {
- MUI->replaceAllUsesWith(MUI->getOperand());
- MUI->eraseFromParent();
- Changed = true;
- continue;
- }
-
- // mark_function_escape just gets zapped.
- if (isa<MarkFunctionEscapeInst>(Inst)) {
- Inst->eraseFromParent();
- Changed = true;
- continue;
- }
+ MUI->replaceAllUsesWith(MUI->getOperand());
+ MUI->eraseFromParent();
+ Changed = true;
}
}
+
return Changed;
}
namespace {
+
/// Perform definitive initialization analysis and promote alloc_box uses into
/// SSA registers for later SSA-based dataflow passes.
class DefiniteInitialization : public SILFunctionTransform {
-
/// The entry point to the transformation.
void run() override {
// Don't rerun diagnostics on deserialized functions.
@@ -2967,16 +2860,9 @@
if (checkDefiniteInitialization(*getFunction())) {
invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
}
-
- DEBUG(getFunction()->verify());
-
- // Lower raw-sil only instructions used by this pass, like "assign".
- if (lowerRawSILOperations(*getFunction()))
- invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
-
}
-
};
+
} // end anonymous namespace
SILTransform *swift::createDefiniteInitialization() {
diff --git a/lib/SILOptimizer/Mandatory/MandatoryOptUtils.cpp b/lib/SILOptimizer/Mandatory/MandatoryOptUtils.cpp
new file mode 100644
index 0000000..fb7716d
--- /dev/null
+++ b/lib/SILOptimizer/Mandatory/MandatoryOptUtils.cpp
@@ -0,0 +1,98 @@
+//===--- MandatoryOptUtils.cpp --------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "sil-mandatory-utils"
+#include "MandatoryOptUtils.h"
+#include "swift/AST/DiagnosticEngine.h"
+#include "swift/AST/DiagnosticsSIL.h"
+#include "swift/AST/Expr.h"
+#include "swift/ClangImporter/ClangModule.h"
+#include "swift/SIL/InstructionUtils.h"
+#include "swift/SIL/SILArgument.h"
+#include "swift/SIL/SILBuilder.h"
+#include "swift/SILOptimizer/PassManager/Passes.h"
+#include "swift/SILOptimizer/PassManager/Transforms.h"
+#include "swift/SILOptimizer/Utils/CFG.h"
+#include "swift/SILOptimizer/Utils/Local.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+
+STATISTIC(NumAssignRewritten, "Number of assigns rewritten");
+
+using namespace swift;
+
+/// Emit the sequence that an assign instruction lowers to once we know
+/// if it is an initialization or an assignment. If it is an assignment,
+/// a live-in value can be provided to optimize out the reload.
+void swift::lowerAssignInstruction(SILBuilderWithScope &B, AssignInst *Inst,
+ PartialInitializationKind isInitialization) {
+ DEBUG(llvm::dbgs() << " *** Lowering [isInit=" << unsigned(isInitialization)
+ << "]: " << *Inst << "\n");
+
+ ++NumAssignRewritten;
+
+ SILValue Src = Inst->getSrc();
+ SILLocation Loc = Inst->getLoc();
+
+ if (isInitialization == PartialInitializationKind::IsInitialization ||
+ Inst->getDest()->getType().isTrivial(Inst->getModule())) {
+
+ // If this is an initialization, or the storage type is trivial, we
+ // can just replace the assignment with a store.
+ assert(isInitialization != PartialInitializationKind::IsReinitialization);
+ B.createTrivialStoreOr(Loc, Src, Inst->getDest(),
+ StoreOwnershipQualifier::Init);
+ Inst->eraseFromParent();
+ return;
+ }
+
+ if (isInitialization == PartialInitializationKind::IsReinitialization) {
+ // We have a case where a convenience initializer on a class
+ // delegates to a factory initializer from a protocol extension.
+ // Factory initializers give us a whole new instance, so the existing
+ // instance, which has not been initialized and never will be, must be
+ // freed using dealloc_partial_ref.
+ SILValue Pointer =
+ B.createLoad(Loc, Inst->getDest(), LoadOwnershipQualifier::Take);
+ B.createStore(Loc, Src, Inst->getDest(), StoreOwnershipQualifier::Init);
+
+ auto MetatypeTy = CanMetatypeType::get(
+ Inst->getDest()->getType().getASTType(), MetatypeRepresentation::Thick);
+ auto SILMetatypeTy = SILType::getPrimitiveObjectType(MetatypeTy);
+ SILValue Metatype = B.createValueMetatype(Loc, SILMetatypeTy, Pointer);
+
+ B.createDeallocPartialRef(Loc, Pointer, Metatype);
+ Inst->eraseFromParent();
+ return;
+ }
+
+ assert(isInitialization == PartialInitializationKind::IsNotInitialization);
+ // Otherwise, we need to replace the assignment with the full
+ // load/store/release dance. Note that the new value is already
+ // considered to be retained (by the semantics of the storage type),
+ // and we're transferring that ownership count into the destination.
+
+ // This is basically TypeLowering::emitStoreOfCopy, except that if we have
+ // a known incoming value, we can avoid the load.
+ SILValue IncomingVal =
+ B.createLoad(Loc, Inst->getDest(), LoadOwnershipQualifier::Take);
+ B.createStore(Inst->getLoc(), Src, Inst->getDest(),
+ StoreOwnershipQualifier::Init);
+
+ B.emitDestroyValueOperation(Loc, IncomingVal);
+ Inst->eraseFromParent();
+}
diff --git a/lib/SILOptimizer/Mandatory/MandatoryOptUtils.h b/lib/SILOptimizer/Mandatory/MandatoryOptUtils.h
new file mode 100644
index 0000000..f9c02f4
--- /dev/null
+++ b/lib/SILOptimizer/Mandatory/MandatoryOptUtils.h
@@ -0,0 +1,46 @@
+//===--- MandatoryOptUtils.h ----------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+///
+/// Contains utility operations used by various mandatory passes.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_SILOPTIMIZER_MANDATORY_MANDATORYOOPTUTILS_H
+#define SWIFT_SILOPTIMIZER_MANDATORY_MANDATORYOOPTUTILS_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace swift {
+
+class SILBuilderWithScope;
+class AssignInst;
+
+enum class PartialInitializationKind {
+ /// The box contains a fully-initialized value.
+ IsNotInitialization,
+
+ /// The box contains a class instance that we own, but the instance has
+ /// not been initialized and should be freed with a special SIL
+ /// instruction made for this purpose.
+ IsReinitialization,
+
+ /// The box contains an undefined value that should be ignored.
+ IsInitialization,
+};
+
+void lowerAssignInstruction(SILBuilderWithScope &B, AssignInst *Inst,
+ PartialInitializationKind isInitialization)
+ LLVM_LIBRARY_VISIBILITY;
+
+} // namespace swift
+
+#endif
diff --git a/lib/SILOptimizer/Mandatory/RawSILInstLowering.cpp b/lib/SILOptimizer/Mandatory/RawSILInstLowering.cpp
new file mode 100644
index 0000000..235b504
--- /dev/null
+++ b/lib/SILOptimizer/Mandatory/RawSILInstLowering.cpp
@@ -0,0 +1,89 @@
+//===--- RawSILInstLowering.cpp -------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#include "MandatoryOptUtils.h"
+#include "swift/SIL/SILBuilder.h"
+#include "swift/SIL/SILFunction.h"
+#include "swift/SIL/SILInstruction.h"
+#include "swift/SILOptimizer/PassManager/Passes.h"
+#include "swift/SILOptimizer/PassManager/Transforms.h"
+
+using namespace swift;
+
+/// lowerRawSILOperations - There are a variety of raw-sil instructions like
+/// 'assign' that are only used by this pass. Now that definite initialization
+/// checking is done, remove them.
+static bool lowerRawSILOperations(SILFunction &Fn) {
+ bool Changed = false;
+ for (auto &BB : Fn) {
+ auto I = BB.begin(), E = BB.end();
+ while (I != E) {
+ SILInstruction *Inst = &*I;
+ ++I;
+
+ // Unprocessed assigns just lower into assignments, not initializations.
+ if (auto *AI = dyn_cast<AssignInst>(Inst)) {
+ SILBuilderWithScope B(AI);
+ lowerAssignInstruction(B, AI,
+ PartialInitializationKind::IsNotInitialization);
+ // Assign lowering may split the block. If it did,
+ // reset our iteration range to the block after the insertion.
+ if (B.getInsertionBB() != &BB)
+ I = E;
+ Changed = true;
+ continue;
+ }
+
+ // mark_uninitialized just becomes a noop, resolving to its operand.
+ if (auto *MUI = dyn_cast<MarkUninitializedInst>(Inst)) {
+ MUI->replaceAllUsesWith(MUI->getOperand());
+ MUI->eraseFromParent();
+ Changed = true;
+ continue;
+ }
+
+ // mark_function_escape just gets zapped.
+ if (isa<MarkFunctionEscapeInst>(Inst)) {
+ Inst->eraseFromParent();
+ Changed = true;
+ continue;
+ }
+ }
+ }
+ return Changed;
+}
+
+//===----------------------------------------------------------------------===//
+// Top Level Entrypoint
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class RawSILInstLowering : public SILFunctionTransform {
+ void run() override {
+ // Do not try to relower raw instructions in canonical SIL. There won't be
+ // any there.
+ if (getFunction()->wasDeserializedCanonical()) {
+ return;
+ }
+
+ // Lower raw-sil only instructions used by this pass, like "assign".
+ if (lowerRawSILOperations(*getFunction()))
+ invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
+ }
+};
+
+} // end anonymous namespace
+
+SILTransform *swift::createRawSILInstLowering() {
+ return new RawSILInstLowering();
+}
diff --git a/lib/SILOptimizer/PassManager/PassPipeline.cpp b/lib/SILOptimizer/PassManager/PassPipeline.cpp
index 04b8955..3e6a280 100644
--- a/lib/SILOptimizer/PassManager/PassPipeline.cpp
+++ b/lib/SILOptimizer/PassManager/PassPipeline.cpp
@@ -71,6 +71,14 @@
P.addOwnershipModelEliminator();
}
+/// Passes for performing definite initialization. Must be run together in this
+/// order.
+static void addDefiniteInitialization(SILPassPipelinePlan &P) {
+ P.addMarkUninitializedFixup();
+ P.addDefiniteInitialization();
+ P.addRawSILInstLowering();
+}
+
static void addMandatoryOptPipeline(SILPassPipelinePlan &P,
const SILOptions &Options) {
P.startPipeline("Guaranteed Passes");
@@ -86,8 +94,7 @@
P.addAllocBoxToStack();
P.addNoReturnFolding();
- P.addMarkUninitializedFixup();
- P.addDefiniteInitialization();
+ addDefiniteInitialization(P);
P.addClosureLifetimeFixup();
P.addOwnershipModelEliminator();
P.addMandatoryInlining();
diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
index 58ae94f..02502e0 100644
--- a/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
+++ b/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
@@ -30,42 +30,25 @@
/// DiagnoseStaticExclusivity must be able to fully analyze all @inout_aliasable
/// parameters because they aren't dynamically enforced. This optimization
/// completely ignores @inout_aliasable paramters because it only cares about
-/// dynamic enforcement. This optimization also does not attempt to look at
-/// subaccess paths, because it should not weaken enforcement in any way--a
-/// program that traps at -Onone should also trap at -O.
+/// dynamic enforcement. This optimization also does not attempt to
+/// differentiate accesses on disjoint subaccess paths, because it should not
+/// weaken enforcement in any way--a program that traps at -Onone should also
+/// trap at -O.
///
-/// AccessFolding is a forward data flow analysis that tracks open accesses. If
+/// Access folding is a forward data flow analysis that tracks open accesses. If
/// any path to an access' end of scope has a potentially conflicting access,
/// then that access is marked as a nested conflict.
///
/// Pass order dependencies:
-/// - Benefits from running after AccessEnforcementSelection.
+/// - Will benefit from running after AccessEnforcementSelection.
///
/// TODO: Perform another run of AccessEnforcementSelection immediately before
/// this pass. Currently, that pass only works well when run before
/// AllocBox2Stack. Ideally all such closure analysis passes are combined into a
-/// shared anlysis with a set of associated optimizations that can be rerun at
+/// shared analysis with a set of associated optimizations that can be rerun at
/// any point in the pipeline. Until then, we could settle for a partially
/// working AccessEnforcementSelection, or expand it somewhat to handle
/// alloc_stack.
-///
-/// TODO: Add test case. Use SideEffectAnalysis to ignore calls without global
-/// effects. Also scan the arguments to see if there are closure captures. If
-/// this isn't sufficient, add a bit to SideEffectAnalysis for NonlocalAccess.
-///
-/// TODO: Add test case. For Local variables. Ignore global side effects if
-/// none of the intervening calls can access the captured variable.
-///
-/// TODO: Add test case. For Class/Global variables. Ignore global side effects
-/// if callee analysis and interprocedural analysis tell us that none of the
-/// intervening calls access that variable.
-///
-/// TODO: As a separate module pass, find global/class accesses to properties
-/// that are never passed "reentrantly". That optmimization could make use of
-/// the no_nested_conflict flags set in this pass. If *none* of a module-private
-/// variable's accesses have nested conflict, then they can be downgraded to
-/// static checks en masse.
-///
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "access-enforcement-opts"
@@ -81,13 +64,23 @@
using namespace swift;
namespace swift {
+/// Represents the identity of a storage location being accessed.
+///
/// A value-based subclass of AccessedStorage with identical layout. This
/// provides access to pass-specific data in reserved bits.
///
-/// The fully-qualified class name allows for the declaration of bitfields in
-/// AccessedStorage. In this file, it is aliased to AccessInfo.
+/// The fully descriptive class name allows forward declaration in order to
+/// define bitfields in AccessedStorage.
+///
+/// Aliased to AccessInfo in this file.
class AccessEnforcementOptsInfo : public AccessedStorage {
public:
+ AccessEnforcementOptsInfo(const AccessedStorage &storage)
+ : AccessedStorage(storage) {
+ Bits.AccessEnforcementOptsInfo.beginAccessIndex = 0;
+ Bits.AccessEnforcementOptsInfo.seenNestedConflict = false;
+ }
+
/// Get a unique index for this access within its function.
unsigned getAccessIndex() const {
return Bits.AccessEnforcementOptsInfo.beginAccessIndex;
@@ -114,19 +107,20 @@
<< (seenNestedConflict() ? "" : "no ") << "conflict>\n";
}
};
+using AccessInfo = AccessEnforcementOptsInfo;
} // namespace swift
-using AccessInfo = AccessEnforcementOptsInfo;
-
namespace {
+// Sparse access sets are used temporarily for fast operations by local
+// reachability analysis. We don't care if they take more space.
class SparseAccessSet;
-/// A dense set of begin_[unpaired_]access instructions... because very few
-/// accesses are typically in-progress at a particular program point,
-/// particularly at block boundaries.
+/// A dense set of begin_access instructions as a compact vector. Reachability
+/// results are stored here because very few accesses are typically in-progress
+/// at a particular program point, particularly at block boundaries.
using DenseAccessSet = SmallVector<BeginAccessInst *, 4>;
-/// Perform the access folding optimization on a function.
+/// Analyze a function's formal access to determine nested conflicts.
///
/// Maps each begin access instruction to its AccessInfo, which:
/// - identifies the accessed memory for conflict detection
@@ -136,9 +130,9 @@
///
/// If, after computing reachability, an access' conflict flag is still not set,
/// then all paths in its scope are conflict free. Reachability begins at a
-/// begin_[unpaired_]access instruction and ends either at a potential conflict
-/// or at the end_[unpaired_]access instruction that is associated with the
-/// begin access.
+/// begin_access instruction and ends either at a potential conflict
+/// or at the end_access instruction that is associated with the
+/// begin_access.
///
/// Forward data flow computes `blockOutAccess` for each block. At a control
/// flow merge, this analysis forms an intersection of reachable accesses on
@@ -149,47 +143,60 @@
/// when a block is first visited, blockOutAccess contains the maximal
/// reachability set. Further iteration would only reduce this set.
///
-/// The only result of this analysis used by the optimization is the conflict
-/// flag in AccessInfo. Since reducing a reachability set cannot further
-/// detect conflicts, there is no need to iterate to a reachability fix point.
-class AccessFolding {
- friend class SparseAccessSet;
+/// The only result of this analysis is the seenNestedConflict flags in
+/// AccessInfo. Since reducing a reachability set cannot further detect
+/// conflicts, there is no need to iterate to a reachability fix point.
+class AccessConflictAnalysis {
+public:
+ using AccessMap = llvm::SmallDenseMap<BeginAccessInst *, AccessInfo, 32>;
+ // This result of this analysis is a map from all BeginAccessInst in this
+ // function to AccessInfo.
+ struct Result {
+ /// Map each begin access to its AccessInfo with index, data, and flags.
+ /// Iterating over this map is nondeterministic. If it is necessary to order
+ /// the accesses, then AccessInfo::getAccessIndex() can be used.
+ AccessMap accessMap;
+ /// Convenience.
+ ///
+ /// Note: If AccessInfo has already been retrieved, get the index directly
+ /// from it instead of calling this to avoid additional hash lookup.
+ unsigned getAccessIndex(BeginAccessInst *beginAccess) const {
+ return getAccessInfo(beginAccess).getAccessIndex();
+ }
+
+ /// Get the AccessInfo for a BeginAccessInst within this function. All
+ /// accesses are mapped by identifyBeginAccesses().
+ AccessInfo &getAccessInfo(BeginAccessInst *beginAccess) {
+ auto iter = accessMap.find(beginAccess);
+ assert(iter != accessMap.end());
+ return iter->second;
+ }
+ const AccessInfo &getAccessInfo(BeginAccessInst *beginAccess) const {
+ return const_cast<Result &>(*this).getAccessInfo(beginAccess);
+ }
+ };
+
+private:
SILFunction *F;
PostOrderFunctionInfo *PO;
AccessedStorageAnalysis *ASA;
- /// Map each begin access to its index, data, and flags.
- llvm::SmallDenseMap<BeginAccessInst *, AccessInfo, 32> beginAccessMap;
-
- /// Tracks the in-progress accesses at the end of each block.
+ /// Tracks the in-scope accesses at the end of each block, for the purpose of
+ /// finding nested conflicts. (Out-of-scope accesses are currently only
+ /// tracked locally for the purpose of merging access scopes.)
llvm::SmallDenseMap<SILBasicBlock *, DenseAccessSet, 32> blockOutAccess;
+ Result result;
+
public:
- AccessFolding(SILFunction *F, PostOrderFunctionInfo *PO,
- AccessedStorageAnalysis *ASA)
+ AccessConflictAnalysis(SILFunction *F, PostOrderFunctionInfo *PO,
+ AccessedStorageAnalysis *ASA)
: F(F), PO(PO), ASA(ASA) {}
- void perform();
+ Result &&analyze() &&;
protected:
- /// Get the AccessInfo for a BeginAccessInst within this function. All
- /// accesses are mapped by identifyBeginAccesses().
- AccessInfo &getAccessInfo(BeginAccessInst *beginAccess) {
- auto iter = beginAccessMap.find(beginAccess);
- assert(iter != beginAccessMap.end());
- return iter->second;
- }
- const AccessInfo &getAccessInfo(BeginAccessInst *beginAccess) const {
- return const_cast<AccessFolding &>(*this).getAccessInfo(beginAccess);
- }
-
- /// Convenience. If AccessInfo has already been retrieved, get the index
- /// directly from it instead of calling this to avoid additional hash lookup.
- unsigned getAccessIndex(BeginAccessInst *beginAccess) const {
- return getAccessInfo(beginAccess).getAccessIndex();
- }
-
void identifyBeginAccesses();
void visitBeginAccess(BeginAccessInst *beginAccess,
@@ -203,8 +210,6 @@
SparseAccessSet &mergedAccesses);
void visitBlock(SILBasicBlock *BB);
-
- void foldNonNestedAccesses();
};
/// A sparse set of in-flight accesses.
@@ -212,96 +217,134 @@
/// Explodes a DenseAccessSet into a temporary sparse set for comparison
/// and membership.
///
-/// The AccessFolding pass provides the instruction to index mapping. Rather
-/// than having all instances of SparseAccessSet reference the pass, it is only
-/// passed in for the operations that require it.
+/// The AccessConflictAnalysis result provides the instruction to index
+/// mapping.
class SparseAccessSet {
- llvm::SmallBitVector bitmask; // Most functions have < 64 accesses.
- DenseAccessSet denseVec;
+ AccessConflictAnalysis::Result &result;
+
+ // Mark the in-scope accesses.
+ // (Most functions have < 64 accesses.)
+ llvm::SmallBitVector inScopeBitmask;
+ // Mark a potential conflicts on each access since the last begin/end marker.
+ llvm::SmallBitVector conflictBitmask;
+ DenseAccessSet denseVec; // Hold all local accesses seen thus far.
public:
- /// Internally, the denseVec may contain entries that have been removed from
- /// the bitmask. Iteration checks for membership in the bitmask.
- class Iterator {
- const AccessFolding &pass;
+ /// Iterate over in-scope, conflict free access.
+ class NoNestedConflictIterator {
const SparseAccessSet &sparseSet;
DenseAccessSet::const_iterator denseIter;
public:
- Iterator(const SparseAccessSet &set, const AccessFolding &pass)
- : pass(pass), sparseSet(set), denseIter(set.denseVec.begin()) {}
+ NoNestedConflictIterator(const SparseAccessSet &set)
+ : sparseSet(set), denseIter(set.denseVec.begin()) {}
BeginAccessInst *next() {
auto end = sparseSet.denseVec.end();
while (denseIter != end) {
BeginAccessInst *beginAccess = *denseIter;
++denseIter;
- unsigned sparseIndex = pass.getAccessIndex(beginAccess);
- if (sparseSet.bitmask[sparseIndex])
+ unsigned sparseIndex = sparseSet.result.getAccessIndex(beginAccess);
+ if (sparseSet.inScopeBitmask[sparseIndex]
+ && !sparseSet.conflictBitmask[sparseIndex]) {
return beginAccess;
+ }
}
return nullptr;
}
};
- SparseAccessSet(AccessFolding &pass) : bitmask(pass.beginAccessMap.size()) {}
+ SparseAccessSet(AccessConflictAnalysis::Result &result)
+ : result(result), inScopeBitmask(result.accessMap.size()),
+ conflictBitmask(result.accessMap.size()) {}
- SparseAccessSet(const DenseAccessSet &denseVec, AccessFolding &pass)
- : bitmask(pass.beginAccessMap.size()), denseVec(denseVec) {
+ // All accessed in the given denseVec are presumed to be in-scope and conflict
+ // free.
+ SparseAccessSet(const DenseAccessSet &denseVec,
+ AccessConflictAnalysis::Result &result)
+ : result(result), inScopeBitmask(result.accessMap.size()),
+ conflictBitmask(result.accessMap.size()), denseVec(denseVec) {
for (BeginAccessInst *beginAccess : denseVec)
- bitmask.set(pass.getAccessIndex(beginAccess));
+ inScopeBitmask.set(result.getAccessIndex(beginAccess));
}
-
- bool isEmpty(AccessFolding &pass) const {
- Iterator iterator(*this, pass);
+ bool hasConflictFreeAccess() const {
+ NoNestedConflictIterator iterator(*this);
return iterator.next() == nullptr;
}
- bool contains(unsigned index) const { return bitmask[index]; }
+ bool hasInScopeAccess() const {
+ return llvm::any_of(denseVec, [this](BeginAccessInst *beginAccess) {
+ unsigned sparseIndex = result.getAccessIndex(beginAccess);
+ return inScopeBitmask[sparseIndex];
+ });
+ }
+
+ bool isInScope(unsigned index) const { return inScopeBitmask[index]; }
// Insert the given BeginAccessInst with its corresponding reachability index.
- // Return true if the set was expanded.
- bool insert(BeginAccessInst *beginAccess, unsigned index) {
- if (bitmask[index])
- return false;
-
- bitmask.set(index);
+ // Set the in-scope bit and reset the conflict bit.
+ bool enterScope(BeginAccessInst *beginAccess, unsigned index) {
+ assert(!inScopeBitmask[index]
+ && "nested access should not be dynamically enforced.");
+ inScopeBitmask.set(index);
+ conflictBitmask.reset(index);
denseVec.push_back(beginAccess);
return true;
}
- /// Erase an access from this set based on the index provided by its mapped
- /// AccessInfo.
- ///
- /// Does not invalidate Iterator.
- void erase(unsigned index) { bitmask.reset(index); }
+ /// End the scope of the given access by marking it in-scope and clearing the
+ /// conflict bit. (The conflict bit only marks conflicts since the last begin
+ /// *or* end access).
+ void exitScope(unsigned index) { inScopeBitmask.reset(index); }
- bool isEquivalent(const SparseAccessSet &other) const {
- return bitmask == other.bitmask;
- }
+ bool seenConflict(unsigned index) const { return conflictBitmask[index]; }
+
+ void setConflict(unsigned index) { conflictBitmask.set(index); }
// Only merge accesses that are present on the `other` map. i.e. erase
// all accesses in this map that are not present in `other`.
- void merge(const SparseAccessSet &other) { bitmask &= other.bitmask; }
-
- void copyInto(DenseAccessSet &other, AccessFolding &pass) {
- other.clear();
- Iterator iterator(*this, pass);
- while (BeginAccessInst *beginAccess = iterator.next()) {
- other.push_back(beginAccess);
- }
+ void merge(const SparseAccessSet &other) {
+ inScopeBitmask &= other.inScopeBitmask;
+ // Currently only conflict free accesses are preserved across blocks by this
+ // analysis. Otherwise, taking the union of conflict bits would be valid.
+ assert(other.conflictBitmask.none());
}
- void dump(AccessFolding &pass) const {
- Iterator iterator(*this, pass);
- while (BeginAccessInst *beginAccess = iterator.next()) {
+ void copyNoNestedConflictInto(DenseAccessSet &other) {
+ other.clear();
+ NoNestedConflictIterator iterator(*this);
+ while (BeginAccessInst *beginAccess = iterator.next())
+ other.push_back(beginAccess);
+ }
+
+ // Dump only the accesses with no conflict up to this point.
+ void dump() const {
+ for (BeginAccessInst *beginAccess : denseVec) {
+ unsigned sparseIndex = result.getAccessIndex(beginAccess);
+ if (conflictBitmask[sparseIndex])
+ continue;
+
llvm::dbgs() << *beginAccess << " ";
- pass.getAccessInfo(beginAccess).dump();
+ if (!inScopeBitmask[sparseIndex])
+ llvm::dbgs() << " [noscope]";
+ result.getAccessInfo(beginAccess).dump();
}
}
};
} // namespace
+// Top-level driver for AccessConflictAnalysis.
+AccessConflictAnalysis::Result &&AccessConflictAnalysis::analyze() && {
+ // Populate beginAccessMap.
+ identifyBeginAccesses();
+
+ // Perform data flow and set the conflict flags on AccessInfo.
+ for (auto *BB : PO->getReversePostOrder())
+ visitBlock(BB);
+
+ return std::move(result);
+}
+
// Find all begin access operations in this function. Map each access to
// AccessInfo, which includes its identified memory location, identifying
// index, and analysis result flags.
@@ -310,30 +353,33 @@
// isn't explicitly paired, it may be possible after devirtualization and
// inlining to find all uses of the scratch buffer. However, this doesn't
// currently happen in practice (rdar://40033735).
-void AccessFolding::identifyBeginAccesses() {
+void AccessConflictAnalysis::identifyBeginAccesses() {
for (auto &BB : *F) {
for (auto &I : BB) {
auto *beginAccess = dyn_cast<BeginAccessInst>(&I);
if (!beginAccess)
continue;
+ if (beginAccess->getEnforcement() != SILAccessEnforcement::Dynamic)
+ continue;
+
// The accessed base is expected to be valid for begin_access, but for
// now, since this optimization runs at the end of the pipeline, we
- // gracefully handle unrecognized source address patterns, which show up
+ // gracefully ignore unrecognized source address patterns, which show up
// here as an invalid `storage` value.
const AccessedStorage &storage =
findAccessedStorageNonNested(beginAccess->getSource());
if (!storage)
continue;
- auto iterAndSuccess = beginAccessMap.try_emplace(
+ auto iterAndSuccess = result.accessMap.try_emplace(
beginAccess, static_cast<const AccessInfo &>(storage));
(void)iterAndSuccess;
assert(iterAndSuccess.second);
// Add a pass-specific access index to the mapped storage object.
AccessInfo &info = iterAndSuccess.first->second;
- info.setAccessIndex(beginAccessMap.size()-1);
+ info.setAccessIndex(result.accessMap.size() - 1);
assert(!info.seenNestedConflict());
}
}
@@ -344,7 +390,7 @@
/// conflicts. Erasing from SparseAccessSet does not invalidate any iterators.
static void recordConflict(AccessInfo &info, SparseAccessSet &accessSet) {
info.setSeenNestedConflict();
- accessSet.erase(info.getAccessIndex());
+ accessSet.setConflict(info.getAccessIndex());
}
// Given an "inner" access, check for potential conflicts with any outer access.
@@ -357,22 +403,22 @@
//
// Record the inner access in the accessSet.
//
-void AccessFolding::visitBeginAccess(BeginAccessInst *innerBeginAccess,
- SparseAccessSet &accessSet) {
+void AccessConflictAnalysis::visitBeginAccess(BeginAccessInst *innerBeginAccess,
+ SparseAccessSet &accessSet) {
if (innerBeginAccess->getEnforcement() != SILAccessEnforcement::Dynamic)
return;
- const AccessInfo &innerAccess = getAccessInfo(innerBeginAccess);
+ const AccessInfo &innerAccess = result.getAccessInfo(innerBeginAccess);
SILAccessKind innerAccessKind = innerBeginAccess->getAccessKind();
- SparseAccessSet::Iterator accessIter(accessSet, *this);
+ SparseAccessSet::NoNestedConflictIterator accessIter(accessSet);
while (BeginAccessInst *outerBeginAccess = accessIter.next()) {
// If both are reads, keep the mapped access.
if (!accessKindMayConflict(innerAccessKind,
outerBeginAccess->getAccessKind())) {
continue;
}
- AccessInfo &outerAccess = getAccessInfo(outerBeginAccess);
+ AccessInfo &outerAccess = result.getAccessInfo(outerBeginAccess);
// If there is no potential conflict, leave the outer access mapped.
if (!outerAccess.isDistinctFrom(innerAccess))
@@ -389,38 +435,38 @@
// Record the current access in the map. It can potentially be folded
// regardless of whether it may conflict with an outer access.
bool inserted =
- accessSet.insert(innerBeginAccess, innerAccess.getAccessIndex());
+ accessSet.enterScope(innerBeginAccess, innerAccess.getAccessIndex());
(void)inserted;
assert(inserted && "the same begin_access cannot be seen twice.");
}
-void AccessFolding::visitEndAccess(EndAccessInst *endAccess,
+void AccessConflictAnalysis::visitEndAccess(EndAccessInst *endAccess,
SparseAccessSet &accessSet) {
auto *beginAccess = endAccess->getBeginAccess();
if (beginAccess->getEnforcement() != SILAccessEnforcement::Dynamic)
return;
- unsigned index = getAccessIndex(beginAccess);
- DEBUG(if (accessSet.contains(index)) llvm::dbgs()
+ unsigned index = result.getAccessIndex(beginAccess);
+ DEBUG(if (accessSet.seenConflict(index)) llvm::dbgs()
<< "No conflict on one path from " << *beginAccess << " to "
<< *endAccess);
// Erase this access from the sparse set. We only want to detect conflicts
// within the access scope.
- accessSet.erase(index);
+ accessSet.exitScope(index);
}
-void AccessFolding::visitFullApply(FullApplySite fullApply,
+void AccessConflictAnalysis::visitFullApply(FullApplySite fullApply,
SparseAccessSet &accessSet) {
FunctionAccessedStorage callSiteAccesses;
ASA->getCallSiteEffects(callSiteAccesses, fullApply);
- SparseAccessSet::Iterator accessIter(accessSet, *this);
+ SparseAccessSet::NoNestedConflictIterator accessIter(accessSet);
while (BeginAccessInst *outerBeginAccess = accessIter.next()) {
// If there is no potential conflict, leave the outer access mapped.
SILAccessKind accessKind = outerBeginAccess->getAccessKind();
- AccessInfo &outerAccess = getAccessInfo(outerBeginAccess);
+ AccessInfo &outerAccess = result.getAccessInfo(outerBeginAccess);
if (!callSiteAccesses.mayConflictWith(accessKind, outerAccess))
continue;
@@ -436,7 +482,7 @@
// accesses that are still present in all predecessors. The absence of a begin
// access from a visited predecessor indicates the presence of a conflict. A
// block has been visited if it has a map entry in blockOutAccess.
-void AccessFolding::mergePredAccesses(SILBasicBlock *succBB,
+void AccessConflictAnalysis::mergePredAccesses(SILBasicBlock *succBB,
SparseAccessSet &mergedAccesses) {
for (SILBasicBlock *predBB : succBB->getPredecessorBlocks()) {
auto mapI = blockOutAccess.find(predBB);
@@ -444,14 +490,14 @@
continue;
const DenseAccessSet &predSet = mapI->second;
- mergedAccesses.merge(SparseAccessSet(predSet, *this));
+ mergedAccesses.merge(SparseAccessSet(predSet, result));
}
}
// Compute access reachability within the given block.
-void AccessFolding::visitBlock(SILBasicBlock *BB) {
+void AccessConflictAnalysis::visitBlock(SILBasicBlock *BB) {
// Sparse set for tracking accesses with an individual block.
- SparseAccessSet accessSet(*this);
+ SparseAccessSet accessSet(result);
mergePredAccesses(BB, accessSet);
for (auto &I : *BB) {
@@ -467,29 +513,38 @@
visitFullApply(fullApply, accessSet);
}
}
- if (BB->getTerminator()->isFunctionExiting())
- assert(accessSet.isEquivalent(*this) && "no postdominating end_access");
-
- DEBUG(if (!accessSet.isEmpty(*this)) {
- llvm::dbgs() << "Initializing accesses out of bb" << BB->getDebugID()
- << "\n";
- accessSet.dump(*this);
+ DEBUG(if (accessSet.hasConflictFreeAccess()) {
+ llvm::dbgs() << "Initializing no-conflict access out of bb"
+ << BB->getDebugID() << "\n";
+ accessSet.dump();
});
+ if (BB->getTerminator()->isFunctionExiting())
+ assert(!accessSet.hasInScopeAccess() && "no postdominating end_access");
// Initialize blockOutAccess for this block with the current access set.
- accessSet.copyInto(blockOutAccess[BB], *this);
+ accessSet.copyNoNestedConflictInto(blockOutAccess[BB]);
}
-// Data-flow analysis is now complete. Any begin_access remaining in
-// nonNestedBeginAccessInstructions can be marked "non-nested".
-//
-// Note: If we later support marking begin_unpaired_access [no_nested_conflict],
-// then we also need to remove any corresponding end_unpaired_access. That can
-// be done either by recording the end_unpaired_access instructions during
-// analysis and deleting them here in the same order, or sorting them here by
-// their begin_unpaired_access index.
-void AccessFolding::foldNonNestedAccesses() {
- for (auto &beginAccessAndInfo : beginAccessMap) {
+// -----------------------------------------------------------------------------
+// MARK: Access Enforcement Optimization
+// -----------------------------------------------------------------------------
+
+/// Perform access folding.
+///
+/// Data-flow analysis is now complete. Any begin_access that has seen a
+/// conflict can be given the [no_nested_conflict] instruction attribute.
+///
+/// Note: If we later support marking begin_unpaired_access
+/// [no_nested_conflict], then we also need to remove any corresponding
+/// end_unpaired_access. That can be done either by recording the
+/// end_unpaired_access instructions during analysis and deleting them here in
+/// the same order, or sorting them here by their begin_unpaired_access index.
+static bool
+foldNonNestedAccesses(AccessConflictAnalysis::AccessMap &accessMap) {
+ bool changed = false;
+ // Iteration over accessMap is nondeterministic. Setting the conflict flags
+ // can be done in any order.
+ for (auto &beginAccessAndInfo : accessMap) {
BeginAccessInst *beginAccess = beginAccessAndInfo.first;
AccessInfo &info = beginAccessAndInfo.second;
if (info.seenNestedConflict())
@@ -497,20 +552,48 @@
// Optimize this begin_access by setting [no_nested_conflict].
beginAccess->setNoNestedConflict(true);
+ changed = true;
+ DEBUG(llvm::dbgs() << "Folding " << *beginAccess);
}
+ return changed;
}
-// Top-level driver for AccessFolding forward data flow optimization.
-void AccessFolding::perform() {
- // Populate beginAccessMap.
- identifyBeginAccesses();
+/// Eliminate accesses to uniquely identified local storage for which no
+/// accesses can have nested conflicts. This is only valid if the function's
+/// local storage cannot be potentially modified by unidentified access.
+///
+/// This simply invalidates the AccessMap result rather than erasing individual
+/// entries.
+static bool
+removeLocalNonNestedAccess(AccessConflictAnalysis::Result &&result,
+ const FunctionAccessedStorage &functionAccess) {
+ if (functionAccess.hasUnidentifiedAccess())
+ return false;
- // Perform data flow and set the conflict flags on AccessInfo.
- for (auto *BB : PO->getReversePostOrder())
- visitBlock(BB);
+ bool changed = false;
+ SmallVector<BeginAccessInst *, 8> deadAccesses;
+ for (auto &beginAccessAndInfo : result.accessMap) {
+ BeginAccessInst *beginAccess = beginAccessAndInfo.first;
+ AccessInfo &info = beginAccessAndInfo.second;
+ if (info.seenNestedConflict() || !info.isLocal())
+ continue;
- // Fold any accesses that don't have nested conflicts.
- foldNonNestedAccesses();
+ // This particular access to local storage is marked
+ // [no_nested_conflict]. Now check FunctionAccessedStorage to determine if
+ // that is true for all access to the same storage.
+ if (functionAccess.hasNoNestedConflict(info))
+ deadAccesses.push_back(beginAccess);
+ }
+ std::sort(deadAccesses.begin(), deadAccesses.end(),
+ [&result](BeginAccessInst *a, BeginAccessInst *b) {
+ return result.getAccessIndex(a) < result.getAccessIndex(b);
+ });
+ for (BeginAccessInst *beginAccess : deadAccesses) {
+ DEBUG(llvm::dbgs() << "Removing dead access " << *beginAccess);
+ changed = true;
+ removeBeginAccess(beginAccess);
+ }
+ return changed;
}
namespace {
@@ -520,15 +603,33 @@
if (F->empty())
return;
- // Perform access folding. May mark begin_access with no_nested_conflict and
- // may removed end_unpaired_access.
PostOrderFunctionInfo *PO = getAnalysis<PostOrderAnalysis>()->get(F);
AccessedStorageAnalysis *ASA = getAnalysis<AccessedStorageAnalysis>();
- AccessFolding folding(F, PO, ASA);
- folding.perform();
+ auto result = AccessConflictAnalysis(F, PO, ASA).analyze();
+
+ // Perform access folding by setting the [no_nested_conflict] flag on
+ // begin_access instructions.
+ if (!foldNonNestedAccesses(result.accessMap))
+ return;
+
+ // Recompute AccessStorageAnalysis, just for this function, to update the
+ // StorageAccessInfo::noNestedConflict status for each accessed storage.
+ invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
+
+ // Use the updated AccessedStorageAnalysis to find any uniquely identified
+ // local storage that has no nested conflict on any of its accesses within
+ // this function. These can be removed entirely.
+ //
+ // Note that the storage address may be passed as an argument and there may
+ // be nested conflicts within that call, but none of the accesses within
+ // this function will overlap.
+ const FunctionAccessedStorage &functionAccess = ASA->getEffects(F);
+ if (removeLocalNonNestedAccess(std::move(result), functionAccess))
+ invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
+ // `result` is now invalid.
}
};
-}
+} // namespace
SILTransform *swift::createAccessEnforcementOpts() {
return new AccessEnforcementOpts();
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 993b651..1674ec3 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -2670,7 +2670,7 @@
ApplyExpr *apply = CallExpr::create(
tc.Context, result, arg, expr->getArgumentLabels(),
expr->getArgumentLabelLocs(), expr->hasTrailingClosure(),
- /*implicit=*/false, Type(), getType);
+ /*implicit=*/expr->isImplicit(), Type(), getType);
result = finishApply(apply, Type(), cs.getConstraintLocator(expr));
}
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 6f4651d..b6513af 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -1002,6 +1002,10 @@
bool diagnoseSubscriptErrors(SubscriptExpr *SE, bool performingSet);
+ /// Diagnose the usage of 'subscript' instead of the operator when calling
+ /// a subscript and offer a fixit if the inputs are compatible.
+ bool diagnoseSubscriptMisuse(ApplyExpr *callExpr);
+
bool visitExpr(Expr *E);
bool visitIdentityExpr(IdentityExpr *E);
bool visitTryExpr(TryExpr *E);
@@ -5434,6 +5438,144 @@
return false;
}
+bool FailureDiagnosis::diagnoseSubscriptMisuse(ApplyExpr *callExpr) {
+ auto UDE = dyn_cast<UnresolvedDotExpr>(callExpr->getFn());
+ if (!UDE)
+ return false;
+
+ auto baseExpr = UDE->getBase();
+ if (!baseExpr || UDE->getName().getBaseName() != getTokenText(tok::kw_subscript))
+ return false;
+
+ auto baseType = CS.getType(baseExpr);
+ // Look up subscript declarations.
+ auto lookup = CS.lookupMember(baseType->getRValueType(),
+ DeclName(DeclBaseName::createSubscript()));
+ auto nonSubscrLookup = CS.lookupMember(baseType->getRValueType(),
+ UDE->getName());
+ // Make sure we only found subscript declarations. If not, the problem
+ // is different - return.
+ if (lookup.empty() || !nonSubscrLookup.empty())
+ return false;
+ // Try to resolve a type of the argument expression.
+ auto argExpr = typeCheckChildIndependently(callExpr->getArg(),
+ Type(), CTP_CallArgument);
+ if (!argExpr)
+ return CS.TC.Diags.hadAnyError();
+
+ SmallVector<Identifier, 2> scratch;
+ ArrayRef<Identifier> argLabels = callExpr->getArgumentLabels(scratch);
+ SmallVector<OverloadChoice, 2> choices;
+
+ for (auto candidate : lookup)
+ choices.push_back(OverloadChoice(baseType, candidate.getValueDecl(),
+ UDE->getFunctionRefKind()));
+ CalleeCandidateInfo candidateInfo(baseType, choices,
+ callArgHasTrailingClosure(argExpr),
+ CS, true);
+ struct TypeConvertibleChecker {
+ ConstraintSystem &CS;
+
+ TypeConvertibleChecker(ConstraintSystem &CS) : CS(CS) {}
+
+ // Checks whether type1 is implicitly convertible to type2
+ bool isImplicitlyConvertible(Type type1, Type type2) {
+ if (!type1 || !type2)
+ return false;
+
+ if (auto tup1 = type1->getAs<TupleType>()) {
+ if (auto tup2 = type2->getAs<TupleType>())
+ return isImplicitlyConvertibleTuple(tup1, tup2);
+ else
+ return false;
+ }
+ if (type1->isEqual(type2) || type2->is<GenericTypeParamType>() ||
+ CS.TC.isSubtypeOf(type1, type2, CS.DC))
+ return true;
+ return false;
+ }
+
+ bool isImplicitlyConvertibleTuple(TupleType *tup1, TupleType *tup2) {
+ if (tup1->getNumElements() != tup2->getNumElements())
+ return false;
+
+ for (unsigned i = 0, e = tup1->getNumElements(); i < e; i ++) {
+ auto element1 = tup1->getElement(i);
+ auto element2 = tup2->getElement(i);
+ if (element1.hasName()) {
+ if (!element2.hasName() || element1.getName() !=
+ element2.getName())
+ return false;
+ }
+ if (!isImplicitlyConvertible(element1.getType(),
+ element2.getType()))
+ return false;
+ }
+ return true;
+ }
+ } checker(CS);
+ auto params = swift::decomposeArgType(CS.getType(argExpr), argLabels);
+ using ClosenessPair = CalleeCandidateInfo::ClosenessResultTy;
+
+ candidateInfo.filterList([&](UncurriedCandidate cand) -> ClosenessPair {
+ auto candFuncType = cand.getUncurriedFunctionType();
+ if (!candFuncType)
+ return {CC_GeneralMismatch, {}};
+
+ auto candParams = candFuncType->getParams();
+ if (params.size() != candParams.size())
+ return {CC_GeneralMismatch, {}};
+
+ for (unsigned i = 0, e = params.size(); i < e; i ++) {
+ if (checker.isImplicitlyConvertible(params[i].getType(),
+ candParams[i].getType()))
+ continue;
+ return {CC_GeneralMismatch, {}};
+ }
+ return {CC_ExactMatch, {}};
+ });
+
+ auto *locator = CS.getConstraintLocator(UDE, ConstraintLocator::Member);
+ auto memberRange = baseExpr->getSourceRange();
+ if (locator)
+ locator = simplifyLocator(CS, locator, memberRange);
+ auto nameLoc = DeclNameLoc(memberRange.Start);
+
+ auto diag = diagnose(baseExpr->getLoc(),
+ diag::could_not_find_subscript_member_did_you_mean,
+ baseType);
+ diag.highlight(memberRange).highlight(nameLoc.getSourceRange());
+
+ auto showNote = [&]() {
+ diag.flush();
+ if (candidateInfo.size() == 1)
+ diagnose(candidateInfo.candidates.front().getDecl(),
+ diag::kind_declared_here, DescriptiveDeclKind::Subscript);
+ };
+ if (candidateInfo.closeness != CC_ExactMatch) {
+ showNote();
+ return true;
+ }
+ auto toCharSourceRange = Lexer::getCharSourceRangeFromSourceRange;
+ auto lastArgSymbol = toCharSourceRange(CS.TC.Context.SourceMgr,
+ argExpr->getEndLoc());
+
+ diag.fixItReplace(SourceRange(argExpr->getStartLoc()),
+ getTokenText(tok::l_square));
+ diag.fixItRemove(nameLoc.getSourceRange());
+ diag.fixItRemove(SourceRange(UDE->getDotLoc()));
+ if (CS.TC.Context.SourceMgr.extractText(lastArgSymbol) ==
+ getTokenText(tok::r_paren))
+ diag.fixItReplace(SourceRange(argExpr->getEndLoc()),
+ getTokenText(tok::r_square));
+ else
+ diag.fixItInsertAfter(argExpr->getEndLoc(),
+ getTokenText(tok::r_square));
+ showNote();
+
+ return true;
+}
+
// Check if there is a structural problem in the function expression
// by performing type checking with the option to allow unresolved
// type variables. If that is going to produce a function type with
@@ -5480,11 +5622,18 @@
auto originalFnType = CS.getType(callExpr->getFn());
if (shouldTypeCheckFunctionExpr(CS.TC, CS.DC, fnExpr)) {
+
+ // If we are misusing a subscript, diagnose that and provide a fixit.
+ // We diagnose this here to have enough context to offer an appropriate fixit.
+ if (diagnoseSubscriptMisuse(callExpr)) {
+ return CS.TC.Diags.hadAnyError();
+ }
// Type check the function subexpression to resolve a type for it if
// possible.
fnExpr = typeCheckChildIndependently(callExpr->getFn());
- if (!fnExpr)
- return true;
+ if (!fnExpr) {
+ return CS.TC.Diags.hadAnyError();
+ }
}
SWIFT_DEFER {
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 1ac031c..4d04dc5 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1592,8 +1592,8 @@
false)
.highlight(SourceRange(expr->getLAngleLoc(),
expr->getRAngleLoc()));
- tc.diagnose(bgt->getDecl(), diag::generic_type_declared_here,
- bgt->getDecl()->getName());
+ tc.diagnose(bgt->getDecl(), diag::kind_identifier_declared_here,
+ DescriptiveDeclKind::GenericType, bgt->getDecl()->getName());
return Type();
}
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 83585f9..0c84f2a 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1802,15 +1802,96 @@
return false;
}
+// Attempt to find a disjunction of bind constraints where all options
+// in the disjunction are binding the same type variable.
+//
+// Prefer disjunctions where the bound type variable is also the
+// right-hand side of a conversion constraint, since having a concrete
+// type that we're converting to can make it possible to split the
+// constraint system into multiple ones.
+static Constraint *selectBestBindingDisjunction(
+ ConstraintSystem &cs, SmallVectorImpl<Constraint *> &disjunctions) {
+
+ // Collect any disjunctions that simply attempt bindings for a
+ // type variable.
+ SmallVector<Constraint *, 8> bindingDisjunctions;
+ for (auto *disjunction : disjunctions) {
+ llvm::Optional<TypeVariableType *> commonTypeVariable;
+ if (llvm::all_of(
+ disjunction->getNestedConstraints(),
+ [&](Constraint *bindingConstraint) {
+ if (bindingConstraint->getKind() != ConstraintKind::Bind)
+ return false;
+
+ auto *tv =
+ bindingConstraint->getFirstType()->getAs<TypeVariableType>();
+ // Only do this for simple type variable bindings, not for
+ // bindings like: ($T1) -> $T2 bind String -> Int
+ if (!tv)
+ return false;
+
+ if (!commonTypeVariable.hasValue())
+ commonTypeVariable = tv;
+
+ if (commonTypeVariable.getValue() != tv)
+ return false;
+
+ return true;
+ })) {
+ bindingDisjunctions.push_back(disjunction);
+ }
+ }
+
+ for (auto *disjunction : bindingDisjunctions) {
+ auto nested = disjunction->getNestedConstraints();
+ assert(!nested.empty());
+ auto *tv = cs.simplifyType(nested[0]->getFirstType())
+ ->getRValueType()
+ ->getAs<TypeVariableType>();
+ assert(tv);
+
+ SmallVector<Constraint *, 8> constraints;
+ cs.getConstraintGraph().gatherConstraints(
+ tv, constraints, ConstraintGraph::GatheringKind::EquivalenceClass);
+
+ for (auto *constraint : constraints) {
+ if (constraint->getKind() != ConstraintKind::Conversion)
+ continue;
+
+ auto toType =
+ cs.simplifyType(constraint->getSecondType())->getRValueType();
+ auto *toTV = toType->getAs<TypeVariableType>();
+ if (tv != toTV)
+ continue;
+
+ return disjunction;
+ }
+ }
+
+ // If we had any binding disjunctions, return the first of
+ // those. These ensure that we attempt to bind types earlier than
+ // trying the elements of other disjunctions, which can often mean
+ // we fail faster.
+ if (!bindingDisjunctions.empty())
+ return bindingDisjunctions[0];
+
+ return nullptr;
+}
+
Constraint *ConstraintSystem::selectDisjunction(
SmallVectorImpl<Constraint *> &disjunctions) {
if (disjunctions.empty())
return nullptr;
+ auto *disjunction =
+ selectBestBindingDisjunction(*this, disjunctions);
+ if (disjunction)
+ return disjunction;
+
// Pick the smallest disjunction.
// FIXME: This heuristic isn't great, but it helped somewhat for
// overload sets.
- auto disjunction = disjunctions[0];
+ disjunction = disjunctions[0];
auto bestSize = disjunction->countActiveNestedConstraints();
if (bestSize > 2) {
for (auto contender : llvm::makeArrayRef(disjunctions).slice(1)) {
diff --git a/lib/Sema/CalleeCandidateInfo.cpp b/lib/Sema/CalleeCandidateInfo.cpp
index 1c31a5b..ef25107 100644
--- a/lib/Sema/CalleeCandidateInfo.cpp
+++ b/lib/Sema/CalleeCandidateInfo.cpp
@@ -835,7 +835,7 @@
// the uncurry level is 1 if self has already been applied.
unsigned uncurryLevel = 0;
if (decl->getDeclContext()->isTypeContext() &&
- selfAlreadyApplied)
+ selfAlreadyApplied && !isa<SubscriptDecl>(decl))
uncurryLevel = 1;
candidates.push_back({ decl, uncurryLevel });
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index ccdb26a..d28b0c5 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -1738,11 +1738,9 @@
TC.diagnose(behavior->getLoc(),
diag::property_behavior_protocol_reqt_ambiguous,
TC.Context.Id_value);
- TC.diagnose(valueProp->getLoc(),
- diag::property_behavior_protocol_reqt_here,
+ TC.diagnose(valueProp->getLoc(), diag::identifier_declared_here,
TC.Context.Id_value);
- TC.diagnose(foundVar->getLoc(),
- diag::property_behavior_protocol_reqt_here,
+ TC.diagnose(foundVar->getLoc(), diag::identifier_declared_here,
TC.Context.Id_value);
break;
}
@@ -2026,6 +2024,12 @@
}
}
+ // Inherit the @discardableResult attribute.
+ if (superclassCtor->getAttrs().hasAttribute<DiscardableResultAttr>()) {
+ auto *clonedAttr = new (ctx) DiscardableResultAttr(/*implicit=*/true);
+ ctor->getAttrs().add(clonedAttr);
+ }
+
// Make sure the constructor is only as available as its superclass's
// constructor.
AvailabilityInference::applyInferredAvailableAttrs(ctor, superclassCtor, ctx);
diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp
index 223155e..b114d6b 100644
--- a/lib/Sema/DerivedConformances.cpp
+++ b/lib/Sema/DerivedConformances.cpp
@@ -402,7 +402,8 @@
TC.diagnose(ConformanceDecl->getLoc(),
diag::cannot_synthesize_in_crossfile_extension,
getProtocolType());
- TC.diagnose(Nominal->getLoc(), diag::type_declared_here);
+ TC.diagnose(Nominal->getLoc(), diag::kind_declared_here,
+ DescriptiveDeclKind::Type);
return true;
}
diff --git a/lib/Sema/TypeCheckCaptures.cpp b/lib/Sema/TypeCheckCaptures.cpp
index c9fe99c..20df65a 100644
--- a/lib/Sema/TypeCheckCaptures.cpp
+++ b/lib/Sema/TypeCheckCaptures.cpp
@@ -271,7 +271,8 @@
NTD->getDescriptiveKind(),
D->getBaseName().getIdentifier());
- TC.diagnose(NTD->getLoc(), diag::type_declared_here);
+ TC.diagnose(NTD->getLoc(), diag::kind_declared_here,
+ DescriptiveDeclKind::Type);
TC.diagnose(D, diag::decl_declared_here, D->getFullName());
return { false, DRE };
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 869657c..e1f3f93 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -707,7 +707,7 @@
template<typename T>
static void checkCircularity(TypeChecker &tc, T *decl,
Diag<StringRef> circularDiag,
- Diag<Identifier> declHereDiag,
+ DescriptiveDeclKind declKind,
SmallVectorImpl<T *> &path) {
switch (decl->getCircularityCheck()) {
case CircularityCheck::Checked:
@@ -750,7 +750,8 @@
// Diagnose the cycle.
tc.diagnose(decl->getLoc(), circularDiag, pathStr);
for (auto i = cycleStart + 1, iEnd = path.end(); i != iEnd; ++i) {
- tc.diagnose(*i, declHereDiag, (*i)->getName());
+ tc.diagnose(*i, diag::kind_identifier_declared_here,
+ declKind, (*i)->getName());
}
// Set this declaration as invalid, then break the cycle somehow.
@@ -766,7 +767,7 @@
decl->setCircularityCheck(CircularityCheck::Checking);
T *scratch = nullptr;
for (auto inherited : getInheritedForCycleCheck(tc, decl, &scratch)) {
- checkCircularity(tc, inherited, circularDiag, declHereDiag, path);
+ checkCircularity(tc, inherited, circularDiag, declKind, path);
}
decl->setCircularityCheck(CircularityCheck::Checked);
path.pop_back();
@@ -1835,7 +1836,7 @@
if (auto CITR = dyn_cast<ComponentIdentTypeRepr>(complainRepr)) {
const ValueDecl *VD = CITR->getBoundDecl();
- TC.diagnose(VD, diag::type_declared_here);
+ TC.diagnose(VD, diag::kind_declared_here, DescriptiveDeclKind::Type);
}
}
@@ -3428,11 +3429,9 @@
diag::property_behavior_protocol_reqt_ambiguous,
TC.Context.Id_initStorage);
TC.diagnose(defaultInitStorageDecl->getLoc(),
- diag::property_behavior_protocol_reqt_here,
- TC.Context.Id_initStorage);
+ diag::identifier_declared_here, TC.Context.Id_initStorage);
TC.diagnose(parameterizedInitStorageDecl->getLoc(),
- diag::property_behavior_protocol_reqt_here,
- TC.Context.Id_initStorage);
+ diag::identifier_declared_here, TC.Context.Id_initStorage);
conformance->setInvalid();
continue;
}
@@ -3501,8 +3500,7 @@
TC.diagnose(behavior->getLoc(),
diag::property_behavior_invalid_parameter_reqt,
behaviorProto->getName());
- TC.diagnose(varReqt->getLoc(),
- diag::property_behavior_protocol_reqt_here,
+ TC.diagnose(varReqt->getLoc(), diag::identifier_declared_here,
TC.Context.Id_parameter);
conformance->setInvalid();
continue;
@@ -3772,7 +3770,8 @@
== dc->getParentModule()) {
if (!PGD->isInvalid()) {
diagnose(rel.NameLoc, diag::precedence_group_lower_within_module);
- diagnose(group->getNameLoc(), diag::precedence_group_declared_here);
+ diagnose(group->getNameLoc(), diag::kind_declared_here,
+ DescriptiveDeclKind::PrecedenceGroup);
isInvalid = true;
}
} else {
@@ -4476,7 +4475,7 @@
SmallVector<EnumDecl *, 8> path;
path.push_back(ED);
checkCircularity(TC, ED, diag::circular_enum_inheritance,
- diag::enum_here, path);
+ DescriptiveDeclKind::Enum, path);
}
for (Decl *member : ED->getMembers())
@@ -4636,7 +4635,7 @@
SmallVector<ClassDecl *, 8> path;
path.push_back(CD);
checkCircularity(TC, CD, diag::circular_class_inheritance,
- diag::class_here, path);
+ DescriptiveDeclKind::Class, path);
}
for (Decl *Member : CD->getMembers())
@@ -4760,7 +4759,7 @@
SmallVector<ProtocolDecl *, 8> path;
path.push_back(PD);
checkCircularity(TC, PD, diag::circular_protocol_def,
- diag::protocol_here, path);
+ DescriptiveDeclKind::Protocol, path);
// Make sure the parent protocols have been fully validated.
for (auto inherited : PD->getLocalProtocols()) {
@@ -6877,7 +6876,7 @@
if (mentionsItself) {
diagnose(defaultDefinition.getLoc(), diag::recursive_type_reference,
assocType->getDescriptiveKind(), assocType->getName());
- diagnose(assocType, diag::type_declared_here);
+ diagnose(assocType, diag::kind_declared_here, DescriptiveDeclKind::Type);
}
}
}
@@ -7007,8 +7006,8 @@
diagnose(proto->getLoc(),
diag::objc_protocol_inherits_non_objc_protocol,
proto->getDeclaredType(), inherited->getDeclaredType());
- diagnose(inherited->getLoc(), diag::protocol_here,
- inherited->getName());
+ diagnose(inherited->getLoc(), diag::kind_identifier_declared_here,
+ DescriptiveDeclKind::Protocol, inherited->getName());
isObjC = None;
}
}
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 33b36ee..a85f440 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -2732,9 +2732,9 @@
}
}
- diags.diagnose(requirement, diag::protocol_requirement_here,
+ diags.diagnose(requirement, diag::kind_declname_declared_here,
+ DescriptiveDeclKind::Requirement,
requirement->getFullName());
-
});
}
@@ -2835,7 +2835,8 @@
}
}
- diags.diagnose(requirement, diag::protocol_requirement_here,
+ diags.diagnose(requirement, diag::kind_declname_declared_here,
+ DescriptiveDeclKind::Requirement,
requirement->getFullName());
});
break;
@@ -2873,7 +2874,8 @@
witness->getFullName(),
conformance->getProtocol()->getFullName());
emitDeclaredHereIfNeeded(diags, diagLoc, witness);
- diags.diagnose(requirement, diag::protocol_requirement_here,
+ diags.diagnose(requirement, diag::kind_declname_declared_here,
+ DescriptiveDeclKind::Requirement,
requirement->getFullName());
});
break;
@@ -3516,7 +3518,8 @@
"@nonobjc ");
}
- TC.diagnose(requirement, diag::protocol_requirement_here,
+ TC.diagnose(requirement, diag::kind_declname_declared_here,
+ DescriptiveDeclKind::Requirement,
requirement->getFullName());
Conformance->setInvalid();
@@ -4484,7 +4487,8 @@
.fixItInsert(witness->getAttributeInsertionLoc(false), "@nonobjc ");
}
- tc.diagnose(req, diag::protocol_requirement_here, req->getFullName());
+ tc.diagnose(req, diag::kind_declname_declared_here,
+ DescriptiveDeclKind::Requirement, req->getFullName());
}
/// Whether the given protocol is "NSCoding".
diff --git a/lib/Sema/TypeCheckSwitchStmt.cpp b/lib/Sema/TypeCheckSwitchStmt.cpp
index b2fcbed..b2cf0c9 100644
--- a/lib/Sema/TypeCheckSwitchStmt.cpp
+++ b/lib/Sema/TypeCheckSwitchStmt.cpp
@@ -377,18 +377,14 @@
// (_ : Ty1) <= (_ : Ty2) iff D(Ty1) == D(Ty2)
if (canDecompose(this->getType(), DC)) {
- SmallVector<Space, 4> disjuncts;
- decompose(TC, DC, this->getType(), disjuncts);
- Space or1Space = Space::forDisjunct(disjuncts);
+ Space or1Space = decompose(TC, DC, this->getType());
if (or1Space.isSubspace(other, TC, DC)) {
return true;
}
}
if (canDecompose(other.getType(), DC)) {
- SmallVector<Space, 4> disjuncts;
- decompose(TC, DC, other.getType(), disjuncts);
- Space or2Space = Space::forDisjunct(disjuncts);
+ Space or2Space = decompose(TC, DC, other.getType());
return this->isSubspace(or2Space, TC, DC);
}
@@ -406,17 +402,13 @@
if (!canDecompose(this->getType(), DC)) {
return false;
}
- SmallVector<Space, 4> disjuncts;
- decompose(TC, DC, this->getType(), disjuncts);
- Space or1Space = Space::forDisjunct(disjuncts);
+ Space or1Space = decompose(TC, DC, this->getType());
return or1Space.isSubspace(other, TC, DC);
}
PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
// (_ : Ty1) <= H(p1 | ... | pn) iff D(Ty1) <= H(p1 | ... | pn)
if (canDecompose(this->getType(), DC)) {
- SmallVector<Space, 4> disjuncts;
- decompose(TC, DC, this->getType(), disjuncts);
- Space or1Space = Space::forDisjunct(disjuncts);
+ Space or1Space = decompose(TC, DC, this->getType());
return or1Space.isSubspace(other, TC, DC);
}
// An undecomposable type is always larger than its constructor space.
@@ -501,6 +493,11 @@
}
}
+ static Space intersect(const Space &a, const Space &b, TypeChecker &TC,
+ const DeclContext *DC) {
+ return a.intersect(b, TC, DC).simplify(TC, DC);
+ }
+
// Returns the intersection of this space with another. The intersection
// is the largest shared subspace occupied by both arguments.
Space intersect(const Space &other, TypeChecker &TC,
@@ -519,11 +516,10 @@
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Disjunct): {
// S & (S1 || ... || Sn) iff (S & S1) && ... && (S & Sn)
SmallVector<Space, 4> intersectedCases;
- std::transform(other.getSpaces().begin(), other.getSpaces().end(),
- std::back_inserter(intersectedCases),
- [&](const Space &s) {
- return this->intersect(s, TC, DC);
- });
+ std::transform(
+ other.getSpaces().begin(), other.getSpaces().end(),
+ std::back_inserter(intersectedCases),
+ [&](const Space &s) { return intersect(*this, s, TC, DC); });
return Space::forDisjunct(intersectedCases);
}
@@ -533,38 +529,26 @@
PAIRCASE (SpaceKind::Disjunct, SpaceKind::BooleanConstant):
PAIRCASE (SpaceKind::Disjunct, SpaceKind::UnknownCase): {
// (S1 || ... || Sn) & S iff (S & S1) && ... && (S & Sn)
- SmallVector<Space, 4> intersectedCases;
- std::transform(this->getSpaces().begin(), this->getSpaces().end(),
- std::back_inserter(intersectedCases),
- [&](const Space &s) {
- return s.intersect(other, TC, DC);
- });
- return Space::forDisjunct(intersectedCases);
+ return intersect(other, *this, TC, DC);
}
PAIRCASE (SpaceKind::Type, SpaceKind::Type): {
// Optimization: The intersection of equal types is that type.
if (this->getType()->isEqual(other.getType())) {
return other;
} else if (canDecompose(this->getType(), DC)) {
- SmallVector<Space, 4> spaces;
- decompose(TC, DC, this->getType(), spaces);
- auto decomposition = Space::forDisjunct(spaces);
- return decomposition.intersect(other, TC, DC);
+ auto decomposition = decompose(TC, DC, this->getType());
+ return intersect(decomposition, other, TC, DC);
} else if (canDecompose(other.getType(), DC)) {
- SmallVector<Space, 4> spaces;
- decompose(TC, DC, other.getType(), spaces);
- auto disjunctSp = Space::forDisjunct(spaces);
- return this->intersect(disjunctSp, TC, DC);
+ auto decomposition = decompose(TC, DC, other.getType());
+ return intersect(*this, decomposition, TC, DC);
} else {
return other;
}
}
PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
if (canDecompose(this->getType(), DC)) {
- SmallVector<Space, 4> spaces;
- decompose(TC, DC, this->getType(), spaces);
- auto decomposition = Space::forDisjunct(spaces);
- return decomposition.intersect(other, TC, DC);
+ auto decomposition = decompose(TC, DC, this->getType());
+ return intersect(decomposition, other, TC, DC);
} else {
return other;
}
@@ -582,10 +566,11 @@
PAIRCASE (SpaceKind::Constructor, SpaceKind::UnknownCase): {
SmallVector<Space, 4> newSubSpaces;
- for (auto subSpace : this->getSpaces()) {
- Space nextSpace = subSpace.intersect(other, TC, DC);
- newSubSpaces.push_back(nextSpace.simplify(TC, DC));
- }
+ std::transform(this->getSpaces().begin(), this->getSpaces().end(),
+ std::back_inserter(newSubSpaces),
+ [&](const Space &subSpace) {
+ return intersect(subSpace, other, TC, DC);
+ });
return Space::forConstructor(this->getType(), this->getHead(),
this->canDowngradeToWarning(),
newSubSpaces);
@@ -609,13 +594,13 @@
auto j = other.getSpaces().begin();
for (; i != this->getSpaces().end() && j != other.getSpaces().end();
++i, ++j) {
- auto intersection = (*i).intersect(*j, TC, DC).simplify(TC, DC);
+ auto result = intersect(*i, *j, TC, DC);
// If at least one of the constructor sub-spaces is empty,
// it makes the whole space empty as well.
- if (intersection.isEmpty()) {
+ if (result.isEmpty()) {
return Space();
}
- paramSpace.push_back(intersection);
+ paramSpace.push_back(result);
}
return Space::forDisjunct(paramSpace);
@@ -623,7 +608,7 @@
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Type):
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Constructor):
- return other.intersect(*this, TC, DC);
+ return intersect(other, *this, TC, DC);
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::UnknownCase):
if (other.isAllowedButNotRequired())
return other;
@@ -638,10 +623,8 @@
}
if (canDecompose(other.getType(), DC)) {
- SmallVector<Space, 4> spaces;
- decompose(TC, DC, other.getType(), spaces);
- auto disjunctSp = Space::forDisjunct(spaces);
- return this->intersect(disjunctSp, TC, DC);
+ auto decomposition = decompose(TC, DC, other.getType());
+ return intersect(*this, decomposition, TC, DC);
}
return Space();
}
@@ -651,14 +634,7 @@
return Space();
PAIRCASE (SpaceKind::Type, SpaceKind::BooleanConstant): {
- if (canDecompose(this->getType(), DC)) {
- SmallVector<Space, 4> spaces;
- decompose(TC, DC, this->getType(), spaces);
- auto disjunctSp = Space::forDisjunct(spaces);
- return disjunctSp.intersect(other, TC, DC);
- } else {
- return Space();
- }
+ return intersect(other, *this, TC, DC);
}
PAIRCASE (SpaceKind::Empty, SpaceKind::BooleanConstant):
@@ -701,23 +677,18 @@
if (this->getType()->isEqual(other.getType())) {
return Space();
} else if (canDecompose(this->getType(), DC)) {
- SmallVector<Space, 4> spaces;
- this->decompose(TC, DC, this->getType(), spaces);
- return Space::forDisjunct(spaces).intersect(other, TC, DC);
+ auto decomposition = decompose(TC, DC, this->getType());
+ return intersect(decomposition, other, TC, DC);
} else if (canDecompose(other.getType(), DC)) {
- SmallVector<Space, 4> spaces;
- this->decompose(TC, DC, other.getType(), spaces);
- auto decomp = Space::forDisjunct(spaces);
- return this->intersect(decomp, TC, DC);
+ auto decomposition = decompose(TC, DC, other.getType());
+ return intersect(*this, decomposition, TC, DC);
}
return Space();
}
PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
if (canDecompose(this->getType(), DC)) {
- SmallVector<Space, 4> spaces;
- this->decompose(TC, DC, this->getType(), spaces);
- auto decomp = Space::forDisjunct(spaces);
- return decomp.minus(other, TC, DC, minusCount);
+ auto decomposition = decompose(TC, DC, this->getType());
+ return decomposition.minus(other, TC, DC, minusCount);
} else {
return *this;
}
@@ -802,7 +773,7 @@
auto &s2 = *j;
// If the intersection of each subspace is ever empty then the
// two spaces are disjoint and their difference is the first space.
- if (s1.intersect(s2, TC, DC).simplify(TC, DC).isEmpty()) {
+ if (intersect(s1, s2, TC, DC).isEmpty()) {
return *this;
}
@@ -862,10 +833,8 @@
}
if (canDecompose(other.getType(), DC)) {
- SmallVector<Space, 4> spaces;
- this->decompose(TC, DC, other.getType(), spaces);
- auto disjunctSp = Space::forDisjunct(spaces);
- return this->minus(disjunctSp, TC, DC, minusCount);
+ auto decomposition = decompose(TC, DC, other.getType());
+ return this->minus(decomposition, TC, DC, minusCount);
}
return *this;
}
@@ -876,9 +845,7 @@
PAIRCASE (SpaceKind::Type, SpaceKind::BooleanConstant): {
if (canDecompose(this->getType(), DC)) {
- SmallVector<Space, 4> spaces;
- this->decompose(TC, DC, this->getType(), spaces);
- auto orSpace = Space::forDisjunct(spaces);
+ auto orSpace = decompose(TC, DC, this->getType());
return orSpace.minus(other, TC, DC, minusCount);
} else {
return *this;
@@ -1117,6 +1084,13 @@
}
}
+ static Space decompose(TypeChecker &TC, const DeclContext *DC,
+ Type type) {
+ SmallVector<Space, 4> spaces;
+ decompose(TC, DC, type, spaces);
+ return Space::forDisjunct(spaces);
+ }
+
static bool canDecompose(Type tp, const DeclContext *DC) {
return tp->is<TupleType>() || tp->isBool() ||
tp->getEnumOrBoundGenericEnum();
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index ba411d2..3b23afd 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -460,8 +460,8 @@
genericParams->size(), genericArgs.size(),
genericArgs.size() < genericParams->size())
.highlight(generic->getAngleBrackets());
- diagnose(decl, diag::generic_type_declared_here,
- decl->getName());
+ diagnose(decl, diag::kind_identifier_declared_here,
+ DescriptiveDeclKind::GenericType, decl->getName());
return ErrorType::get(Context);
}
@@ -495,7 +495,8 @@
if (!genericDecl->hasValidSignature()) {
diagnose(loc, diag::recursive_type_reference,
genericDecl->getDescriptiveKind(), genericDecl->getName());
- diagnose(genericDecl, diag::type_declared_here);
+ diagnose(genericDecl, diag::kind_declared_here,
+ DescriptiveDeclKind::Type);
return ErrorType::get(Context);
}
@@ -671,8 +672,8 @@
diag.fixItInsertAfter(loc, genericArgsToAdd);
}
}
- tc.diagnose(unbound->getDecl(), diag::generic_type_declared_here,
- unbound->getDecl()->getName());
+ tc.diagnose(unbound->getDecl(), diag::kind_identifier_declared_here,
+ DescriptiveDeclKind::GenericType, unbound->getDecl()->getName());
}
// Produce a diagnostic if the type we referenced was an
@@ -730,7 +731,8 @@
if (!typeDecl->hasInterfaceType()) {
TC.diagnose(loc, diag::recursive_type_reference,
typeDecl->getDescriptiveKind(), typeDecl->getName());
- TC.diagnose(typeDecl->getLoc(), diag::type_declared_here);
+ TC.diagnose(typeDecl->getLoc(), diag::kind_declared_here,
+ DescriptiveDeclKind::Type);
return ErrorType::get(TC.Context);
}
}
@@ -871,7 +873,8 @@
// FIXME: If any of the candidates (usually just one) are in the same
// module we could offer a fix-it.
for (auto lookupResult : inaccessibleResults)
- tc.diagnose(lookupResult.getValueDecl(), diag::type_declared_here);
+ tc.diagnose(lookupResult.getValueDecl(), diag::kind_declared_here,
+ DescriptiveDeclKind::Type);
// Don't try to recover here; we'll get more access-related diagnostics
// downstream if we do.
@@ -937,7 +940,8 @@
// FIXME: If any of the candidates (usually just one) are in the same module
// we could offer a fix-it.
for (auto lookupResult : inaccessibleMembers)
- tc.diagnose(lookupResult.first, diag::type_declared_here);
+ tc.diagnose(lookupResult.first, diag::kind_declared_here,
+ DescriptiveDeclKind::Type);
// Don't try to recover here; we'll get more access-related diagnostics
// downstream if we do.
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 51714c3..831de7e 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -3943,7 +3943,9 @@
unsigned abbrCode = DeclTypeAbbrCodes[UnboundGenericTypeLayout::Code];
UnboundGenericTypeLayout::emitRecord(Out, ScratchRecord, abbrCode,
- addDeclRef(generic->getDecl()),
+ addDeclRef(generic->getDecl(),
+ /*forceSerialization*/false,
+ /*allowTypeAliasXRef*/true),
addTypeRef(generic->getParent()));
break;
}
diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp
index 9a97e82..0e2aec9 100644
--- a/lib/TBDGen/TBDGen.cpp
+++ b/lib/TBDGen/TBDGen.cpp
@@ -92,28 +92,32 @@
auto conformanceIsFixed = SILWitnessTable::conformanceIsSerialized(
normalConformance);
- auto addSymbolIfNecessary = [&](SILDeclRef declRef) {
- auto witnessLinkage = declRef.getLinkage(ForDefinition);
+ auto addSymbolIfNecessary = [&](ValueDecl *requirementDecl,
+ ValueDecl *witnessDecl) {
+ auto witnessLinkage = SILDeclRef(witnessDecl).getLinkage(ForDefinition);
if (conformanceIsFixed &&
fixmeWitnessHasLinkageThatNeedsToBePublic(witnessLinkage)) {
Mangle::ASTMangler Mangler;
- addSymbol(Mangler.mangleWitnessThunk(normalConformance,
- declRef.getDecl()));
+ addSymbol(
+ Mangler.mangleWitnessThunk(normalConformance, requirementDecl));
}
};
- normalConformance->forEachValueWitness(nullptr, [&](ValueDecl *valueReq,
- Witness witness) {
- if (isa<AbstractFunctionDecl>(valueReq)) {
- addSymbolIfNecessary(SILDeclRef(valueReq));
- } else if (auto *storage = dyn_cast<AbstractStorageDecl>(valueReq)) {
- if (auto *getter = storage->getGetter())
- addSymbolIfNecessary(SILDeclRef(getter));
- if (auto *setter = storage->getGetter())
- addSymbolIfNecessary(SILDeclRef(setter));
- if (auto *materializeForSet = storage->getMaterializeForSetFunc())
- addSymbolIfNecessary(SILDeclRef(materializeForSet));
- }
- });
+ normalConformance->forEachValueWitness(
+ nullptr, [&](ValueDecl *valueReq, Witness witness) {
+ auto witnessDecl = witness.getDecl();
+ if (isa<AbstractFunctionDecl>(valueReq)) {
+ addSymbolIfNecessary(valueReq, witnessDecl);
+ } else if (auto *storage = dyn_cast<AbstractStorageDecl>(valueReq)) {
+ auto witnessStorage = cast<AbstractStorageDecl>(witnessDecl);
+ if (auto *getter = storage->getGetter())
+ addSymbolIfNecessary(getter, witnessStorage->getGetter());
+ if (auto *setter = storage->getSetter())
+ addSymbolIfNecessary(setter, witnessStorage->getSetter());
+ if (auto *materializeForSet = storage->getMaterializeForSetFunc())
+ addSymbolIfNecessary(materializeForSet,
+ witnessStorage->getMaterializeForSetFunc());
+ }
+ });
}
}
@@ -146,6 +150,22 @@
}
}
+void TBDGenVisitor::visitAccessorDecl(AccessorDecl *AD) {
+ // Do nothing: accessors are always nested within the storage decl, but
+ // sometimes appear outside it too. To avoid double-walking them, we
+ // explicitly visit them as members of the storage and ignore them when we
+ // visit them as part of the main walk, here.
+}
+
+void TBDGenVisitor::visitAbstractStorageDecl(AbstractStorageDecl *ASD) {
+ // Explicitly look at each accessor here: see visitAccessorDecl.
+ SmallVector<Decl *, 8> accessors;
+ ASD->getAllAccessorFunctions(accessors);
+ for (auto accessor : accessors) {
+ visitAbstractFunctionDecl(cast<AbstractFunctionDecl>(accessor));
+ }
+}
+
void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
// statically/globally stored variables have some special handling.
if (VD->hasStorage() && isGlobalOrStaticVar(VD)) {
@@ -158,6 +178,8 @@
if (!FileHasEntryPoint || VD->isStatic())
addSymbol(SILDeclRef(VD, SILDeclRef::Kind::GlobalAccessor));
}
+
+ visitAbstractStorageDecl(VD);
}
void TBDGenVisitor::visitNominalTypeDecl(NominalTypeDecl *NTD) {
@@ -332,18 +354,28 @@
}
}
+void TBDGenVisitor::addFirstFileSymbols() {
+ if (!Opts.ModuleLinkName.empty()) {
+ SmallString<32> buf;
+ addSymbol(irgen::encodeForceLoadSymbolName(buf, Opts.ModuleLinkName));
+ }
+}
+
static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
StringSet &symbols,
- bool hasMultipleIGMs,
llvm::raw_ostream *os,
- StringRef installName) {
+ TBDGenOptions &opts) {
auto isWholeModule = singleFile == nullptr;
const auto &target = M->getASTContext().LangOpts.Target;
- UniversalLinkageInfo linkInfo(target, hasMultipleIGMs, isWholeModule);
+ UniversalLinkageInfo linkInfo(target, opts.HasMultipleIGMs, isWholeModule);
- TBDGenVisitor visitor(symbols, target, linkInfo, M, installName);
+ TBDGenVisitor visitor(symbols, target, linkInfo, M, opts);
auto visitFile = [&](FileUnit *file) {
+ if (file == M->getFiles()[0]) {
+ visitor.addFirstFileSymbols();
+ }
+
SmallVector<Decl *, 16> decls;
file->getTopLevelDecls(decls);
@@ -376,18 +408,16 @@
}
void swift::enumeratePublicSymbols(FileUnit *file, StringSet &symbols,
- bool hasMultipleIGMs) {
+ TBDGenOptions &opts) {
enumeratePublicSymbolsAndWrite(file->getParentModule(), file, symbols,
- hasMultipleIGMs, nullptr, StringRef());
+ nullptr, opts);
}
void swift::enumeratePublicSymbols(ModuleDecl *M, StringSet &symbols,
- bool hasMultipleIGMs) {
- enumeratePublicSymbolsAndWrite(M, nullptr, symbols, hasMultipleIGMs, nullptr,
- StringRef());
+ TBDGenOptions &opts) {
+ enumeratePublicSymbolsAndWrite(M, nullptr, symbols, nullptr, opts);
}
void swift::writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os,
- bool hasMultipleIGMs, StringRef installName) {
+ TBDGenOptions &opts) {
StringSet symbols;
- enumeratePublicSymbolsAndWrite(M, nullptr, symbols, hasMultipleIGMs, &os,
- installName);
+ enumeratePublicSymbolsAndWrite(M, nullptr, symbols, &os, opts);
}
diff --git a/lib/TBDGen/TBDGenVisitor.h b/lib/TBDGen/TBDGenVisitor.h
index 5cbc0d7..741e9c4 100644
--- a/lib/TBDGen/TBDGenVisitor.h
+++ b/lib/TBDGen/TBDGenVisitor.h
@@ -33,6 +33,9 @@
using StringSet = llvm::StringSet<>;
namespace swift {
+
+struct TBDGenOptions;
+
namespace tbdgen {
class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
@@ -41,7 +44,7 @@
const llvm::Triple &Triple;
const UniversalLinkageInfo &UniversalLinkInfo;
ModuleDecl *SwiftModule;
- StringRef InstallName;
+ TBDGenOptions &Opts;
private:
bool FileHasEntryPoint = false;
@@ -73,9 +76,9 @@
public:
TBDGenVisitor(StringSet &symbols, const llvm::Triple &triple,
const UniversalLinkageInfo &universalLinkInfo,
- ModuleDecl *swiftModule, StringRef installName)
+ ModuleDecl *swiftModule, TBDGenOptions &opts)
: Symbols(symbols), Triple(triple), UniversalLinkInfo(universalLinkInfo),
- SwiftModule(swiftModule), InstallName(installName) {}
+ SwiftModule(swiftModule), Opts(opts) {}
void setFileHasEntryPoint(bool hasEntryPoint) {
FileHasEntryPoint = hasEntryPoint;
@@ -84,10 +87,15 @@
addSymbol("main");
}
+ /// \brief Adds the global symbols associated with the first file.
+ void addFirstFileSymbols();
+
void visitPatternBindingDecl(PatternBindingDecl *PBD);
void visitAbstractFunctionDecl(AbstractFunctionDecl *AFD);
+ void visitAccessorDecl(AccessorDecl *AD);
+
void visitNominalTypeDecl(NominalTypeDecl *NTD);
void visitClassDecl(ClassDecl *CD);
@@ -98,6 +106,8 @@
void visitProtocolDecl(ProtocolDecl *PD);
+ void visitAbstractStorageDecl(AbstractStorageDecl *ASD);
+
void visitVarDecl(VarDecl *VD);
void visitEnumDecl(EnumDecl *ED);
diff --git a/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift b/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
index 2a717b1..ecb24b6 100644
--- a/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
+++ b/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
@@ -107,12 +107,12 @@
///
/// An image of interest must have the following sections in the __DATA
/// segment:
-/// - __swift4_fieldmd
-/// - __swift4_assocty
-/// - __swift4_builtin
-/// - __swift4_capture
-/// - __swift4_typeref
-/// - __swift4_reflstr (optional, may have been stripped out)
+/// - __swift5_fieldmd
+/// - __swift5_assocty
+/// - __swift5_builtin
+/// - __swift5_capture
+/// - __swift5_typeref
+/// - __swift5_reflstr (optional, may have been stripped out)
///
/// - Parameter i: The index of the loaded image as reported by Dyld.
/// - Returns: A `ReflectionInfo` containing the locations of all of the
@@ -123,12 +123,12 @@
to: UnsafePointer<MachHeader>.self)
let imageName = _dyld_get_image_name(i)!
- let fieldmd = getSectionInfo("__swift4_fieldmd", header)
- let assocty = getSectionInfo("__swift4_assocty", header)
- let builtin = getSectionInfo("__swift4_builtin", header)
- let capture = getSectionInfo("__swift4_capture", header)
- let typeref = getSectionInfo("__swift4_typeref", header)
- let reflstr = getSectionInfo("__swift4_reflstr", header)
+ let fieldmd = getSectionInfo("__swift5_fieldmd", header)
+ let assocty = getSectionInfo("__swift5_assocty", header)
+ let builtin = getSectionInfo("__swift5_builtin", header)
+ let capture = getSectionInfo("__swift5_capture", header)
+ let typeref = getSectionInfo("__swift5_typeref", header)
+ let reflstr = getSectionInfo("__swift5_reflstr", header)
return ReflectionInfo(imageName: String(validatingUTF8: imageName)!,
fieldmd: fieldmd,
assocty: assocty,
diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp
index fc98c18..9863468 100644
--- a/stdlib/public/runtime/Casting.cpp
+++ b/stdlib/public/runtime/Casting.cpp
@@ -1866,7 +1866,7 @@
// .Some
// Single payload enums are guaranteed layout compatible with their
// payload. Only the source's payload needs to be taken or destroyed.
- return {false, payloadType};
+ return checkDynamicCastFromOptional(dest, src, payloadType, targetType, flags);
}
/******************************************************************************/
diff --git a/stdlib/public/runtime/Enum.cpp b/stdlib/public/runtime/Enum.cpp
index b30a404..bcdf669 100644
--- a/stdlib/public/runtime/Enum.cpp
+++ b/stdlib/public/runtime/Enum.cpp
@@ -89,12 +89,14 @@
auto vwtable = getMutableVWTableForInit(self, layoutFlags);
size_t align = payloadLayout->flags.getAlignment();
+ bool isBT = payloadLayout->flags.isBitwiseTakable();
TypeLayout layout;
layout.size = size;
- layout.flags = payloadLayout->flags
- .withExtraInhabitants(unusedExtraInhabitants > 0)
- .withEnumWitnesses(true)
- .withInlineStorage(ValueWitnessTable::isValueInline(size, align));
+ layout.flags =
+ payloadLayout->flags.withExtraInhabitants(unusedExtraInhabitants > 0)
+ .withEnumWitnesses(true)
+ .withInlineStorage(
+ ValueWitnessTable::isValueInline(isBT, size, align));
auto rawStride = llvm::alignTo(size, align);
layout.stride = rawStride == 0 ? 1 : rawStride;
@@ -200,14 +202,14 @@
TypeLayout layout;
layout.size = totalSize;
layout.flags = ValueWitnessFlags()
- .withAlignmentMask(alignMask)
- .withPOD(isPOD)
- .withBitwiseTakable(isBT)
- // TODO: Extra inhabitants
- .withExtraInhabitants(false)
- .withEnumWitnesses(true)
- .withInlineStorage(ValueWitnessTable::isValueInline(totalSize, alignMask+1))
- ;
+ .withAlignmentMask(alignMask)
+ .withPOD(isPOD)
+ .withBitwiseTakable(isBT)
+ // TODO: Extra inhabitants
+ .withExtraInhabitants(false)
+ .withEnumWitnesses(true)
+ .withInlineStorage(ValueWitnessTable::isValueInline(
+ isBT, totalSize, alignMask + 1));
auto rawStride = (totalSize + alignMask) & ~alignMask;
layout.stride = rawStride == 0 ? 1 : rawStride;
diff --git a/stdlib/public/runtime/ExistentialMetadataImpl.h b/stdlib/public/runtime/ExistentialMetadataImpl.h
index 3d849e3..3183b8a 100644
--- a/stdlib/public/runtime/ExistentialMetadataImpl.h
+++ b/stdlib/public/runtime/ExistentialMetadataImpl.h
@@ -107,20 +107,9 @@
static Container *initializeWithTake(Container *dest, Container *src,
A... args) {
src->copyTypeInto(dest, args...);
- auto *type = src->getType();
- auto *vwt = type->getValueWitnesses();
-
- if (vwt->isValueInline()) {
- auto *destValue =
- reinterpret_cast<OpaqueValue *>(dest->getBuffer(args...));
- auto *srcValue =
- reinterpret_cast<OpaqueValue *>(src->getBuffer(args...));
-
- type->vw_initializeWithTake(destValue, srcValue);
- } else {
- // initWithTake of the reference to the cow box.
- copyReference(dest, src, Dest::Init, Source::Take, args...);
- }
+ auto from = src->getBuffer(args...);
+ auto to = dest->getBuffer(args...);
+ memcpy(to, from, sizeof(ValueBuffer));
return dest;
}
@@ -338,7 +327,7 @@
static constexpr size_t alignment = alignof(Container);
static constexpr size_t stride = sizeof(Container);
static constexpr size_t isPOD = false;
- static constexpr bool isBitwiseTakable = false;
+ static constexpr bool isBitwiseTakable = true;
static constexpr unsigned numExtraInhabitants = 0;
};
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.cpp b/stdlib/public/runtime/ImageInspectionCOFF.cpp
index 915f827..29fec32 100644
--- a/stdlib/public/runtime/ImageInspectionCOFF.cpp
+++ b/stdlib/public/runtime/ImageInspectionCOFF.cpp
@@ -41,7 +41,7 @@
const swift::MetadataSections *sections = registered;
while (true) {
const swift::MetadataSections::Range &protocols =
- sections->swift4_protocols;
+ sections->swift5_protocols;
if (protocols.length)
addImageProtocolsBlockCallback(reinterpret_cast<void *>(protocols.start),
protocols.length);
@@ -56,7 +56,7 @@
const swift::MetadataSections *sections = registered;
while (true) {
const swift::MetadataSections::Range &conformances =
- sections->swift4_protocol_conformances;
+ sections->swift5_protocol_conformances;
if (conformances.length)
addImageProtocolConformanceBlockCallback(reinterpret_cast<void *>(conformances.start),
conformances.length);
@@ -71,7 +71,7 @@
const swift::MetadataSections *sections = registered;
while (true) {
const swift::MetadataSections::Range &type_metadata =
- sections->swift4_type_metadata;
+ sections->swift5_type_metadata;
if (type_metadata.length)
addImageTypeMetadataRecordBlockCallback(reinterpret_cast<void *>(type_metadata.start),
type_metadata.length);
@@ -85,7 +85,7 @@
void swift::initializeTypeFieldLookup() {
const swift::MetadataSections *sections = registered;
while (true) {
- const swift::MetadataSections::Range &fields = sections->swift4_fieldmd;
+ const swift::MetadataSections::Range &fields = sections->swift5_fieldmd;
if (fields.length)
addImageTypeFieldDescriptorBlockCallback(
reinterpret_cast<void *>(fields.start), fields.length);
@@ -103,20 +103,20 @@
record(sections);
- const auto &protocols_section = sections->swift4_protocols;
+ const auto &protocols_section = sections->swift5_protocols;
const void *protocols =
reinterpret_cast<void *>(protocols_section.start);
if (protocols_section.length)
addImageProtocolsBlockCallback(protocols, protocols_section.length);
- const auto &protocol_conformances = sections->swift4_protocol_conformances;
+ const auto &protocol_conformances = sections->swift5_protocol_conformances;
const void *conformances =
reinterpret_cast<void *>(protocol_conformances.start);
if (protocol_conformances.length)
addImageProtocolConformanceBlockCallback(conformances,
protocol_conformances.length);
- const auto &type_metadata = sections->swift4_type_metadata;
+ const auto &type_metadata = sections->swift5_type_metadata;
const void *metadata = reinterpret_cast<void *>(type_metadata.start);
if (type_metadata.length)
addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.h b/stdlib/public/runtime/ImageInspectionCOFF.h
index 2ce5fa6..75e0266 100644
--- a/stdlib/public/runtime/ImageInspectionCOFF.h
+++ b/stdlib/public/runtime/ImageInspectionCOFF.h
@@ -45,13 +45,13 @@
size_t length;
};
- Range swift4_protocols;
- Range swift4_protocol_conformances;
- Range swift4_type_metadata;
- Range swift4_typeref;
- Range swift4_reflstr;
- Range swift4_fieldmd;
- Range swift4_assocty;
+ Range swift5_protocols;
+ Range swift5_protocol_conformances;
+ Range swift5_type_metadata;
+ Range swift5_typeref;
+ Range swift5_reflstr;
+ Range swift5_fieldmd;
+ Range swift5_assocty;
};
} // namespace swift
diff --git a/stdlib/public/runtime/ImageInspectionELF.cpp b/stdlib/public/runtime/ImageInspectionELF.cpp
index 00340c5..3dfe95f 100644
--- a/stdlib/public/runtime/ImageInspectionELF.cpp
+++ b/stdlib/public/runtime/ImageInspectionELF.cpp
@@ -46,7 +46,7 @@
const swift::MetadataSections *sections = registered;
while (true) {
const swift::MetadataSections::Range &protocols =
- sections->swift4_protocols;
+ sections->swift5_protocols;
if (protocols.length)
addImageProtocolsBlockCallback(reinterpret_cast<void *>(protocols.start),
protocols.length);
@@ -60,7 +60,7 @@
const swift::MetadataSections *sections = registered;
while (true) {
const swift::MetadataSections::Range &conformances =
- sections->swift4_protocol_conformances;
+ sections->swift5_protocol_conformances;
if (conformances.length)
addImageProtocolConformanceBlockCallback(reinterpret_cast<void *>(conformances.start),
conformances.length);
@@ -75,7 +75,7 @@
const swift::MetadataSections *sections = registered;
while (true) {
const swift::MetadataSections::Range &type_metadata =
- sections->swift4_type_metadata;
+ sections->swift5_type_metadata;
if (type_metadata.length)
addImageTypeMetadataRecordBlockCallback(reinterpret_cast<void *>(type_metadata.start),
type_metadata.length);
@@ -89,7 +89,7 @@
void swift::initializeTypeFieldLookup() {
const swift::MetadataSections *sections = registered;
while (true) {
- const swift::MetadataSections::Range &fields = sections->swift4_fieldmd;
+ const swift::MetadataSections::Range &fields = sections->swift5_fieldmd;
if (fields.length)
addImageTypeFieldDescriptorBlockCallback(
reinterpret_cast<void *>(fields.start), fields.length);
@@ -111,20 +111,20 @@
record(sections);
- const auto &protocols_section = sections->swift4_protocols;
+ const auto &protocols_section = sections->swift5_protocols;
const void *protocols =
reinterpret_cast<void *>(protocols_section.start);
if (protocols_section.length)
addImageProtocolsBlockCallback(protocols, protocols_section.length);
- const auto &protocol_conformances = sections->swift4_protocol_conformances;
+ const auto &protocol_conformances = sections->swift5_protocol_conformances;
const void *conformances =
reinterpret_cast<void *>(protocol_conformances.start);
if (protocol_conformances.length)
addImageProtocolConformanceBlockCallback(conformances,
protocol_conformances.length);
- const auto &type_metadata = sections->swift4_type_metadata;
+ const auto &type_metadata = sections->swift5_type_metadata;
const void *metadata = reinterpret_cast<void *>(type_metadata.start);
if (type_metadata.length)
addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
diff --git a/stdlib/public/runtime/ImageInspectionELF.h b/stdlib/public/runtime/ImageInspectionELF.h
index b88be22..9505360 100644
--- a/stdlib/public/runtime/ImageInspectionELF.h
+++ b/stdlib/public/runtime/ImageInspectionELF.h
@@ -45,13 +45,13 @@
size_t length;
};
- Range swift4_protocols;
- Range swift4_protocol_conformances;
- Range swift4_type_metadata;
- Range swift4_typeref;
- Range swift4_reflstr;
- Range swift4_fieldmd;
- Range swift4_assocty;
+ Range swift5_protocols;
+ Range swift5_protocol_conformances;
+ Range swift5_type_metadata;
+ Range swift5_typeref;
+ Range swift5_reflstr;
+ Range swift5_fieldmd;
+ Range swift5_assocty;
};
} // namespace swift
diff --git a/stdlib/public/runtime/ImageInspectionMachO.cpp b/stdlib/public/runtime/ImageInspectionMachO.cpp
index 2972a8d..f8c86d2 100644
--- a/stdlib/public/runtime/ImageInspectionMachO.cpp
+++ b/stdlib/public/runtime/ImageInspectionMachO.cpp
@@ -31,16 +31,16 @@
namespace {
/// The Mach-O section name for the section containing protocol descriptor
/// references. This lives within SEG_TEXT.
-constexpr const char ProtocolsSection[] = "__swift4_protos";
+constexpr const char ProtocolsSection[] = "__swift5_protos";
/// The Mach-O section name for the section containing protocol conformances.
/// This lives within SEG_TEXT.
-constexpr const char ProtocolConformancesSection[] = "__swift4_proto";
+constexpr const char ProtocolConformancesSection[] = "__swift5_proto";
/// The Mach-O section name for the section containing type references.
/// This lives within SEG_TEXT.
-constexpr const char TypeMetadataRecordSection[] = "__swift4_types";
+constexpr const char TypeMetadataRecordSection[] = "__swift5_types";
/// The Mach-O section name for the section containing type field references.
/// This lives within SEG_TEXT.
-constexpr const char TypeFieldRecordSection[] = "__swift4_fieldmd";
+constexpr const char TypeFieldRecordSection[] = "__swift5_fieldmd";
#if __POINTER_WIDTH__ == 64
using mach_header_platform = mach_header_64;
@@ -57,7 +57,7 @@
assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!");
#endif
- // Look for a __swift4_proto section.
+ // Look for a __swift5_proto section.
unsigned long size;
const uint8_t *section =
getsectiondata(reinterpret_cast<const mach_header_platform *>(mh),
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 2a7a72f..83c0622 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -1057,23 +1057,6 @@
return tuple_projectBuffer<IsPOD, IsInline>(dest, metatype);
}
-/// Generic tuple value witness for 'initializeBufferWithTakeOfBuffer'.
-template <bool IsPOD, bool IsInline>
-static OpaqueValue *tuple_initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
- ValueBuffer *src,
- const Metadata *metatype) {
- assert(IsPOD == tuple_getValueWitnesses(metatype)->isPOD());
- assert(IsInline == tuple_getValueWitnesses(metatype)->isValueInline());
- if (IsInline) {
- return tuple_initializeWithTake<IsPOD, IsInline>(
- tuple_projectBuffer<IsPOD, IsInline>(dest, metatype),
- tuple_projectBuffer<IsPOD, IsInline>(src, metatype), metatype);
- }
- auto *srcReference = *reinterpret_cast<HeapObject**>(src);
- *reinterpret_cast<HeapObject**>(dest) = srcReference;
- return tuple_projectBuffer<IsPOD, IsInline>(dest, metatype);
-}
-
template <bool IsPOD, bool IsInline>
static unsigned tuple_getEnumTagSinglePayload(const OpaqueValue *enumAddr,
unsigned numEmptyCases,
@@ -1215,13 +1198,15 @@
if (!eltLayout->flags.isPOD()) isPOD = false;
if (!eltLayout->flags.isBitwiseTakable()) isBitwiseTakable = false;
}
- bool isInline = ValueWitnessTable::isValueInline(size, alignMask + 1);
+ bool isInline =
+ ValueWitnessTable::isValueInline(isBitwiseTakable, size, alignMask + 1);
layout.size = size;
- layout.flags = ValueWitnessFlags().withAlignmentMask(alignMask)
- .withPOD(isPOD)
- .withBitwiseTakable(isBitwiseTakable)
- .withInlineStorage(isInline);
+ layout.flags = ValueWitnessFlags()
+ .withAlignmentMask(alignMask)
+ .withPOD(isPOD)
+ .withBitwiseTakable(isBitwiseTakable)
+ .withInlineStorage(isInline);
layout.stride = std::max(size_t(1), roundUpToAlignMask(size, alignMask));
}
@@ -1558,20 +1543,6 @@
return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
}
-static OpaqueValue *pod_indirect_initializeBufferWithTakeOfBuffer(
- ValueBuffer *dest, ValueBuffer *src, const Metadata *self) {
- auto wtable = self->getValueWitnesses();
- auto *srcReference = *reinterpret_cast<HeapObject**>(src);
- *reinterpret_cast<HeapObject**>(dest) = srcReference;
-
- // Project the address of the value in the buffer.
- unsigned alignMask = wtable->getAlignmentMask();
- // Compute the byte offset of the object in the box.
- unsigned byteOffset = (sizeof(HeapObject) + alignMask) & ~alignMask;
- auto *bytePtr = reinterpret_cast<char *>(srcReference);
- return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
-}
-
static void pod_noop(void *object, const Metadata *self) {
}
#define pod_direct_destroy \
@@ -1588,9 +1559,6 @@
#define pod_direct_initializeBufferWithCopyOfBuffer \
pointer_function_cast<value_witness_types::initializeBufferWithCopyOfBuffer> \
(pod_direct_initializeWithCopy)
-#define pod_direct_initializeBufferWithTakeOfBuffer \
- pointer_function_cast<value_witness_types::initializeBufferWithTakeOfBuffer> \
- (pod_direct_initializeWithCopy)
#define pod_direct_assignWithCopy pod_direct_initializeWithCopy
#define pod_indirect_assignWithCopy pod_direct_initializeWithCopy
#define pod_direct_initializeWithTake pod_direct_initializeWithCopy
@@ -1703,23 +1671,12 @@
// Use POD value witnesses for operations that do an initializeWithTake.
if (flags.isInlineStorage()) {
vwtable->initializeWithTake = pod_direct_initializeWithTake;
- vwtable->initializeBufferWithTakeOfBuffer
- = pod_direct_initializeBufferWithTakeOfBuffer;
} else {
vwtable->initializeWithTake = pod_indirect_initializeWithTake;
- vwtable->initializeBufferWithTakeOfBuffer
- = pod_indirect_initializeBufferWithTakeOfBuffer;
}
return;
}
- if (!flags.isInlineStorage()) {
- // For values stored out-of-line, initializeBufferWithTakeOfBuffer is
- // always a memcpy.
- vwtable->initializeBufferWithTakeOfBuffer
- = pod_indirect_initializeBufferWithTakeOfBuffer;
- return;
- }
}
/***************************************************************************/
@@ -2569,7 +2526,7 @@
Data.flags = ValueWitnessFlags()
.withAlignment(Box::Container::getAlignment(numWitnessTables))
.withPOD(false)
- .withBitwiseTakable(false)
+ .withBitwiseTakable(true)
.withInlineStorage(false)
.withExtraInhabitants(false);
Data.stride = Box::Container::getStride(numWitnessTables);
diff --git a/stdlib/public/runtime/MetadataImpl.h b/stdlib/public/runtime/MetadataImpl.h
index bcd562f..a52a8f4 100644
--- a/stdlib/public/runtime/MetadataImpl.h
+++ b/stdlib/public/runtime/MetadataImpl.h
@@ -620,31 +620,28 @@
Allocate,
OffsetZero
};
-constexpr FixedPacking getFixedPacking(size_t size, size_t alignment) {
- return (canBeInline(size, alignment) ? FixedPacking::OffsetZero
- : FixedPacking::Allocate);
+constexpr FixedPacking getFixedPacking(bool isBitwiseTakable, size_t size,
+ size_t alignment) {
+ return (canBeInline(isBitwiseTakable, size, alignment)
+ ? FixedPacking::OffsetZero
+ : FixedPacking::Allocate);
}
/// A CRTP base class which provides default implementations of a
/// number of value witnesses.
-template <class Impl, size_t Size, size_t Alignment,
- FixedPacking Packing = getFixedPacking(Size, Alignment)>
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment,
+ FixedPacking Packing =
+ getFixedPacking(isBitwiseTakable, Size, Alignment)>
struct BufferValueWitnesses;
/// An implementation of ValueBase suitable for classes that can be
/// allocated inline.
-template <class Impl, size_t Size, size_t Alignment>
-struct BufferValueWitnesses<Impl, Size, Alignment, FixedPacking::OffsetZero>
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment>
+struct BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
+ FixedPacking::OffsetZero>
: BufferValueWitnessesBase<Impl> {
static constexpr bool isInline = true;
- static OpaqueValue *initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
- ValueBuffer *src,
- const Metadata *self) {
- return Impl::initializeWithTake(reinterpret_cast<OpaqueValue*>(dest),
- reinterpret_cast<OpaqueValue*>(src),
- self);
- }
static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
ValueBuffer *src,
const Metadata *self) {
@@ -655,26 +652,12 @@
/// An implementation of BufferValueWitnesses suitable for types that
/// cannot be allocated inline.
-template <class Impl, size_t Size, size_t Alignment>
-struct BufferValueWitnesses<Impl, Size, Alignment, FixedPacking::Allocate>
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment>
+struct BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
+ FixedPacking::Allocate>
: BufferValueWitnessesBase<Impl> {
static constexpr bool isInline = false;
- static OpaqueValue *initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
- ValueBuffer *src,
- const Metadata *self) {
- auto wtable = self->getValueWitnesses();
- auto *srcReference = *reinterpret_cast<HeapObject **>(src);
- *reinterpret_cast<HeapObject **>(dest) = srcReference;
-
- // Project the address of the value in the buffer.
- unsigned alignMask = wtable->getAlignmentMask();
- // Compute the byte offset of the object in the box.
- unsigned byteOffset = (sizeof(HeapObject) + alignMask) & ~alignMask;
- auto *bytePtr = reinterpret_cast<char *>(srcReference);
- return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
- }
-
static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
ValueBuffer *src,
const Metadata *self) {
@@ -695,26 +678,6 @@
/// fixed in size.
template <class Impl, bool IsKnownAllocated>
struct NonFixedBufferValueWitnesses : BufferValueWitnessesBase<Impl> {
- static OpaqueValue *initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
- ValueBuffer *src,
- const Metadata *self) {
- auto vwtable = self->getValueWitnesses();
- (void)vwtable;
- if (!IsKnownAllocated && vwtable->isValueInline()) {
- return Impl::initializeWithTake(reinterpret_cast<OpaqueValue *>(dest),
- reinterpret_cast<OpaqueValue *>(src),
- self);
- } else {
- auto reference = src->PrivateData[0];
- dest->PrivateData[0] = reference;
- // Project the address of the value in the buffer.
- unsigned alignMask = vwtable->getAlignmentMask();
- // Compute the byte offset of the object in the box.
- unsigned byteOffset = (sizeof(HeapObject) + alignMask) & ~alignMask;
- auto *bytePtr = reinterpret_cast<char *>(reference);
- return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
- }
- }
static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
ValueBuffer *src,
@@ -741,15 +704,16 @@
/// Provides implementations for
/// getEnumTagSinglePayload/storeEnumTagSinglePayload.
-template<class Impl, size_t Size, size_t Alignment, bool hasExtraInhabitants>
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment,
+ bool hasExtraInhabitants>
struct FixedSizeBufferValueWitnesses;
/// A fixed size buffer value witness that can rely on the presents of the extra
/// inhabitant functions.
-template <class Impl, size_t Size, size_t Alignment>
-struct FixedSizeBufferValueWitnesses<Impl, Size, Alignment,
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment>
+struct FixedSizeBufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
true /*hasExtraInhabitants*/>
- : BufferValueWitnesses<Impl, Size, Alignment> {
+ : BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment> {
static unsigned getEnumTagSinglePayload(const OpaqueValue *enumAddr,
unsigned numEmptyCases,
@@ -771,10 +735,10 @@
/// A fixed size buffer value witness that cannot rely on the presents of the
/// extra inhabitant functions.
-template <class Impl, size_t Size, size_t Alignment>
-struct FixedSizeBufferValueWitnesses<Impl, Size, Alignment,
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment>
+struct FixedSizeBufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
false /*hasExtraInhabitants*/>
- : BufferValueWitnesses<Impl, Size, Alignment> {
+ : BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment> {
static unsigned getEnumTagSinglePayload(const OpaqueValue *enumAddr,
unsigned numEmptyCases,
@@ -801,11 +765,12 @@
/// The box type has to provide a numExtraInhabitants member, but as
/// long as it's zero, the rest is fine.
template <class Box>
-struct ValueWitnesses : FixedSizeBufferValueWitnesses<
- ValueWitnesses<Box>, Box::size, Box::alignment,
- hasExtraInhabitants(Box::numExtraInhabitants)> {
+struct ValueWitnesses
+ : FixedSizeBufferValueWitnesses<
+ ValueWitnesses<Box>, Box::isBitwiseTakable, Box::size, Box::alignment,
+ hasExtraInhabitants(Box::numExtraInhabitants)> {
using Base = FixedSizeBufferValueWitnesses<
- ValueWitnesses<Box>, Box::size, Box::alignment,
+ ValueWitnesses<Box>, Box::isBitwiseTakable, Box::size, Box::alignment,
hasExtraInhabitants(Box::numExtraInhabitants)>;
static constexpr size_t size = Box::size;
@@ -817,7 +782,7 @@
static constexpr bool hasExtraInhabitants = (numExtraInhabitants != 0);
static constexpr ValueWitnessFlags flags =
ValueWitnessFlags().withAlignmentMask(alignment - 1)
- .withInlineStorage(Base::isInline)
+ .withInlineStorage(Base::isInline && isBitwiseTakable)
.withPOD(isPOD)
.withBitwiseTakable(isBitwiseTakable)
.withExtraInhabitants(hasExtraInhabitants);
diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp
index 7efbc04..07ce6c8 100644
--- a/stdlib/public/runtime/MetadataLookup.cpp
+++ b/stdlib/public/runtime/MetadataLookup.cpp
@@ -23,7 +23,6 @@
#include "swift/Runtime/Concurrent.h"
#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Metadata.h"
-#include "swift/Runtime/Mutex.h"
#include "swift/Strings.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
@@ -106,11 +105,9 @@
struct TypeMetadataPrivateState {
ConcurrentMap<NominalTypeDescriptorCacheEntry> NominalCache;
- std::vector<TypeMetadataSection> SectionsToScan;
- Mutex SectionsToScanLock;
+ ConcurrentReadableArray<TypeMetadataSection> SectionsToScan;
TypeMetadataPrivateState() {
- SectionsToScan.reserve(16);
initializeTypeMetadataRecordLookup();
}
@@ -122,7 +119,6 @@
_registerTypeMetadataRecords(TypeMetadataPrivateState &T,
const TypeMetadataRecord *begin,
const TypeMetadataRecord *end) {
- ScopedLock guard(T.SectionsToScanLock);
T.SectionsToScan.push_back(TypeMetadataSection{begin, end});
}
@@ -296,12 +292,9 @@
// returns the nominal type descriptor for the type named by typeName
static const TypeContextDescriptor *
-_searchTypeMetadataRecords(const TypeMetadataPrivateState &T,
+_searchTypeMetadataRecords(TypeMetadataPrivateState &T,
Demangle::NodePointer node) {
- unsigned sectionIdx = 0;
- unsigned endSectionIdx = T.SectionsToScan.size();
- for (; sectionIdx < endSectionIdx; ++sectionIdx) {
- auto §ion = T.SectionsToScan[sectionIdx];
+ for (auto §ion : T.SectionsToScan.snapshot()) {
for (const auto &record : section) {
if (auto ntd = record.getTypeContextDescriptor()) {
if (_contextDescriptorMatchesMangling(ntd, node)) {
@@ -342,9 +335,7 @@
return Value->getDescription();
// Check type metadata records
- T.SectionsToScanLock.withLock([&] {
- foundNominal = _searchTypeMetadataRecords(T, node);
- });
+ foundNominal = _searchTypeMetadataRecords(T, node);
// Check protocol conformances table. Note that this has no support for
// resolving generic types yet.
@@ -395,11 +386,9 @@
struct ProtocolMetadataPrivateState {
ConcurrentMap<ProtocolDescriptorCacheEntry> ProtocolCache;
- std::vector<ProtocolSection> SectionsToScan;
- Mutex SectionsToScanLock;
+ ConcurrentReadableArray<ProtocolSection> SectionsToScan;
ProtocolMetadataPrivateState() {
- SectionsToScan.reserve(16);
initializeProtocolLookup();
}
};
@@ -411,7 +400,6 @@
_registerProtocols(ProtocolMetadataPrivateState &C,
const ProtocolRecord *begin,
const ProtocolRecord *end) {
- ScopedLock guard(C.SectionsToScanLock);
C.SectionsToScan.push_back(ProtocolSection{begin, end});
}
@@ -439,12 +427,9 @@
}
static const ProtocolDescriptor *
-_searchProtocolRecords(const ProtocolMetadataPrivateState &C,
+_searchProtocolRecords(ProtocolMetadataPrivateState &C,
const llvm::StringRef protocolName){
- unsigned sectionIdx = 0;
- unsigned endSectionIdx = C.SectionsToScan.size();
- for (; sectionIdx < endSectionIdx; ++sectionIdx) {
- auto §ion = C.SectionsToScan[sectionIdx];
+ for (auto §ion : C.SectionsToScan.snapshot()) {
for (const auto &record : section) {
if (auto protocol = record.Protocol.getPointer()) {
// Drop the "S$" prefix from the protocol record. It's not used in
@@ -472,9 +457,7 @@
return Value->getDescription();
// Check type metadata records
- T.SectionsToScanLock.withLock([&] {
- foundProtocol = _searchProtocolRecords(T, mangledName);
- });
+ foundProtocol = _searchProtocolRecords(T, mangledName);
if (foundProtocol) {
T.ProtocolCache.getOrInsert(mangledName, foundProtocol);
@@ -534,7 +517,7 @@
DynamicFieldSection(const FieldDescriptor **fields, size_t size)
: Begin(fields), End(fields + size) {}
- const FieldDescriptor **begin() { return Begin; }
+ const FieldDescriptor **begin() const { return Begin; }
const FieldDescriptor **end() const { return End; }
};
@@ -542,13 +525,10 @@
struct FieldCacheState {
ConcurrentMap<FieldDescriptorCacheEntry> FieldCache;
- Mutex SectionsLock;
- std::vector<StaticFieldSection> StaticSections;
- std::vector<DynamicFieldSection> DynamicSections;
+ ConcurrentReadableArray<StaticFieldSection> StaticSections;
+ ConcurrentReadableArray<DynamicFieldSection> DynamicSections;
FieldCacheState() {
- StaticSections.reserve(16);
- DynamicSections.reserve(8);
initializeTypeFieldLookup();
}
};
@@ -559,7 +539,6 @@
void swift::swift_registerFieldDescriptors(const FieldDescriptor **records,
size_t size) {
auto &cache = FieldCache.get();
- ScopedLock guard(cache.SectionsLock);
cache.DynamicSections.push_back({records, size});
}
@@ -570,7 +549,6 @@
// Field cache should always be sufficiently initialized by this point.
auto &cache = FieldCache.unsafeGetAlreadyInitialized();
- ScopedLock guard(cache.SectionsLock);
cache.StaticSections.push_back({recordsBegin, recordsEnd});
}
@@ -1216,16 +1194,15 @@
return;
}
- ScopedLock guard(cache.SectionsLock);
// Otherwise let's try to find it in one of the sections.
- for (auto §ion : cache.DynamicSections) {
+ for (auto §ion : cache.DynamicSections.snapshot()) {
for (const auto *descriptor : section) {
if (isRequestedDescriptor(*descriptor))
return;
}
}
- for (const auto §ion : cache.StaticSections) {
+ for (const auto §ion : cache.StaticSections.snapshot()) {
for (auto &descriptor : section) {
if (isRequestedDescriptor(descriptor))
return;
diff --git a/stdlib/public/runtime/ProtocolConformance.cpp b/stdlib/public/runtime/ProtocolConformance.cpp
index 703e334..0877082 100644
--- a/stdlib/public/runtime/ProtocolConformance.cpp
+++ b/stdlib/public/runtime/ProtocolConformance.cpp
@@ -326,14 +326,11 @@
// Iterate over all of the sections and verify all of the protocol
// descriptors.
auto &Self = const_cast<ConformanceState &>(*this);
- Self.SectionsToScan.read([](const ConformanceSection *ptr, size_t count) -> char {
- for (size_t i = 0; i < count; i++) {
- for (const auto &Record : ptr[i]) {
- Record.get()->verify();
- }
+ for (const auto &Section : Self.SectionsToScan.snapshot()) {
+ for (const auto &Record : Section) {
+ Record.get()->verify();
}
- return 0;
- });
+ }
}
#endif
@@ -445,7 +442,7 @@
}
// Check if the negative cache entry is up-to-date.
- if (Value->getFailureGeneration() == C.SectionsToScan.count()) {
+ if (Value->getFailureGeneration() == C.SectionsToScan.snapshot().count()) {
// Negative cache entry is up-to-date. Return failure along with
// the original query type's own cache entry, if we found one.
// (That entry may be out of date but the caller still has use for it.)
@@ -546,100 +543,94 @@
auto failureEntry = FoundConformance.failureEntry;
// Prepare to scan conformance records.
- size_t scannedCount;
- auto returnNull = C.SectionsToScan
- .read([&](const ConformanceSection *ptr, size_t count) -> bool {
- scannedCount = count;
- // Scan only sections that were not scanned yet.
- // If we found an out-of-date negative cache entry,
- // we need not to re-scan the sections that it covers.
- auto startIndex = failureEntry ? failureEntry->getFailureGeneration() : 0;
- auto endIndex = count;
+ auto snapshot = C.SectionsToScan.snapshot();
- // If there are no unscanned sections outstanding
- // then we can cache failure and give up now.
- if (startIndex == endIndex) {
- C.cacheFailure(type, protocol, count);
- return true;
+ // Scan only sections that were not scanned yet.
+ // If we found an out-of-date negative cache entry,
+ // we need not to re-scan the sections that it covers.
+ auto startIndex = failureEntry ? failureEntry->getFailureGeneration() : 0;
+ auto endIndex = snapshot.count();
+
+ // If there are no unscanned sections outstanding
+ // then we can cache failure and give up now.
+ if (startIndex == endIndex) {
+ C.cacheFailure(type, protocol, snapshot.count());
+ return nullptr;
+ }
+
+ /// Local function to retrieve the witness table and record the result.
+ auto recordWitnessTable = [&](const ProtocolConformanceDescriptor &descriptor,
+ const Metadata *type) {
+ switch (descriptor.getConformanceKind()) {
+ case ConformanceFlags::ConformanceKind::WitnessTable:
+ // If the record provides a nondependent witness table for all
+ // instances of a generic type, cache it for the generic pattern.
+ C.cacheSuccess(type, protocol, descriptor.getStaticWitnessTable());
+ return;
+
+ case ConformanceFlags::ConformanceKind::WitnessTableAccessor:
+ // If the record provides a dependent witness table accessor,
+ // cache the result for the instantiated type metadata.
+ C.cacheSuccess(type, protocol, descriptor.getWitnessTable(type));
+ return;
+
+ case ConformanceFlags::ConformanceKind::ConditionalWitnessTableAccessor: {
+ auto witnessTable = descriptor.getWitnessTable(type);
+ if (witnessTable)
+ C.cacheSuccess(type, protocol, witnessTable);
+ else
+ C.cacheFailure(type, protocol, snapshot.count());
+ return;
+ }
}
- /// Local function to retrieve the witness table and record the result.
- auto recordWitnessTable = [&](const ProtocolConformanceDescriptor &descriptor,
- const Metadata *type) {
- switch (descriptor.getConformanceKind()) {
- case ConformanceFlags::ConformanceKind::WitnessTable:
- // If the record provides a nondependent witness table for all
- // instances of a generic type, cache it for the generic pattern.
- C.cacheSuccess(type, protocol, descriptor.getStaticWitnessTable());
- return;
+ // Always fail, because we cannot interpret a future conformance
+ // kind.
+ C.cacheFailure(type, protocol, snapshot.count());
+ };
- case ConformanceFlags::ConformanceKind::WitnessTableAccessor:
- // If the record provides a dependent witness table accessor,
- // cache the result for the instantiated type metadata.
- C.cacheSuccess(type, protocol, descriptor.getWitnessTable(type));
- return;
+ // Really scan conformance records.
+ for (size_t i = startIndex; i < endIndex; i++) {
+ auto §ion = snapshot.Start[i];
+ // Eagerly pull records for nondependent witnesses into our cache.
+ for (const auto &record : section) {
+ auto &descriptor = *record.get();
- case ConformanceFlags::ConformanceKind::ConditionalWitnessTableAccessor: {
- auto witnessTable = descriptor.getWitnessTable(type);
- if (witnessTable)
- C.cacheSuccess(type, protocol, witnessTable);
- else
- C.cacheFailure(type, protocol, count);
- return;
- }
- }
+ // If the record applies to a specific type, cache it.
+ if (auto metadata = descriptor.getCanonicalTypeMetadata()) {
+ auto P = descriptor.getProtocol();
- // Always fail, because we cannot interpret a future conformance
- // kind.
- C.cacheFailure(type, protocol, count);
- };
+ // Look for an exact match.
+ if (protocol != P)
+ continue;
- // Really scan conformance records.
- for (size_t i = startIndex; i < endIndex; i++) {
- auto §ion = ptr[i];
- // Eagerly pull records for nondependent witnesses into our cache.
- for (const auto &record : section) {
- auto &descriptor = *record.get();
+ if (!isRelatedType(type, metadata, /*candidateIsMetadata=*/true))
+ continue;
- // If the record applies to a specific type, cache it.
- if (auto metadata = descriptor.getCanonicalTypeMetadata()) {
- auto P = descriptor.getProtocol();
+ // Record the witness table.
+ recordWitnessTable(descriptor, metadata);
- // Look for an exact match.
- if (protocol != P)
- continue;
+ // TODO: "Nondependent witness table" probably deserves its own flag.
+ // An accessor function might still be necessary even if the witness table
+ // can be shared.
+ } else if (descriptor.getTypeKind()
+ == TypeMetadataRecordKind::DirectNominalTypeDescriptor ||
+ descriptor.getTypeKind()
+ == TypeMetadataRecordKind::IndirectNominalTypeDescriptor) {
+ auto R = descriptor.getTypeContextDescriptor();
+ auto P = descriptor.getProtocol();
- if (!isRelatedType(type, metadata, /*candidateIsMetadata=*/true))
- continue;
+ // Look for an exact match.
+ if (protocol != P)
+ continue;
- // Record the witness table.
- recordWitnessTable(descriptor, metadata);
+ if (!isRelatedType(type, R, /*candidateIsMetadata=*/false))
+ continue;
- // TODO: "Nondependent witness table" probably deserves its own flag.
- // An accessor function might still be necessary even if the witness table
- // can be shared.
- } else if (descriptor.getTypeKind()
- == TypeMetadataRecordKind::DirectNominalTypeDescriptor ||
- descriptor.getTypeKind()
- == TypeMetadataRecordKind::IndirectNominalTypeDescriptor) {
- auto R = descriptor.getTypeContextDescriptor();
- auto P = descriptor.getProtocol();
-
- // Look for an exact match.
- if (protocol != P)
- continue;
-
- if (!isRelatedType(type, R, /*candidateIsMetadata=*/false))
- continue;
-
- recordWitnessTable(descriptor, type);
- }
+ recordWitnessTable(descriptor, type);
}
}
- return false;
- });
-
- if (returnNull) return nullptr;
+ }
// Conformance scan is complete.
// Search the cache once more, and this time update the cache if necessary.
@@ -648,7 +639,7 @@
if (FoundConformance.isAuthoritative) {
return FoundConformance.witnessTable;
} else {
- C.cacheFailure(type, protocol, scannedCount);
+ C.cacheFailure(type, protocol, snapshot.count());
return nullptr;
}
}
@@ -657,19 +648,15 @@
swift::_searchConformancesByMangledTypeName(Demangle::NodePointer node) {
auto &C = Conformances.get();
- return C.SectionsToScan
- .read([&](const ConformanceSection *ptr, size_t count) -> const TypeContextDescriptor * {
- for (size_t i = 0; i < count; i++) {
- auto §ion = ptr[i];
- for (const auto &record : section) {
- if (auto ntd = record->getTypeContextDescriptor()) {
- if (_contextDescriptorMatchesMangling(ntd, node))
- return ntd;
- }
+ for (auto §ion : C.SectionsToScan.snapshot()) {
+ for (const auto &record : section) {
+ if (auto ntd = record->getTypeContextDescriptor()) {
+ if (_contextDescriptorMatchesMangling(ntd, node))
+ return ntd;
}
}
- return nullptr;
- });
+ }
+ return nullptr;
}
/// Resolve a reference to a generic parameter to type metadata.
diff --git a/stdlib/public/runtime/SwiftRT-ELF.cpp b/stdlib/public/runtime/SwiftRT-ELF.cpp
index 47ba9a7..56074d2 100644
--- a/stdlib/public/runtime/SwiftRT-ELF.cpp
+++ b/stdlib/public/runtime/SwiftRT-ELF.cpp
@@ -24,14 +24,14 @@
__attribute__((__visibility__("hidden"))) extern const char __stop_##name;
extern "C" {
-DECLARE_SWIFT_SECTION(swift4_protocols)
-DECLARE_SWIFT_SECTION(swift4_protocol_conformances)
-DECLARE_SWIFT_SECTION(swift4_type_metadata)
+DECLARE_SWIFT_SECTION(swift5_protocols)
+DECLARE_SWIFT_SECTION(swift5_protocol_conformances)
+DECLARE_SWIFT_SECTION(swift5_type_metadata)
-DECLARE_SWIFT_SECTION(swift4_typeref)
-DECLARE_SWIFT_SECTION(swift4_reflstr)
-DECLARE_SWIFT_SECTION(swift4_fieldmd)
-DECLARE_SWIFT_SECTION(swift4_assocty)
+DECLARE_SWIFT_SECTION(swift5_typeref)
+DECLARE_SWIFT_SECTION(swift5_reflstr)
+DECLARE_SWIFT_SECTION(swift5_fieldmd)
+DECLARE_SWIFT_SECTION(swift5_assocty)
}
#undef DECLARE_SWIFT_SECTION
@@ -53,14 +53,14 @@
nullptr,
nullptr,
- SWIFT_SECTION_RANGE(swift4_protocols),
- SWIFT_SECTION_RANGE(swift4_protocol_conformances),
- SWIFT_SECTION_RANGE(swift4_type_metadata),
+ SWIFT_SECTION_RANGE(swift5_protocols),
+ SWIFT_SECTION_RANGE(swift5_protocol_conformances),
+ SWIFT_SECTION_RANGE(swift5_type_metadata),
- SWIFT_SECTION_RANGE(swift4_typeref),
- SWIFT_SECTION_RANGE(swift4_reflstr),
- SWIFT_SECTION_RANGE(swift4_fieldmd),
- SWIFT_SECTION_RANGE(swift4_assocty),
+ SWIFT_SECTION_RANGE(swift5_typeref),
+ SWIFT_SECTION_RANGE(swift5_reflstr),
+ SWIFT_SECTION_RANGE(swift5_fieldmd),
+ SWIFT_SECTION_RANGE(swift5_assocty),
};
#undef SWIFT_SECTION_RANGE
diff --git a/test/ClangImporter/Inputs/custom-modules/ConditionallyFoo.h b/test/ClangImporter/Inputs/custom-modules/ConditionallyFoo.h
new file mode 100644
index 0000000..598a0ba
--- /dev/null
+++ b/test/ClangImporter/Inputs/custom-modules/ConditionallyFoo.h
@@ -0,0 +1,3 @@
+#ifdef WANT_FOO
+int foo();
+#endif
diff --git a/test/ClangImporter/Inputs/custom-modules/module.map b/test/ClangImporter/Inputs/custom-modules/module.map
index f7c389a..1f4c987 100644
--- a/test/ClangImporter/Inputs/custom-modules/module.map
+++ b/test/ClangImporter/Inputs/custom-modules/module.map
@@ -212,3 +212,8 @@
module Warnings7 { header "Warnings7.h" }
module Warnings8 { header "Warnings8.h" }
module Warnings9 { header "Warnings9.h" }
+
+module ConditionallyFoo {
+ header "ConditionallyFoo.h"
+ config_macros [exhaustive] WANT_FOO
+}
\ No newline at end of file
diff --git a/test/ClangImporter/Inputs/no-fake-source-buffer-excerpts.h b/test/ClangImporter/Inputs/no-fake-source-buffer-excerpts.h
new file mode 100644
index 0000000..5254c40
--- /dev/null
+++ b/test/ClangImporter/Inputs/no-fake-source-buffer-excerpts.h
@@ -0,0 +1,2 @@
+#define WANT_FOO
+@import ConditionallyFoo;
diff --git a/test/ClangImporter/no-fake-source-buffer-excerpts.swift b/test/ClangImporter/no-fake-source-buffer-excerpts.swift
new file mode 100644
index 0000000..7a88953
--- /dev/null
+++ b/test/ClangImporter/no-fake-source-buffer-excerpts.swift
@@ -0,0 +1,11 @@
+// REQUIRES: OS=macosx
+//
+// This triggers a warning about ignored configuration macros; the warning then
+// attempts to emit an excerpt from one of the clang importer's fake buffers
+// (<swift-imported-modules>) which is full of 250kb of nulls. We want to check
+// that we do not emit a gigantic block of nulls to stderr.
+//
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/custom-modules -import-objc-header %S/Inputs/no-fake-source-buffer-excerpts.h %s 2>%t/errors
+// RUN: od -a < %t/errors | %FileCheck %s
+// CHECK-NOT: nul nul nul nul
diff --git a/test/Driver/dump-parse.swift b/test/Driver/dump-parse.swift
index a782033..30cdf5c 100644
--- a/test/Driver/dump-parse.swift
+++ b/test/Driver/dump-parse.swift
@@ -1,8 +1,8 @@
// RUN: not %target-swift-frontend -dump-parse %s 2>&1 | %FileCheck %s
// RUN: not %target-swift-frontend -dump-ast %s 2>&1 | %FileCheck %s -check-prefix=CHECK-AST
-// CHECK-LABEL: (func_decl "foo(_:)"
-// CHECK-AST-LABEL: (func_decl "foo(_:)"
+// CHECK-LABEL: (func_decl{{.*}}"foo(_:)"
+// CHECK-AST-LABEL: (func_decl{{.*}}"foo(_:)"
func foo(_ n: Int) -> Int {
// CHECK: (brace_stmt
// CHECK: (return_stmt
@@ -15,8 +15,8 @@
}
// -dump-parse should print an AST even though this code is invalid.
-// CHECK-LABEL: (func_decl "bar()"
-// CHECK-AST-LABEL: (func_decl "bar()"
+// CHECK-LABEL: (func_decl{{.*}}"bar()"
+// CHECK-AST-LABEL: (func_decl{{.*}}"bar()"
func bar() {
// CHECK: (brace_stmt
// CHECK-NEXT: (unresolved_decl_ref_expr type='{{[^']+}}' name=foo
@@ -29,34 +29,34 @@
foo foo foo
}
-// CHECK-LABEL: (enum_decl trailing_semi "TrailingSemi"
+// CHECK-LABEL: (enum_decl{{.*}}trailing_semi "TrailingSemi"
enum TrailingSemi {
- // CHECK-LABEL: (enum_case_decl trailing_semi
+ // CHECK-LABEL: (enum_case_decl{{.*}}trailing_semi
// CHECK-NOT: (enum_element_decl{{.*}}trailing_semi
- // CHECK: (enum_element_decl "A")
- // CHECK: (enum_element_decl "B")
+ // CHECK: (enum_element_decl{{.*}}"A")
+ // CHECK: (enum_element_decl{{.*}}"B")
case A,B;
- // CHECK-LABEL: (subscript_decl trailing_semi
- // CHECK-NOT: (func_decl trailing_semi 'anonname={{.*}}' getter_for=subscript(_:)
- // CHECK: (accessor_decl 'anonname={{.*}}' getter_for=subscript(_:)
+ // CHECK-LABEL: (subscript_decl{{.*}}trailing_semi
+ // CHECK-NOT: (func_decl{{.*}}trailing_semi 'anonname={{.*}}' getter_for=subscript(_:)
+ // CHECK: (accessor_decl{{.*}}'anonname={{.*}}' getter_for=subscript(_:)
subscript(x: Int) -> Int {
- // CHECK-LABEL: (pattern_binding_decl trailing_semi
- // CHECK-NOT: (var_decl trailing_semi "y"
- // CHECK: (var_decl "y"
+ // CHECK-LABEL: (pattern_binding_decl{{.*}}trailing_semi
+ // CHECK-NOT: (var_decl{{.*}}trailing_semi "y"
+ // CHECK: (var_decl{{.*}}"y"
var y = 1;
// CHECK-LABEL: (sequence_expr {{.*}} trailing_semi
y += 1;
- // CHECK-LABEL: (return_stmt trailing_semi
+ // CHECK-LABEL: (return_stmt{{.*}}trailing_semi
return y;
};
};
// The substitution map for a declref should be relatively unobtrustive.
-// CHECK-AST-LABEL: (func_decl "generic(_:)" <T : Hashable> interface type='<T where T : Hashable> (T) -> ()' access=internal captures=(<generic> )
+// CHECK-AST-LABEL: (func_decl{{.*}}"generic(_:)" <T : Hashable> interface type='<T where T : Hashable> (T) -> ()' access=internal captures=(<generic> )
func generic<T: Hashable>(_: T) {}
// CHECK-AST: (pattern_binding_decl
// CHECK-AST: (declref_expr type='(Int) -> ()' location={{.*}} range={{.*}} decl=main.(file).generic@{{.*}} [with (substitution_map generic_signature=<T where T : Hashable> (substitution T -> Int))] function_ref=unapplied))
diff --git a/test/Driver/emit_public_type_metadata_accessors.swift b/test/Driver/emit_public_type_metadata_accessors.swift
new file mode 100644
index 0000000..123c136
--- /dev/null
+++ b/test/Driver/emit_public_type_metadata_accessors.swift
@@ -0,0 +1,3 @@
+// RUN: %target-build-swift %s -emit-public-type-metadata-accessors 2>&1 | %FileCheck %s
+
+// CHECK: the option '-emit-public-type-metadata-accessors' is no longer needed and is deprecated; consider removing it
diff --git a/test/Generics/same_type_constraints.swift b/test/Generics/same_type_constraints.swift
index 9dca6b0..2d8b5cd 100644
--- a/test/Generics/same_type_constraints.swift
+++ b/test/Generics/same_type_constraints.swift
@@ -378,3 +378,19 @@
extension X11 where NotAnInt == Int { }
// expected-warning@-1{{neither type in same-type constraint ('NotAnInt' (aka 'Double') or 'Int') refers to a generic parameter or associated type}}
// expected-error@-2{{generic signature requires types 'NotAnInt' (aka 'Double') and 'Int' to be the same}}
+
+
+struct X12<T> { }
+
+protocol P12 {
+ associatedtype A
+ associatedtype B
+}
+
+func testP12a<T: P12>(_: T) where T.A == X12<Int>, T.A == X12<T.B>, T.B == Int { }
+// expected-warning@-1{{redundant same-type constraint 'T.B' == 'Int'}}
+// expected-note@-2{{same-type constraint 'T.B' == 'Int' written here}}
+
+func testP12b<T: P12>(_: T) where T.B == Int, T.A == X12<T.B>, X12<T.B> == T.A { }
+// expected-warning@-1{{redundant same-type constraint 'T.A' == 'X12<Int>'}}
+// expected-note@-2{{same-type constraint 'T.A' == 'X12<Int>' written here}}
diff --git a/test/IDE/complete_after_self.swift b/test/IDE/complete_after_self.swift
index fe4afbe..b5a3744 100644
--- a/test/IDE/complete_after_self.swift
+++ b/test/IDE/complete_after_self.swift
@@ -166,7 +166,7 @@
init() {
self#^CONSTRUCTOR_SELF_NO_DOT_1^#
-// CONSTRUCTOR_SELF_NO_DOT_1: Begin completions, 23 items
+// CONSTRUCTOR_SELF_NO_DOT_1: Begin completions, 24 items
// CONSTRUCTOR_SELF_NO_DOT_1-DAG: Decl[Constructor]/CurrNominal: .init()[#ThisDerived1#];
// CONSTRUCTOR_SELF_NO_DOT_1-DAG: Decl[Constructor]/CurrNominal: .init({#a: Int#})[#ThisDerived1#];
// CONSTRUCTOR_SELF_NO_DOT_1: End completions
@@ -177,9 +177,10 @@
init(a : Int) {
self.#^CONSTRUCTOR_SELF_DOT_1^#
-// CONSTRUCTOR_SELF_DOT_1: Begin completions, 18 items
+// CONSTRUCTOR_SELF_DOT_1: Begin completions, 19 items
// CONSTRUCTOR_SELF_DOT_1-DAG: Decl[Constructor]/CurrNominal: init()[#ThisDerived1#];
// CONSTRUCTOR_SELF_DOT_1-DAG: Decl[Constructor]/CurrNominal: init({#a: Int#})[#ThisDerived1#];
+
// CONSTRUCTOR_SELF_DOT_1: End completions
let d: ThisDerived1
d.#^CONSTRUCTOR_NONSELF_DOT_1^#
@@ -187,23 +188,23 @@
deinit {
self#^DESTRUCTOR_SELF_NO_DOT_1^#
-// DESTRUCTOR_SELF_NO_DOT_1: Begin completions, 20 items
+// DESTRUCTOR_SELF_NO_DOT_1: Begin completions, 21 items
// DESTRUCTOR_SELF_NO_DOT_1: End completions
self.#^DESTRUCTOR_SELF_DOT_1^#
-// DESTRUCTOR_SELF_DOT_1: Begin completions, 15 items
+// DESTRUCTOR_SELF_DOT_1: Begin completions, 16 items
// DESTRUCTOR_SELF_DOT_1: End completions
}
func test1() {
self#^FUNC_SELF_NO_DOT_1^#
-// FUNC_SELF_NO_DOT_1: Begin completions, 20 items
+// FUNC_SELF_NO_DOT_1: Begin completions, 21 items
// FUNC_SELF_NO_DOT_1: End completions
}
func test2() {
self.#^FUNC_SELF_DOT_1^#
-// FUNC_SELF_DOT_1: Begin completions, 15 items
+// FUNC_SELF_DOT_1: Begin completions, 16 items
// FUNC_SELF_DOT_1: End completions
}
@@ -236,12 +237,14 @@
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[Class]/Super: .BaseExtNestedClass[#ThisBase1.BaseExtNestedClass#]
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[Enum]/Super: .BaseExtNestedEnum[#ThisBase1.BaseExtNestedEnum#]
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[TypeAlias]/Super: .BaseExtNestedTypealias[#Int#]
+// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Keyword[self]/CurrNominal: .self[#ThisDerived1.Type#]; name=self
// FUNC_STATIC_SELF_NO_DOT_1-NEXT: End completions
}
class func staticTest2() {
self.#^FUNC_STATIC_SELF_DOT_1^#
// FUNC_STATIC_SELF_DOT_1: Begin completions
+// FUNC_STATIC_SELF_DOT_1-NEXT: Keyword[self]/CurrNominal: self[#ThisDerived1.Type#]; name=self
// FUNC_STATIC_SELF_DOT_1-NEXT: Decl[InstanceMethod]/CurrNominal: derivedFunc0({#self: ThisDerived1#})[#() -> Void#]
// FUNC_STATIC_SELF_DOT_1-NEXT: Decl[StaticVar]/CurrNominal: derivedStaticVar[#Int#]
// FUNC_STATIC_SELF_DOT_1-NEXT: Decl[StaticMethod]/CurrNominal: derivedStaticFunc0()[#Void#]
@@ -307,7 +310,8 @@
init() {}
init(x: Int) {
self.#^STRUCT_CONSTRUCTOR_SELF_DOT_1^#
-// STRUCT_CONSTRUCTOR_SELF_DOT_1: Begin completions, 3 items
+// STRUCT_CONSTRUCTOR_SELF_DOT_1: Begin completions, 4 items
+// STRUCT_CONSTRUCTOR_SELF_DOT_1-DAG: Keyword[self]/CurrNominal: self[#S1#]; name=self
// STRUCT_CONSTRUCTOR_SELF_DOT_1-DAG: Decl[Constructor]/CurrNominal: init()[#S1#];
// STRUCT_CONSTRUCTOR_SELF_DOT_1-DAG: Decl[Constructor]/CurrNominal: init({#x: Int#})[#S1#];
// STRUCT_CONSTRUCTOR_SELF_DOT_1-DAG: Decl[InstanceMethod]/CurrNominal: f()[#Void#];
diff --git a/test/IDE/complete_associated_types.swift b/test/IDE/complete_associated_types.swift
index fad21e7..dfa0eee 100644
--- a/test/IDE/complete_associated_types.swift
+++ b/test/IDE/complete_associated_types.swift
@@ -179,7 +179,7 @@
}
// STRUCT_TYPE_COUNT: Begin completions, 26 items
-// STRUCT_INSTANCE: Begin completions, 14 items
+// STRUCT_INSTANCE: Begin completions, 15 items
// STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal: deduceCommonA()[#Int#]
// STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal: deduceCommonB()[#Int#]
// STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal: deduceCommonC()[#Int#]
@@ -194,6 +194,7 @@
// STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal: deduceBarBaseC()[#Int#]
// STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal: deduceBarBaseD()[#Int#]
// STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal: deduceBarD()[#Int#]
+// STRUCT_INSTANCE-DAG: Keyword[self]/CurrNominal: self[#StructWithAssociatedTypes#]; name=self
// STRUCT_INSTANCE: End completions
// STRUCT_TYPES: Begin completions
@@ -266,7 +267,7 @@
func testBrokenConformances1() {
StructWithBrokenConformance.#^BROKEN_CONFORMANCE_1^#
}
-// BROKEN_CONFORMANCE_1: Begin completions, 34 items
+// BROKEN_CONFORMANCE_1: Begin completions, 35 items
// BROKEN_CONFORMANCE_1-DAG: Decl[TypeAlias]/CurrNominal: DefaultedTypeCommonA[#StructWithBrokenConformance.DefaultedTypeCommonA#]; name=DefaultedTypeCommonA
// BROKEN_CONFORMANCE_1-DAG: Decl[TypeAlias]/CurrNominal: DefaultedTypeCommonB[#StructWithBrokenConformance.DefaultedTypeCommonB#]; name=DefaultedTypeCommonB
// BROKEN_CONFORMANCE_1-DAG: Decl[TypeAlias]/CurrNominal: FooBaseDefaultedTypeB[#StructWithBrokenConformance.FooBaseDefaultedTypeB#]; name=FooBaseDefaultedTypeB
diff --git a/test/IDE/complete_at_top_level.swift b/test/IDE/complete_at_top_level.swift
index 0ec1446..6879375 100644
--- a/test/IDE/complete_at_top_level.swift
+++ b/test/IDE/complete_at_top_level.swift
@@ -178,7 +178,8 @@
// TYPE_CHECKED_EXPR_1: Begin completions
// TYPE_CHECKED_EXPR_1-NEXT: Decl[InstanceVar]/CurrNominal: .instanceVar[#Int#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_1-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
-// TYPE_CHECKED_EXPR_1-NEXT:BuiltinOperator/None: = {#FooStruct#}[#Void#]; name== FooStruct
+// TYPE_CHECKED_EXPR_1-NEXT: BuiltinOperator/None: = {#FooStruct#}[#Void#]; name== FooStruct
+// TYPE_CHECKED_EXPR_1-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct#]; name=self
// TYPE_CHECKED_EXPR_1-NEXT: End completions
func resyncParser2() {}
@@ -191,6 +192,7 @@
// TYPE_CHECKED_EXPR_2-NEXT: Decl[InstanceVar]/CurrNominal: .instanceVar[#Int#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_2-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_2-NEXT: BuiltinOperator/None: = {#FooStruct#}[#Void#]; name== FooStruct
+// TYPE_CHECKED_EXPR_2-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct#]; name=self
// TYPE_CHECKED_EXPR_2-NEXT: End completions
func resyncParser3() {}
@@ -200,12 +202,14 @@
// TYPE_CHECKED_EXPR_3-NEXT: Decl[InstanceVar]/CurrNominal: .instanceVar[#Int#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_3-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_3-NEXT: BuiltinOperator/None: = {#FooStruct#}[#Void#]; name== FooStruct
+// TYPE_CHECKED_EXPR_3-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct#]; name=self
// TYPE_CHECKED_EXPR_3-NEXT: End completions
func resyncParser4() {}
fooObject.#^TYPE_CHECKED_EXPR_4^#
// TYPE_CHECKED_EXPR_4: Begin completions
+// TYPE_CHECKED_EXPR_4-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// TYPE_CHECKED_EXPR_4-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_4-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_4-NEXT: End completions
@@ -214,6 +218,7 @@
fooObject.#^TYPE_CHECKED_EXPR_5^#.bar
// TYPE_CHECKED_EXPR_5: Begin completions
+// TYPE_CHECKED_EXPR_5-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// TYPE_CHECKED_EXPR_5-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_5-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_5-NEXT: End completions
@@ -236,6 +241,7 @@
fooObjectWithErrorInInit.#^TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1^#
// TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1: Begin completions
+// TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
// TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1-NEXT: End completions
@@ -259,6 +265,7 @@
// TOP_LEVEL_VAR_INIT_2-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#self: FooStruct#})[#(Int) -> Void#]{{; name=.+$}}
// TOP_LEVEL_VAR_INIT_2-NEXT: Decl[Constructor]/CurrNominal: ({#instanceVar: Int#})[#FooStruct#]{{; name=.+$}}
// TOP_LEVEL_VAR_INIT_2-NEXT: Decl[Constructor]/CurrNominal: ()[#FooStruct#]{{; name=.+$}}
+// TOP_LEVEL_VAR_INIT_2-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct.Type#]; name=self
// TOP_LEVEL_VAR_INIT_2-NEXT: End completions
func resyncParser8() {}
diff --git a/test/IDE/complete_call_arg.swift b/test/IDE/complete_call_arg.swift
index 51bacbf..2bfe9ff 100644
--- a/test/IDE/complete_call_arg.swift
+++ b/test/IDE/complete_call_arg.swift
@@ -413,7 +413,8 @@
self.collectionView? .#^BOUND_IUO^#x
self.collectionView! .#^FORCED_IUO^#x
}
- // MEMBEROF_IUO: Begin completions, 1 items
+ // MEMBEROF_IUO: Begin completions, 2 items
+ // MEMBEROF_IUO: Keyword[self]/CurrNominal: self[#Foo#]; name=self
// MEMBEROF_IUO: Decl[InstanceVar]/CurrNominal: x[#Int#]; name=x
// MEMBEROF_IUO: End completions
}
diff --git a/test/IDE/complete_constructor.swift b/test/IDE/complete_constructor.swift
index b84176e..f0de365 100644
--- a/test/IDE/complete_constructor.swift
+++ b/test/IDE/complete_constructor.swift
@@ -43,8 +43,9 @@
func testImplicitConstructors1() {
ImplicitConstructors1#^IMPLICIT_CONSTRUCTORS_1^#
-// IMPLICIT_CONSTRUCTORS_1: Begin completions, 1 items
+// IMPLICIT_CONSTRUCTORS_1: Begin completions, 2 items
// IMPLICIT_CONSTRUCTORS_1-DAG: Decl[Constructor]/CurrNominal: ()[#ImplicitConstructors1#]{{; name=.+$}}
+// IMPLICIT_CONSTRUCTORS_1-DAG: Keyword[self]/CurrNominal: .self[#ImplicitConstructors1.Type#]; name=self
// IMPLICIT_CONSTRUCTORS_1: End completions
}
func testImplicitConstructors1P() {
@@ -58,9 +59,10 @@
func testImplicitConstructors2() {
ImplicitConstructors2#^IMPLICIT_CONSTRUCTORS_2^#
-// IMPLICIT_CONSTRUCTORS_2: Begin completions, 2 items
+// IMPLICIT_CONSTRUCTORS_2: Begin completions, 3 items
// IMPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ({#instanceVar: Int#})[#ImplicitConstructors2#]{{; name=.+$}}
// IMPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ()[#ImplicitConstructors2#]{{; name=.+$}}
+// IMPLICIT_CONSTRUCTORS_2-DAG: Keyword[self]/CurrNominal: .self[#ImplicitConstructors2.Type#]; name=self
// IMPLICIT_CONSTRUCTORS_2: End completions
}
func testImplicitConstructors2P() {
@@ -78,10 +80,11 @@
func testExplicitConstructors1() {
ExplicitConstructors1#^EXPLICIT_CONSTRUCTORS_1^#
-// EXPLICIT_CONSTRUCTORS_1: Begin completions, 3 items
+// EXPLICIT_CONSTRUCTORS_1: Begin completions, 4 items
// EXPLICIT_CONSTRUCTORS_1-DAG: Decl[Constructor]/CurrNominal: ()[#ExplicitConstructors1#]{{; name=.+$}}
// EXPLICIT_CONSTRUCTORS_1-DAG: Decl[Constructor]/CurrNominal: ({#a: Int#})[#ExplicitConstructors1#]{{; name=.+$}}
// EXPLICIT_CONSTRUCTORS_1-DAG: Decl[Constructor]/CurrNominal: ({#a: Int#}, {#b: Float#})[#ExplicitConstructors1#]{{; name=.+$}}
+// EXPLICIT_CONSTRUCTORS_1-DAG: Keyword[self]/CurrNominal: .self[#ExplicitConstructors1.Type#]; name=self
// EXPLICIT_CONSTRUCTORS_1: End completions
}
func testExplicitConstructors1P() {
@@ -94,10 +97,11 @@
ExplicitConstructors1#^EXPLICIT_CONSTRUCTORS_2^#
-// EXPLICIT_CONSTRUCTORS_2: Begin completions, 3 items
+// EXPLICIT_CONSTRUCTORS_2: Begin completions, 4 items
// EXPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ()[#ExplicitConstructors1#]
// EXPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ({#a: Int#})[#ExplicitConstructors1#]
// EXPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ({#a: Int#}, {#b: Float#})[#ExplicitConstructors1#]
+// EXPLICIT_CONSTRUCTORS_2-DAG: Keyword[self]/CurrNominal: .self[#ExplicitConstructors1.Type#]; name=self
// EXPLICIT_CONSTRUCTORS_2: End completions
ExplicitConstructors1(#^EXPLICIT_CONSTRUCTORS_2P^#
@@ -130,9 +134,10 @@
func testExplicitConstructorsSelector1() {
ExplicitConstructorsSelector1#^EXPLICIT_CONSTRUCTORS_SELECTOR_1^#
-// EXPLICIT_CONSTRUCTORS_SELECTOR_1: Begin completions, 2 items
+// EXPLICIT_CONSTRUCTORS_SELECTOR_1: Begin completions, 3 items
// EXPLICIT_CONSTRUCTORS_SELECTOR_1-DAG: Decl[Constructor]/CurrNominal: ({#int: Int#})[#ExplicitConstructorsSelector1#]{{; name=.+$}}
// EXPLICIT_CONSTRUCTORS_SELECTOR_1-DAG: Decl[Constructor]/CurrNominal: ({#int: Int#}, {#andFloat: Float#})[#ExplicitConstructorsSelector1#]{{; name=.+$}}
+// EXPLICIT_CONSTRUCTORS_SELECTOR_1-DAG: Keyword[self]/CurrNominal: .self[#ExplicitConstructorsSelector1.Type#]; name=self
// EXPLICIT_CONSTRUCTORS_SELECTOR_1: End completions
}
@@ -145,11 +150,12 @@
func testExplicitConstructorsSelector2() {
ExplicitConstructorsSelector2#^EXPLICIT_CONSTRUCTORS_SELECTOR_2^#
-// EXPLICIT_CONSTRUCTORS_SELECTOR_2: Begin completions, 4 items
+// EXPLICIT_CONSTRUCTORS_SELECTOR_2: Begin completions, 5 items
// EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Decl[Constructor]/CurrNominal: ({#noArgs: ()#})[#ExplicitConstructorsSelector2#]{{; name=.+$}}
// EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Decl[Constructor]/CurrNominal: ({#Int#})[#ExplicitConstructorsSelector2#]{{; name=.+$}}
// EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Decl[Constructor]/CurrNominal: ({#Int#}, {#withFloat: Float#})[#ExplicitConstructorsSelector2#]{{; name=.+$}}
// EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Decl[Constructor]/CurrNominal: ({#int: Int#}, {#Float#})[#ExplicitConstructorsSelector2#]{{; name=.+$}}
+// EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Keyword[self]/CurrNominal: .self[#ExplicitConstructorsSelector2.Type#]; name=self
// EXPLICIT_CONSTRUCTORS_SELECTOR_2: End completions
}
@@ -174,9 +180,10 @@
func testExplicitConstructorsBaseDerived1() {
ExplicitConstructorsDerived1#^EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1^#
}
-// EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1: Begin completions, 2 items
+// EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1: Begin completions, 3 items
// EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1-DAG: Decl[Constructor]/CurrNominal: ()[#ExplicitConstructorsDerived1#]{{; name=.+$}}
// EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1-DAG: Decl[Constructor]/CurrNominal: ({#a: Int#})[#ExplicitConstructorsDerived1#]{{; name=.+$}}
+// EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1-DAG: Keyword[self]/CurrNominal: .self[#ExplicitConstructorsDerived1.Type#]; name=self
// EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1: End completions
func testGetInitFromMetatype1() {
@@ -184,6 +191,7 @@
}
// INIT_FROM_METATYPE1: Begin completions
+// INIT_FROM_METATYPE1-NEXT: Keyword[self]/CurrNominal: self[#ExplicitConstructorsBase1.Type#]; name=self
// INIT_FROM_METATYPE1-NEXT: Decl[Constructor]/CurrNominal: init()[#ExplicitConstructorsBase1#]{{; name=.+$}}
// INIT_FROM_METATYPE1-NEXT: Decl[Constructor]/CurrNominal: init({#a: Int#})[#ExplicitConstructorsBase1#]{{; name=.+$}}
// INIT_FROM_METATYPE1-NEXT: End completions
diff --git a/test/IDE/complete_crashes.swift b/test/IDE/complete_crashes.swift
index 8549d0e..4cfcfa9 100644
--- a/test/IDE/complete_crashes.swift
+++ b/test/IDE/complete_crashes.swift
@@ -30,9 +30,10 @@
func badMembers2(_ a: BadMembers2) {
a#^BAD_MEMBERS_2^#
}
-// BAD_MEMBERS_2: Begin completions, 2 items
+// BAD_MEMBERS_2: Begin completions, 3 items
// BAD_MEMBERS_2-NEXT: Decl[InstanceVar]/CurrNominal: .prop[#Int#]{{; name=.+$}}
// BAD_MEMBERS_2-NEXT: Decl[Subscript]/CurrNominal: [{#Int#}][#Double#]{{; name=.+$}}
+// BAD_MEMBERS_2-NEXT: Keyword[self]/CurrNominal: .self[#BadMembers2#]; name=self
// BAD_MEMBERS_2-NEXT: End completions
func globalFunc() {}
@@ -220,10 +221,11 @@
func foo_38149042(bar: Bar_38149042) {
_ = bar.foo? #^RDAR_38149042^# .x
}
-// RDAR_38149042: Begin completions, 3 items
+// RDAR_38149042: Begin completions, 4 items
// RDAR_38149042-DAG: Decl[InstanceVar]/CurrNominal: .x[#Int#]; name=x
// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']=== {#AnyObject?#}[#Bool#]; name==== AnyObject?
// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']!== {#AnyObject?#}[#Bool#]; name=!== AnyObject?
+// RDAR_38149042-DAG: Keyword[self]/CurrNominal: .self[#Baz_38149042#]; name=self
// RDAR_38149042: End completions
// rdar://problem/38272904
diff --git a/test/IDE/complete_doc_keyword.swift b/test/IDE/complete_doc_keyword.swift
index 7ed141c..318a461 100644
--- a/test/IDE/complete_doc_keyword.swift
+++ b/test/IDE/complete_doc_keyword.swift
@@ -93,6 +93,7 @@
let c = C1()
c.#^MEMBER1^#
// MEMBER1: Begin completions
+// MEMBER1-NEXT: Keyword[self]/CurrNominal: self[#C1#]; name=self
// MEMBER1-NEXT: Decl[InstanceVar]/CurrNominal/keyword[v1, Int]/recommended[v2]: v1[#Int#]
// MEMBER1-NEXT: Decl[InstanceVar]/CurrNominal/keyword[v2, Int]/recommendedover[v1]: v2[#Int#]
// MEMBER1-NEXT: Decl[InstanceMethod]/CurrNominal/keyword[f1, func]/recommended[f2]: f1()[#Void#]
@@ -103,6 +104,7 @@
let s = S3()
s.#^MEMBER2^#
// MEMBER2: Begin completions
+// MEMBER2-NEXT: Keyword[self]/CurrNominal: self[#S3#]; name=self
// MEMBER2-NEXT: Decl[InstanceMethod]/CurrNominal/nonmutatingvariant[fooing]: foo()[#Void#]
// MEMBER2-NEXT: Decl[InstanceMethod]/CurrNominal/mutatingvariant[foo]: fooing()[#S3#]
}
diff --git a/test/IDE/complete_dynamic_lookup.swift b/test/IDE/complete_dynamic_lookup.swift
index 9d6a060..d0419fe 100644
--- a/test/IDE/complete_dynamic_lookup.swift
+++ b/test/IDE/complete_dynamic_lookup.swift
@@ -234,9 +234,11 @@
// TLOC_MEMBERS_NO_DOT-NEXT: Decl[InstanceVar]/CurrNominal: .topLevelObjcClass_Property1[#Int#]{{; name=.+$}}
// TLOC_MEMBERS_NO_DOT-NEXT: Decl[InfixOperatorFunction]/OtherModule[Swift]: === {#AnyObject?#}[#Bool#];
// TLOC_MEMBERS_NO_DOT-NEXT: Decl[InfixOperatorFunction]/OtherModule[Swift]: !== {#AnyObject?#}[#Bool#];
+// TLOC_MEMBERS_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#TopLevelObjcClass#]; name=self
// TLOC_MEMBERS_NO_DOT-NEXT: End completions
// TLOC_MEMBERS_DOT: Begin completions
+// TLOC_MEMBERS_DOT-NEXT: Keyword[self]/CurrNominal: self[#TopLevelObjcClass#]; name=self
// TLOC_MEMBERS_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: returnsObjcClass({#(i): Int#})[#TopLevelObjcClass#]{{; name=.+$}}
// TLOC_MEMBERS_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: topLevelObjcClass_InstanceFunc1()[#Void#]{{; name=.+$}}
// TLOC_MEMBERS_DOT-NEXT: Decl[InstanceVar]/CurrNominal: topLevelObjcClass_Property1[#Int#]{{; name=.+$}}
@@ -474,6 +476,7 @@
}
// DL_FUNC_NAME_BANG_1: Begin completions
// DL_FUNC_NAME_BANG_1-NEXT: Pattern/CurrModule: ({#Int#})[#TopLevelObjcClass#]
+// DL_FUNC_NAME_BANG_1-NEXT: Keyword[self]/CurrNominal: .self[#(Int) -> TopLevelObjcClass#]; name=self
// DL_FUNC_NAME_BANG_1-NEXT: End completions
func testAnyObject14() {
diff --git a/test/IDE/complete_enum_elements.swift b/test/IDE/complete_enum_elements.swift
index 94b3126..b8e0152 100644
--- a/test/IDE/complete_enum_elements.swift
+++ b/test/IDE/complete_enum_elements.swift
@@ -91,9 +91,11 @@
// FOO_ENUM_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .hash({#self: FooEnum#})[#(into: inout Hasher) -> Void#]; name=hash(FooEnum)
// FOO_ENUM_NO_DOT-NEXT: Decl[TypeAlias]/CurrNominal: .AllCases[#[FooEnum]#]{{; name=.+$}}
// FOO_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .allCases[#[FooEnum]#]{{; name=.+$}}
+// FOO_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#FooEnum.Type#]; name=self
// FOO_ENUM_NO_DOT-NEXT: End completions
// FOO_ENUM_DOT: Begin completions
+// FOO_ENUM_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooEnum.Type#]; name=self
// FOO_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Foo1[#FooEnum#]{{; name=.+$}}
// FOO_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Foo2[#FooEnum#]{{; name=.+$}}
// FOO_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: hash({#self: FooEnum#})[#(into: inout Hasher) -> Void#]; name=hash(FooEnum)
@@ -102,6 +104,7 @@
// FOO_ENUM_DOT-NEXT: End completions
// FOO_ENUM_DOT_INVALID: Begin completions
+// FOO_ENUM_DOT_INVALID-NEXT: Keyword[self]/CurrNominal: self[#FooEnum.Type#]; name=self
// FOO_ENUM_DOT_INVALID-NEXT: Decl[EnumElement]/CurrNominal: Foo1[#FooEnum#]{{; name=.+$}}
// FOO_ENUM_DOT_INVALID-NEXT: Decl[EnumElement]/CurrNominal: Foo2[#FooEnum#]{{; name=.+$}}
// FOO_ENUM_DOT_INVALID-NEXT: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: hash({#self: FooEnum#})[#(into: inout Hasher) -> Void#]; name=hash(FooEnum)
@@ -165,9 +168,11 @@
// BAR_ENUM_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .barInstanceFunc({#self: &BarEnum#})[#() -> Void#]{{; name=.+$}}
// BAR_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .staticVar[#Int#]{{; name=.+$}}
// BAR_ENUM_NO_DOT-NEXT: Decl[StaticMethod]/CurrNominal: .barStaticFunc()[#Void#]{{; name=.+$}}
+// BAR_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#BarEnum.Type#]; name=self
// BAR_ENUM_NO_DOT-NEXT: End completions
// BAR_ENUM_DOT: Begin completions
+// BAR_ENUM_DOT-NEXT: Keyword[self]/CurrNominal: self[#BarEnum.Type#]; name=self
// BAR_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Bar1[#BarEnum#]{{; name=.+$}}
// BAR_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Bar2()[#() -> BarEnum#]{{; name=.+$}}
// BAR_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Bar3({#Int#})[#(Int) -> BarEnum#]{{; name=.+$}}
@@ -201,13 +206,14 @@
// BAZ_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/ExprSpecific: .Baz2({#T#})[#(T) -> BazEnum<T>#]{{; name=.+$}}
// BAZ_ENUM_TYPE_CONTEXT: End completions
-// BAZ_INT_ENUM_NO_DOT: Begin completions, 6 items
+// BAZ_INT_ENUM_NO_DOT: Begin completions, 7 items
// BAZ_INT_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal: .Baz1[#BazEnum<T>#]{{; name=.+$}}
// BAZ_INT_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal: .Baz2({#T#})[#(T) -> BazEnum<T>#]{{; name=.+$}}
// BAZ_INT_ENUM_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .bazInstanceFunc({#self: &BazEnum<Int>#})[#() -> Void#]{{; name=.+$}}
// BAZ_INT_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .staticVar[#Int#]{{; name=.+$}}
// BAZ_INT_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .staticVarT[#Int#]{{; name=.+$}}
// BAZ_INT_ENUM_NO_DOT-NEXT: Decl[StaticMethod]/CurrNominal: .bazStaticFunc()[#Void#]{{; name=.+$}}
+// BAZ_INT_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#BazEnum<Int>.Type#]; name=self
// BAZ_INT_ENUM_NO_DOT-NEXT: End completions
// BAZ_T_ENUM_NO_DOT: Begin completions
@@ -217,9 +223,11 @@
// BAZ_T_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .staticVar[#Int#]{{; name=.+$}}
// BAZ_T_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .staticVarT[#_#]{{; name=.+$}}
// BAZ_T_ENUM_NO_DOT-NEXT: Decl[StaticMethod]/CurrNominal: .bazStaticFunc()[#Void#]{{; name=.+$}}
+// BAZ_T_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#BazEnum<_>.Type#]; name=self
// BAZ_T_ENUM_NO_DOT-NEXT: End completions
-// BAZ_INT_ENUM_DOT: Begin completions, 6 items
+// BAZ_INT_ENUM_DOT: Begin completions, 7 items
+// BAZ_INT_ENUM_DOT-NEXT: Keyword[self]/CurrNominal: self[#BazEnum<Int>.Type#]; name=self
// BAZ_INT_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Baz1[#BazEnum<T>#]{{; name=.+$}}
// BAZ_INT_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Baz2({#T#})[#(T) -> BazEnum<T>#]{{; name=.+$}}
// BAZ_INT_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: bazInstanceFunc({#self: &BazEnum<Int>#})[#() -> Void#]{{; name=.+$}}
@@ -228,7 +236,8 @@
// BAZ_INT_ENUM_DOT-NEXT: Decl[StaticMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: bazStaticFunc()[#Void#]{{; name=.+$}}
// BAZ_INT_ENUM_DOT-NEXT: End completions
-// BAZ_T_ENUM_DOT: Begin completions, 6 items
+// BAZ_T_ENUM_DOT: Begin completions, 7 items
+// BAZ_T_ENUM_DOT-NEXT: Keyword[self]/CurrNominal: self[#BazEnum<_>.Type#]; name=self
// BAZ_T_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Baz1[#BazEnum<T>#]{{; name=.+$}}
// BAZ_T_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Baz2({#T#})[#(T) -> BazEnum<T>#]{{; name=.+$}}
// BAZ_T_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: bazInstanceFunc({#self: &BazEnum<_>#})[#() -> Void#]{{; name=.+$}}
@@ -247,15 +256,17 @@
// QUX_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/ExprSpecific: .Qux2[#QuxEnum#]{{; name=.+$}}
// QUX_ENUM_TYPE_CONTEXT: End completions
-// QUX_ENUM_NO_DOT: Begin completions, 5 items
+// QUX_ENUM_NO_DOT: Begin completions, 6 items
// QUX_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal: .Qux1[#QuxEnum#]{{; name=.+$}}
// QUX_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal: .Qux2[#QuxEnum#]{{; name=.+$}}
// QUX_ENUM_NO_DOT-NEXT: Decl[TypeAlias]/CurrNominal: .RawValue[#Int#]{{; name=.+$}}
// QUX_ENUM_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .hash({#self: QuxEnum#})[#(into: inout Hasher) -> Void#]; name=hash(QuxEnum)
// QUX_ENUM_NO_DOT-NEXT: Decl[Constructor]/CurrNominal: ({#rawValue: Int#})[#QuxEnum?#]{{; name=.+$}}
+// QUX_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#QuxEnum.Type#]; name=self
// QUX_ENUM_NO_DOT-NEXT: End completions
-// QUX_ENUM_DOT: Begin completions, 5 items
+// QUX_ENUM_DOT: Begin completions, 6 items
+// QUX_ENUM_DOT-NEXT: Keyword[self]/CurrNominal: self[#QuxEnum.Type#]; name=self
// QUX_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Qux1[#QuxEnum#]{{; name=.+$}}
// QUX_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Qux2[#QuxEnum#]{{; name=.+$}}
// QUX_ENUM_DOT-NEXT: Decl[TypeAlias]/CurrNominal: RawValue[#Int#]{{; name=.+$}}
diff --git a/test/IDE/complete_exception.swift b/test/IDE/complete_exception.swift
index f810cf1..e3aadfb 100644
--- a/test/IDE/complete_exception.swift
+++ b/test/IDE/complete_exception.swift
@@ -196,8 +196,9 @@
} catch {
error.#^INSIDE_CATCH_ERR_DOT1^#
}
-// ERROR_DOT-NOT: Begin completions
}
+// ERROR_DOT: Begin completions
+// ERROR_DOT: Keyword[self]/CurrNominal: self[#Error#]; name=self
func test013() {
do {
} catch let e {
diff --git a/test/IDE/complete_expr_tuple.swift b/test/IDE/complete_expr_tuple.swift
index b2bfb9f..c5d712d 100644
--- a/test/IDE/complete_expr_tuple.swift
+++ b/test/IDE/complete_expr_tuple.swift
@@ -27,7 +27,7 @@
var t = (1, 2.0)
t#^TUPLE_NO_DOT_1^#
}
-// TUPLE_NO_DOT_1: Begin completions, 9 items
+// TUPLE_NO_DOT_1: Begin completions, 10 items
// TUPLE_NO_DOT_1-DAG: Pattern/CurrNominal: .0[#Int#]{{; name=.+$}}
// TUPLE_NO_DOT_1-DAG: Pattern/CurrNominal: .1[#Double#]{{; name=.+$}}
// TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#(Int, Double)#}[#Bool#]{{; name=.+$}}
@@ -37,13 +37,14 @@
// TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#(Int, Double)#}[#Bool#]{{; name=.+$}}
// TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#(Int, Double)#}[#Bool#]{{; name=.+$}}
// TUPLE_NO_DOT_1-DAG: BuiltinOperator/None: = {#(Int, Double)#}[#Void#]{{; name=.+$}}
+// TUPLE_NO_DOT_1-NEXT: Keyword[self]/CurrNominal: .self[#(Int, Double)#]; name=self
// TUPLE_NO_DOT_1-NEXT: End completions
func testTupleNoDot2() {
var t = (foo: 1, bar: 2.0)
t#^TUPLE_NO_DOT_2^#
}
-// TUPLE_NO_DOT_2: Begin completions, 9 items
+// TUPLE_NO_DOT_2: Begin completions, 10 items
// TUPLE_NO_DOT_2-DAG: Pattern/CurrNominal: .foo[#Int#]{{; name=.+$}}
// TUPLE_NO_DOT_2-DAG: Pattern/CurrNominal: .bar[#Double#]{{; name=.+$}}
// TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#(Int, Double)#}[#Bool#]{{; name=.+$}}
@@ -53,13 +54,14 @@
// TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#(Int, Double)#}[#Bool#]{{; name=.+$}}
// TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#(Int, Double)#}[#Bool#]{{; name=.+$}}
// TUPLE_NO_DOT_2-DAG: BuiltinOperator/None: = {#(foo: Int, bar: Double)#}[#Void#]{{; name=.+$}}
+// TUPLE_NO_DOT_2-DAG: Keyword[self]/CurrNominal: .self[#(foo: Int, bar: Double)#]; name=self
// TUPLE_NO_DOT_2-NEXT: End completions
func testTupleNoDot3() {
var t = (foo: 1, 2.0)
t#^TUPLE_NO_DOT_3^#
}
-// TUPLE_NO_DOT_3: Begin completions, 9 items
+// TUPLE_NO_DOT_3: Begin completions, 10 items
// TUPLE_NO_DOT_3-DAG: Pattern/CurrNominal: .foo[#Int#]{{; name=.+$}}
// TUPLE_NO_DOT_3-DAG: Pattern/CurrNominal: .1[#Double#]{{; name=.+$}}
// TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#(Int, Double)#}[#Bool#]{{; name=.+$}}
@@ -69,13 +71,15 @@
// TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#(Int, Double)#}[#Bool#]{{; name=.+$}}
// TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#(Int, Double)#}[#Bool#]{{; name=.+$}}
// TUPLE_NO_DOT_3-DAG: BuiltinOperator/None: = {#(foo: Int, Double)#}[#Void#]{{; name=.+$}}
+// TUPLE_NO_DOT_3-DAG: Keyword[self]/CurrNominal: .self[#(foo: Int, Double)#]; name=self
// TUPLE_NO_DOT_3-NEXT: End completions
func testTupleDot1() {
var t = (1, 2.0)
t.#^TUPLE_DOT_1^#
}
-// TUPLE_DOT_1: Begin completions, 2 items
+// TUPLE_DOT_1: Begin completions, 3 items
+// TUPLE_DOT_1-NEXT: Keyword[self]/CurrNominal: self[#(Int, Double)#]; name=self
// TUPLE_DOT_1-NEXT: Pattern/CurrNominal: 0[#Int#]{{; name=.+$}}
// TUPLE_DOT_1-NEXT: Pattern/CurrNominal: 1[#Double#]{{; name=.+$}}
// TUPLE_DOT_1-NEXT: End completions
@@ -84,7 +88,8 @@
var t = (foo: 1, bar: 2.0)
t.#^TUPLE_DOT_2^#
}
-// TUPLE_DOT_2: Begin completions, 2 items
+// TUPLE_DOT_2: Begin completions, 3 items
+// TUPLE_DOT_2-NEXT: Keyword[self]/CurrNominal: self[#(foo: Int, bar: Double)#]; name=self
// TUPLE_DOT_2-NEXT: Pattern/CurrNominal: foo[#Int#]{{; name=.+$}}
// TUPLE_DOT_2-NEXT: Pattern/CurrNominal: bar[#Double#]{{; name=.+$}}
// TUPLE_DOT_2-NEXT: End completions
@@ -93,7 +98,8 @@
var t = (foo: 1, 2.0)
t.#^TUPLE_DOT_3^#
}
-// TUPLE_DOT_3: Begin completions, 2 items
+// TUPLE_DOT_3: Begin completions, 3 items
+// TUPLE_DOT_3-NEXT: Keyword[self]/CurrNominal: self[#(foo: Int, Double)#]; name=self
// TUPLE_DOT_3-NEXT: Pattern/CurrNominal: foo[#Int#]{{; name=.+$}}
// TUPLE_DOT_3-NEXT: Pattern/CurrNominal: 1[#Double#]{{; name=.+$}}
// TUPLE_DOT_3-NEXT: End completions
@@ -107,7 +113,8 @@
var t = (foo: FooStruct(), i: Int)
t.foo.#^TUPLE_NESTED_1^#
}
-// TUPLE_NESTED_1: Begin completions, 2 items
+// TUPLE_NESTED_1: Begin completions, 3 items
+// TUPLE_NESTED_1-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// TUPLE_NESTED_1-NEXT: Decl[InstanceVar]/CurrNominal: fooInstanceVar[#Int#]{{; name=.+$}}
// TUPLE_NESTED_1-NEXT: Decl[InstanceVar]/CurrNominal: barInstanceVar[#Double#]{{; name=.+$}}
// TUPLE_NESTED_1-NEXT: End completions
diff --git a/test/IDE/complete_from_clang_framework.swift b/test/IDE/complete_from_clang_framework.swift
index 0ff5e6a..e580884 100644
--- a/test/IDE/complete_from_clang_framework.swift
+++ b/test/IDE/complete_from_clang_framework.swift
@@ -44,6 +44,7 @@
func testSwiftCompletions(foo: SwiftStruct) {
foo.#^SWIFT_COMPLETIONS^#
// SWIFT_COMPLETIONS: Begin completions
+// SWIFT_COMPLETIONS-NEXT: Keyword[self]/CurrNominal: self[#SwiftStruct#]; name=self
// SWIFT_COMPLETIONS-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// SWIFT_COMPLETIONS-NEXT: End completions
}
@@ -227,6 +228,7 @@
fooFunc1#^FUNCTION_CALL_1^#
// FUNCTION_CALL_1: Begin completions
// FUNCTION_CALL_1-NEXT: Pattern/CurrModule: ({#(a): Int32#})[#Int32#]{{; name=.+$}}
+// FUNCTION_CALL_1-NEXT: Keyword[self]/CurrNominal: .self[#(Int32) -> Int32#]; name=self
// FUNCTION_CALL_1-NEXT: End completions
}
@@ -234,6 +236,7 @@
fooFunc1AnonymousParam#^FUNCTION_CALL_2^#
// FUNCTION_CALL_2: Begin completions
// FUNCTION_CALL_2-NEXT: Pattern/CurrModule: ({#Int32#})[#Int32#]{{; name=.+$}}
+// FUNCTION_CALL_2-NEXT: Keyword[self]/CurrNominal: .self[#(Int32) -> Int32#]; name=self
// FUNCTION_CALL_2-NEXT: End completions
}
@@ -242,6 +245,7 @@
// CLANG_STRUCT_MEMBERS_1: Begin completions
// CLANG_STRUCT_MEMBERS_1-NEXT: Decl[Constructor]/CurrNominal: ()[#FooStruct1#]{{; name=.+$}}
// CLANG_STRUCT_MEMBERS_1-NEXT: Decl[Constructor]/CurrNominal: ({#x: Int32#}, {#y: Double#})[#FooStruct1#]{{; name=.+$}}
+// CLANG_STRUCT_MEMBERS_1-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct1.Type#]; name=self
// CLANG_STRUCT_MEMBERS_1-NEXT: End completions
}
@@ -267,6 +271,7 @@
// CLANG_CLASS_MEMBERS_1-NEXT: Decl[InstanceMethod]/CurrNominal: .nonInternalMeth({#self: FooClassBase#})[#() -> Any?#]
// CLANG_CLASS_MEMBERS_1-NEXT: Decl[StaticMethod]/CurrNominal: ._internalMeth1()[#Any!#]
// CLANG_CLASS_MEMBERS_1-NEXT: Decl[InstanceMethod]/CurrNominal: ._internalMeth1({#self: FooClassBase#})[#() -> Any?#]
+// CLANG_CLASS_MEMBERS_1-NEXT: Keyword[self]/CurrNominal: .self[#FooClassBase.Type#]; name=self
// CLANG_CLASS_MEMBERS_1-NEXT: End completions
}
@@ -299,6 +304,7 @@
// CLANG_CLASS_MEMBERS_2-NEXT: Decl[InstanceMethod]/Super: .nonInternalMeth({#self: FooClassBase#})[#() -> Any?#]
// CLANG_CLASS_MEMBERS_2-NEXT: Decl[StaticMethod]/Super: ._internalMeth1()[#Any!#]
// CLANG_CLASS_MEMBERS_2-NEXT: Decl[InstanceMethod]/Super: ._internalMeth1({#self: FooClassBase#})[#() -> Any?#]
+// CLANG_CLASS_MEMBERS_2-NEXT: Keyword[self]/CurrNominal: .self[#FooClassDerived.Type#]; name=self
// CLANG_CLASS_MEMBERS_2-NEXT: End completions
}
diff --git a/test/IDE/complete_from_clang_importer_framework.swift b/test/IDE/complete_from_clang_importer_framework.swift
index 3979d7b..1a4fe14 100644
--- a/test/IDE/complete_from_clang_importer_framework.swift
+++ b/test/IDE/complete_from_clang_importer_framework.swift
@@ -59,7 +59,8 @@
func testClangMember1() {
var FS = FooStruct1()
FS.#^CLANG_MEMBER1^#
-// CLANG_MEMBERS1: Begin completions, 2 items
+// CLANG_MEMBERS1: Begin completions, 3 items
// CLANG_MEMBERS1-DAG: Decl[InstanceVar]/CurrNominal/keyword[x, Struct1]/recommended[y]: x[#Int32#]{{; name=.+$}}
// CLANG_MEMBERS1-DAG: Decl[InstanceVar]/CurrNominal/keyword[y, Struct1]/recommendedover[x]: y[#Double#]{{; name=.+$}}
+// CLANG_MEMBERS1-DAG: Keyword[self]/CurrNominal: self[#FooStruct1#]; name=self
}
diff --git a/test/IDE/complete_from_constraint_extensions.swift b/test/IDE/complete_from_constraint_extensions.swift
index 1b91f54..52b91f9 100644
--- a/test/IDE/complete_from_constraint_extensions.swift
+++ b/test/IDE/complete_from_constraint_extensions.swift
@@ -22,7 +22,8 @@
I1.#^CONSTRAINT1^#
}
-// CONSTRAINT1: Begin completions, 1 items
+// CONSTRAINT1: Begin completions, 2 items
+// CONSTRAINT1-NEXT: Keyword[self]/CurrNominal: self[#Example<S1>#]; name=self
// CONSTRAINT1-NEXT: Decl[InstanceMethod]/CurrNominal: P1Method()[#Void#]; name=P1Method()
// CONSTRAINT1-NEXT: End completions
@@ -31,7 +32,8 @@
I2.#^CONSTRAINT2^#
}
-// CONSTRAINT2: Begin completions, 1 items
+// CONSTRAINT2: Begin completions, 2 items
+// CONSTRAINT2-NEXT: Keyword[self]/CurrNominal: self[#Example<S2>#]; name=self
// CONSTRAINT2-NEXT: Decl[InstanceMethod]/CurrNominal: P2Method()[#Void#]; name=P2Method()
// CONSTRAINT2-NEXT: End completions
@@ -48,6 +50,7 @@
func foo3() {
ConcreteCollection<Int>().#^CONSTRAINT3^#
}
-// CONSTRAINT3: Begin completions, 1 items
+// CONSTRAINT3: Begin completions, 2 items
+// CONSTRAINT3-NEXT: Keyword[self]/CurrNominal: self[#ConcreteCollection<Int>#]; name=self
// CONSTRAINT3-NEXT: Decl[InstanceVar]/Super: indices[#MyDefaultIndices<ConcreteCollection<Int>>#]; name=indices
// CONSTRAINT3-NEXT: End completions
diff --git a/test/IDE/complete_from_swift_module.swift b/test/IDE/complete_from_swift_module.swift
index 77794ed..5763610 100644
--- a/test/IDE/complete_from_swift_module.swift
+++ b/test/IDE/complete_from_swift_module.swift
@@ -54,6 +54,7 @@
foo_swift_module.FooSwiftStruct.#^MODULE_QUALIFIED_2^#
}
// MODULE_QUALIFIED_2: Begin completions
+// MODULE_QUALIFIED_2-NEXT: Keyword[self]/CurrNominal: self[#FooSwiftStruct.Type#]; name=self
// MODULE_QUALIFIED_2-NEXT: Decl[InstanceMethod]/CurrNominal: fooInstanceFunc({#self: FooSwiftStruct#})[#() -> Void#]{{; name=.+$}}
// MODULE_QUALIFIED_2-NEXT: Decl[Constructor]/CurrNominal: init()[#FooSwiftStruct#]{{; name=.+$}}
// MODULE_QUALIFIED_2-NEXT: End completions
@@ -72,6 +73,7 @@
// MODULE_QUALIFIED_4: Begin completions
// MODULE_QUALIFIED_4-NEXT: Decl[Constructor]/CurrNominal: ({#t: _#}, {#u: _#})[#BarGenericSwiftStruct2<_, _>#]; name=(t: _, u: _)
// MODULE_QUALIFIED_4-NEXT: Decl[InstanceMethod]/CurrNominal: .bar2InstanceFunc({#self: BarGenericSwiftStruct2<_, _>#})[#() -> Void#]; name=bar2InstanceFunc(BarGenericSwiftStruct2<_, _>)
+// MODULE_QUALIFIED_4-NEXT: Keyword[self]/CurrNominal: .self[#BarGenericSwiftStruct2<_, _>.Type#]; name=self
// MODULE_QUALIFIED_4-NEXT: End completions
func testCompleteModuleQualified5() {
diff --git a/test/IDE/complete_func_body_typechecking.swift b/test/IDE/complete_func_body_typechecking.swift
index 7c4d1d1..8856a9d 100644
--- a/test/IDE/complete_func_body_typechecking.swift
+++ b/test/IDE/complete_func_body_typechecking.swift
@@ -40,6 +40,7 @@
}
// FOO_STRUCT_COMMON: Begin completions
+// FOO_STRUCT_COMMON-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// FOO_STRUCT_COMMON-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// FOO_STRUCT_COMMON-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
// FOO_STRUCT_COMMON-NEXT: Decl[InstanceMethod]/CurrNominal: builderFunc1()[#FooStruct#]{{; name=.+$}}
diff --git a/test/IDE/complete_generic_optional.swift b/test/IDE/complete_generic_optional.swift
index 588760c..b2f7f47 100644
--- a/test/IDE/complete_generic_optional.swift
+++ b/test/IDE/complete_generic_optional.swift
@@ -11,6 +11,7 @@
// SR-642 Code completion does not instantiate generic arguments of a type wrapped in an optional
let x: Foo<Bar>? = Foo<Bar>()
x.#^FOO_OPTIONAL_1^#
-// FOO_OPTIONAL_1: Begin completions, 6 items
+// FOO_OPTIONAL_1: Begin completions, 7 items
// FOO_OPTIONAL_1-DAG: Decl[InstanceMethod]/CurrNominal/Erase[1]: ?.myFunction({#(foobar): Bar#})[#Void#]; name=myFunction(foobar: Bar)
+// FOO_OPTIONAL_1-DAG: Keyword[self]/CurrNominal: self[#Foo<Bar>?#]; name=self
// FOO_OPTIONAL_1: End completions
diff --git a/test/IDE/complete_in_accessors.swift b/test/IDE/complete_in_accessors.swift
index 99ea62a..dd08693 100644
--- a/test/IDE/complete_in_accessors.swift
+++ b/test/IDE/complete_in_accessors.swift
@@ -125,6 +125,7 @@
func returnsInt() -> Int {}
// FOO_OBJECT_DOT: Begin completions
+// FOO_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
// FOO_OBJECT_DOT-NEXT: End completions
diff --git a/test/IDE/complete_in_closures.swift b/test/IDE/complete_in_closures.swift
index 9e4d43c..e41f910 100644
--- a/test/IDE/complete_in_closures.swift
+++ b/test/IDE/complete_in_closures.swift
@@ -64,6 +64,7 @@
}
// FOO_OBJECT_DOT: Begin completions
+// FOO_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
// FOO_OBJECT_DOT-NEXT: End completions
diff --git a/test/IDE/complete_init_inherited.swift b/test/IDE/complete_init_inherited.swift
index f661695..62d650c 100644
--- a/test/IDE/complete_init_inherited.swift
+++ b/test/IDE/complete_init_inherited.swift
@@ -15,6 +15,7 @@
// TEST_A-NEXT: Decl[Constructor]/CurrNominal: ({#int: Int#})[#A#]{{; name=.+$}}
// TEST_A-NEXT: Decl[Constructor]/CurrNominal: ({#double: Double#})[#A#]{{; name=.+$}}
// TEST_A-NEXT: Decl[Constructor]/CurrNominal: ({#float: Float#})[#A#]{{; name=.+$}}
+// TEST_A-NEXT: Keyword[self]/CurrNominal: .self[#A.Type#]; name=self
// TEST_A-NEXT: End completions
class B : A {
@@ -27,6 +28,7 @@
// TEST_B-NEXT: Decl[Constructor]/CurrNominal: ({#int: Int#})[#B#]{{; name=.+$}}
// TEST_B-NEXT: Decl[Constructor]/CurrNominal: ({#double: Double#})[#B#]{{; name=.+$}}
// TEST_B-NEXT: Decl[Constructor]/Super: ({#float: Float#})[#A#]{{; name=.+$}}
+// TEST_B-NEXT: Keyword[self]/CurrNominal: .self[#B.Type#]; name=self
// TEST_B-NEXT: End completions
class C : B {
@@ -42,6 +44,7 @@
// TEST_C: Begin completions
// TEST_C-NEXT: Decl[Constructor]/CurrNominal: ({#int: Int#})[#C#]{{; name=.+$}}
// TEST_C-NEXT: Decl[Constructor]/CurrNominal: ({#c: C#})[#C#]{{; name=.+$}}
+// TEST_C-NEXT: Keyword[self]/CurrNominal: .self[#C.Type#]; name=self
// TEST_C-NEXT: End completions
class D : C {
@@ -59,6 +62,7 @@
// TEST_D-NEXT: Decl[Constructor]/CurrNominal: ({#d: D#})[#D#]{{; name=.+$}}
// TEST_D-NEXT: Decl[Constructor]/CurrNominal: ({#int: Int#})[#D#]{{; name=.+$}}
// TEST_D-NEXT: Decl[Constructor]/Super: ({#c: C#})[#C#]{{; name=.+$}}
+// TEST_D-NEXT: Keyword[self]/CurrNominal: .self[#D.Type#]; name=self
// TEST_D-NEXT: End completions
func testA() {
diff --git a/test/IDE/complete_lazy_initialized_var.swift b/test/IDE/complete_lazy_initialized_var.swift
index b287a40..d77b6f6 100644
--- a/test/IDE/complete_lazy_initialized_var.swift
+++ b/test/IDE/complete_lazy_initialized_var.swift
@@ -8,6 +8,7 @@
}
// This test checks that we don't include extra hidden declarations into code completion results. If you add more declarations to the type, update this test properly.
-// LAZYVAR1: Begin completions, 1 items
+// LAZYVAR1: Begin completions, 2 items
+// LAZYVAR1-NEXT: Keyword[self]/CurrNominal: self[#FooClass1#]; name=self
// LAZYVAR1-NEXT: Decl[InstanceVar]/CurrNominal: lazyVar1[#Int#]{{; name=.+$}}
// LAZYVAR1-NEXT: End completions
diff --git a/test/IDE/complete_member_decls_from_parent_decl_context.swift b/test/IDE/complete_member_decls_from_parent_decl_context.swift
index 9d3ffb8..fa70353 100644
--- a/test/IDE/complete_member_decls_from_parent_decl_context.swift
+++ b/test/IDE/complete_member_decls_from_parent_decl_context.swift
@@ -324,11 +324,12 @@
// NESTED_NOMINAL_DECL_A_4: End completions
NestedInnerA(aInstanceVar: 42)#^NESTED_NOMINAL_DECL_A_5^#
-// NESTED_NOMINAL_DECL_A_5: Begin completions, 4 items
+// NESTED_NOMINAL_DECL_A_5: Begin completions, 5 items
// NESTED_NOMINAL_DECL_A_5-NEXT: Decl[InstanceMethod]/CurrNominal: .aTestInstanceFunc()[#Void#]{{; name=.+$}}
// NESTED_NOMINAL_DECL_A_5-NEXT: Decl[InstanceVar]/CurrNominal: .aInstanceVar[#Int#]{{; name=.+$}}
// NESTED_NOMINAL_DECL_A_5-NEXT: Decl[InstanceMethod]/CurrNominal: .aInstanceFunc()[#Void#]{{; name=.+$}}
// NESTED_NOMINAL_DECL_A_5-NEXT: Decl[Subscript]/CurrNominal: [{#Int#}][#Double#]{{; name=.+$}}
+// NESTED_NOMINAL_DECL_A_5-NEXT: Keyword[self]/CurrNominal: .self[#NestedInnerA#]; name=self
// NESTED_NOMINAL_DECL_A_5-NEXT: End completions
}
@@ -433,11 +434,12 @@
// NESTED_NOMINAL_DECL_B_4: End completions
NestedInnerB(bInstanceVar: 42)#^NESTED_NOMINAL_DECL_B_5^#
-// NESTED_NOMINAL_DECL_B_5: Begin completions, 4 items
+// NESTED_NOMINAL_DECL_B_5: Begin completions, 5 items
// NESTED_NOMINAL_DECL_B_5-DAG: Decl[InstanceMethod]/CurrNominal: .bTestInstanceFunc()[#Void#]{{; name=.+$}}
// NESTED_NOMINAL_DECL_B_5-DAG: Decl[InstanceVar]/CurrNominal: .bInstanceVar[#Int#]{{; name=.+$}}
// NESTED_NOMINAL_DECL_B_5-DAG: Decl[InstanceMethod]/CurrNominal: .bInstanceFunc()[#Void#]{{; name=.+$}}
// NESTED_NOMINAL_DECL_B_5-DAG: Decl[Subscript]/CurrNominal: [{#Int#}][#Double#]{{; name=.+$}}
+// NESTED_NOMINAL_DECL_B_5-DAG: Keyword[self]/CurrNominal: .self[#NestedInnerB#]; name=self
// NESTED_NOMINAL_DECL_B_5: End completions
}
@@ -524,11 +526,12 @@
// NESTED_NOMINAL_DECL_C_4: End completions
NestedInnerC(cInstanceVar: 42)#^NESTED_NOMINAL_DECL_C_5^#
-// NESTED_NOMINAL_DECL_C_5: Begin completions, 4 items
+// NESTED_NOMINAL_DECL_C_5: Begin completions, 5 items
// NESTED_NOMINAL_DECL_C_5-NEXT: Decl[InstanceMethod]/CurrNominal: .cTestInstanceFunc()[#Void#]{{; name=.+$}}
// NESTED_NOMINAL_DECL_C_5-NEXT: Decl[InstanceVar]/CurrNominal: .cInstanceVar[#Int#]{{; name=.+$}}
// NESTED_NOMINAL_DECL_C_5-NEXT: Decl[InstanceMethod]/CurrNominal: .cInstanceFunc()[#Void#]{{; name=.+$}}
// NESTED_NOMINAL_DECL_C_5-NEXT: Decl[Subscript]/CurrNominal: [{#Int#}][#Double#]{{; name=.+$}}
+// NESTED_NOMINAL_DECL_C_5-NEXT: Keyword[self]/CurrNominal: .self[#NestedInnerC#]; name=self
// NESTED_NOMINAL_DECL_C_5-NEXT: End completions
}
diff --git a/test/IDE/complete_members_optional.swift b/test/IDE/complete_members_optional.swift
index f03b539..2cf8ba4 100644
--- a/test/IDE/complete_members_optional.swift
+++ b/test/IDE/complete_members_optional.swift
@@ -28,16 +28,18 @@
func optionalMembers1(_ a: HasOptionalMembers1) {
a.#^OPTIONAL_MEMBERS_1^#
}
-// OPTIONAL_MEMBERS_1: Begin completions, 2 items
+// OPTIONAL_MEMBERS_1: Begin completions, 3 items
// OPTIONAL_MEMBERS_1-DAG: Decl[InstanceMethod]/CurrNominal: optionalInstanceFunc!()[#Int#]{{; name=.+$}}
// OPTIONAL_MEMBERS_1-DAG: Decl[InstanceVar]/CurrNominal: optionalInstanceProperty[#Int?#]{{; name=.+$}}
+// OPTIONAL_MEMBERS_1-DAG: Keyword[self]/CurrNominal: self[#HasOptionalMembers1#]; name=self
// OPTIONAL_MEMBERS_1: End completions
func optionalMembers2<T : HasOptionalMembers1>(_ a: T) {
T.#^OPTIONAL_MEMBERS_2^#
}
-// OPTIONAL_MEMBERS_2: Begin completions, 3 items
+// OPTIONAL_MEMBERS_2: Begin completions, 4 items
// OPTIONAL_MEMBERS_2-DAG: Decl[InstanceMethod]/Super: optionalInstanceFunc!({#self: HasOptionalMembers1#})[#() -> Int#]{{; name=.+$}}
// OPTIONAL_MEMBERS_2-DAG: Decl[StaticMethod]/Super: optionalClassFunc!()[#Int#]{{; name=.+$}}
// OPTIONAL_MEMBERS_2-DAG: Decl[StaticVar]/Super: optionalClassProperty[#Int?#]{{; name=.+$}}
+// OPTIONAL_MEMBERS_2-DAG: Keyword[self]/CurrNominal: self[#T.Type#]; name=self
// OPTIONAL_MEMBERS_2: End completions
diff --git a/test/IDE/complete_multiple_files.swift b/test/IDE/complete_multiple_files.swift
index 484edc7..8ee8999 100644
--- a/test/IDE/complete_multiple_files.swift
+++ b/test/IDE/complete_multiple_files.swift
@@ -13,6 +13,7 @@
fooObject.#^T1^#
}
// T1: Begin completions
+// T1-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// T1-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// T1-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
//
@@ -24,6 +25,7 @@
genericFooObject.#^T2^#
}
// T2: Begin completions
+// T2-NEXT: Keyword[self]/CurrNominal: self[#GenericFooStruct<Void>#]; name=self
// T2-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// T2-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
//
diff --git a/test/IDE/complete_name_lookup.swift b/test/IDE/complete_name_lookup.swift
index 3319439..c900379 100644
--- a/test/IDE/complete_name_lookup.swift
+++ b/test/IDE/complete_name_lookup.swift
@@ -15,6 +15,7 @@
var instanceProperty: Int { return 0 }
}
// FOO_OBJECT_DOT: Begin completions
+// FOO_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal: instanceProperty[#Int#]
// FOO_OBJECT_DOT-NEXT: End completions
@@ -22,6 +23,7 @@
var instanceProperty: Int { return 0 }
}
// BAR_OBJECT_DOT: Begin completions
+// BAR_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#BarStruct#]; name=self
// BAR_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal: instanceProperty[#Int#]
// BAR_OBJECT_DOT-NEXT: End completions
diff --git a/test/IDE/complete_not_recommended.swift b/test/IDE/complete_not_recommended.swift
index e90b7e4..a8d0697 100644
--- a/test/IDE/complete_not_recommended.swift
+++ b/test/IDE/complete_not_recommended.swift
@@ -1,5 +1,6 @@
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=MEMBER | %FileCheck %s -check-prefix=CHECK1
-// CHECK1: Begin completions, 2 items
+// CHECK1: Begin completions, 3 items
+// CHECK1: Keyword[self]/CurrNominal: self[#A.Type#]; name=self
// CHECK1: Decl[InstanceMethod]/CurrNominal: foo({#self: A#})[#() -> Void#]
// CHECK1: Decl[Constructor]/CurrNominal: init()[#A#]; name=init(){{$}}
// CHECK1: End completions
diff --git a/test/IDE/complete_operators.swift b/test/IDE/complete_operators.swift
index 0aec8db..a4c2159 100644
--- a/test/IDE/complete_operators.swift
+++ b/test/IDE/complete_operators.swift
@@ -119,7 +119,8 @@
func testPostfix8(x: S) {
x#^POSTFIX_8^#
}
-// POSTFIX_8-NOT: ***
+// POSTFIX_8: Begin completions
+// POSTFIX_8: Keyword[self]/CurrNominal: .self[#S#]; name=self
protocol P {
associatedtype T
@@ -250,16 +251,18 @@
S2#^INFIX_11^#
}
-// INFIX_11: Begin completions, 1 items
+// INFIX_11: Begin completions, 2 items
// INFIX_11-DAG: Decl[Constructor]/CurrNominal: ()[#S2#]; name=()
+// INFIX_11-DAG: Keyword[self]/CurrNominal: .self[#S2.Type#]; name=self
// INFIX_11: End completions
func testInfix12() {
P#^INFIX_12^#
}
-// INFIX_12: Begin completions, 2 items
+// INFIX_12: Begin completions, 3 items
// INFIX_12-NEXT: Decl[AssociatedType]/CurrNominal: .T; name=T
// INFIX_12-NEXT: Decl[InstanceMethod]/CurrNominal: .foo({#self: P#})[#() -> P.T#]; name=foo(P)
+// INFIX_12-NEXT: Keyword[self]/CurrNominal: .self[#P.Protocol#]; name=self
// INFIX_12: End completions
func testInfix13() {
@@ -273,17 +276,19 @@
func testInfix15<T: P where T.T == S2>() {
T#^INFIX_15^#
}
-// INFIX_15: Begin completions, 2 items
+// INFIX_15: Begin completions, 3 items
// INFIX_15-NEXT: Decl[AssociatedType]/Super: .T; name=T
// INFIX_15-NEXT: Decl[InstanceMethod]/Super: .foo({#self: P#})[#() -> S2#]; name=foo(P)
+// INFIX_15-NEXT: Keyword[self]/CurrNominal: .self[#T.Type#]; name=self
// INFIX_15: End completions
func testInfix16<T: P where T.T == S2>() {
T.foo#^INFIX_16^#
}
-// INFIX_16: Begin completions, 1 items
+// INFIX_16: Begin completions, 2 items
// INFIX_16-NEXT: Pattern/CurrModule: ({#(self): T#})[#() -> S2#]; name=(self: T)
+// INFIX_16-NEXT: Keyword[self]/CurrNominal: .self[#(T) -> () -> S2#]; name=self
// INFIX_16: End completions
func testInfix17(x: Void) {
@@ -325,7 +330,7 @@
func testInfix22() {
E.B#^INFIX_22^#
}
-// INFIX_22: Begin completions, 1 items
+// INFIX_22: Begin completions, 2 items
// INFIX_22-NEXT: Pattern/CurrModule: ({#S2#})[#E#]; name=(S2)
// INFIX_22: End completions
diff --git a/test/IDE/complete_overridden_decls.swift b/test/IDE/complete_overridden_decls.swift
index 6927e4c..1decf28 100644
--- a/test/IDE/complete_overridden_decls.swift
+++ b/test/IDE/complete_overridden_decls.swift
@@ -54,6 +54,7 @@
b.#^OVER_BASE_1^#
}
// OVER_BASE_1: Begin completions
+// OVER_BASE_1-NEXT: Keyword[self]/CurrNominal: self[#TestABase#]; name=self
// OVER_BASE_1-NEXT: Decl[InstanceVar]/CurrNominal: baseInstanceVar[#FooBase#]{{; name=.+$}}
// OVER_BASE_1-NEXT: Decl[InstanceVar]/CurrNominal: baseOverInstanceVar[#FooBase#]{{; name=.+$}}
// OVER_BASE_1-NEXT: Decl[InstanceMethod]/CurrNominal: baseOverFunc()[#Void#]{{; name=.+$}}
@@ -65,6 +66,7 @@
d.#^OVER_DERIVED_1^#
}
// OVER_DERIVED_1: Begin completions
+// OVER_DERIVED_1-NEXT: Keyword[self]/CurrNominal: self[#TestADerived#]; name=self
// OVER_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal: derivedInstanceVar[#FooBase#]{{; name=.+$}}
// OVER_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal: baseOverInstanceVar[#FooDerived#]{{; name=.+$}}
// OVER_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal: derivedOverInstanceVar[#FooBase#]{{; name=.+$}}
@@ -78,6 +80,7 @@
md.#^OVER_MORE_DERIVED_1^#
}
// OVER_MORE_DERIVED_1: Begin completions
+// OVER_MORE_DERIVED_1-NEXT: Keyword[self]/CurrNominal: self[#TestAMoreDerived#]; name=self
// OVER_MORE_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal: moreDerivedInstanceVar[#FooBase#]{{; name=.+$}}
// OVER_MORE_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal: baseOverInstanceVar[#FooMoreDerived#]{{; name=.+$}}
// OVER_MORE_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal: derivedOverInstanceVar[#FooDerived#]{{; name=.+$}}
diff --git a/test/IDE/complete_return.swift b/test/IDE/complete_return.swift
index 8252086..bc33e3a 100644
--- a/test/IDE/complete_return.swift
+++ b/test/IDE/complete_return.swift
@@ -54,6 +54,7 @@
func testReturnInt2(_ fooObject: FooStruct) {
return fooObject.#^RETURN_INT_2^#
// RETURN_INT_2: Begin completions
+// RETURN_INT_2-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// RETURN_INT_2-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// RETURN_INT_2-NEXT: End completions
}
diff --git a/test/IDE/complete_stdlib_optional.swift b/test/IDE/complete_stdlib_optional.swift
index 6712c74..22c12aa 100644
--- a/test/IDE/complete_stdlib_optional.swift
+++ b/test/IDE/complete_stdlib_optional.swift
@@ -135,9 +135,11 @@
// OBJCCLASS_MEMBERS_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc()[#ObjcClass#]
// OBJCCLASS_MEMBERS_NO_DOT-NEXT: Decl[InfixOperatorFunction]/OtherModule[Swift]: === {#AnyObject?#}[#Bool#]
// OBJCCLASS_MEMBERS_NO_DOT-NEXT: Decl[InfixOperatorFunction]/OtherModule[Swift]: !== {#AnyObject?#}[#Bool#]
+// OBJCCLASS_MEMBERS_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#ObjcClass#]; name=self
// OBJCCLASS_MEMBERS_NO_DOT-NEXT: End completions
// OBJCCLASS_MEMBERS_DOT: Begin completions
+// OBJCCLASS_MEMBERS_DOT-NEXT: Keyword[self]/CurrNominal: self[#ObjcClass#]; name=self
// OBJCCLASS_MEMBERS_DOT-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]
// OBJCCLASS_MEMBERS_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc()[#ObjcClass#]
// OBJCCLASS_MEMBERS_DOT-NEXT: End completions
diff --git a/test/IDE/complete_unicode.swift b/test/IDE/complete_unicode.swift
index c5228d5..560dbee 100644
--- a/test/IDE/complete_unicode.swift
+++ b/test/IDE/complete_unicode.swift
@@ -15,6 +15,7 @@
Unicode1().#^UNICODE_1^#
}
// UNICODE_1: Begin completions
+// UNICODE_1-NEXT: Keyword[self]/CurrNominal: self[#Unicode1#]; name=self
// UNICODE_1-NEXT: Decl[InstanceMethod]/CurrNominal: Идентификаторы_с_кириллицей_допустимы()[#Void#]{{; name=.+$}}
// UNICODE_1-NEXT: Decl[InstanceMethod]/CurrNominal: Ідентіфікатори_українською_також_працюють()[#Void#]{{; name=.+$}}
// UNICODE_1-NEXT: Decl[InstanceMethod]/CurrNominal: 識別子は()[#Void#]{{; name=.+$}}
diff --git a/test/IDE/complete_value_expr.swift b/test/IDE/complete_value_expr.swift
index 3295371..fbfbbdb 100644
--- a/test/IDE/complete_value_expr.swift
+++ b/test/IDE/complete_value_expr.swift
@@ -295,6 +295,7 @@
var fooObject: FooStruct
// FOO_OBJECT_DOT: Begin completions
+// FOO_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal: lazyInstanceVar[#Int#]{{; name=.+$}}
// FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
@@ -361,9 +362,11 @@
// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceVar]/CurrNominal: .extProp[#Int#]{{; name=.+$}}
// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .extFunc0()[#Void#]{{; name=.+$}}
// FOO_OBJECT_NO_DOT-NEXT: BuiltinOperator/None: = {#Foo
+// FOO_OBJECT_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct#]; name=self
// FOO_OBJECT_NO_DOT-NEXT: End completions
// FOO_STRUCT_DOT: Begin completions
+// FOO_STRUCT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct.Type#]; name=self
// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0({#self: &FooStruct#})[#() -> Void#]{{; name=.+$}}
// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc1({#self: &FooStruct#})[#(Int) -> Void#]{{; name=.+$}}
// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc2({#self: &FooStruct#})[#(Int, b: inout Double) -> Void#]{{; name=.+$}}
@@ -455,6 +458,7 @@
// FOO_STRUCT_NO_DOT-NEXT: Decl[Class]/CurrNominal: .ExtNestedClass[#FooStruct.ExtNestedClass#]{{; name=.+$}}
// FOO_STRUCT_NO_DOT-NEXT: Decl[Enum]/CurrNominal: .ExtNestedEnum[#FooStruct.ExtNestedEnum#]{{; name=.+$}}
// FOO_STRUCT_NO_DOT-NEXT: Decl[TypeAlias]/CurrNominal: .ExtNestedTypealias[#Int#]{{; name=.+$}}
+// FOO_STRUCT_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct.Type#]; name=self
// FOO_STRUCT_NO_DOT-NEXT: End completions
func testObjectExpr() {
@@ -501,31 +505,37 @@
FooStruct.instanceFunc0(&fs)#^IMPLICITLY_CURRIED_FUNC_0^#
// IMPLICITLY_CURRIED_FUNC_0: Begin completions
// IMPLICITLY_CURRIED_FUNC_0-NEXT: Pattern/CurrModule: ()[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_FUNC_0-NEXT: Keyword[self]/CurrNominal: .self[#() -> ()#]; name=self
// IMPLICITLY_CURRIED_FUNC_0-NEXT: End completions
FooStruct.instanceFunc1(&fs)#^IMPLICITLY_CURRIED_FUNC_1^#
// IMPLICITLY_CURRIED_FUNC_1: Begin completions
// IMPLICITLY_CURRIED_FUNC_1-NEXT: Pattern/CurrModule: ({#(a): Int#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_FUNC_1-NEXT: Keyword[self]/CurrNominal: .self[#(Int) -> ()#]; name=self
// IMPLICITLY_CURRIED_FUNC_1-NEXT: End completions
FooStruct.instanceFunc2(&fs)#^IMPLICITLY_CURRIED_FUNC_2^#
// IMPLICITLY_CURRIED_FUNC_2: Begin completions
// IMPLICITLY_CURRIED_FUNC_2-NEXT: Pattern/CurrModule: ({#(a): Int#}, {#b: &Double#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_FUNC_2-NEXT: Keyword[self]/CurrNominal: .self[#(Int, inout Double) -> ()#]; name=self
// IMPLICITLY_CURRIED_FUNC_2-NEXT: End completions
FooStruct.varargInstanceFunc0(&fs)#^IMPLICITLY_CURRIED_VARARG_FUNC_0^#
// IMPLICITLY_CURRIED_VARARG_FUNC_0: Begin completions
// IMPLICITLY_CURRIED_VARARG_FUNC_0-NEXT: Pattern/CurrModule: ({#(v): Int...#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_VARARG_FUNC_0-NEXT: Keyword[self]/CurrNominal: .self[#(Int...) -> ()#]; name=self
// IMPLICITLY_CURRIED_VARARG_FUNC_0-NEXT: End completions
FooStruct.varargInstanceFunc1(&fs)#^IMPLICITLY_CURRIED_VARARG_FUNC_1^#
// IMPLICITLY_CURRIED_VARARG_FUNC_1: Begin completions
// IMPLICITLY_CURRIED_VARARG_FUNC_1-NEXT: Pattern/CurrModule: ({#(a): Float#}, {#v: Int...#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_VARARG_FUNC_1-NEXT: Keyword[self]/CurrNominal: .self[#(Float, Int...) -> ()#]; name=self
// IMPLICITLY_CURRIED_VARARG_FUNC_1-NEXT: End completions
FooStruct.varargInstanceFunc2(&fs)#^IMPLICITLY_CURRIED_VARARG_FUNC_2^#
// IMPLICITLY_CURRIED_VARARG_FUNC_2: Begin completions
// IMPLICITLY_CURRIED_VARARG_FUNC_2-NEXT: Pattern/CurrModule: ({#(a): Float#}, {#b: Double#}, {#v: Int...#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_VARARG_FUNC_2-NEXT: Keyword[self]/CurrNominal: .self[#(Float, Double, Int...) -> ()#]; name=self
// IMPLICITLY_CURRIED_VARARG_FUNC_2-NEXT: End completions
// This call is ambiguous, and the expression is invalid.
@@ -798,12 +808,14 @@
// VF1: Begin completions
// VF1-NEXT: Pattern/CurrModule: ()[#Double#]{{; name=.+$}}
// VF1-NEXT: BuiltinOperator/None: = {#() -> Double##() -> Double#}[#Void#]
+// VF1-NEXT: Keyword[self]/CurrNominal: .self[#() -> Double#]; name=self
// VF1-NEXT: End completions
funcTypeVarsObject.funcVar2#^VF2^#
// VF2: Begin completions
// VF2-NEXT: Pattern/CurrModule: ({#Int#})[#Double#]{{; name=.+$}}
// VF2-NEXT: BuiltinOperator/None: = {#(Int) -> Double##(Int) -> Double#}[#Void#]
+// VF2-NEXT: Keyword[self]/CurrNominal: .self[#(Int) -> Double#]; name=self
// VF2-NEXT: End completions
}
@@ -825,6 +837,7 @@
func testLookInBase() {
membersDerived.#^BASE_MEMBERS^#
// BASE_MEMBERS: Begin completions
+// BASE_MEMBERS-DAG: Keyword[self]/CurrNominal: self[#MembersDerived#]; name=self
// BASE_MEMBERS-NEXT: Decl[InstanceVar]/CurrNominal: derivedVar[#Int#]{{; name=.+$}}
// BASE_MEMBERS-NEXT: Decl[InstanceMethod]/CurrNominal: derivedInstanceFunc()[#Void#]{{; name=.+$}}
// BASE_MEMBERS-NEXT: Decl[InstanceVar]/Super: baseVar[#Int#]{{; name=.+$}}
@@ -835,6 +848,7 @@
func testLookInBaseStatic() {
MembersDerived.#^BASE_MEMBERS_STATIC^#
// BASE_MEMBERS_STATIC: Begin completions
+// BASE_MEMBERS_STATIC-NEXT: Keyword[self]/CurrNominal: self[#MembersDerived.Type#]; name=self
// BASE_MEMBERS_STATIC-NEXT: Decl[InstanceMethod]/CurrNominal: derivedInstanceFunc({#self: MembersDerived#})[#() -> Void#]{{; name=.+$}}
// BASE_MEMBERS_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: derivedStaticFunc()[#Void#]{{; name=.+$}}
// BASE_MEMBERS_STATIC-NEXT: Decl[Constructor]/CurrNominal: init()[#MembersDerived#]; name=init(){{$}}
@@ -853,6 +867,7 @@
// PROTO_MEMBERS_NO_DOT_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooInstanceFunc0()[#Double#]{{; name=.+$}}
// PROTO_MEMBERS_NO_DOT_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
// PROTO_MEMBERS_NO_DOT_1-NEXT: Decl[Subscript]/CurrNominal: [{#Int#}][#Double#]{{; name=.+$}}
+// PROTO_MEMBERS_NO_DOT_1-NEXT: Keyword[self]/CurrNominal: .self[#FooProtocol#]; name=self
// PROTO_MEMBERS_NO_DOT_1-NEXT: End completions
}
@@ -867,6 +882,7 @@
// PROTO_MEMBERS_NO_DOT_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooInstanceFunc0()[#Double#]{{; name=.+$}}
// PROTO_MEMBERS_NO_DOT_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
// PROTO_MEMBERS_NO_DOT_2-NEXT: Decl[Subscript]/CurrNominal: [{#Int#}][#Double#]{{; name=.+$}}
+// PROTO_MEMBERS_NO_DOT_2-NEXT: Keyword[self]/CurrNominal: .self[#BarProtocol & FooProtocol#]; name=self
// PROTO_MEMBERS_NO_DOT_2-NEXT: End completions
}
@@ -883,12 +899,14 @@
// PROTO_MEMBERS_NO_DOT_3-NEXT: Decl[InstanceMethod]/Super: .fooInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
// PROTO_MEMBERS_NO_DOT_3-NEXT: Decl[Subscript]/Super: [{#Int#}][#Double#]{{; name=.+$}}
// PROTO_MEMBERS_NO_DOT_3-NEXT: Decl[InstanceMethod]/CurrNominal: .fooExInstanceFunc0()[#Double#]{{; name=.+$}}
+// PROTO_MEMBERS_NO_DOT_3-NEXT: Keyword[self]/CurrNominal: .self[#BarExProtocol & FooExProtocol#]; name=self
// PROTO_MEMBERS_NO_DOT_3-NEXT: End completions
}
func testLookInProto1() {
fooProtocolInstance.#^PROTO_MEMBERS_1^#
// PROTO_MEMBERS_1: Begin completions
+// PROTO_MEMBERS_1-NEXT: Keyword[self]/CurrNominal: self[#FooProtocol#]; name=self
// PROTO_MEMBERS_1-NEXT: Decl[InstanceVar]/CurrNominal: fooInstanceVar1[#Int#]{{; name=.+$}}
// PROTO_MEMBERS_1-NEXT: Decl[InstanceVar]/CurrNominal: fooInstanceVar2[#Int#]{{; name=.+$}}
// PROTO_MEMBERS_1-NEXT: Decl[InstanceMethod]/CurrNominal: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -899,6 +917,7 @@
func testLookInProto2() {
fooBarProtocolInstance.#^PROTO_MEMBERS_2^#
// PROTO_MEMBERS_2: Begin completions
+// PROTO_MEMBERS_2-NEXT: Keyword[self]/CurrNominal: self[#BarProtocol & FooProtocol#]; name=self
// PROTO_MEMBERS_2-NEXT: Decl[InstanceVar]/CurrNominal: barInstanceVar[#Int#]{{; name=.+$}}
// PROTO_MEMBERS_2-NEXT: Decl[InstanceMethod]/CurrNominal: barInstanceFunc0()[#Double#]{{; name=.+$}}
// PROTO_MEMBERS_2-NEXT: Decl[InstanceMethod]/CurrNominal: barInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
@@ -912,6 +931,7 @@
func testLookInProto3() {
fooExBarExProtocolInstance.#^PROTO_MEMBERS_3^#
// PROTO_MEMBERS_3: Begin completions
+// PROTO_MEMBERS_3-NEXT: Keyword[self]/CurrNominal: self[#BarExProtocol & FooExProtocol#]; name=self
// PROTO_MEMBERS_3-NEXT: Decl[InstanceVar]/Super: barInstanceVar[#Int#]{{; name=.+$}}
// PROTO_MEMBERS_3-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc0()[#Double#]{{; name=.+$}}
// PROTO_MEMBERS_3-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
@@ -948,6 +968,7 @@
func testResolveFuncParam3<Foo : FooProtocol>(_ foo: Foo) {
foo.#^RESOLVE_FUNC_PARAM_3^#
// RESOLVE_FUNC_PARAM_3: Begin completions
+// RESOLVE_FUNC_PARAM_3-NEXT: Keyword[self]/CurrNominal: self[#Foo#]; name=self
// RESOLVE_FUNC_PARAM_3-NEXT: Decl[InstanceVar]/Super: fooInstanceVar1[#Int#]{{; name=.+$}}
// RESOLVE_FUNC_PARAM_3-NEXT: Decl[InstanceVar]/Super: fooInstanceVar2[#Int#]{{; name=.+$}}
// RESOLVE_FUNC_PARAM_3-NEXT: Decl[InstanceMethod]/Super: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -958,6 +979,7 @@
func testResolveFuncParam4<FooBar : FooProtocol & BarProtocol>(_ fooBar: FooBar) {
fooBar.#^RESOLVE_FUNC_PARAM_4^#
// RESOLVE_FUNC_PARAM_4: Begin completions
+// RESOLVE_FUNC_PARAM_4-NEXT: Keyword[self]/CurrNominal: self[#FooBar#]; name=self
// RESOLVE_FUNC_PARAM_4-NEXT: Decl[InstanceVar]/Super: barInstanceVar[#Int#]{{; name=.+$}}
// RESOLVE_FUNC_PARAM_4-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc0()[#Double#]{{; name=.+$}}
// RESOLVE_FUNC_PARAM_4-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
@@ -971,6 +993,7 @@
func testResolveFuncParam5<FooExBarEx : FooExProtocol & BarExProtocol>(_ a: FooExBarEx) {
a.#^RESOLVE_FUNC_PARAM_5^#
// RESOLVE_FUNC_PARAM_5: Begin completions
+// RESOLVE_FUNC_PARAM_5-NEXT: Keyword[self]/CurrNominal: self[#FooExBarEx#]; name=self
// RESOLVE_FUNC_PARAM_5-NEXT: Decl[InstanceVar]/Super: barInstanceVar[#Int#]{{; name=.+$}}
// RESOLVE_FUNC_PARAM_5-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc0()[#Double#]{{; name=.+$}}
// RESOLVE_FUNC_PARAM_5-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
@@ -986,6 +1009,7 @@
func testResolveFuncParam6<Foo : FooProtocol where Foo : FooClass>(_ foo: Foo) {
foo.#^RESOLVE_FUNC_PARAM_6^#
// RESOLVE_FUNC_PARAM_6: Begin completions
+// RESOLVE_FUNC_PARAM_6-NEXT: Keyword[self]/CurrNominal: self[#Foo#]; name=self
// RESOLVE_FUNC_PARAM_6-NEXT: Decl[InstanceVar]/Super: fooInstanceVar1[#Int#]{{; name=.+$}}
// RESOLVE_FUNC_PARAM_6-NEXT: Decl[InstanceVar]/Super: fooInstanceVar2[#Int#]{{; name=.+$}}
// RESOLVE_FUNC_PARAM_6-NEXT: Decl[InstanceMethod]/Super: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -1006,6 +1030,7 @@
init<Foo : FooProtocol>(foo: Foo) {
foo.#^RESOLVE_CONSTRUCTOR_PARAM_2^#
// RESOLVE_CONSTRUCTOR_PARAM_2: Begin completions
+// RESOLVE_CONSTRUCTOR_PARAM_2-NEXT: Keyword[self]/CurrNominal: self[#Foo#]; name=self
// RESOLVE_CONSTRUCTOR_PARAM_2-NEXT: Decl[InstanceVar]/Super: fooInstanceVar1[#Int#]{{; name=.+$}}
// RESOLVE_CONSTRUCTOR_PARAM_2-NEXT: Decl[InstanceVar]/Super: fooInstanceVar2[#Int#]{{; name=.+$}}
// RESOLVE_CONSTRUCTOR_PARAM_2-NEXT: Decl[InstanceMethod]/Super: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -1018,6 +1043,7 @@
init(foo: Foo) {
foo.#^RESOLVE_CONSTRUCTOR_PARAM_3^#
// RESOLVE_CONSTRUCTOR_PARAM_3: Begin completions
+// RESOLVE_CONSTRUCTOR_PARAM_3-NEXT: Keyword[self]/CurrNominal: self[#Foo#]; name=self
// RESOLVE_CONSTRUCTOR_PARAM_3-NEXT: Decl[InstanceVar]/Super: fooInstanceVar1[#Int#]{{; name=.+$}}
// RESOLVE_CONSTRUCTOR_PARAM_3-NEXT: Decl[InstanceVar]/Super: fooInstanceVar2[#Int#]{{; name=.+$}}
// RESOLVE_CONSTRUCTOR_PARAM_3-NEXT: Decl[InstanceMethod]/Super: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -1047,6 +1073,7 @@
// FUNC_PAREN_PATTERN_1: Begin completions
// FUNC_PAREN_PATTERN_1-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#Int#})[#Void#]{{; name=.+$}}
// FUNC_PAREN_PATTERN_1-NEXT: Decl[Subscript]/CurrNominal: [{#Int#}][#Int#]{{; name=.+$}}
+// FUNC_PAREN_PATTERN_1-NEXT: Keyword[self]/CurrNominal: .self[#FuncParenPattern#]; name=self
// FUNC_PAREN_PATTERN_1-NEXT: End completions
}
@@ -1056,6 +1083,7 @@
// FUNC_PAREN_PATTERN_2-NEXT: Decl[Constructor]/CurrNominal: ({#Int#})[#FuncParenPattern#]{{; name=.+$}}
// FUNC_PAREN_PATTERN_2-NEXT: Decl[Constructor]/CurrNominal: ({#(Int, Int)#})[#FuncParenPattern#]{{; name=.+$}}
// FUNC_PAREN_PATTERN_2-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#self: &FuncParenPattern#})[#(Int) -> Void#]{{; name=.+$}}
+// FUNC_PAREN_PATTERN_2-NEXT: Keyword[self]/CurrNominal: .self[#FuncParenPattern.Type#]; name=self
// FUNC_PAREN_PATTERN_2-NEXT: End completions
}
@@ -1063,6 +1091,7 @@
fpp.instanceFunc#^FUNC_PAREN_PATTERN_3^#
// FUNC_PAREN_PATTERN_3: Begin completions
// FUNC_PAREN_PATTERN_3-NEXT: Pattern/CurrModule: ({#Int#})[#Void#]{{; name=.+$}}
+// FUNC_PAREN_PATTERN_3-NEXT: Keyword[self]/CurrNominal: .self[#(Int) -> ()#]; name=self
// FUNC_PAREN_PATTERN_3-NEXT: End completions
}
@@ -1081,6 +1110,7 @@
// CHAINED_CALLS_1-DAG: Decl[InstanceMethod]/CurrNominal: .doFoo()[#SomeBuilder#]{{; name=.+$}}
// CHAINED_CALLS_1-DAG: Decl[InstanceMethod]/CurrNominal: .doBar()[#SomeBuilder#]{{; name=.+$}}
// CHAINED_CALLS_1-DAG: Decl[InstanceMethod]/CurrNominal: .doBaz({#(z): Double#})[#SomeBuilder#]{{; name=.+$}}
+// CHAINED_CALLS_1-DAG: Keyword[self]/CurrNominal: .self[#SomeBuilder#]; name=self
// CHAINED_CALLS_1: End completions
}
@@ -1090,6 +1120,7 @@
// CHAINED_CALLS_2-DAG: Decl[InstanceMethod]/CurrNominal: .doFoo()[#SomeBuilder#]{{; name=.+$}}
// CHAINED_CALLS_2-DAG: Decl[InstanceMethod]/CurrNominal: .doBar()[#SomeBuilder#]{{; name=.+$}}
// CHAINED_CALLS_2-DAG: Decl[InstanceMethod]/CurrNominal: .doBaz({#(z): Double#})[#SomeBuilder#]{{; name=.+$}}
+// CHAINED_CALLS_2-DAG: Keyword[self]/CurrNominal: .self[#SomeBuilder#]; name=self
// CHAINED_CALLS_2: End completions
}
@@ -1100,6 +1131,7 @@
// CHAINED_CALLS_3-DAG: Decl[InstanceMethod]/CurrNominal: .doFoo()[#SomeBuilder#]{{; name=.+$}}
// CHAINED_CALLS_3-DAG: Decl[InstanceMethod]/CurrNominal: .doBar()[#SomeBuilder#]{{; name=.+$}}
// CHAINED_CALLS_3-DAG: Decl[InstanceMethod]/CurrNominal: .doBaz({#z: Double#})[#SomeBuilder#]{{; name=.+$}}
+// CHAINED_CALLS_3-DAG: Keyword[self]/CurrNominal: .self[#SomeBuilder#]; name=self
// CHAINED_CALLS_3: End completions
}
@@ -1113,6 +1145,7 @@
// RESOLVE_GENERIC_PARAMS_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): FooStruct#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): FooStruct#})[#FooStruct#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_1-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<FooStruct>#]; name=self
// RESOLVE_GENERIC_PARAMS_1-NEXT: End completions
FooGenericStruct<FooStruct>#^RESOLVE_GENERIC_PARAMS_1_STATIC^#
@@ -1127,6 +1160,7 @@
// RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooVoidStaticFunc1({#(a): FooStruct#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooTStaticFunc1({#(a): FooStruct#})[#FooStruct#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<FooStruct>.Type#]; name=self
// RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: End completions
}
@@ -1138,6 +1172,7 @@
// RESOLVE_GENERIC_PARAMS_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): FooProtocol#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): FooProtocol#})[#FooProtocol#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_2-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<Foo>#]; name=self
// RESOLVE_GENERIC_PARAMS_2-NEXT: End completions
FooGenericStruct<Foo>#^RESOLVE_GENERIC_PARAMS_2_STATIC^#
@@ -1152,6 +1187,7 @@
// RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooVoidStaticFunc1({#(a): FooProtocol#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooTStaticFunc1({#(a): FooProtocol#})[#FooProtocol#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<Foo>.Type#]; name=self
// RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: End completions
}
@@ -1164,10 +1200,11 @@
// RESOLVE_GENERIC_PARAMS_3-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): FooStruct#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_3-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): FooStruct#})[#FooStruct#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_3-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_3-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<FooStruct>#]; name=self
// RESOLVE_GENERIC_PARAMS_3-NEXT: End completions
FooGenericStruct<FooStruct>#^RESOLVE_GENERIC_PARAMS_3_STATIC^#
-// RESOLVE_GENERIC_PARAMS_3_STATIC: Begin completions, 10 items
+// RESOLVE_GENERIC_PARAMS_3_STATIC: Begin completions, 11 items
// RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[Constructor]/CurrNominal: ()[#FooGenericStruct<FooStruct>#]; name=()
// RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[Constructor]/CurrNominal: ({#t: FooStruct#})[#FooGenericStruct<FooStruct>#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#self: &FooGenericStruct<FooStruct>#})[#(FooStruct) -> Void#]{{; name=.+$}}
@@ -1178,6 +1215,7 @@
// RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooVoidStaticFunc1({#(a): FooStruct#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooTStaticFunc1({#(a): FooStruct#})[#FooStruct#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<FooStruct>.Type#]; name=self
// RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: End completions
}
@@ -1189,6 +1227,7 @@
// RESOLVE_GENERIC_PARAMS_4-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): T#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_4-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): T#})[#T#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_4-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_4-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<T>#]; name=self
// RESOLVE_GENERIC_PARAMS_4-NEXT: End completions
FooGenericStruct<T>#^RESOLVE_GENERIC_PARAMS_4_STATIC^#
@@ -1203,6 +1242,7 @@
// RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooVoidStaticFunc1({#(a): T#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooTStaticFunc1({#(a): T#})[#T#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<T>.Type#]; name=self
// RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: End completions
}
@@ -1214,6 +1254,7 @@
// RESOLVE_GENERIC_PARAMS_5-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): U#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_5-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_5-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_5-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<U>#]; name=self
// RESOLVE_GENERIC_PARAMS_5-NEXT: End completions
FooGenericStruct<U>#^RESOLVE_GENERIC_PARAMS_5_STATIC^#
@@ -1228,6 +1269,7 @@
// RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooVoidStaticFunc1({#(a): U#})[#Void#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooTStaticFunc1({#(a): U#})[#U#]{{; name=.+$}}
// RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: Decl[StaticMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: Keyword[self]/CurrNominal: .self[#FooGenericStruct<U>.Type#]; name=self
// RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: End completions
}
}
@@ -1263,6 +1305,7 @@
BuilderStyle().#^TC_UNSOLVED_VARIABLES_1^#
}
// TC_UNSOLVED_VARIABLES_1: Begin completions
+// TC_UNSOLVED_VARIABLES_1-NEXT: Keyword[self]/CurrNominal: self[#BuilderStyle<_>#]; name=self
// TC_UNSOLVED_VARIABLES_1-NEXT: Decl[InstanceVar]/CurrNominal: count[#Int#]{{; name=.+$}}
// TC_UNSOLVED_VARIABLES_1-NEXT: Decl[InstanceMethod]/CurrNominal: addString({#(s): String#})[#BuilderStyle<_>#]{{; name=.+$}}
// TC_UNSOLVED_VARIABLES_1-NEXT: Decl[InstanceMethod]/CurrNominal: add({#(t): _#})[#BuilderStyle<_>#]{{; name=.+$}}
@@ -1273,6 +1316,7 @@
BuilderStyle().addString("abc").#^TC_UNSOLVED_VARIABLES_2^#
}
// TC_UNSOLVED_VARIABLES_2: Begin completions
+// TC_UNSOLVED_VARIABLES_2-NEXT: Keyword[self]/CurrNominal: self[#BuilderStyle<_>#]; name=self
// TC_UNSOLVED_VARIABLES_2-NEXT: Decl[InstanceVar]/CurrNominal: count[#Int#]{{; name=.+$}}
// TC_UNSOLVED_VARIABLES_2-NEXT: Decl[InstanceMethod]/CurrNominal: addString({#(s): String#})[#BuilderStyle<_>#]{{; name=.+$}}
// TC_UNSOLVED_VARIABLES_2-NEXT: Decl[InstanceMethod]/CurrNominal: add({#(t): _#})[#BuilderStyle<_>#]{{; name=.+$}}
@@ -1283,6 +1327,7 @@
BuilderStyle().addString("abc").add(42).#^TC_UNSOLVED_VARIABLES_3^#
}
// TC_UNSOLVED_VARIABLES_3: Begin completions
+// TC_UNSOLVED_VARIABLES_3-NEXT: Keyword[self]/CurrNominal: self[#BuilderStyle<Int>#]; name=self
// TC_UNSOLVED_VARIABLES_3-NEXT: Decl[InstanceVar]/CurrNominal: count[#Int#]{{; name=.+$}}
// TC_UNSOLVED_VARIABLES_3-NEXT: Decl[InstanceMethod]/CurrNominal: addString({#(s): String#})[#BuilderStyle<Int>#]{{; name=.+$}}
// TC_UNSOLVED_VARIABLES_3-NEXT: Decl[InstanceMethod]/CurrNominal: add({#(t): Int#})[#BuilderStyle<Int>#]{{; name=.+$}}
@@ -1648,26 +1693,29 @@
func testDeDuped(_ x: dedupS) {
x#^PROTOCOL_EXT_DEDUP_1^#
// FIXME: Should produce 3 items (?)
-// PROTOCOL_EXT_DEDUP_1: Begin completions, 6 items
+// PROTOCOL_EXT_DEDUP_1: Begin completions, 7 items
// PROTOCOL_EXT_DEDUP_1: Decl[InstanceMethod]/CurrNominal: .foo()[#Int#]; name=foo()
// PROTOCOL_EXT_DEDUP_1: Decl[InstanceVar]/CurrNominal: .bar[#Int#]; name=bar
// PROTOCOL_EXT_DEDUP_1: Decl[Subscript]/CurrNominal: [{#Int#}][#Int#]; name=[Int]
+// PROTOCOL_EXT_DEDUP_1: Keyword[self]/CurrNominal: .self[#dedupS#]; name=self
// PROTOCOL_EXT_DEDUP_1: End completions
}
func testDeDuped2(_ x: dedupP) {
x#^PROTOCOL_EXT_DEDUP_2^#
-// PROTOCOL_EXT_DEDUP_2: Begin completions, 3 items
+// PROTOCOL_EXT_DEDUP_2: Begin completions, 4 items
// PROTOCOL_EXT_DEDUP_2: Decl[InstanceMethod]/CurrNominal: .foo()[#dedupP.T#]; name=foo()
// PROTOCOL_EXT_DEDUP_2: Decl[InstanceVar]/CurrNominal: .bar[#dedupP.T#]; name=bar
// PROTOCOL_EXT_DEDUP_2: Decl[Subscript]/CurrNominal: [{#Self.T#}][#Self.T#]; name=[Self.T]
+// PROTOCOL_EXT_DEDUP_2: Keyword[self]/CurrNominal: .self[#dedupP#]; name=self
// PROTOCOL_EXT_DEDUP_2: End completions
}
func testDeDuped3<T : dedupP where T.T == Int>(_ x: T) {
x#^PROTOCOL_EXT_DEDUP_3^#
-// PROTOCOL_EXT_DEDUP_3: Begin completions, 3 items
+// PROTOCOL_EXT_DEDUP_3: Begin completions, 4 items
// PROTOCOL_EXT_DEDUP_3: Decl[InstanceMethod]/Super: .foo()[#Int#]; name=foo()
// PROTOCOL_EXT_DEDUP_3: Decl[InstanceVar]/Super: .bar[#Int#]; name=bar
// PROTOCOL_EXT_DEDUP_3: Decl[Subscript]/Super: [{#Self.T#}][#Self.T#]; name=[Self.T]
+// PROTOCOL_EXT_DEDUP_3: Keyword[self]/CurrNominal: .self[#T#]; name=self
// PROTOCOL_EXT_DEDUP_3: End completions
}
@@ -1778,6 +1826,7 @@
func test1() {
let person = Person(firstName: otherField.#^DOT_EXPR_NON_NOMINAL_1^#)
// DOT_EXPR_NON_NOMINAL_1-NOT: Instance
+// DOT_EXPR_NON_NOMINAL_1: Keyword[self]/CurrNominal: self[#Other#]; name=self
// DOT_EXPR_NON_NOMINAL_1: Decl[InstanceVar]/CurrNominal: nameFromOther[#Int#];
// DOT_EXPR_NON_NOMINAL_1-NOT: Instance
}
@@ -1785,6 +1834,7 @@
let person = Person(firstName: 1.#^DOT_EXPR_NON_NOMINAL_2^#)
// DOT_EXPR_NON_NOMINAL_2-NOT: otherField
// DOT_EXPR_NON_NOMINAL_2-NOT: firstName
+// DOT_EXPR_NON_NOMINAL_2: Keyword[self]/CurrNominal: self[#Int#]; name=self
// DOT_EXPR_NON_NOMINAL_2: Decl[InstanceVar]/CurrNominal: hashValue[#Int#];
// DOT_EXPR_NON_NOMINAL_2-NOT: otherField
// DOT_EXPR_NON_NOMINAL_2-NOT: firstName
diff --git a/test/IDE/complete_with_closure_param.swift b/test/IDE/complete_with_closure_param.swift
index 43f86bd..4e144b9 100644
--- a/test/IDE/complete_with_closure_param.swift
+++ b/test/IDE/complete_with_closure_param.swift
@@ -15,7 +15,7 @@
FooStruct().#^COMPLETE^#
-// CHECK: Begin completions, 7 items
+// CHECK: Begin completions, 8 items
// CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod1({#(callback): (Int, Int) -> Void##(Int, Int) -> Void#})[#Void#]; name=instanceMethod1(callback: (Int, Int) -> Void){{$}}
// CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod2({#(callback): ((Int, Int) -> Void)?##(Int, Int) -> Void#})[#Void#]{{; name=.+$}}
// CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod3({#(callback): ((Int, Int) -> Void)??##(Int, Int) -> Void#})[#Void#]{{; name=.+$}}
@@ -23,4 +23,5 @@
// CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod5({#(callback): (Int, Int) -> Bool##(Int, Int) -> Bool#})[#Void#]{{; name=.+$}}
// CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod6({#(callback): FunctionTypealias?##(Int, Int) -> Bool#})[#Void#]{{; name=.+$}}
// CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod7({#(callback): OptionalFunctionTypealias##(Int, Int) -> Bool#})[#Void#]{{; name=.+$}}
+// CHECK-DAG: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
// CHECK: End completions
diff --git a/test/IRGen/Inputs/emit_public_type_metadata_accessors_other.swift b/test/IRGen/Inputs/emit_public_type_metadata_accessors_other.swift
deleted file mode 100644
index 0d52c92..0000000
--- a/test/IRGen/Inputs/emit_public_type_metadata_accessors_other.swift
+++ /dev/null
@@ -1,3 +0,0 @@
-func foo() -> Any {
- return Wrapper()
-}
diff --git a/test/IRGen/builtins.swift b/test/IRGen/builtins.swift
index bc07d9f..bf70c20 100644
--- a/test/IRGen/builtins.swift
+++ b/test/IRGen/builtins.swift
@@ -225,12 +225,12 @@
// CHECK: define hidden {{.*}}void @"$S8builtins27generic_sizeof_alignof_testyyxlF"
func generic_sizeof_alignof_test<T>(_: T) {
- // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
+ // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 8
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
// CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to i64
// CHECK-NEXT: store i64 [[SIZE]], i64* [[S:%.*]]
var s = Builtin.sizeof(T.self)
- // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 10
+ // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
// CHECK-NEXT: [[T2:%.*]] = ptrtoint i8* [[T1]] to i64
// CHECK-NEXT: [[T3:%.*]] = and i64 [[T2]], 65535
@@ -241,7 +241,7 @@
// CHECK: define hidden {{.*}}void @"$S8builtins21generic_strideof_testyyxlF"
func generic_strideof_test<T>(_: T) {
- // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 11
+ // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 10
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
// CHECK-NEXT: [[STRIDE:%.*]] = ptrtoint i8* [[T1]] to i64
// CHECK-NEXT: store i64 [[STRIDE]], i64* [[S:%.*]]
@@ -771,7 +771,7 @@
// CHECK-LABEL: define {{.*}} @{{.*}}generic_ispod_test
func generic_ispod_test<T>(_: T) {
- // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 10
+ // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
// CHECK-NEXT: [[FLAGS:%.*]] = ptrtoint i8* [[T1]] to i64
// CHECK-NEXT: [[ISNOTPOD:%.*]] = and i64 [[FLAGS]], 65536
diff --git a/test/IRGen/closure.swift b/test/IRGen/closure.swift
index 826f354..ddc1fa7 100644
--- a/test/IRGen/closure.swift
+++ b/test/IRGen/closure.swift
@@ -4,7 +4,7 @@
// -- partial_apply context metadata
-// CHECK: [[METADATA:@.*]] = private constant %swift.full_boxmetadata { void (%swift.refcounted*)* @objectdestroy, i8** null, %swift.type { i64 64 }, i32 16, i8* bitcast ({ i32, i32, i32, i32 }* @"\01l__swift4_reflection_descriptor" to i8*) }
+// CHECK: [[METADATA:@.*]] = private constant %swift.full_boxmetadata { void (%swift.refcounted*)* @objectdestroy, i8** null, %swift.type { i64 64 }, i32 16, i8* bitcast ({ i32, i32, i32, i32 }* @"\01l__swift5_reflection_descriptor" to i8*) }
func a(i i: Int) -> (Int) -> Int {
return { x in i }
diff --git a/test/IRGen/emit_public_type_metadata_accessors.swift b/test/IRGen/emit_public_type_metadata_accessors.swift
deleted file mode 100644
index 0cefc03..0000000
--- a/test/IRGen/emit_public_type_metadata_accessors.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %swift -module-name test -target x86_64-apple-macosx10.9 -emit-ir -parse-stdlib -emit-public-type-metadata-accessors -primary-file %s %S/Inputs/emit_public_type_metadata_accessors_other.swift | %FileCheck --check-prefix=CHECK-PUBLIC %s
-
-// RUN: %swift -module-name test -target x86_64-apple-macosx10.9 -emit-ir -parse-stdlib -primary-file %s %S/Inputs/emit_public_type_metadata_accessors_other.swift | %FileCheck --check-prefix=CHECK-NONPUBLIC %s
-
-private class C { }
-
-// CHECK-PUBLIC: define swiftcc %swift.metadata_response @"$S4test3Foo33_DEC9477CC6E8E6E7A9CE422B1DBE7EA4LLVMa"
-// CHECK-NONPUBLIC: define internal swiftcc %swift.metadata_response @"$S4test3Foo33_DEC9477CC6E8E6E7A9CE422B1DBE7EA4LLVMa"
-private struct Foo {
- private let c: C = C()
-}
-
-public struct Wrapper {
- private let foo: Foo = Foo()
-}
-
-
diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil
index d5a6e50..83cc36d 100644
--- a/test/IRGen/enum.sil
+++ b/test/IRGen/enum.sil
@@ -127,11 +127,11 @@
// CHECK: @"$S4enum16DynamicSingletonOMP" = internal constant <{ {{.*}} }> <{
// CHECK-SAME: @"$S4enum16DynamicSingletonOMi"
-// CHECK-SAME: [18 x i8*]* @"$S4enum16DynamicSingletonOWV"
+// CHECK-SAME: [17 x i8*]* @"$S4enum16DynamicSingletonOWV"
// -- No-payload enums have extra inhabitants in
// their value witness table.
-// CHECK: @"$S4enum10NoPayloadsOWV" = internal constant [18 x i8*] [
+// CHECK: @"$S4enum10NoPayloadsOWV" = internal constant [17 x i8*] [
// -- ...
// -- size
// CHECK-SAME: i8* inttoptr ([[WORD:i32|i64]] 1 to i8*),
@@ -149,7 +149,7 @@
// -- Single-payload enums take unused extra inhabitants from their payload
// as their own.
-// CHECK: @"$S4enum19SinglePayloadNestedOWV" = internal constant [18 x i8*] [
+// CHECK: @"$S4enum19SinglePayloadNestedOWV" = internal constant [17 x i8*] [
// -- ...
// -- size
// CHECK-SAME: i8* inttoptr ([[WORD]] 1 to i8*),
@@ -165,16 +165,16 @@
// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$S4enum19SinglePayloadNestedOwxg" to i8*)
// CHECK-SAME: ]
-// CHECK: @"$S4enum20DynamicSinglePayloadOWV" = internal constant [18 x i8*] [
+// CHECK: @"$S4enum20DynamicSinglePayloadOWV" = internal constant [17 x i8*] [
// CHECK-SAME: i8* null
// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @"$S4enum20DynamicSinglePayloadOwxs" to i8*)
// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$S4enum20DynamicSinglePayloadOwxg" to i8*)
// CHECK: @"$S4enum20DynamicSinglePayloadOMP" = internal constant <{ {{.*}} }> <{
// CHECK-SAME: @"$S4enum20DynamicSinglePayloadOMi"
-// CHECK-SAME: [18 x i8*]* @"$S4enum20DynamicSinglePayloadOWV"
+// CHECK-SAME: [17 x i8*]* @"$S4enum20DynamicSinglePayloadOWV"
-// CHECK: @"$S4enum18MultiPayloadNestedOWV" = internal constant [18 x i8*] [
+// CHECK: @"$S4enum18MultiPayloadNestedOWV" = internal constant [17 x i8*] [
// -- size
// CHECK-32-SAME: i8* inttoptr ([[WORD]] 5 to i8*),
// CHECK-64-SAME: i8* inttoptr ([[WORD]] 9 to i8*),
@@ -1209,7 +1209,7 @@
// CHECK: [[TMP:%.*]] = bitcast %swift.type* %T to i8***
// CHECK: [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
-// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 7
+// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 6
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
// CHECK: %getEnumTagSinglePayload = bitcast i8* [[WITNESS]] to i32 (%swift.opaque*, i32, %swift.type*)*
// CHECK: [[CASE_INDEX:%.*]] = call i32 %getEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 3, %swift.type* %T)
@@ -1240,7 +1240,7 @@
// CHECK: [[TMP:%.*]] = bitcast %swift.type* %T to i8***
// CHECK: [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
-// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
+// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 7
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
// CHECK: %storeEnumTagSinglePayload = bitcast i8* [[WITNESS]] to void (%swift.opaque*, i32, i32, %swift.type*)*
// CHECK: call void %storeEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 0, i32 3, %swift.type* %T)
@@ -1256,7 +1256,7 @@
// CHECK: [[TMP:%.*]] = bitcast %swift.type* %T to i8***
// CHECK: [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
-// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
+// CHECK: [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 7
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
// CHECK: %storeEnumTagSinglePayload = bitcast i8* [[WITNESS]] to void (%swift.opaque*, i32, i32, %swift.type*)*
// CHECK: call void %storeEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 1, i32 3, %swift.type* %T)
@@ -2640,7 +2640,7 @@
// CHECK: [[T_VWTS:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
// CHECK: [[T_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T_VWTS]], [[WORD]] -1
// CHECK: [[T_VWT:%.*]] = load i8**, i8*** [[T_VWT_ADDR]]
-// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 9
+// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 8
// CHECK: call void @swift_initEnumMetadataSingleCase(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]])
// CHECK: ret %swift.metadata_response
@@ -2659,7 +2659,7 @@
// CHECK: [[T_VWTS:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
// CHECK: [[T_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T_VWTS]], [[WORD]] -1
// CHECK: [[T_VWT:%.*]] = load i8**, i8*** [[T_VWT_ADDR]]
-// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 9
+// CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 8
// CHECK: call void @swift_initEnumMetadataSinglePayload(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]], i32 3)
// CHECK-64-LABEL: define linkonce_odr hidden void @"$S4enum17StructWithWeakVarVwxs"(%swift.opaque* noalias %dest, i32 %index, %swift.type* %StructWithWeakVar)
diff --git a/test/IRGen/enum_dynamic_multi_payload.sil b/test/IRGen/enum_dynamic_multi_payload.sil
index 514fd58..331f184 100644
--- a/test/IRGen/enum_dynamic_multi_payload.sil
+++ b/test/IRGen/enum_dynamic_multi_payload.sil
@@ -433,7 +433,7 @@
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
// CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
-// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
+// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
// CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF0]]
// CHECK: [[BUF1:%.*]] = getelementptr {{.*}} [[BUF]], i32 0, i32 1
@@ -445,7 +445,7 @@
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[U_CHECKED]] to i8***
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
// CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
-// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
+// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
// CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF1]]
// CHECK: call void @swift_initEnumMetadataMultiPayload(%swift.type* [[METADATA]], {{i(32|64)}} 0, {{i(32|64)}} 2, i8*** [[BUF0]])
diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift
index 3a7585b..692f7c6 100644
--- a/test/IRGen/enum_resilience.swift
+++ b/test/IRGen/enum_resilience.swift
@@ -119,7 +119,7 @@
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 17
+// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 16
// CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
// CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA]])
@@ -148,7 +148,7 @@
// CHECK-NEXT: [[VWT_ADDR2:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR2]], [[INT]] -1
// CHECK-NEXT: [[VWT2:%.*]] = load i8**, i8*** [[VWT_ADDR2]]
-// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 17
+// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 16
// CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
// CHECK-NEXT: [[WITNESS_FN:%destructiveInjectEnumTag]] = bitcast i8* [[WITNESS]]
// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA2]])
@@ -165,7 +165,7 @@
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
// CHECK: [[WITNESS_FOR_SIZE:%size]] = ptrtoint i8* [[WITNESS]]
// CHECK: [[ALLOCA:%.*]] = alloca i8, {{.*}} [[WITNESS_FOR_SIZE]], align 16
@@ -177,7 +177,7 @@
// CHECK: [[WITNESS_FN:%initializeWithCopy]] = bitcast i8* [[WITNESS]]
// CHECK: [[ENUM_COPY:%.*]] = call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.opaque* noalias %0, %swift.type* [[METADATA]])
-// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 15
+// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 14
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
// CHECK: [[WITNESS_FN:%getEnumTag]] = bitcast i8* [[WITNESS]]
// CHECK: [[TAG:%.*]] = call i32 [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.type* [[METADATA]])
diff --git a/test/IRGen/enum_value_semantics.sil b/test/IRGen/enum_value_semantics.sil
index 4de87f8..e5a6417 100644
--- a/test/IRGen/enum_value_semantics.sil
+++ b/test/IRGen/enum_value_semantics.sil
@@ -94,14 +94,13 @@
}
-// CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOWV" = internal constant [18 x i8*] [
+// CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOWV" = internal constant [17 x i8*] [
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
-// CHECK: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
// CHECK: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$S20enum_value_semantics20SinglePayloadTrivialOwet" to i8*),
// CHECK: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$S20enum_value_semantics20SinglePayloadTrivialOwst" to i8*),
// CHECK: i8* inttoptr (i64 9 to i8*),
@@ -118,13 +117,13 @@
// CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOMf" =
// CHECK-SAME: internal constant <{ {{.*}} }> <{
-// CHECK-SAME: i8** getelementptr inbounds ([18 x i8*], [18 x i8*]* @"$S20enum_value_semantics20SinglePayloadTrivialOWV", i32 0, i32 0),
+// CHECK-SAME: i8** getelementptr inbounds ([17 x i8*], [17 x i8*]* @"$S20enum_value_semantics20SinglePayloadTrivialOWV", i32 0, i32 0),
// CHECK-SAME: i64 2,
// CHECK-SAME: {{.*}}* @"$S20enum_value_semantics20SinglePayloadTrivialOMn"
// CHECK-SAME: }>
-// CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOWV" = internal constant [18 x i8*] [
+// CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOWV" = internal constant [17 x i8*] [
// CHECK: i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwCP" to i8*),
// CHECK: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwxx" to i8*),
// CHECK: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwcp" to i8*),
@@ -148,7 +147,7 @@
// CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOMf" =
// CHECK-SAME: internal constant <{ {{.*}} }> <{
-// CHECK-SAME: i8** getelementptr inbounds ([18 x i8*], [18 x i8*]* @"$S20enum_value_semantics23SinglePayloadNontrivialOWV", i32 0, i32 0),
+// CHECK-SAME: i8** getelementptr inbounds ([17 x i8*], [17 x i8*]* @"$S20enum_value_semantics23SinglePayloadNontrivialOWV", i32 0, i32 0),
// CHECK-SAME: i64 2,
// CHECK-SAME: {{.*}}* @"$S20enum_value_semantics23SinglePayloadNontrivialOMn"
// CHECK-SAME: }>
@@ -166,7 +165,7 @@
// Pattern flags. 0x400000 == (MetadataKind::Enum << 21).
// CHECK-SAME: i32 4194304,
// Value witness table.
-// CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint ([18 x i8*]* @"$S20enum_value_semantics18GenericFixedLayoutOWV" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32 }>, <{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP", i32 0, i32 3) to i64)) to i32)
+// CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint ([17 x i8*]* @"$S20enum_value_semantics18GenericFixedLayoutOWV" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32 }>, <{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP", i32 0, i32 3) to i64)) to i32)
// CHECK-SAME: }>
sil @single_payload_nontrivial_copy_destroy : $(@owned SinglePayloadNontrivial) -> () {
diff --git a/test/IRGen/existentials.sil b/test/IRGen/existentials.sil
index 20ee97c..d376d57 100644
--- a/test/IRGen/existentials.sil
+++ b/test/IRGen/existentials.sil
@@ -5,6 +5,14 @@
sil_stage canonical
import Swift
+protocol P {}
+
+// NonBitwiseTakableBit = 0x00100000. This struct is bitwise takable because
+// 0x30007 = 196615.
+// CHECK: @"$S12existentials14BitwiseTakableVWV" = internal constant [11 x i8*] {{.*}} i8* inttoptr (i64 196615 to i8*)
+struct BitwiseTakable {
+ var p: P
+}
protocol CP: class {}
diff --git a/test/IRGen/existentials_objc.sil b/test/IRGen/existentials_objc.sil
index 02569f64..2f001e0 100644
--- a/test/IRGen/existentials_objc.sil
+++ b/test/IRGen/existentials_objc.sil
@@ -42,20 +42,11 @@
// CHECK: call %Any* @"$SypWOb"(%Any* %1, %Any* %0)
// CHECK-NEXT: ret void
-// CHECK-DAG: define linkonce_odr hidden %Any* @"$SypWOb"([[ANY:%Any]]*, %Any*)
-// CHECK: [[T0:%.*]] = getelementptr inbounds [[ANY]], [[ANY]]* [[SRC:%0]], i32 0, i32 1
-// CHECK-NEXT: [[TYPE:%.*]] = load %swift.type*, %swift.type** [[T0]], align 8
-// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[ANY]], [[ANY]]* [[DEST:%1]], i32 0, i32 1
-// CHECK-NEXT: store %swift.type* [[TYPE]], %swift.type** [[T0]], align 8
-// CHECK-NEXT: [[FROM_BUFFER_ADDR:%.*]] = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0
-// CHECK-NEXT: [[TO_BUFFER_ADDR:%.*]] = getelementptr inbounds %Any, %Any* %1, i32 0, i32 0
-// CHECK-NEXT: [[CAST:%.*]] = bitcast %swift.type* [[TYPE]] to i8***
-// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], i64 -1
-// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK-NEXT: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 6
-// CHECK-NEXT: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
-// CHECK-NEXT: [[INITWITHTAKEBUFFER:%.*]] = bitcast i8* [[VW]]
-// CHECK-NEXT: call %swift.opaque* [[INITWITHTAKEBUFFER]]({{.*}} [[TO_BUFFER_ADDR]], {{.*}} [[FROM_BUFFER_ADDR]], %swift.type* [[TYPE]])
+// CHECK-DAG: define linkonce_odr hidden %Any* @"$SypWOb"(%Any*, %Any*)
+// CHECK: %2 = bitcast %Any* %1 to i8*
+// CHECK-NEXT: %3 = bitcast %Any* %0 to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %3, i64 32, i32 8, i1 false)
+// CHECK-NEXT: ret %Any* %1
// rdar://problem/19035529
@objc protocol OP {}
diff --git a/test/IRGen/existentials_opaque_boxed.sil b/test/IRGen/existentials_opaque_boxed.sil
index 2f02228..cf5b22b 100644
--- a/test/IRGen/existentials_opaque_boxed.sil
+++ b/test/IRGen/existentials_opaque_boxed.sil
@@ -41,7 +41,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[METATYPE]]
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[FLAG_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK: [[FLAG_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
// CHECK: [[FLAG_WITNESS:%.*]] = load i8*, i8** [[FLAG_WITNESS_ADDR]]
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[FLAG_WITNESS]]
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -115,7 +115,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[META]] to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** %3, {{(i64|i32)}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
// CHECK: [[MASKED:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -132,7 +132,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[META]] to i8***
// CHECK: [[VWT_ADDR2:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
// CHECK: [[VWT2:%.*]] = load i8**, i8*** [[VWT_ADDR2]]
-// CHECK: [[VW_ADDR2:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 9
+// CHECK: [[VW_ADDR2:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 8
// CHECK: [[VW2:%.*]] = load i8*, i8** [[VW_ADDR2]]
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[VW2]] to {{(i64|i32)}}
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
@@ -164,7 +164,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %1 to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -207,7 +207,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %1 to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -244,7 +244,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
// CHECK: [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -301,7 +301,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[DEST_TYPE]] to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
// CHECK: [[MASKED:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -339,7 +339,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[DEST_TYPE]] to i8***
// CHECK: [[DEST_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
// CHECK: [[DEST_VWT:%.*]] = load i8**, i8*** [[DEST_VWT_ADDR]]
-// CHECK: [[DEST_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[DEST_VWT]], i32 10
+// CHECK: [[DEST_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[DEST_VWT]], i32 9
// CHECK: [[DEST_VW:%.*]] = load i8*, i8** [[DEST_VW_ADDR]]
// CHECK: [[DEST_FLAGS:%.*]] = ptrtoint i8* [[DEST_VW]] to {{(i64|i32)}}
// CHECK: [[DEST_ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[DEST_FLAGS]], 131072
@@ -347,7 +347,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* [[SRC_TYPE]] to i8***
// CHECK: [[SRC_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
// CHECK: [[SRC_VWT:%.*]] = load i8**, i8*** [[SRC_VWT_ADDR]]
-// CHECK: [[SRC_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SRC_VWT]], i32 10
+// CHECK: [[SRC_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SRC_VWT]], i32 9
// CHECK: [[SRC_VW:%.*]] = load i8*, i8** [[SRC_VW_ADDR]]
// CHECK: [[SRC_FLAGS:%.*]] = ptrtoint i8* [[SRC_VW]] to {{(i64|i32)}}
// CHECK: [[SRC_ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[SRC_FLAGS]], 131072
@@ -443,25 +443,11 @@
return %t : $()
}
-// CHECK: define linkonce_odr hidden %T25existentials_opaque_boxed11ExistentialP* @"$S25existentials_opaque_boxed11Existential_pWOb"(%T25existentials_opaque_boxed11ExistentialP*, %T25existentials_opaque_boxed11ExistentialP*)
-// CHECK: [[METADATA_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %0, i32 0, i32 1
-// CHECK: [[METADATA:%.*]] = load %swift.type*, %swift.type** [[METADATA_ADDR]]
-// CHECK: [[LOCAL_METADATA_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %1, i32 0, i32 1
-// CHECK: store %swift.type* [[METADATA]], %swift.type** [[LOCAL_METADATA_ADDR]]
-// CHECK: [[PWT_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %0, i32 0, i32 2
-// CHECK: [[PWT:%.*]] = load i8**, i8*** [[PWT_ADDR]]
-// CHECK: [[LOCAL_PWT_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %1, i32 0, i32 2
-// CHECK: store i8** [[PWT]], i8*** [[LOCAL_PWT_ADDR]]
-// CHECK: [[BUFFER_ARG_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %0, i32 0, i32 0
-// CHECK: [[BUFFER_LOCAL_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %1, i32 0, i32 0
-// CHECK: [[CAST_ADDR:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
-// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST_ADDR]], {{(i64|i32)}} -1
-// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 6
-// CHECK: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
-// CHECK: [[INITWITHTAKEBUFFER:%.*]] = bitcast i8* [[VW]]
-// CHECK: call %swift.opaque* [[INITWITHTAKEBUFFER]]({{.*}} [[BUFFER_LOCAL_ADDR]], {{.*}} [[BUFFER_ARG_ADDR]], %swift.type* [[METADATA]])
-// CHECK: ret %T25existentials_opaque_boxed11ExistentialP* %1
+// CHECK-LABEL: define linkonce_odr hidden %T25existentials_opaque_boxed11ExistentialP* @"$S25existentials_opaque_boxed11Existential_pWOb"(%T25existentials_opaque_boxed11ExistentialP*, %T25existentials_opaque_boxed11ExistentialP*)
+// CHECK: %2 = bitcast %T25existentials_opaque_boxed11ExistentialP* %1 to i8*
+// CHECK: %3 = bitcast %T25existentials_opaque_boxed11ExistentialP* %0 to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.{{(i64|i32)}}(i8* %2, i8* %3, {{(i64 40|i32 20)}}, {{(i32 8|i32 4)}}, i1 false)
+// CHECK: ret %T25existentials_opaque_boxed11ExistentialP* %1
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_initWithTake_existential_addr(%T25existentials_opaque_boxed11ExistentialP*
// CHECK: [[LOCAL:%.*]] = alloca %T25existentials_opaque_boxed11ExistentialP
diff --git a/test/IRGen/generic_casts.swift b/test/IRGen/generic_casts.swift
index 19d6fce..a8ea816 100644
--- a/test/IRGen/generic_casts.swift
+++ b/test/IRGen/generic_casts.swift
@@ -38,7 +38,7 @@
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], i64 -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
- // CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+ // CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
// CHECK: [[T_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
diff --git a/test/IRGen/generic_classes.sil b/test/IRGen/generic_classes.sil
index c6d89f8..5468524 100644
--- a/test/IRGen/generic_classes.sil
+++ b/test/IRGen/generic_classes.sil
@@ -389,7 +389,7 @@
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[B_CHECKED]] to i8***
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[T1]], align 8
-// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[FIELDS_ADDR]], i32 0
// CHECK: store i8** [[T0]], i8*** [[T1]], align 8
// CHECK: call void @swift_initClassMetadata(%swift.type* [[METADATA]], i64 0, i64 1, i8*** [[FIELDS_ADDR]], i64* [[OFFSETS]])
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index 6b5a754..14bc524 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -228,20 +228,6 @@
// CHECK-NEXT: ret %swift.opaque* [[T2]]
-// initializeBufferWithTakeOfBuffer
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S15generic_structs13SingleDynamicVwTK"([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %"SingleDynamic<T>") {{.*}} {
-// CHECK: %T = load %swift.type*,
-// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* %T to i8***
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
-// CHECK-NEXT: %T.valueWitnesses = load i8**, i8*** [[T1]]
-// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 6
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]],
-// CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[T1]] to %swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)*
-// CHECK-NEXT: [[T0:%.*]] = call %swift.opaque* [[FN]]([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %T)
-// CHECK-NEXT: [[T1:%.*]] = bitcast %swift.opaque* [[T0]] to {{.*}}
-// CHECK-NEXT: [[T2:%.*]] = bitcast {{.*}} [[T1]] to %swift.opaque*
-// CHECK-NEXT: ret %swift.opaque* [[T2]]
-
protocol HasAssociatedType {
associatedtype Assoc
}
diff --git a/test/IRGen/generic_tuples.swift b/test/IRGen/generic_tuples.swift
index c94739b..b2fc7f4 100644
--- a/test/IRGen/generic_tuples.swift
+++ b/test/IRGen/generic_tuples.swift
@@ -18,7 +18,7 @@
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], i64 -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
// CHECK: [[X_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
diff --git a/test/IRGen/global_resilience.sil b/test/IRGen/global_resilience.sil
index 200a217..e02d869 100644
--- a/test/IRGen/global_resilience.sil
+++ b/test/IRGen/global_resilience.sil
@@ -125,7 +125,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 10
+// CHECK: [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 9
// CHECK: [[FLAGSWITNESS:%.*]] = load i8*, i8** [[FLAGS_ADDR]]
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[FLAGSWITNESS]] to i{{.*}}
// CHECK: [[ISNOTINLINE:%.*]] = and {{.*}} [[FLAGS]], 131072
@@ -136,7 +136,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[SIZE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[SIZE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[SIZEWITNESS:%.*]] = load i8*, i8** [[SIZE_ADDR]]
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZEWITNESS]]
// CHECK: [[ALIGN:%.*]] = and {{.*}} [[FLAGS]], 65535
@@ -155,7 +155,7 @@
// CHECK: [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 10
+// CHECK: [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 9
// CHECK: [[FLAGSWITNESS:%.*]] = load i8*, i8** [[FLAGS_ADDR]]
// CHECK: [[FLAGS:%.*]] = ptrtoint i8* [[FLAGSWITNESS]] to i{{.*}}
// CHECK: [[ISNOTINLINE:%.*]] = and {{.*}} [[FLAGS]], 131072
diff --git a/test/IRGen/indexing.sil b/test/IRGen/indexing.sil
index 14bbd17..d8153fe 100644
--- a/test/IRGen/indexing.sil
+++ b/test/IRGen/indexing.sil
@@ -45,7 +45,7 @@
// CHECK: %3 = bitcast %swift.type* %T to i8***
// CHECK-NEXT: %4 = getelementptr inbounds i8**, i8*** %3, i64 -1
// CHECK-NEXT: %T.valueWitnesses = load i8**, i8*** %4, align 8
-// CHECK-NEXT: %5 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 11
+// CHECK-NEXT: %5 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 10
// CHECK-NEXT: %6 = load i8*, i8** %5, align 8
// CHECK-NEXT: %stride = ptrtoint i8* %6 to i64
// CHECK-NEXT: %7 = mul nsw i64 %1, %stride
diff --git a/test/IRGen/lifetime.sil b/test/IRGen/lifetime.sil
index 91b1a7d..365302c 100644
--- a/test/IRGen/lifetime.sil
+++ b/test/IRGen/lifetime.sil
@@ -22,7 +22,7 @@
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], {{(i32|i64)}} -1
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK-NEXT: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
// CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
// CHECK-NEXT: [[Y_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
@@ -61,7 +61,7 @@
// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], {{(i32|i64)}} -1
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK-NEXT: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
// CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
// CHECK-NEXT: [[Y_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
diff --git a/test/IRGen/multi_file_resilience.swift b/test/IRGen/multi_file_resilience.swift
index 02aef2c..aeedb66 100644
--- a/test/IRGen/multi_file_resilience.swift
+++ b/test/IRGen/multi_file_resilience.swift
@@ -16,7 +16,7 @@
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
// CHECK: [[VWT:%.*]] = load i8**,
// Allocate 'copy'.
-// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
// CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
diff --git a/test/IRGen/multi_module_resilience.swift b/test/IRGen/multi_module_resilience.swift
index cfd146a..ed3411f 100644
--- a/test/IRGen/multi_module_resilience.swift
+++ b/test/IRGen/multi_module_resilience.swift
@@ -20,7 +20,7 @@
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
// CHECK: [[VWT:%.*]] = load i8**,
// Allocate 'copy'.
-// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
// CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
@@ -49,7 +49,7 @@
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
// CHECK: [[VWT:%.*]] = load i8**,
// Allocate 'copy'.
-// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
// CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
diff --git a/test/IRGen/partial_apply.sil b/test/IRGen/partial_apply.sil
index 2d1a8c3..67c8e6f 100644
--- a/test/IRGen/partial_apply.sil
+++ b/test/IRGen/partial_apply.sil
@@ -233,7 +233,7 @@
// CHECK: [[T_METADATA_BASE:%.*]] = bitcast %swift.type* %T to i8***
// CHECK: [[T_VWTABLE_ADDR:%.*]] = getelementptr {{.*}} [[T_METADATA_BASE]], [[WORD:i[0-9]+]] -1
// CHECK: [[T_VWTABLE:%.*]] = load {{.*}} [[T_VWTABLE_ADDR]]
-// CHECK: [[T_FLAGS_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 10
+// CHECK: [[T_FLAGS_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 9
// CHECK: [[T_FLAGS_PTR:%.*]] = load {{.*}} [[T_FLAGS_ADDR]]
// CHECK: [[T_FLAGS:%.*]] = ptrtoint {{.*}} [[T_FLAGS_PTR]] to [[WORD]]
// CHECK: [[T_ALIGN_MASK:%.*]] = and [[WORD]] [[T_FLAGS]], 65535
@@ -245,7 +245,7 @@
// CHECK: [[T_OFFSET:%.*]] = and [[WORD]] [[T_UP_TO_ALIGN_1]], [[T_ALIGN_MASK_NOT]]
// -- Add the size of T to start the Int field.
-// CHECK: [[T_SIZE_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 9
+// CHECK: [[T_SIZE_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 8
// CHECK: [[T_SIZE_PTR:%.*]] = load {{.*}} [[T_SIZE_ADDR]]
// CHECK: [[T_SIZE:%.*]] = ptrtoint {{.*}} [[T_SIZE_PTR]] to [[WORD]]
// CHECK: [[T_END:%.*]] = add [[WORD]] [[T_OFFSET]], [[T_SIZE]]
diff --git a/test/IRGen/reflection_metadata.swift b/test/IRGen/reflection_metadata.swift
index 0065eae..0664561 100644
--- a/test/IRGen/reflection_metadata.swift
+++ b/test/IRGen/reflection_metadata.swift
@@ -2,51 +2,51 @@
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -disable-reflection-names -emit-ir %s | %FileCheck %s --check-prefix=STRIP_REFLECTION_NAMES
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -disable-reflection-metadata -emit-ir %s | %FileCheck %s --check-prefix=STRIP_REFLECTION_METADATA
-// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift4_reflect
-// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift4_fieldmd
-// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift4_assocty
-// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift4_capture
-// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift4_typeref
-// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift4_reflstr
-// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift4_builtin
+// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift5_reflect
+// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift5_fieldmd
+// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift5_assocty
+// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift5_capture
+// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift5_typeref
+// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift5_reflstr
+// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift5_builtin
-// STRIP_REFLECTION_NAMES-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift4_fieldmd
+// STRIP_REFLECTION_NAMES-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift5_fieldmd
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_reflect
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_fieldmd
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_assocty
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_capture
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_typeref
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_reflstr
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_builtin
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_reflect
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_fieldmd
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_assocty
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_capture
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_typeref
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_reflstr
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_builtin
// CHECK-DAG: @__swift_reflection_version = linkonce_odr hidden constant i16 {{[0-9]+}}
-// CHECK-DAG: private constant [2 x i8] c"i\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"ms\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"me\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"mc\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"C\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"S\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"E\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"I\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"t\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [4 x i8] c"mgs\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [4 x i8] c"mge\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [4 x i8] c"mgc\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"GC\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"GS\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"GE\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"i\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"ms\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"me\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"mc\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"C\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"S\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"E\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"I\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"t\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [4 x i8] c"mgs\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [4 x i8] c"mge\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [4 x i8] c"mgc\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"GC\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"GS\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"GE\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: @"\01l__swift4_reflection_descriptor" = private constant { {{.*}} } { i32 1, i32 1, i32 2, {{.*}} }
+// CHECK-DAG: @"\01l__swift5_reflection_descriptor" = private constant { {{.*}} } { i32 1, i32 1, i32 2, {{.*}} }
-// CHECK-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata7MyClassCMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata11ConformanceVAA10MyProtocolAAMA" = internal constant {{.*}}swift4_assocty
-// CHECK-DAG: @"$S19reflection_metadata8MyStructVMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata6MyEnumOMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata14MyGenericClassCMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata15MyGenericStructVMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata13MyGenericEnumOMF" = internal constant {{.*}}swift4_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata7MyClassCMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata11ConformanceVAA10MyProtocolAAMA" = internal constant {{.*}}swift5_assocty
+// CHECK-DAG: @"$S19reflection_metadata8MyStructVMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata6MyEnumOMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata14MyGenericClassCMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata15MyGenericStructVMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata13MyGenericEnumOMF" = internal constant {{.*}}swift5_fieldmd
public protocol MyProtocol {
associatedtype Inner
diff --git a/test/IRGen/reflection_metadata_imported.swift b/test/IRGen/reflection_metadata_imported.swift
index 4af3fd7..f8a61b1 100644
--- a/test/IRGen/reflection_metadata_imported.swift
+++ b/test/IRGen/reflection_metadata_imported.swift
@@ -4,10 +4,10 @@
// CHECK-DAG: @__swift_reflection_version = linkonce_odr hidden constant i16 {{[0-9]+}}
-// CHECK-DAG: @"$S28reflection_metadata_imported15HasImportedTypeVMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$SSo1AVMB" = linkonce_odr hidden constant {{.*}}swift4_builtin
-// CHECK-DAG: @"$SSo11CrappyColorVMB" = linkonce_odr hidden constant {{.*}}swift4_builtin
-// CHECK-DAG: @"$SSo11CrappyColorVs16RawRepresentableSCMA" = linkonce_odr hidden constant {{.*}}swift4_assocty
+// CHECK-DAG: @"$S28reflection_metadata_imported15HasImportedTypeVMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$SSo1AVMB" = linkonce_odr hidden constant {{.*}}swift5_builtin
+// CHECK-DAG: @"$SSo11CrappyColorVMB" = linkonce_odr hidden constant {{.*}}swift5_builtin
+// CHECK-DAG: @"$SSo11CrappyColorVs16RawRepresentableSCMA" = linkonce_odr hidden constant {{.*}}swift5_assocty
struct HasImportedType {
let a: A
diff --git a/test/IRGen/struct_resilience.swift b/test/IRGen/struct_resilience.swift
index a3b6bb1..34c081d 100644
--- a/test/IRGen/struct_resilience.swift
+++ b/test/IRGen/struct_resilience.swift
@@ -25,7 +25,7 @@
// CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
// CHECK: [[WITNESS_FOR_SIZE:%.*]] = ptrtoint i8* [[WITNESS]]
// CHECK: [[ALLOCA:%.*]] = alloca i8, {{.*}} [[WITNESS_FOR_SIZE]], align 16
@@ -170,6 +170,24 @@
_ = s.method
}
+public func wantsAny(_ any: Any) {}
+
+public func resilientAny(s : ResilientWeakRef) {
+ wantsAny(s)
+}
+
+// CHECK-LABEL: define{{.*}} swiftcc void @"$S17struct_resilience12resilientAny1sy0c1_A016ResilientWeakRefV_tF"(%swift.opaque* noalias nocapture)
+// CHECK: entry:
+// CHECK: [[ANY:%.*]] = alloca %Any
+// CHECK: [[META:%.*]] = call swiftcc %swift.metadata_response @"$S16resilient_struct16ResilientWeakRefVMa"([[INT]] 0)
+// CHECK: [[META2:%.*]] = extractvalue %swift.metadata_response %3, 0
+// CHECK: [[TYADDR:%.*]] = getelementptr inbounds %Any, %Any* %1, i32 0, i32 1
+// CHECK: store %swift.type* [[META2]], %swift.type** [[TYADDR]]
+// CHECK: call %swift.opaque* @__swift_allocate_boxed_opaque_existential_0(%Any* [[ANY]])
+// CHECK: call swiftcc void @"$S17struct_resilience8wantsAnyyyypF"(%Any* noalias nocapture dereferenceable({{(32|16)}}) [[ANY]])
+// CHECK: call void @__swift_destroy_boxed_opaque_existential_0(%Any* [[ANY]])
+// CHECK: ret void
+
// Public metadata accessor for our resilient struct
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.metadata_response @"$S17struct_resilience6MySizeVMa"
diff --git a/test/IRGen/swift3-metadata-coff.swift b/test/IRGen/swift3-metadata-coff.swift
index 38d0887..15441b7 100644
--- a/test/IRGen/swift3-metadata-coff.swift
+++ b/test/IRGen/swift3-metadata-coff.swift
@@ -25,7 +25,7 @@
return { gg = s }
}
-// CHECK-DAG: @"\01l__swift4_reflection_descriptor" = private constant {{.*}}, section ".sw5cptr$B"
+// CHECK-DAG: @"\01l__swift5_reflection_descriptor" = private constant {{.*}}, section ".sw5cptr$B"
// CHECK-DAG: @"{{.*}}" = {{.*}} c"Sq", {{.*}} section ".sw5tyrf$B"
// CHECK-DAG: @{{[0-9]+}} = {{.*}} c"none\00", section ".sw5rfst$B"
// CHECK-DAG: @{{[0-9]+}} = {{.*}} c"some\00", section ".sw5rfst$B"
diff --git a/test/IRGen/type_layout.swift b/test/IRGen/type_layout.swift
index a97a86c..b9fd828 100644
--- a/test/IRGen/type_layout.swift
+++ b/test/IRGen/type_layout.swift
@@ -34,14 +34,14 @@
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
// CHECK: [[T_VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
- // CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
+ // CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
// CHECK: store i8** [[T_LAYOUT]]
var z: T
// -- native class, use standard NativeObject value witness
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 8)
var a: C
// -- Single-element struct, shares layout of its field (Builtin.Int64)
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
var c: SSing
// -- Multi-element structs use open-coded layouts
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_16_8_0_pod, i32 0, i32 0)
@@ -53,13 +53,13 @@
// CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_[[REF_XI]]_bt, i32 0, i32 0)
var f: SMult3
// -- Single-case enum, shares layout of its field (Builtin.Int64)
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
var g: ESing
// -- Multi-case enum, open-coded layout
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
var h: EMult
// -- Single-element generic struct, shares layout of its field (T)
- // CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
+ // CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
// CHECK: store i8** [[T_LAYOUT]]
var i: GSing<T>
// -- Multi-element generic struct, need to derive from metadata
@@ -71,13 +71,13 @@
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
// CHECK: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
- // CHECK: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
+ // CHECK: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
// CHECK: store i8** [[LAYOUT]]
var j: GMult<T>
// -- Common layout, reuse common value witness table layout
- // CHECK: store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 9)
+ // CHECK: store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 8)
var k: CommonLayout
// -- Single-field aggregate with alignment
- // CHECK: store i8** getelementptr (i8*, i8** @"$SBi128_WV", i32 9)
+ // CHECK: store i8** getelementptr (i8*, i8** @"$SBi128_WV", i32 8)
var l: AlignedFourInts
}
diff --git a/test/IRGen/type_layout_objc.swift b/test/IRGen/type_layout_objc.swift
index 4e42668..976eb19 100644
--- a/test/IRGen/type_layout_objc.swift
+++ b/test/IRGen/type_layout_objc.swift
@@ -33,17 +33,17 @@
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
// CHECK: [[T_VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
- // CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
+ // CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
// CHECK: store i8** [[T_LAYOUT]]
var z: T
// -- native class, use standard NativeObject value witness
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 8)
var a: C
// -- ObjC class, use standard UnknownObject value witness
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOWV", i32 8)
var b: O
// -- Single-element struct, shares layout of its field (Builtin.Int64)
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
var c: SSing
// -- Multi-element structs use open-coded layouts
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_16_8_0_pod, i32 0, i32 0)
@@ -55,13 +55,13 @@
// CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_1000_bt, i32 0, i32 0)
var f: SMult3
// -- Single-case enum, shares layout of its field (Builtin.Int64)
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
var g: ESing
// -- Multi-case enum, open-coded layout
// CHECK: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
var h: EMult
// -- Single-element generic struct, shares layout of its field (T)
- // CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
+ // CHECK: [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
// CHECK: store i8** [[T_LAYOUT]]
var i: GSing<T>
// -- Multi-element generic struct, need to derive from metadata
@@ -73,10 +73,10 @@
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
// CHECK: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
- // CHECK: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
+ // CHECK: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
// CHECK: store i8** [[LAYOUT]]
var j: GMult<T>
// -- Common layout, reuse common value witness table layout
- // CHECK: store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 9)
+ // CHECK: store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 8)
var k: CommonLayout
}
diff --git a/test/IRGen/type_layout_reference_storage.swift b/test/IRGen/type_layout_reference_storage.swift
index 4128fae..9b545e5 100644
--- a/test/IRGen/type_layout_reference_storage.swift
+++ b/test/IRGen/type_layout_reference_storage.swift
@@ -10,23 +10,23 @@
var z: T
// -- Known-Swift-refcounted type
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 8)
unowned(safe) var cs: C
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
unowned(unsafe) var cu: C
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
weak var cwo: C?
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
weak var cwi: C!
// -- Known-Swift-refcounted archetype
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 8)
unowned(safe) var nc: Native
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
unowned(unsafe) var nu: Native
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
weak var nwo: Native?
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
weak var nwi: Native!
// -- Open-code layout for protocol types with witness tables.
@@ -72,23 +72,23 @@
weak var pqcwi: (P & Q & C)!
// -- Unknown-refcounted existential without witness tables.
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 8)
unowned(safe) var aos: AnyObject
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
unowned(unsafe) var aou: AnyObject
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
weak var aowo: AnyObject?
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
weak var aowi: AnyObject!
// -- Unknown-refcounted archetype
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 8)
unowned(safe) var us: Unknown
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
unowned(unsafe) var uu: Unknown
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
weak var uwo: Unknown?
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
weak var uwi: Unknown!
}
diff --git a/test/IRGen/type_layout_reference_storage_objc.swift b/test/IRGen/type_layout_reference_storage_objc.swift
index bdc4a55..f92974c 100644
--- a/test/IRGen/type_layout_reference_storage_objc.swift
+++ b/test/IRGen/type_layout_reference_storage_objc.swift
@@ -15,52 +15,52 @@
var z: T
// -- ObjC-refcounted class
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
unowned(safe) var cs: C
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
unowned(unsafe) var cu: C
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
weak var cwo: C?
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
weak var cwi: C!
// -- ObjC-refcounted archetype
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
unowned(safe) var os: ObjC
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
unowned(unsafe) var ou: ObjC
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
weak var owo: ObjC?
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
weak var owi: ObjC!
// -- Pure ObjC protocols are unknown-refcounted
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
unowned(safe) var ps: P
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
unowned(unsafe) var pu: P
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
weak var pwo: P?
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
weak var pwi: P!
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
unowned(safe) var pqs: P & Q
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
unowned(unsafe) var pqu: P & Q
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
weak var pqwo: (P & Q)?
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
weak var pqwi: (P & Q)!
// -- Composition with ObjC protocol and native class is native-refcounted
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 8)
unowned(safe) var pncs: (P & NativeClass)
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
unowned(unsafe) var pncu: (P & NativeClass)
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
weak var pncwo: (P & NativeClass)?
- // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+ // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
weak var pncwi: (P & NativeClass)!
// -- Open-code layouts when there are witness tables.
diff --git a/test/IRGen/weak.sil b/test/IRGen/weak.sil
index be03eec..0493b6d 100644
--- a/test/IRGen/weak.sil
+++ b/test/IRGen/weak.sil
@@ -28,9 +28,9 @@
}
// size 8
-// flags 0x1100007 == 1114119 (non-POD, non-inline, non-bitwise-takable)
+// flags 0x130007 == 1245191 (non-POD, non-inline, non-bitwise-takable)
// stride 8
-// CHECK: @"$S4weak1AVWV" = {{.*}} i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 1114119 to i8*), i8* inttoptr (i64 8 to i8*)]
+// CHECK: @"$S4weak1AVWV" = {{.*}} i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 1245191 to i8*), i8* inttoptr (i64 8 to i8*)]
sil @test_weak_load_store : $@convention(thin) (@inout A, Optional<C>) -> () {
bb0(%0 : $*A, %1 : $Optional<C>):
@@ -104,16 +104,19 @@
// initializeBufferWithCopyOfBuffer
// CHECK: define linkonce_odr hidden [[OPAQUE]]* @"$S4weak1AVwCP"([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
-// CHECK: [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]*
-// CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]*
-// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0
-// CHECK-NEXT: call [[WEAK]]* @swift_weakCopyInit([[WEAK]]* returned [[T0]], [[WEAK]]* [[T1]])
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]*
-// CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
-
-// TAILCALL: {{_?}}$S4weak1AVwCP:
-// TAILCALL: jmp {{_?}}swift_weakCopyInit
+// CHECK: [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to %swift.refcounted**
+// CHECK: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to %swift.refcounted**
+// CHECK: [[REF:%.*]] = load %swift.refcounted*, %swift.refcounted** [[SRC]]
+// CHECK: call %swift.refcounted* @swift_retain(%swift.refcounted* returned [[REF]])
+// CHECK: store %swift.refcounted* [[REF]], %swift.refcounted** [[DEST]]
+// CHECK: [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to %swift.refcounted**
+// CHECK: [[REF:%.*]] = load %swift.refcounted*, %swift.refcounted** [[DEST]]
+// CHECK: [[PTR:%.*]] = bitcast %swift.refcounted* [[REF]] to i8*
+// CHECK: [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[PTR]], {{(i64|i32)}} {{(16|8)}}
+// CHECK: [[CAST:%.*]] = bitcast i8* [[PTR2]] to %swift.opaque*
+// CHECK: [[CAST2:%.*]] = bitcast %swift.opaque* [[CAST]] to %T4weak1AV*
+// CHECK: [[CAST3:%.*]] = bitcast %T4weak1AV* [[CAST2]] to %swift.opaque*
+// CHECK: ret %swift.opaque* [[CAST3]]
// destroy
// CHECK: define linkonce_odr hidden void @"$S4weak1AVwxx"([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
@@ -166,6 +169,3 @@
// TAILCALL: {{_?}}$S4weak1AVwta:
// TAILCALL: jmp {{_?}}swift_weakTakeAssign
-
-// TAILCALL: {{_?}}$S4weak1AVwTK:
-// TAILCALL: jmp {{_?}}swift_weakTakeInit
diff --git a/test/IRGen/weak_value_witnesses.sil b/test/IRGen/weak_value_witnesses.sil
index 872cf7d..a3fbbd0 100644
--- a/test/IRGen/weak_value_witnesses.sil
+++ b/test/IRGen/weak_value_witnesses.sil
@@ -25,36 +25,38 @@
var y: T
}
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8JustWeakVwTK"(
-// CHECK: [[DEST:%.*]] = bitcast [24 x i8]* %dest to %T20weak_value_witnesses8JustWeakV*
-// CHECK-NEXT: [[SRC:%.*]] = bitcast [24 x i8]* %src to %T20weak_value_witnesses8JustWeakV*
-// CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds %T20weak_value_witnesses8JustWeakV, %T20weak_value_witnesses8JustWeakV* [[DEST]], i32 0, i32 0
-// CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds %T20weak_value_witnesses8JustWeakV, %T20weak_value_witnesses8JustWeakV* [[SRC]], i32 0, i32 0
-// CHECK-NEXT: call %swift.weak* @swift_weakTakeInit(%swift.weak* returned [[DEST_X]], %swift.weak* [[SRC_X]])
-// CHECK-NEXT: [[T0:%.*]] = bitcast %T20weak_value_witnesses8JustWeakV* [[DEST]] to %swift.opaque*
-// CHECK-NEXT: ret %swift.opaque* [[T0]]
+// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8JustWeakVwTK"(
// The default memcpy-ing witness is good enough for NoWeak.
// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses6NoWeakVwtk"(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self)
// CHECK-NOT: @"$S20weak_value_witnesses6NoWeakVwTK"
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8JustWeakVwCP"
+// CHECK: entry:
+// CHECK: load %swift.refcounted*, %swift.refcounted**
+// CHECK: call %swift.refcounted* @swift_retain
+// CHECK: store %swift.refcounted*
+// CHECK: load %swift.refcounted*
+// CHECK: getelementptr inbounds i8
+// CHECK: ret %swift.opaque
+// CHECK:}
+
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8SomeWeakVwCP"
+// CHECK:entry:
+// CHECK: load %swift.refcounted*, %swift.refcounted**
+// CHECK: call %swift.refcounted* @swift_retain
+// CHECK: store %swift.refcounted*
+// CHECK: load %swift.refcounted*
+// CHECK: getelementptr inbounds i8
+// CHECK: ret %swift.opaque
+// CHECK:}
+
// Weak references must be taken by swift_weakTakeInit.
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8SomeWeakVwtk"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %SomeWeak)
// CHECK: call %swift.weak* @swift_weakTakeInit
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8SomeWeakVwTK"(
-// CHECK: [[DEST:%.*]] = bitcast [24 x i8]* %dest to %T20weak_value_witnesses8SomeWeakV*
-// CHECK-NEXT: [[SRC:%.*]] = bitcast [24 x i8]* %src to %T20weak_value_witnesses8SomeWeakV*
-// CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds %T20weak_value_witnesses8SomeWeakV, %T20weak_value_witnesses8SomeWeakV* [[DEST]], i32 0, i32 0
-// CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds %T20weak_value_witnesses8SomeWeakV, %T20weak_value_witnesses8SomeWeakV* [[SRC]], i32 0, i32 0
-// CHECK-NEXT: [[T0:%.*]] = load %T20weak_value_witnesses1CC*, %T20weak_value_witnesses1CC** [[SRC_X]], align 8
-// CHECK-NEXT: store %T20weak_value_witnesses1CC* [[T0]], %T20weak_value_witnesses1CC** [[DEST_X]], align 8
-// CHECK-NEXT: [[DEST_Y:%.*]] = getelementptr inbounds %T20weak_value_witnesses8SomeWeakV, %T20weak_value_witnesses8SomeWeakV* [[DEST]], i32 0, i32 1
-// CHECK-NEXT: [[SRC_Y:%.*]] = getelementptr inbounds %T20weak_value_witnesses8SomeWeakV, %T20weak_value_witnesses8SomeWeakV* [[SRC]], i32 0, i32 1
-// CHECK-NEXT: call %swift.weak* @swift_weakTakeInit(%swift.weak* returned [[DEST_Y]], %swift.weak* [[SRC_Y]])
-// CHECK-NEXT: [[T0:%.*]] = bitcast %T20weak_value_witnesses8SomeWeakV* [[DEST]] to %swift.opaque*
-// CHECK-NEXT: ret %swift.opaque* [[T0]]
+// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8SomeWeakVwTK"(
// Generic types must be taken using their value witness.
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses3GenVwtk"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %"Gen<T>")
diff --git a/test/Inputs/resilient_struct.swift b/test/Inputs/resilient_struct.swift
index 01982d4..902e25e 100644
--- a/test/Inputs/resilient_struct.swift
+++ b/test/Inputs/resilient_struct.swift
@@ -77,3 +77,13 @@
self.d = d
}
}
+
+public class Referent {}
+
+public struct ResilientWeakRef {
+ public weak var ref: Referent?
+
+ public init (_ r: Referent) {
+ ref = r
+ }
+}
diff --git a/test/Interpreter/Inputs/enum-nonexhaustivity.h b/test/Interpreter/Inputs/enum-nonexhaustivity.h
index 2bfc08a..47b9602 100644
--- a/test/Interpreter/Inputs/enum-nonexhaustivity.h
+++ b/test/Interpreter/Inputs/enum-nonexhaustivity.h
@@ -4,10 +4,10 @@
NonExhaustiveEnumC = 2,
} __attribute__((enum_extensibility(open)));
-enum NonExhaustiveEnum getExpectedValue(void) {
+static enum NonExhaustiveEnum getExpectedValue(void) {
return NonExhaustiveEnumB;
}
-enum NonExhaustiveEnum getUnexpectedValue(void) {
+static enum NonExhaustiveEnum getUnexpectedValue(void) {
return (enum NonExhaustiveEnum)3;
}
@@ -17,9 +17,9 @@
LyingExhaustiveEnumC = 2,
} __attribute__((enum_extensibility(closed)));
-enum LyingExhaustiveEnum getExpectedLiarValue(void) {
+static enum LyingExhaustiveEnum getExpectedLiarValue(void) {
return LyingExhaustiveEnumB;
}
-enum LyingExhaustiveEnum getUnexpectedLiarValue(void) {
+static enum LyingExhaustiveEnum getUnexpectedLiarValue(void) {
return (enum LyingExhaustiveEnum)3;
}
diff --git a/test/Interpreter/Inputs/unions-and-bitfields.h b/test/Interpreter/Inputs/unions-and-bitfields.h
index 596603b..e870061 100644
--- a/test/Interpreter/Inputs/unions-and-bitfields.h
+++ b/test/Interpreter/Inputs/unions-and-bitfields.h
@@ -50,12 +50,12 @@
};
};
-void populate(void *memory) {
+static void populate(void *memory) {
const uint32_t value = 0x11223344;
memcpy(memory, &value, sizeof(value));
}
-void populateAtOffset(void *memory) {
+static void populateAtOffset(void *memory) {
const uint32_t value = 0x11223344;
memcpy((char *)memory + sizeof(uint32_t), &value, sizeof(value));
}
diff --git a/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h b/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h
index d07687e..7339685 100644
--- a/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h
+++ b/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h
@@ -4,9 +4,9 @@
int barGlobalFunc(int a);
-int barGlobalVariable = 1;
+extern int barGlobalVariable;
-int barGlobalVariableOldEnumElement = 1;
+extern int barGlobalVariableOldEnumElement;
int barGlobalFuncOldName(int a);
diff --git a/test/Migrator/qualified-replacement.swift b/test/Migrator/qualified-replacement.swift
index a8e68b3..47bb412 100644
--- a/test/Migrator/qualified-replacement.swift
+++ b/test/Migrator/qualified-replacement.swift
@@ -14,8 +14,6 @@
_ = Cities.CityKind.Town
_ = ToplevelType()
_ = ToplevelType(recordName: "")
- bar(.orderedSame)
}
func foo(_: ToplevelType) {}
-func bar(_ : FooComparisonResult) {}
diff --git a/test/Migrator/qualified-replacement.swift.expected b/test/Migrator/qualified-replacement.swift.expected
index 7b1344c..b3ec305 100644
--- a/test/Migrator/qualified-replacement.swift.expected
+++ b/test/Migrator/qualified-replacement.swift.expected
@@ -10,12 +10,10 @@
_ = NewPropertyUserInterface.newFieldPlus
NewPropertyUserInterface.newMethodPlus(1)
_ = NewFooComparisonResult.NewFooOrderedSame
- let _ : FooComparisonResult = .NewFooOrderedSame
+ let _ : FooComparisonResult = NewFooComparisonResult.NewFooOrderedSame
_ = NewCityKind.NewTown
_ = ToplevelWrapper.internalType()
_ = ToplevelWrapper.internalType(recordName: "")
- bar(.NewFooOrderedSame)
}
func foo(_: ToplevelWrapper.internalType) {}
-func bar(_ : FooComparisonResult) {}
diff --git a/test/NameBinding/import-resolution-overload.swift b/test/NameBinding/import-resolution-overload.swift
index 0e8bcd3..e453a7e 100644
--- a/test/NameBinding/import-resolution-overload.swift
+++ b/test/NameBinding/import-resolution-overload.swift
@@ -55,7 +55,7 @@
var foo: Int { return 0 }
}
-// CHECK-LABEL: func_decl "testHasFooSub(_:)"
+// CHECK-LABEL: func_decl{{.*}}"testHasFooSub(_:)"
func testHasFooSub(_ hfs: HasFooSub) -> Int {
// CHECK: return_stmt
// CHECK-NOT: func_decl
@@ -67,7 +67,7 @@
var bar: Int { return 0 }
}
-// CHECK-LABEL: func_decl "testHasBar(_:)"
+// CHECK-LABEL: func_decl{{.*}}"testHasBar(_:)"
func testHasBar(_ hb: HasBar) -> Int {
// CHECK: return_stmt
// CHECK-NOT: func_decl
diff --git a/test/Parse/if_expr.swift b/test/Parse/if_expr.swift
index aa20ad4..3378ba7 100644
--- a/test/Parse/if_expr.swift
+++ b/test/Parse/if_expr.swift
@@ -1,6 +1,6 @@
// RUN: %target-swift-frontend -dump-ast %s 2>&1 | %FileCheck %s
-// CHECK: (func_decl "r13756261(_:_:)"
+// CHECK: (func_decl{{.*}}"r13756261(_:_:)"
func r13756261(_ x: Bool, _ y: Int) -> Int {
// CHECK: (if_expr
// CHECK: (call_expr
@@ -15,7 +15,7 @@
return (x) ? y : (x) ? y : (x) ? y : y
}
-// CHECK: (func_decl "r13756221(_:_:)"
+// CHECK: (func_decl{{.*}}"r13756221(_:_:)"
func r13756221(_ x: Bool, _ y: Int) -> Int {
// CHECK: (if_expr
// CHECK: (call_expr
@@ -33,7 +33,7 @@
: y
}
-// CHECK: (func_decl "telescoping_if(_:_:)"
+// CHECK: (func_decl{{.*}}"telescoping_if(_:_:)"
func telescoping_if(_ x: Bool, _ y: Int) -> Int {
// CHECK: (if_expr
// CHECK: (call_expr
@@ -69,7 +69,7 @@
func +<< (x: Bool, y: Bool) -> Bool {}
func +== (x: Bool, y: Bool) -> Bool {}
-// CHECK: (func_decl "prec_above(_:_:_:)"
+// CHECK: (func_decl{{.*}}"prec_above(_:_:_:)"
func prec_above(_ x: Bool, _ y: Bool, _ z: Bool) -> Bool {
// (x +>> y) ? (y +>> z) : ((x +>> y) ? (y +>> z) : (x +>> y))
// CHECK: (if_expr
@@ -82,7 +82,7 @@
return x +>> y ? y +>> z : x +>> y ? y +>> z : x +>> y
}
-// CHECK: (func_decl "prec_below(_:_:_:)"
+// CHECK: (func_decl{{.*}}"prec_below(_:_:_:)"
func prec_below(_ x: Bool, _ y: Bool, _ z: Bool) -> Bool {
// The middle arm of the ternary is max-munched, so this is:
// ((x +<< (y ? (y +<< z) : x)) +<< (y ? (y +<< z) : x)) +<< y
@@ -102,7 +102,7 @@
return x +<< y ? y +<< z : x +<< y ? y +<< z : x +<< y
}
-// CHECK: (func_decl "prec_equal(_:_:_:)"
+// CHECK: (func_decl{{.*}}"prec_equal(_:_:_:)"
func prec_equal(_ x: Bool, _ y: Bool, _ z: Bool) -> Bool {
// The middle arm of the ternary is max-munched, so this is:
// x +== (y ? (y +== z) : (x +== (y ? (y +== z) : (x +== y))))
diff --git a/test/SILOptimizer/access_enforcement_opts.sil b/test/SILOptimizer/access_enforcement_opts.sil
index 0ab5dcc..c5dc155 100644
--- a/test/SILOptimizer/access_enforcement_opts.sil
+++ b/test/SILOptimizer/access_enforcement_opts.sil
@@ -32,9 +32,6 @@
return %6 : $X
}
-// Preserve begin/end scope for nested conflicts,
-// after inlining (read|modify)AndPerform.
-//
// func testNestedAccess() {
// readAndPerform(&globalX) {
// globalX = X()
@@ -47,6 +44,9 @@
// globalX.i = 12
// }
// }
+// Preserve begin/end scope for nested conflicts,
+// after inlining (read|modify)AndPerform.
+//
// CHECK-LABEL: sil hidden @testNestedAccess : $@convention(thin) () -> () {
// CHECK: [[F1:%.*]] = function_ref @testNestedAccessClosure1 : $@convention(thin) () -> ()
// CHECK: [[C1:%.*]] = convert_function [[F1]] : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
@@ -144,13 +144,13 @@
return %7 : $()
}
-// Demote disjoint global access to non-nested access.
-//
// func testDisjointAccess() {
// modifyAndPerform(&globalOtherX) {
// globalX.i = 12 // no-trap
// }
// }
+// Demote disjoint global access to non-nested access.
+//
// CHECK-LABEL: sil hidden @testDisjointAccess : $@convention(thin) () -> () {
// CHECK: bb0:
// CHECK: [[GLOBALX:%.*]] = global_addr @globalOtherX : $*X
@@ -194,6 +194,11 @@
// _blackHole(x.i) // no-trap
// }
// }
+// Demote both read accesses to non_nested, then remove the local outer access.
+//
+// CHECK-LABEL: sil @testCaptureReadRead : $@convention(thin) () -> () {
+// CHECK-NOT: begin_access
+// CHECK-LABEL: } // end sil function 'testCaptureReadRead'
sil @testCaptureReadRead : $@convention(thin) () -> () {
bb0:
%0 = alloc_stack $X, var, name "x"
@@ -215,6 +220,9 @@
return %18 : $()
}
+// CHECK-LABEL: sil private @testCaptureReadReadClosure1 : $@convention(thin) (@inout_aliasable X) -> () {
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %0 : $*X
+// CHECK-LABEL: } // end sil function 'testCaptureReadReadClosure1'
sil private @testCaptureReadReadClosure1 : $@convention(thin) (@inout_aliasable X) -> () {
bb0(%0 : $*X):
%2 = begin_access [read] [dynamic] %0 : $*X
@@ -228,13 +236,18 @@
return %11 : $()
}
-// Without allocBoxtoStack:
+// Without allocBoxToStack:
// public func testCaptureBoxReadRead() {
// var x = X()
// readAndPerform(&x) {
// _blackHole(x.i) // no-trap
// }
// }
+// Demote both read accesses to non_nested, and remove the local outer access.
+//
+// CHECK-LABEL: sil @testCaptureBoxReadRead : $@convention(thin) () -> () {
+// CHECK-NOT: begin_access
+// CHECK-LABEL: } // end sil function 'testCaptureBoxReadRead'
sil @testCaptureBoxReadRead : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var X }, var, name "x"
@@ -255,6 +268,10 @@
return %17 : $()
}
+// CHECK-LABEL: sil private @testCaptureBoxReadReadClosure1 : $@convention(thin) (@guaranteed { var X }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var X }, 0
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %1 : $*X
+// CHECK-LABEL: } // end sil function 'testCaptureBoxReadReadClosure1'
sil private @testCaptureBoxReadReadClosure1 : $@convention(thin) (@guaranteed { var X }) -> () {
bb0(%0 : ${ var X }):
%1 = project_box %0 : ${ var X }, 0
@@ -277,6 +294,7 @@
// // Inside never-escape closure: [modify] [dynamic]
// doTwo(c, { x = 42 })
// }
+// Demote each closure access to non_nested.
sil @testDoubleCapture : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Int64 }, var, name "x"
@@ -304,6 +322,10 @@
return %24 : $()
}
+// CHECK-LABEL: sil private @testDoubleCaptureClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function 'testDoubleCaptureClosure1'
sil private @testDoubleCaptureClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
bb0(%0 : ${ var Int64 }):
%1 = project_box %0 : ${ var Int64 }, 0
@@ -316,6 +338,9 @@
return %8 : $()
}
+// CHECK-LABEL: sil private @testDoubleCaptureClosure2 : $@convention(thin) (@inout_aliasable Int64) -> () {
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %0 : $*Int64
+// CHECK-LABEL: } // end sil function 'testDoubleCaptureClosure2'
sil private @testDoubleCaptureClosure2 : $@convention(thin) (@inout_aliasable Int64) -> () {
bb0(%0 : $*Int64):
%2 = integer_literal $Builtin.Int64, 42
@@ -327,14 +352,17 @@
return %7 : $()
}
-// Demote read/read access to [no_nested_conflict].
-//
// public func testInoutReadEscapeRead() {
// var x = 3
// let c = { let y = x; _blackHole(y) }
// readAndPerform(&x, closure: c)
// _blackHole(x)
// }
+// Demote read/read access to [no_nested_conflict].
+//
+// CHECK-LABEL: sil @testInoutReadEscapeRead : $@convention(thin) () -> () {
+// CHECK-NOT: begin_access
+// CHECK-LABEL: } // end sil function 'testInoutReadEscapeRead'
sil @testInoutReadEscapeRead : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Int64 }, var, name "x"
@@ -365,6 +393,10 @@
return %30 : $()
}
+// CHECK-LABEL: sil private @testInoutReadEscapeReadClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function 'testInoutReadEscapeReadClosure1'
sil private @testInoutReadEscapeReadClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
bb0(%0 : ${ var Int64 }):
%1 = project_box %0 : ${ var Int64 }, 0
@@ -385,6 +417,15 @@
// readAndPerform(&x, closure: c)
// _blackHole(x)
// }
+// Preserve the scope of the outer inout access. Runtime trap expected.
+//
+// CHECK-LABEL: sil @testInoutReadEscapeWrite : $@convention(thin) () -> () {
+// CHECK: [[BOX:%.*]] = alloc_box ${ var Int64 }, var, name "x"
+// CHECK: [[BOXADR:%.*]] = project_box [[BOX]] : ${ var Int64 }, 0
+// CHECK: begin_access [read] [dynamic] [[BOXADR]] : $*Int64
+// CHECK: apply
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function 'testInoutReadEscapeWrite'
sil @testInoutReadEscapeWrite : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Int64 }, var, name "x"
@@ -417,6 +458,10 @@
return %30 : $()
}
+// CHECK-LABEL: sil private @testInoutReadEscapeWriteClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function 'testInoutReadEscapeWriteClosure1'
sil private @testInoutReadEscapeWriteClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
bb0(%0 : ${ var Int64 }):
%1 = project_box %0 : ${ var Int64 }, 0
@@ -429,7 +474,21 @@
return %8 : $()
}
-// testInoutWriteEscapeRead()
+// public func testInoutWriteEscapeRead() {
+// var x = 3
+// let c = { let y = x; _blackHole(y) }
+// modifyAndPerform(&x, closure: c)
+// _blackHole(x)
+// }
+// Preserve the scope of the outer inout access. Runtime trap expected.
+//
+// CHECK-LABEL: sil @$S17enforce_with_opts24testInoutWriteEscapeReadyyF : $@convention(thin) () -> () {
+// CHECK: [[BOX:%.*]] = alloc_box ${ var Int64 }, var, name "x"
+// CHECK: [[BOXADR:%.*]] = project_box [[BOX]] : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [[BOXADR]] : $*Int64
+// CHECK: apply
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function '$S17enforce_with_opts24testInoutWriteEscapeReadyyF'
sil @$S17enforce_with_opts24testInoutWriteEscapeReadyyF : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Int64 }, var, name "x"
@@ -466,6 +525,10 @@
}
// closure #1 in testInoutWriteEscapeRead()
+// CHECK-LABEL: sil private @$S17enforce_with_opts24testInoutWriteEscapeReadyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %1
+// CHECK-LABEL: } // end sil function '$S17enforce_with_opts24testInoutWriteEscapeReadyyFyycfU_'
sil private @$S17enforce_with_opts24testInoutWriteEscapeReadyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
// %0
bb0(%0 : ${ var Int64 }):
@@ -482,7 +545,21 @@
return %12 : $()
}
-// testInoutWriteEscapeWrite()
+// public func testInoutWriteEscapeWrite() {
+// var x = 3
+// let c = { x = 42 }
+// modifyAndPerform(&x, closure: c)
+// _blackHole(x)
+// }
+// Preserve the scope of the outer inout access. Runtime trap expected.
+//
+// CHECK-LABEL: sil @$S17enforce_with_opts020testInoutWriteEscapeF0yyF : $@convention(thin) () -> () {
+// CHECK: [[BOX:%.*]] = alloc_box ${ var Int64 }, var, name "x"
+// CHECK: [[BOXADR:%.*]] = project_box [[BOX]] : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [[BOXADR]] : $*Int64
+// CHECK: apply
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function '$S17enforce_with_opts020testInoutWriteEscapeF0yyF'
sil @$S17enforce_with_opts020testInoutWriteEscapeF0yyF : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Int64 }, var, name "x"
@@ -518,7 +595,10 @@
return %30 : $()
}
-// closure #1 in testInoutWriteEscapeWrite()
+// CHECK-LABEL: sil private @$S17enforce_with_opts020testInoutWriteEscapeF0yyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function '$S17enforce_with_opts020testInoutWriteEscapeF0yyFyycfU_'
sil private @$S17enforce_with_opts020testInoutWriteEscapeF0yyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
// %0
bb0(%0 : ${ var Int64 }):
@@ -534,6 +614,13 @@
}
// testInoutReadNoescapeRead()
+// public func testInoutReadNoescapeRead() {
+// var x = 3
+// let c = { let y = x; _blackHole(y) }
+// doOne { readAndPerform(&x, closure: c) }
+// }
+// The outer inout access is not folded because we the optimizer can't resolve
+// the call to the inner closure from the outer closure.
sil @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyF : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Int64 }, var, name "x"
@@ -563,6 +650,10 @@
}
// closure #1 in testInoutReadNoescapeRead()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyycfU_'
sil private @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
// %0
bb0(%0 : ${ var Int64 }):
@@ -580,6 +671,9 @@
}
// closure #2 in testInoutReadNoescapeRead()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// CHECK: begin_access [read] [dynamic] %0 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyyXEfU0_'
sil private @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
// %0
// %1
@@ -597,6 +691,13 @@
}
// testInoutReadNoescapeWrite()
+// public func testInoutReadNoescapeWrite() {
+// var x = 3
+// let c = { x = 7 }
+// doOne { readAndPerform(&x, closure: c) }
+// }
+// The outer inout access scope (closure #2) must be preserved.
+// Expected to trap at runtime.
sil @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyF : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Int64 }, var, name "x"
@@ -626,6 +727,9 @@
}
// closure #1 in testInoutReadNoescapeWrite()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyycfU_'
sil private @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
// %0
bb0(%0 : ${ var Int64 }):
@@ -641,9 +745,10 @@
}
// closure #2 in testInoutReadNoescapeWrite()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// CHECK: begin_access [read] [dynamic] %0 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyyXEfU0_'
sil private @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
-// %0
-// %1
bb0(%0 : $*Int64, %1 : $@callee_guaranteed () -> ()):
debug_value_addr %0 : $*Int64, var, name "x", argno 1
debug_value %1 : $@callee_guaranteed () -> (), let, name "c", argno 2
@@ -658,20 +763,27 @@
}
// testInoutWriteEscapeReadClosure()
-sil @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyF : $@convention(thin) () -> () {
+// public func testInoutWriteNoescapeReadClosure() {
+// var x = 3
+// let c = { let y = x; _blackHole(y) }
+// doOne { modifyAndPerform(&x, closure: c) }
+// }
+// The outer inout access scope (closure #2) must be preserved.
+// Expected to trap at runtime.
+sil @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyF : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Int64 }, var, name "x"
%1 = project_box %0 : ${ var Int64 }, 0
%2 = integer_literal $Builtin.Int64, 3
%3 = struct $Int64 (%2 : $Builtin.Int64)
store %3 to %1 : $*Int64
- // function_ref closure #1 in testInoutWriteEscapeReadClosure()
- %5 = function_ref @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> ()
+ // function_ref closure #1 in testInoutWriteNoescapeReadClosure()
+ %5 = function_ref @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> ()
strong_retain %0 : ${ var Int64 }
%7 = partial_apply [callee_guaranteed] %5(%0) : $@convention(thin) (@guaranteed { var Int64 }) -> ()
debug_value %7 : $@callee_guaranteed () -> (), let, name "c"
- // function_ref closure #2 in testInoutWriteEscapeReadClosure()
- %9 = function_ref @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
+ // function_ref closure #2 in testInoutWriteNoescapeReadClosure()
+ %9 = function_ref @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
strong_retain %7 : $@callee_guaranteed () -> ()
%11 = partial_apply [callee_guaranteed] %9(%1, %7) : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
strong_retain %11 : $@callee_guaranteed () -> ()
@@ -686,8 +798,11 @@
return %20 : $()
}
-// closure #1 in testInoutWriteEscapeReadClosure()
-sil private @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// closure #1 in testInoutWriteNoescapeReadClosure()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyycfU_'
+sil private @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
// %0
bb0(%0 : ${ var Int64 }):
%1 = project_box %0 : ${ var Int64 }, 0
@@ -703,8 +818,11 @@
return %12 : $()
}
-// closure #2 in testInoutWriteEscapeReadClosure()
-sil private @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// closure #2 in testInoutWriteNoescapeReadClosure()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// CHECK: begin_access [modify] [dynamic] %0 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyyXEfU0_'
+sil private @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
// %0
// %1
bb0(%0 : $*Int64, %1 : $@callee_guaranteed () -> ()):
@@ -720,21 +838,26 @@
return %10 : $()
}
-// testInoutWriteEscapeWriteClosure()
-sil @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyF : $@convention(thin) () -> () {
+// testInoutWriteNoescapeWriteClosure()
+// public func testInoutWriteNoescapeWriteClosure() {
+// var x = 3
+// let c = { x = 7 }
+// doOne { modifyAndPerform(&x, closure: c) }
+// }
+sil @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyF : $@convention(thin) () -> () {
bb0:
%0 = alloc_box ${ var Int64 }, var, name "x"
%1 = project_box %0 : ${ var Int64 }, 0
%2 = integer_literal $Builtin.Int64, 3
%3 = struct $Int64 (%2 : $Builtin.Int64)
store %3 to %1 : $*Int64
- // function_ref closure #1 in testInoutWriteEscapeWriteClosure()
- %5 = function_ref @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> ()
+ // function_ref closure #1 in testInoutWriteNoescapeWriteClosure()
+ %5 = function_ref @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> ()
strong_retain %0 : ${ var Int64 }
%7 = partial_apply [callee_guaranteed] %5(%0) : $@convention(thin) (@guaranteed { var Int64 }) -> ()
debug_value %7 : $@callee_guaranteed () -> (), let, name "c"
- // function_ref closure #2 in testInoutWriteEscapeWriteClosure()
- %9 = function_ref @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
+ // function_ref closure #2 in testInoutWriteNoescapeWriteClosure()
+ %9 = function_ref @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
strong_retain %7 : $@callee_guaranteed () -> ()
%11 = partial_apply [callee_guaranteed] %9(%1, %7) : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
strong_retain %11 : $@callee_guaranteed () -> ()
@@ -749,8 +872,11 @@
return %20 : $()
}
-// closure #1 in testInoutWriteEscapeWriteClosure()
-sil private @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// closure #1 in testInoutWriteNoescapeWriteClosure()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyycfU_'
+sil private @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
// %0
bb0(%0 : ${ var Int64 }):
%1 = project_box %0 : ${ var Int64 }, 0
@@ -764,10 +890,11 @@
return %8 : $()
}
-// closure #2 in testInoutWriteEscapeWriteClosure()
-sil private @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
-// %0
-// %1
+// closure #2 in testInoutWriteNoescapeWriteClosure()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// CHECK: begin_access [modify] [dynamic] %0 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyyXEfU0_'
+sil private @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
bb0(%0 : $*Int64, %1 : $@callee_guaranteed () -> ()):
debug_value_addr %0 : $*Int64, var, name "x", argno 1
debug_value %1 : $@callee_guaranteed () -> (), let, name "c", argno 2
diff --git a/test/SILOptimizer/definite-init-wrong-scope2.swift b/test/SILOptimizer/definite-init-wrong-scope2.swift
index 4e05133..5dec46c 100644
--- a/test/SILOptimizer/definite-init-wrong-scope2.swift
+++ b/test/SILOptimizer/definite-init-wrong-scope2.swift
@@ -1,5 +1,5 @@
// RUN: %target-swift-frontend -emit-sil %s -Onone -Xllvm -sil-print-debuginfo \
-// RUN: -o /dev/null -Xllvm -sil-print-after=definite-init \
+// RUN: -o /dev/null -Xllvm -sil-print-after=raw-sil-inst-lowering \
// RUN: -Xllvm -sil-print-only-functions=$S8patatino4BearC6before7before26during5afterACSb_S3btKcfc \
// RUN: 2>&1 | %FileCheck %s
// REQUIRES: executable_test
diff --git a/test/SILOptimizer/definite-init-wrongscope.swift b/test/SILOptimizer/definite-init-wrongscope.swift
index aeabae3..98b241f 100644
--- a/test/SILOptimizer/definite-init-wrongscope.swift
+++ b/test/SILOptimizer/definite-init-wrongscope.swift
@@ -1,5 +1,5 @@
// RUN: %target-swift-frontend -primary-file %s -Onone -emit-sil -Xllvm \
-// RUN: -sil-print-after=definite-init -Xllvm \
+// RUN: -sil-print-after=raw-sil-inst-lowering -Xllvm \
// RUN: -sil-print-only-functions=$S3del1MC4fromAcA12WithDelegate_p_tKcfc \
// RUN: -Xllvm -sil-print-debuginfo -o /dev/null 2>&1 | %FileCheck %s
diff --git a/test/SILOptimizer/definite_init_crashes.sil b/test/SILOptimizer/definite_init_crashes.sil
index b7bce94..e848ce1 100644
--- a/test/SILOptimizer/definite_init_crashes.sil
+++ b/test/SILOptimizer/definite_init_crashes.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering | %FileCheck %s
// These are all regression tests to ensure that the memory promotion pass
// doesn't crash.
diff --git a/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil b/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
index 8127e47..f767856 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -verify | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering -verify | %FileCheck %s
// This test only tests mark_uninitialized [delegatingself]
diff --git a/test/SILOptimizer/definite_init_markuninitialized_derivedself.sil b/test/SILOptimizer/definite_init_markuninitialized_derivedself.sil
index 65934f0..d4c630e 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_derivedself.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_derivedself.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -verify | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering -verify | %FileCheck %s
// This test only tests mark_uninitialized [derivedself]
diff --git a/test/SILOptimizer/definite_init_markuninitialized_rootself.sil b/test/SILOptimizer/definite_init_markuninitialized_rootself.sil
index 4c86e67..2cfd26f 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_rootself.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_rootself.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -verify | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering -verify | %FileCheck %s
// This file tests mark_uninitialized [rootself]
diff --git a/test/SILOptimizer/definite_init_markuninitialized_var.sil b/test/SILOptimizer/definite_init_markuninitialized_var.sil
index f1eef16..31cf09e 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_var.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_var.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -verify | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering -verify | %FileCheck %s
// This file contains tests that test diagnostics emitted for var initialization
// by DI.
diff --git a/test/SILOptimizer/definite_init_scalarization_test.sil b/test/SILOptimizer/definite_init_scalarization_test.sil
index d79d250..e1699fb 100644
--- a/test/SILOptimizer/definite_init_scalarization_test.sil
+++ b/test/SILOptimizer/definite_init_scalarization_test.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering | %FileCheck %s
//
// Make sure that we properly scalarize tuples.
//
diff --git a/test/SILOptimizer/di-conditional-destroy-scope.swift b/test/SILOptimizer/di-conditional-destroy-scope.swift
index 4b6bee9..2e015b3 100644
--- a/test/SILOptimizer/di-conditional-destroy-scope.swift
+++ b/test/SILOptimizer/di-conditional-destroy-scope.swift
@@ -1,5 +1,5 @@
// RUN: %target-swift-frontend -emit-sil %s -Onone -Xllvm \
-// RUN: -sil-print-after=definite-init -Xllvm \
+// RUN: -sil-print-after=raw-sil-inst-lowering -Xllvm \
// RUN: -sil-print-only-functions=$S2fs36RecursibleDirectoryContentsGeneratorC4path10fileSystemAcA12AbsolutePathV_AA04FileH0_ptKc33_F8B132991B28208F48606E87DC165393Llfc \
// RUN: -Xllvm -sil-print-debuginfo -o /dev/null 2>&1 | %FileCheck %s
diff --git a/test/SILOptimizer/retain_release_code_motion.sil b/test/SILOptimizer/retain_release_code_motion.sil
index e10fe72..c2b2e28 100644
--- a/test/SILOptimizer/retain_release_code_motion.sil
+++ b/test/SILOptimizer/retain_release_code_motion.sil
@@ -1,4 +1,5 @@
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -retain-sinking -late-release-hoisting %s | %FileCheck %s
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -release-hoisting %s | %FileCheck --check-prefix=CHECK-RELEASE-HOISTING %s
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -retain-sinking -retain-sinking -late-release-hoisting %s | %FileCheck --check-prefix=CHECK-MULTIPLE-RS-ROUNDS %s
import Builtin
@@ -60,6 +61,10 @@
case some(T)
}
+struct Unowned {
+ @sil_stored unowned let x: @sil_unowned Builtin.NativeObject
+}
+
sil @createS : $@convention(thin) () -> @owned S
sil @use_C2 : $@convention(thin) (C2) -> ()
@@ -620,3 +625,44 @@
return %10 : $()
}
+// CHECK-LABEL: sil @test_unowned
+// CHECK: bb0(%0 : $Builtin.NativeObject):
+// CHECK-NEXT: br bb1
+// CHECK: bb1:
+// CHECK-NEXT: tuple
+// CHECK-NEXT: return
+sil @test_unowned : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+ %1 = ref_to_unowned %0 : $Builtin.NativeObject to $@sil_unowned Builtin.NativeObject
+ %2 = struct $Unowned (%1 : $@sil_unowned Builtin.NativeObject)
+ retain_value %2: $Unowned
+ br bb1
+
+bb1:
+ release_value %2: $Unowned
+ %5 = tuple()
+ return %5 : $()
+}
+
+// CHECK-RELEASE-HOISTING-LABEL: sil @dont_eliminate_strong_retain_and_unowned_release_pair
+// CHECK-RELEASE-HOISTING: = function_ref @blocker
+// CHECK-RELEASE-HOISTING-NEXT: apply
+// CHECK-RELEASE-HOISTING-NEXT: strong_retain %0 : $Builtin.NativeObject
+// CHECK-RELEASE-HOISTING-NEXT: unowned_release %1 : $@sil_unowned Builtin.NativeObject
+sil @dont_eliminate_strong_retain_and_unowned_release_pair : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+ %1 = ref_to_unowned %0 : $Builtin.NativeObject to $@sil_unowned Builtin.NativeObject
+ %2 = struct $Unowned (%1 : $@sil_unowned Builtin.NativeObject)
+ retain_value %2: $Unowned
+ %b = function_ref @blocker : $@convention(thin) () -> ()
+ apply %b() : $@convention(thin) () -> ()
+ strong_retain %0: $Builtin.NativeObject
+ br bb1
+
+bb1:
+ release_value %2: $Unowned
+ apply %b() : $@convention(thin) () -> ()
+ strong_release %0: $Builtin.NativeObject
+ %5 = tuple()
+ return %5 : $()
+}
diff --git a/test/Serialization/Inputs/alias.swift b/test/Serialization/Inputs/alias.swift
index 730d15e..a94128f 100644
--- a/test/Serialization/Inputs/alias.swift
+++ b/test/Serialization/Inputs/alias.swift
@@ -36,3 +36,6 @@
public typealias GG = Outer.G
public typealias GInt = Outer.G<Int>
+
+public struct UnboundStruct<T> {}
+public typealias UnboundAlias<T: Comparable> = UnboundStruct<T>
diff --git a/test/Serialization/typealias.swift b/test/Serialization/typealias.swift
index a97201b..4b5c787 100644
--- a/test/Serialization/typealias.swift
+++ b/test/Serialization/typealias.swift
@@ -1,5 +1,6 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift -module-name alias -emit-module -o %t %S/Inputs/alias.swift
+// RUN: %target-build-swift -I %t %s -module-name typealias -emit-module-path %t/typealias.swiftmodule -o %t/typealias.o
// RUN: llvm-bcanalyzer %t/alias.swiftmodule | %FileCheck %s
// RUN: %target-build-swift -I %t %s -o %t/a.out
// RUN: %target-run %t/a.out | %FileCheck -check-prefix=OUTPUT %s
@@ -53,3 +54,5 @@
let x: GG<Int> = 0
let x2: GInt = 1
+
+public typealias TestUnbound = UnboundAlias
diff --git a/test/SourceKit/CodeComplete/complete_filter.swift b/test/SourceKit/CodeComplete/complete_filter.swift
index 3836c23..63e2d3f 100644
--- a/test/SourceKit/CodeComplete/complete_filter.swift
+++ b/test/SourceKit/CodeComplete/complete_filter.swift
@@ -70,6 +70,7 @@
// CHECK-NEXT: abc()
// CHECK-NEXT: b()
// CHECK-NEXT: c()
+// CHECK-NEXT: self
// CHECK-NEXT: ]
// CHECK-LABEL: Results for filterText: a [
// CHECK-NEXT: aaa()
diff --git a/test/SourceKit/CodeComplete/complete_group_overloads.swift b/test/SourceKit/CodeComplete/complete_group_overloads.swift
index a3414a0..b964f7b 100644
--- a/test/SourceKit/CodeComplete/complete_group_overloads.swift
+++ b/test/SourceKit/CodeComplete/complete_group_overloads.swift
@@ -85,10 +85,11 @@
}
// Inline a lonely group
// RUN: %complete-test -group=overloads -add-inner-results -no-inner-operators -tok=BAR_INIT_0 %s | %FileCheck -check-prefix=BAR_INIT_0 %s
-// BAR_INIT_0-NOT: (:
+// BAR_INIT_0-LABEL: (:
// BAR_INIT_0: ()
// BAR_INIT_0-NEXT: (x: A)
// BAR_INIT_0-NEXT: (x: B)
+// BAR_INIT_0-NEXT: .self
extension Bar {
func foo()
diff --git a/test/SourceKit/CodeComplete/complete_inner.swift b/test/SourceKit/CodeComplete/complete_inner.swift
index 9f41f4d..5bc1057 100644
--- a/test/SourceKit/CodeComplete/complete_inner.swift
+++ b/test/SourceKit/CodeComplete/complete_inner.swift
@@ -59,8 +59,10 @@
// TOP_LEVEL_0-LABEL: Results for filterText: foo [
// TOP_LEVEL_0-NEXT: Foo
+// TOP_LEVEL_0-NEXT: Foo.
// TOP_LEVEL_0-NEXT: Foo(
// TOP_LEVEL_0-NEXT: FooBar
+// TOP_LEVEL_0-NEXT: Foo.self
// TOP_LEVEL_0-NEXT: Foo()
// TOP_LEVEL_0-NEXT: ]
@@ -72,6 +74,7 @@
// TOP_LEVEL_0-NEXT: FooBar
// TOP_LEVEL_0-NEXT: FooBar.
// TOP_LEVEL_0-NEXT: FooBar(
+// TOP_LEVEL_0-NEXT: FooBar.self
// TOP_LEVEL_0-NEXT: FooBar()
// TOP_LEVEL_0-NEXT: FooBar(x: Foo)
// TOP_LEVEL_0-NEXT: FooBar.fooBar()
@@ -92,6 +95,7 @@
// TOP_LEVEL_1-NEXT: abc.
// TOP_LEVEL_1-NEXT: abc===
// TOP_LEVEL_1-NEXT: abc!==
+// TOP_LEVEL_1-NEXT: abc.self
// TOP_LEVEL_1-NEXT: abc.method()
// TOP_LEVEL_1-NEXT: abc.prop
// TOP_LEVEL_1-NEXT: ]
@@ -101,6 +105,7 @@
// TOP_LEVEL_1-NEXT: abd.
// TOP_LEVEL_1-NEXT: abd===
// TOP_LEVEL_1-NEXT: abd!==
+// TOP_LEVEL_1-NEXT: abd.self
// TOP_LEVEL_1-NEXT: abd.base()
// TOP_LEVEL_1-NEXT: ]
@@ -138,12 +143,14 @@
// FOOBAR_QUALIFIED_NOOP-NEXT: ]
// FOOBAR_QUALIFIED_NOOP-LABEL: Results for filterText: prop [
// FOOBAR_QUALIFIED_NOOP-NEXT: prop
+// FOOBAR_QUALIFIED_NOOP-NEXT: prop.self
// FOOBAR_QUALIFIED_NOOP-NEXT: prop.method()
// FOOBAR_QUALIFIED_NOOP-NEXT: prop.prop
// FOOBAR_QUALIFIED_NOOP-NEXT: ]
// RUN: %complete-test %s -group=none -no-include-exact-match -add-inner-results -no-inner-operators -tok=FOOBAR_QUALIFIED | %FileCheck %s -check-prefix=FOOBAR_QUALIFIED_NOEXACT
// FOOBAR_QUALIFIED_NOEXACT-LABEL: Results for filterText: prop [
+// FOOBAR_QUALIFIED_NOEXACT-NEXT: prop.self
// FOOBAR_QUALIFIED_NOEXACT-NEXT: prop.method()
// FOOBAR_QUALIFIED_NOEXACT-NEXT: prop.prop
// FOOBAR_QUALIFIED_NOEXACT-NEXT: ]
diff --git a/test/SourceKit/CodeComplete/complete_member.swift.response b/test/SourceKit/CodeComplete/complete_member.swift.response
index b4977f8..8f4a9ec 100644
--- a/test/SourceKit/CodeComplete/complete_member.swift.response
+++ b/test/SourceKit/CodeComplete/complete_member.swift.response
@@ -33,6 +33,15 @@
key.num_bytes_to_erase: 0,
key.associated_usrs: "s:15complete_member11FooProtocolP14fooInstanceVarSivp",
key.modulename: "complete_member"
+ },
+ {
+ key.kind: source.lang.swift.keyword,
+ key.name: "self",
+ key.sourcetext: "self",
+ key.description: "self",
+ key.typename: "FooProtocol",
+ key.context: source.codecompletion.context.thisclass,
+ key.num_bytes_to_erase: 0
}
]
}
diff --git a/test/SourceKit/CodeComplete/complete_requestlimit.swift b/test/SourceKit/CodeComplete/complete_requestlimit.swift
index ce191b4..2c5bba5 100644
--- a/test/SourceKit/CodeComplete/complete_requestlimit.swift
+++ b/test/SourceKit/CodeComplete/complete_requestlimit.swift
@@ -63,6 +63,7 @@
// B_INSTANCE_0_ALL: a
// B_INSTANCE_0_ALL-NEXT: b
// B_INSTANCE_0_ALL-NEXT: c
+// B_INSTANCE_0_ALL-NEXT: self
// B_INSTANCE_0_1: a
// B_INSTANCE_0_1-NOT: b
@@ -107,6 +108,7 @@
// OVERLOADS_ALL-NEXT: aaa(x: A)
// OVERLOADS_ALL-NEXT: aaa(x: B)
// OVERLOADS_ALL-NEXT: aab()
+// OVERLOADS_ALL-NEXT: self
// limit applies to top-level, not to subgroups
// OVERLOADS_1: aaa:
@@ -121,11 +123,11 @@
// If we return all the results, nextrequeststart == 0
// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw | %FileCheck -check-prefix=NEXT-END %s
// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -limit=5 | %FileCheck -check-prefix=NEXT-END %s
-// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -limit=2 | %FileCheck -check-prefix=NEXT-END %s
+// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -limit=3 | %FileCheck -check-prefix=NEXT-END %s
// NEXT-END: key.nextrequeststart: 0
// If we return the last result, nextrequeststart == 0
-// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -start=1 -limit=1 | %FileCheck -check-prefix=NEXT-END %s
+// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -start=2 -limit=1 | %FileCheck -check-prefix=NEXT-END %s
// Otherwise, it's the next result
// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -limit=1 | %FileCheck -check-prefix=NEXT1 %s
diff --git a/test/SourceKit/SyntaxMapData/Inputs/syntaxmap.swift b/test/SourceKit/SyntaxMapData/Inputs/syntaxmap.swift
index 29c1681..4ba4859 100644
--- a/test/SourceKit/SyntaxMapData/Inputs/syntaxmap.swift
+++ b/test/SourceKit/SyntaxMapData/Inputs/syntaxmap.swift
@@ -49,3 +49,8 @@
// unknownprotocol://awesomeguy.com
_ = -123
+
+func testArgumentLabels(in class: Int, _ case: (_ default: Int) -> Void) -> (in: Int, String) {
+ let result: (in: Int, String) = (0, "test")
+ return something ? result : (in: 2, "foo")
+}
diff --git a/test/SourceKit/SyntaxMapData/syntaxmap.swift.response b/test/SourceKit/SyntaxMapData/syntaxmap.swift.response
index 3e3e5e8..f8e4e84 100644
--- a/test/SourceKit/SyntaxMapData/syntaxmap.swift.response
+++ b/test/SourceKit/SyntaxMapData/syntaxmap.swift.response
@@ -1,6 +1,6 @@
{
key.offset: 0,
- key.length: 859,
+ key.length: 1049,
key.diagnostic_stage: source.diagnostic.stage.swift.parse,
key.syntaxmap: [
{
@@ -432,6 +432,141 @@
key.kind: source.lang.swift.syntaxtype.number,
key.offset: 854,
key.length: 4
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.keyword,
+ key.offset: 860,
+ key.length: 4
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 865,
+ key.length: 18
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 884,
+ key.length: 2
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 887,
+ key.length: 5
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.typeidentifier,
+ key.offset: 894,
+ key.length: 3
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.keyword,
+ key.offset: 899,
+ key.length: 1
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 901,
+ key.length: 4
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.keyword,
+ key.offset: 908,
+ key.length: 1
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 910,
+ key.length: 7
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.typeidentifier,
+ key.offset: 919,
+ key.length: 3
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.typeidentifier,
+ key.offset: 927,
+ key.length: 4
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 937,
+ key.length: 2
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.typeidentifier,
+ key.offset: 941,
+ key.length: 3
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.typeidentifier,
+ key.offset: 946,
+ key.length: 6
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.keyword,
+ key.offset: 958,
+ key.length: 3
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 962,
+ key.length: 6
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 971,
+ key.length: 2
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.typeidentifier,
+ key.offset: 975,
+ key.length: 3
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.typeidentifier,
+ key.offset: 980,
+ key.length: 6
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.number,
+ key.offset: 991,
+ key.length: 1
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.string,
+ key.offset: 994,
+ key.length: 6
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.keyword,
+ key.offset: 1004,
+ key.length: 6
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 1011,
+ key.length: 9
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 1023,
+ key.length: 6
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.identifier,
+ key.offset: 1033,
+ key.length: 2
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.number,
+ key.offset: 1037,
+ key.length: 1
+ },
+ {
+ key.kind: source.lang.swift.syntaxtype.string,
+ key.offset: 1040,
+ key.length: 5
}
]
}
diff --git a/test/TBD/Inputs/extension_types.swift b/test/TBD/Inputs/extension_types.swift
index f60ac6e..938526c 100644
--- a/test/TBD/Inputs/extension_types.swift
+++ b/test/TBD/Inputs/extension_types.swift
@@ -1,4 +1,20 @@
-public protocol Foreign {}
+public protocol Foreign {
+ func foreignMethod()
+ var foreignGet: Int { get }
+ var foreignGetSet: Int { get set }
+}
+public protocol ForeignInherit: Foreign {}
+extension ForeignInherit {
+ public func foreignMethod() {}
+ public var foreignGet: Int { return 0 }
+ public var foreignGetSet: Int {
+ get { return 0 }
+ set {}
+ }
+}
+
public struct ForeignStruct {}
-public struct ForeignStruct2 {}
+public struct ForeignStructInherit {}
+public struct ForeignStructInheritNoDefault {}
+public struct ForeignStructOneExtension {}
diff --git a/test/TBD/extension.swift b/test/TBD/extension.swift
deleted file mode 100644
index 35f1316..0000000
--- a/test/TBD/extension.swift
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: %empty-directory(%t)
-// RUN: %target-build-swift %S/Inputs/extension_types.swift -module-name ExtensionTypes -emit-module -emit-module-path %t/ExtensionTypes.swiftmodule
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t %s
-
-import ExtensionTypes
-
-public protocol Public {}
-internal protocol Internal {}
-private protocol Private {}
-
-extension ForeignStruct: Foreign {}
-extension ForeignStruct: Public {}
-extension ForeignStruct: Internal {}
-extension ForeignStruct: Private {}
-extension ForeignStruct2: Foreign, Public, Internal, Private {}
-
-public struct PublicStruct {}
-public struct PublicStruct2 {}
-internal struct InternalStruct {}
-internal struct InternalStruct2 {}
-private struct PrivateStruct {}
-private struct PrivateStruct2 {}
-
-extension PublicStruct: Foreign {}
-extension PublicStruct: Public {}
-extension PublicStruct: Internal {}
-extension PublicStruct: Private {}
-extension PublicStruct2: Foreign, Public, Internal, Private {}
-
-extension InternalStruct: Foreign {}
-extension InternalStruct: Public {}
-extension InternalStruct: Internal {}
-extension InternalStruct: Private {}
-extension InternalStruct2: Foreign, Public, Internal, Private {}
-
-extension PrivateStruct: Foreign {}
-extension PrivateStruct: Public {}
-extension PrivateStruct: Internal {}
-extension PrivateStruct: Private {}
-extension PrivateStruct2: Foreign, Public, Internal, Private {}
diff --git a/test/TBD/extension.swift.gyb b/test/TBD/extension.swift.gyb
new file mode 100644
index 0000000..49ad01a
--- /dev/null
+++ b/test/TBD/extension.swift.gyb
@@ -0,0 +1,94 @@
+// RUN: %empty-directory(%t)
+// RUN: %gyb %s > %t/main.swift
+
+// Other module is not resilient:
+// RUN: %empty-directory(%t/types)
+// RUN: %target-build-swift %S/Inputs/extension_types.swift -module-name ExtensionTypes -emit-module -emit-module-path %t/types/ExtensionTypes.swiftmodule
+// This module is both not resilient:
+// RUN: %target-swift-frontend -emit-ir -o%t/not_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift
+// ... and resilient:
+// RUN: %target-swift-frontend -emit-ir -o%t/not_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift -enable-resilience
+
+// Other module is resilient:
+// RUN: %empty-directory(%t/types)
+// RUN: %target-build-swift %S/Inputs/extension_types.swift -module-name ExtensionTypes -emit-module -emit-module-path %t/types/ExtensionTypes.swiftmodule -Xfrontend -enable-resilience
+// This module is both not resilient:
+// RUN: %target-swift-frontend -emit-ir -o%t/resilient_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift
+// ... and resilient:
+// RUN: %target-swift-frontend -emit-ir -o%t/resilient_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift -enable-resilience
+
+
+import ExtensionTypes
+
+// This generates all combinations of a public/internal/private struct
+// (plus a public one from another module) being extended to conform
+// to a public/internal/private protocol (plus a public one from
+// another module), both with and without inheritance/defaulting.
+
+%{
+local_decl_names = ["Public", "Internal", "Private"]
+all_decl_names = ["Foreign"] + local_decl_names
+decl_name_to_access = {
+ "Foreign": "public",
+ "Public": "public",
+ "Internal": "internal",
+ "Private": "fileprivate"
+}
+def conformanceBody(protocol):
+ return """
+ {access} func {name}Method() {{}}
+ {access} var {name}Get: Int {{ return 0 }}
+ {access} var {name}GetSet: Int {{
+ get {{ return 0 }}
+ set {{}}
+ }}
+ """.format(access = decl_name_to_access[protocol],
+ name = protocol.lower())
+}%
+
+% for name in local_decl_names:
+% access = name.lower()
+
+${access} protocol ${name} {
+ func ${access}Method()
+ var ${access}Get: Int { get }
+ var ${access}GetSet: Int { get set }
+}
+
+// Defaulted methods:
+${access} protocol ${name}Inherit: Foreign {}
+extension ${name}Inherit {
+ ${conformanceBody(name)}
+}
+
+${access} struct ${name}Struct {}
+${access} struct ${name}StructInherit {}
+${access} struct ${name}StructInheritNoDefault {}
+${access} struct ${name}StructOneExtension {}
+% end
+
+% for sname in all_decl_names:
+% access = sname.lower()
+
+% for pname in all_decl_names:
+// e.g. extension PublicStruct: Private { ... }
+extension ${sname}Struct: ${pname} {
+ ${conformanceBody(pname)}
+}
+
+// e.g. extension PublicStructInherit: PrivateInherit {}
+extension ${sname}StructInherit: ${pname}Inherit {}
+
+// e.g. extension PublicStructInheritNoDefault: PrivateInherit { ... }
+extension ${sname}StructInheritNoDefault: ${pname}Inherit {
+ ${conformanceBody(pname)}
+}
+% end
+
+// e.g. extension PublicStructOneExtension: Foreign, Public, Internal, Private { ... }
+extension ${sname}StructOneExtension: ${", ".join(p for p in all_decl_names)} {
+% for pname in all_decl_names:
+ ${conformanceBody(pname)}
+% end
+}
+% end
diff --git a/test/TBD/global.swift b/test/TBD/global.swift
index af400bf..3a3e6dd 100644
--- a/test/TBD/global.swift
+++ b/test/TBD/global.swift
@@ -1,4 +1,5 @@
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing -enable-resilience %s
public let publicLet: Int = 0
internal let internalLet: Int = 0
diff --git a/test/TBD/struct.swift b/test/TBD/struct.swift
index 9bd42bb..b3a9bb2 100644
--- a/test/TBD/struct.swift
+++ b/test/TBD/struct.swift
@@ -1,4 +1,5 @@
// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-resilience
public struct PublicNothing {}
@@ -44,6 +45,25 @@
}
}
+public struct PublicSubscripts {
+ public subscript(publicGet _: Int) -> Int { return 0 }
+ internal subscript(internalGet _: Int) -> Int { return 0 }
+ private subscript(privateGet _: Int) -> Int { return 0 }
+
+ public subscript(publicGetSet _: Int) -> Int {
+ get {return 0 }
+ set {}
+ }
+ internal subscript(internalGetSet _: Int) -> Int {
+ get {return 0 }
+ set {}
+ }
+ private subscript(privateGetSet _: Int) -> Int {
+ get {return 0 }
+ set {}
+ }
+}
+
public struct PublicStatics {
public static func publicStaticFunc() {}
internal static func internalStaticFunc() {}
@@ -135,6 +155,20 @@
}
}
+internal struct InternalSubscripts {
+ internal subscript(internalGet _: Int) -> Int { return 0 }
+ private subscript(privateGet _: Int) -> Int { return 0 }
+
+ internal subscript(internalGetSet _: Int) -> Int {
+ get {return 0 }
+ set {}
+ }
+ private subscript(privateGetSet _: Int) -> Int {
+ get {return 0 }
+ set {}
+ }
+}
+
internal struct InternalStatics {
internal static func internalStaticFunc() {}
private static func privateStaticFunc() {}
@@ -203,6 +237,15 @@
}
}
+private struct PrivateSubscripts {
+ private subscript(privateGet _: Int) -> Int { return 0 }
+
+ private subscript(privateGetSet _: Int) -> Int {
+ get {return 0 }
+ set {}
+ }
+}
+
private struct PrivateStatics {
private static func privateStaticFunc() {}
diff --git a/test/api-digester/Inputs/APINotesLeft/APINotesTest.h b/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
index 653c8d1..d7be123 100644
--- a/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
+++ b/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
@@ -28,3 +28,5 @@
@end
extern NSString *globalAttributeName;
+
+typedef NSString * CatAttributeName;
\ No newline at end of file
diff --git a/test/api-digester/Inputs/APINotesRight/APINotesTest.h b/test/api-digester/Inputs/APINotesRight/APINotesTest.h
index ddd4963..29e4572 100644
--- a/test/api-digester/Inputs/APINotesRight/APINotesTest.h
+++ b/test/api-digester/Inputs/APINotesRight/APINotesTest.h
@@ -28,3 +28,5 @@
@end
extern AnimalAttributeName globalAttributeName;
+
+typedef NSString * CatAttributeName NS_STRING_ENUM;
diff --git a/test/api-digester/Outputs/apinotes-diags.txt b/test/api-digester/Outputs/apinotes-diags.txt
index 01c7951..fa8e23c 100644
--- a/test/api-digester/Outputs/apinotes-diags.txt
+++ b/test/api-digester/Outputs/apinotes-diags.txt
@@ -1,5 +1,6 @@
/* RawRepresentable Changes */
+APINotesTest(APINotesTest.h): TypeAlias CatAttributeName(NSString) is now String representable
/* Removed Decls */
APINotesTest(APINotesTest.h): Func ObjcProt.protMemberFunc2() has been removed
diff --git a/test/api-digester/Outputs/apinotes-migrator-gen-revert.json b/test/api-digester/Outputs/apinotes-migrator-gen-revert.json
index 97c463a..6025fa4 100644
--- a/test/api-digester/Outputs/apinotes-migrator-gen-revert.json
+++ b/test/api-digester/Outputs/apinotes-migrator-gen-revert.json
@@ -2,9 +2,9 @@
{
"DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+ "NodeAnnotation": "RevertSimpleStringRepresentableUpdate",
+ "ChildIndex": "1",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
"LeftComment": "AnimalAttributeName",
"RightUsr": "",
"RightComment": "String",
@@ -13,174 +13,9 @@
{
"DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
- "NodeAnnotation": "RevertDictionaryKeyUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
- "LeftComment": "",
- "RightUsr": "",
- "RightComment": "",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
"NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
- "LeftComment": "AnimalAttributeName",
- "RightUsr": "",
- "RightComment": "String",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "RevertDictionaryKeyUpdate",
"ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
- "LeftComment": "",
- "RightUsr": "",
- "RightComment": "",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
- "LeftComment": "AnimalAttributeName",
- "RightUsr": "",
- "RightComment": "String",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "RevertOptionalDictionaryKeyUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
- "LeftComment": "",
- "RightUsr": "",
- "RightComment": "",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
- "LeftComment": "AnimalAttributeName",
- "RightUsr": "",
- "RightComment": "String",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "RevertOptionalDictionaryKeyUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
- "LeftComment": "",
- "RightUsr": "",
- "RightComment": "",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
- "LeftComment": "AnimalAttributeName",
- "RightUsr": "",
- "RightComment": "String",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "RevertArrayMemberUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
- "LeftComment": "",
- "RightUsr": "",
- "RightComment": "",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
- "LeftComment": "AnimalAttributeName",
- "RightUsr": "",
- "RightComment": "String",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "RevertArrayMemberUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
- "LeftComment": "",
- "RightUsr": "",
- "RightComment": "",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
- "LeftComment": "AnimalAttributeName",
- "RightUsr": "",
- "RightComment": "String",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "RevertOptionalArrayMemberUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
- "LeftComment": "",
- "RightUsr": "",
- "RightComment": "",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
- "LeftComment": "AnimalAttributeName",
- "RightUsr": "",
- "RightComment": "String",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "RevertOptionalArrayMemberUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
- "LeftComment": "",
- "RightUsr": "",
- "RightComment": "",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
"LeftComment": "AnimalAttributeName",
"RightUsr": "",
"RightComment": "String",
@@ -192,28 +27,105 @@
"NodeAnnotation": "RevertSimpleOptionalStringRepresentableUpdate",
"ChildIndex": "1",
"LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
- "LeftComment": "",
+ "LeftComment": "AnimalAttributeName",
"RightUsr": "",
- "RightComment": "",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "RevertSimpleStringRepresentableUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
- "LeftComment": "",
- "RightUsr": "",
- "RightComment": "",
+ "RightComment": "String",
"ModuleName": "APINotesTest"
},
{
"DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
"NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "1:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
+ "LeftComment": "AnimalAttributeName",
+ "RightUsr": "",
+ "RightComment": "String",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "RevertDictionaryKeyUpdate",
"ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+ "LeftComment": "AnimalAttributeName",
+ "RightUsr": "",
+ "RightComment": "String",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "1:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+ "LeftComment": "AnimalAttributeName",
+ "RightUsr": "",
+ "RightComment": "String",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "RevertArrayMemberUpdate",
+ "ChildIndex": "1",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
+ "LeftComment": "AnimalAttributeName",
+ "RightUsr": "",
+ "RightComment": "String",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "1:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
+ "LeftComment": "AnimalAttributeName",
+ "RightUsr": "",
+ "RightComment": "String",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "RevertOptionalDictionaryKeyUpdate",
+ "ChildIndex": "1",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
+ "LeftComment": "AnimalAttributeName",
+ "RightUsr": "",
+ "RightComment": "String",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "1:0:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
+ "LeftComment": "AnimalAttributeName",
+ "RightUsr": "",
+ "RightComment": "String",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "RevertOptionalArrayMemberUpdate",
+ "ChildIndex": "1",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
+ "LeftComment": "AnimalAttributeName",
+ "RightUsr": "",
+ "RightComment": "String",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "1:0:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
"LeftComment": "AnimalAttributeName",
"RightUsr": "",
"RightComment": "String",
diff --git a/test/api-digester/Outputs/apinotes-migrator-gen.json b/test/api-digester/Outputs/apinotes-migrator-gen.json
index 73ca26d..5e0810d 100644
--- a/test/api-digester/Outputs/apinotes-migrator-gen.json
+++ b/test/api-digester/Outputs/apinotes-migrator-gen.json
@@ -1,10 +1,10 @@
[
{
"DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+ "NodeKind": "Var",
+ "NodeAnnotation": "SimpleStringRepresentableUpdate",
+ "ChildIndex": "0",
+ "LeftUsr": "c:@globalAttributeName",
"LeftComment": "String",
"RightUsr": "",
"RightComment": "AnimalAttributeName",
@@ -12,10 +12,21 @@
},
{
"DiffItemKind": "CommonDiffItem",
+ "NodeKind": "TypeAlias",
+ "NodeAnnotation": "TypeAliasDeclToRawRepresentable",
+ "ChildIndex": "0",
+ "LeftUsr": "c:APINotesTest.h@T@CatAttributeName",
+ "LeftComment": "NSString",
+ "RightUsr": "",
+ "RightComment": "String",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
- "NodeAnnotation": "DictionaryKeyUpdate",
+ "NodeAnnotation": "SimpleStringRepresentableUpdate",
"ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
"LeftComment": "String",
"RightUsr": "",
"RightComment": "AnimalAttributeName",
@@ -25,162 +36,8 @@
"DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
"NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "DictionaryKeyUpdate",
"ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "OptionalDictionaryKeyUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "OptionalDictionaryKeyUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "ArrayMemberUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "ArrayMemberUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "OptionalArrayMemberUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "OptionalArrayMemberUpdate",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "AnimalAttributeName",
- "ModuleName": "APINotesTest"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1:0",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
"LeftComment": "String",
"RightUsr": "",
"RightComment": "AnimalAttributeName",
@@ -200,9 +57,20 @@
{
"DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
- "NodeAnnotation": "SimpleStringRepresentableUpdate",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "1:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
+ "LeftComment": "String",
+ "RightUsr": "",
+ "RightComment": "AnimalAttributeName",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "DictionaryKeyUpdate",
"ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
"LeftComment": "String",
"RightUsr": "",
"RightComment": "AnimalAttributeName",
@@ -212,8 +80,8 @@
"DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
"NodeAnnotation": "TypeRewritten",
- "ChildIndex": "1",
- "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
+ "ChildIndex": "1:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
"LeftComment": "String",
"RightUsr": "",
"RightComment": "AnimalAttributeName",
@@ -222,12 +90,67 @@
{
"DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
- "NodeAnnotation": "GetterToProperty",
- "ChildIndex": "0",
- "LeftUsr": "c:objc(pl)TypeWithMethod(im)getPropertyA",
- "LeftComment": "",
+ "NodeAnnotation": "ArrayMemberUpdate",
+ "ChildIndex": "1",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
+ "LeftComment": "String",
"RightUsr": "",
- "RightComment": "propertyA",
+ "RightComment": "AnimalAttributeName",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "1:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
+ "LeftComment": "String",
+ "RightUsr": "",
+ "RightComment": "AnimalAttributeName",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "OptionalDictionaryKeyUpdate",
+ "ChildIndex": "1",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
+ "LeftComment": "String",
+ "RightUsr": "",
+ "RightComment": "AnimalAttributeName",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "1:0:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
+ "LeftComment": "String",
+ "RightUsr": "",
+ "RightComment": "AnimalAttributeName",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "OptionalArrayMemberUpdate",
+ "ChildIndex": "1",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
+ "LeftComment": "String",
+ "RightUsr": "",
+ "RightComment": "AnimalAttributeName",
+ "ModuleName": "APINotesTest"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "1:0:0",
+ "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
+ "LeftComment": "String",
+ "RightUsr": "",
+ "RightComment": "AnimalAttributeName",
"ModuleName": "APINotesTest"
},
{
@@ -243,25 +166,17 @@
},
{
"DiffItemKind": "CommonDiffItem",
- "NodeKind": "Var",
- "NodeAnnotation": "SimpleStringRepresentableUpdate",
+ "NodeKind": "Function",
+ "NodeAnnotation": "GetterToProperty",
"ChildIndex": "0",
- "LeftUsr": "c:@globalAttributeName",
- "LeftComment": "String",
+ "LeftUsr": "c:objc(pl)TypeWithMethod(im)getPropertyA",
+ "LeftComment": "",
"RightUsr": "",
- "RightComment": "AnimalAttributeName",
+ "RightComment": "propertyA",
"ModuleName": "APINotesTest"
},
{
"DiffItemKind": "TypeMemberDiffItem",
- "Usr": "c:@globalAttributeName",
- "OldPrintedName": "globalAttributeName",
- "OldTypeName": "",
- "NewPrintedName": "globalAttributeName",
- "NewTypeName": "AnimalAttributeName"
- },
- {
- "DiffItemKind": "TypeMemberDiffItem",
"Usr": "c:@ANTGlobalValue",
"OldPrintedName": "oldMember",
"OldTypeName": "OldType",
@@ -270,6 +185,14 @@
},
{
"DiffItemKind": "TypeMemberDiffItem",
+ "Usr": "c:@globalAttributeName",
+ "OldPrintedName": "globalAttributeName",
+ "OldTypeName": "",
+ "NewPrintedName": "globalAttributeName",
+ "NewTypeName": "AnimalAttributeName"
+ },
+ {
+ "DiffItemKind": "TypeMemberDiffItem",
"Usr": "c:objc(pl)TypeWithMethod(cm)plusPrint",
"OldPrintedName": "plusPrint()",
"OldTypeName": "SwiftTypeWithMethodLeft",
diff --git a/test/api-digester/Outputs/macro-gen.json b/test/api-digester/Outputs/macro-gen.json
index 876f7cf..5f7ffd4 100644
--- a/test/api-digester/Outputs/macro-gen.json
+++ b/test/api-digester/Outputs/macro-gen.json
@@ -1,13 +1,35 @@
[
{
"DiffItemKind": "CommonDiffItem",
- "NodeKind": "Constructor",
+ "NodeKind": "Function",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "0",
+ "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
+ "LeftComment": "String",
+ "RightUsr": "",
+ "RightComment": "Int",
+ "ModuleName": "macrogenleft"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
"NodeAnnotation": "TypeRewritten",
"ChildIndex": "1",
- "LeftUsr": "s:12macrogenleft2S1VyACSicfc",
+ "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
"LeftComment": "Int",
"RightUsr": "",
- "RightComment": "Double",
+ "RightComment": "() -> ()",
+ "ModuleName": "macrogenleft"
+ },
+ {
+ "DiffItemKind": "CommonDiffItem",
+ "NodeKind": "Function",
+ "NodeAnnotation": "TypeRewritten",
+ "ChildIndex": "2",
+ "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
+ "LeftComment": "Int",
+ "RightUsr": "",
+ "RightComment": "String",
"ModuleName": "macrogenleft"
},
{
@@ -90,8 +112,8 @@
{
"DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
- "NodeAnnotation": "UnwrapOptional",
- "ChildIndex": "1:0:1",
+ "NodeAnnotation": "WrapOptional",
+ "ChildIndex": "2:0",
"LeftUsr": "s:12macrogenleft2S1V4foo91x1yySays10DictionaryVySiSSSgGG_SaySiGtF",
"LeftComment": "",
"RightUsr": "",
@@ -101,8 +123,8 @@
{
"DiffItemKind": "CommonDiffItem",
"NodeKind": "Function",
- "NodeAnnotation": "WrapOptional",
- "ChildIndex": "2:0",
+ "NodeAnnotation": "UnwrapOptional",
+ "ChildIndex": "1:0:1",
"LeftUsr": "s:12macrogenleft2S1V4foo91x1yySays10DictionaryVySiSSSgGG_SaySiGtF",
"LeftComment": "",
"RightUsr": "",
@@ -144,35 +166,13 @@
},
{
"DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "0",
- "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
- "LeftComment": "String",
- "RightUsr": "",
- "RightComment": "Int",
- "ModuleName": "macrogenleft"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
+ "NodeKind": "Constructor",
"NodeAnnotation": "TypeRewritten",
"ChildIndex": "1",
- "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
+ "LeftUsr": "s:12macrogenleft2S1VyACSicfc",
"LeftComment": "Int",
"RightUsr": "",
- "RightComment": "() -> ()",
- "ModuleName": "macrogenleft"
- },
- {
- "DiffItemKind": "CommonDiffItem",
- "NodeKind": "Function",
- "NodeAnnotation": "TypeRewritten",
- "ChildIndex": "2",
- "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
- "LeftComment": "Int",
- "RightUsr": "",
- "RightComment": "String",
+ "RightComment": "Double",
"ModuleName": "macrogenleft"
}
]
\ No newline at end of file
diff --git a/test/attr/attr_discardableResult.swift b/test/attr/attr_discardableResult.swift
index 8ed2e24..e63ee90 100644
--- a/test/attr/attr_discardableResult.swift
+++ b/test/attr/attr_discardableResult.swift
@@ -185,3 +185,12 @@
return closure
}
SR2948({}) // okay
+
+class SR7562_A {
+ @discardableResult required init(input: Int) { }
+}
+
+class SR7562_B : SR7562_A {}
+
+SR7562_A(input: 10) // okay
+SR7562_B(input: 10) // okay
diff --git a/test/attr/attr_fixed_layout.swift b/test/attr/attr_fixed_layout.swift
index ee08959..47ff4c7 100644
--- a/test/attr/attr_fixed_layout.swift
+++ b/test/attr/attr_fixed_layout.swift
@@ -7,14 +7,14 @@
// Public types with @_fixed_layout are always fixed layout
//
-// RESILIENCE-ON: struct_decl "Point" interface type='Point.Type' access=public non-resilient
-// RESILIENCE-OFF: struct_decl "Point" interface type='Point.Type' access=public non-resilient
+// RESILIENCE-ON: struct_decl{{.*}}"Point" interface type='Point.Type' access=public non-resilient
+// RESILIENCE-OFF: struct_decl{{.*}}"Point" interface type='Point.Type' access=public non-resilient
@_fixed_layout public struct Point {
let x, y: Int
}
-// RESILIENCE-ON: enum_decl "ChooseYourOwnAdventure" interface type='ChooseYourOwnAdventure.Type' access=public non-resilient
-// RESILIENCE-OFF: enum_decl "ChooseYourOwnAdventure" interface type='ChooseYourOwnAdventure.Type' access=public non-resilient
+// RESILIENCE-ON: enum_decl{{.*}}"ChooseYourOwnAdventure" interface type='ChooseYourOwnAdventure.Type' access=public non-resilient
+// RESILIENCE-OFF: enum_decl{{.*}}"ChooseYourOwnAdventure" interface type='ChooseYourOwnAdventure.Type' access=public non-resilient
@_frozen public enum ChooseYourOwnAdventure {
case JumpIntoRabbitHole
case EatMushroom
@@ -24,14 +24,14 @@
// Public types are resilient when -enable-resilience is on
//
-// RESILIENCE-ON: struct_decl "Size" interface type='Size.Type' access=public resilient
-// RESILIENCE-OFF: struct_decl "Size" interface type='Size.Type' access=public non-resilient
+// RESILIENCE-ON: struct_decl{{.*}}"Size" interface type='Size.Type' access=public resilient
+// RESILIENCE-OFF: struct_decl{{.*}}"Size" interface type='Size.Type' access=public non-resilient
public struct Size {
let w, h: Int
}
-// RESILIENCE-ON: enum_decl "TaxCredit" interface type='TaxCredit.Type' access=public resilient
-// RESILIENCE-OFF: enum_decl "TaxCredit" interface type='TaxCredit.Type' access=public non-resilient
+// RESILIENCE-ON: enum_decl{{.*}}"TaxCredit" interface type='TaxCredit.Type' access=public resilient
+// RESILIENCE-OFF: enum_decl{{.*}}"TaxCredit" interface type='TaxCredit.Type' access=public non-resilient
public enum TaxCredit {
case EarnedIncome
case MortgageDeduction
@@ -41,8 +41,8 @@
// Internal types are always fixed layout
//
-// RESILIENCE-ON: struct_decl "Rectangle" interface type='Rectangle.Type' access=internal non-resilient
-// RESILIENCE-OFF: struct_decl "Rectangle" interface type='Rectangle.Type' access=internal non-resilient
+// RESILIENCE-ON: struct_decl{{.*}}"Rectangle" interface type='Rectangle.Type' access=internal non-resilient
+// RESILIENCE-OFF: struct_decl{{.*}}"Rectangle" interface type='Rectangle.Type' access=internal non-resilient
struct Rectangle {
let topLeft: Point
let bottomRight: Size
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index 86f6b59..0e50ee7 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -2038,14 +2038,14 @@
}
-// CHECK-DUMP-LABEL: class_decl "ImplicitClassThrows1"
+// CHECK-DUMP-LABEL: class_decl{{.*}}"ImplicitClassThrows1"
@objc class ImplicitClassThrows1 {
// CHECK: @objc func methodReturnsVoid() throws
- // CHECK-DUMP: func_decl "methodReturnsVoid()"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+ // CHECK-DUMP: func_decl{{.*}}"methodReturnsVoid()"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
func methodReturnsVoid() throws { }
// CHECK: @objc func methodReturnsObjCClass() throws -> Class_ObjC1
- // CHECK-DUMP: func_decl "methodReturnsObjCClass()" {{.*}}foreign_error=NilResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>
+ // CHECK-DUMP: func_decl{{.*}}"methodReturnsObjCClass()" {{.*}}foreign_error=NilResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>
func methodReturnsObjCClass() throws -> Class_ObjC1 {
return Class_ObjC1()
}
@@ -2060,11 +2060,11 @@
func methodReturnsOptionalObjCClass() throws -> Class_ObjC1? { return nil }
// CHECK: @objc func methodWithTrailingClosures(_ s: String, fn1: @escaping ((Int) -> Int), fn2: @escaping (Int) -> Int, fn3: @escaping (Int) -> Int)
- // CHECK-DUMP: func_decl "methodWithTrailingClosures(_:fn1:fn2:fn3:)"{{.*}}foreign_error=ZeroResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+ // CHECK-DUMP: func_decl{{.*}}"methodWithTrailingClosures(_:fn1:fn2:fn3:)"{{.*}}foreign_error=ZeroResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
func methodWithTrailingClosures(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int, fn3: @escaping (Int) -> Int) throws { }
// CHECK: @objc init(degrees: Double) throws
- // CHECK-DUMP: constructor_decl "init(degrees:)"{{.*}}foreign_error=NilResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>
+ // CHECK-DUMP: constructor_decl{{.*}}"init(degrees:)"{{.*}}foreign_error=NilResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>
init(degrees: Double) throws { }
// CHECK: {{^}} func methodReturnsBridgedValueType() throws -> NSRange
@@ -2086,10 +2086,10 @@
}
}
-// CHECK-DUMP-LABEL: class_decl "SubclassImplicitClassThrows1"
+// CHECK-DUMP-LABEL: class_decl{{.*}}"SubclassImplicitClassThrows1"
@objc class SubclassImplicitClassThrows1 : ImplicitClassThrows1 {
// CHECK: @objc override func methodWithTrailingClosures(_ s: String, fn1: @escaping ((Int) -> Int), fn2: @escaping ((Int) -> Int), fn3: @escaping ((Int) -> Int))
- // CHECK-DUMP: func_decl "methodWithTrailingClosures(_:fn1:fn2:fn3:)"{{.*}}foreign_error=ZeroResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+ // CHECK-DUMP: func_decl{{.*}}"methodWithTrailingClosures(_:fn1:fn2:fn3:)"{{.*}}foreign_error=ZeroResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
override func methodWithTrailingClosures(_ s: String, fn1: (@escaping (Int) -> Int), fn2: (@escaping (Int) -> Int), fn3: (@escaping (Int) -> Int)) throws { }
}
@@ -2122,20 +2122,20 @@
@objc(method7) func method7(x: Int) throws { } // expected-error{{@objc' method name provides names for 0 arguments, but method has 2 parameters (including the error parameter)}}
- // CHECK-DUMP: func_decl "method8(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=2,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+ // CHECK-DUMP: func_decl{{.*}}"method8(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=2,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
@objc(method8:fn1:error:fn2:)
func method8(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int) throws { }
- // CHECK-DUMP: func_decl "method9(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+ // CHECK-DUMP: func_decl{{.*}}"method9(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
@objc(method9AndReturnError:s:fn1:fn2:)
func method9(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int) throws { }
}
class SubclassThrowsObjCName : ThrowsObjCName {
- // CHECK-DUMP: func_decl "method8(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=2,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+ // CHECK-DUMP: func_decl{{.*}}"method8(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=2,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
override func method8(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int) throws { }
- // CHECK-DUMP: func_decl "method9(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+ // CHECK-DUMP: func_decl{{.*}}"method9(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
override func method9(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int) throws { }
}
diff --git a/test/decl/protocol/associated_type_overrides.swift b/test/decl/protocol/associated_type_overrides.swift
index 99e8eaf..002d4bf 100644
--- a/test/decl/protocol/associated_type_overrides.swift
+++ b/test/decl/protocol/associated_type_overrides.swift
@@ -4,8 +4,8 @@
associatedtype A
}
-// CHECK-LABEL: protocol "P2"
-// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P1))
+// CHECK-LABEL: (protocol{{.*}}"P2"
+// CHECK-NEXT: (associated_type_decl{{.*}}"A" {{.*}} overridden=P1))
protocol P2 : P1 {
associatedtype A
}
@@ -14,14 +14,14 @@
associatedtype A
}
-// CHECK-LABEL: protocol "P4"
-// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P2, P3))
+// CHECK-LABEL: (protocol{{.*}}"P4"
+// CHECK-NEXT: (associated_type_decl{{.*}}"A" {{.*}} overridden=P2, P3))
protocol P4 : P2, P3 {
associatedtype A
}
-// CHECK-LABEL: protocol "P5"
-// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P4))
+// CHECK-LABEL: (protocol{{.*}}"P5"
+// CHECK-NEXT: (associated_type_decl{{.*}}"A" {{.*}} overridden=P4))
protocol P5 : P4, P2 {
associatedtype A
}
diff --git a/test/decl/protocol/conforms/nscoding.swift b/test/decl/protocol/conforms/nscoding.swift
index ff9ab0f..a53f9df 100644
--- a/test/decl/protocol/conforms/nscoding.swift
+++ b/test/decl/protocol/conforms/nscoding.swift
@@ -12,7 +12,7 @@
import Foundation
// Top-level classes
-// CHECK-NOT: class_decl "CodingA"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"CodingA"{{.*}}@_staticInitializeObjCMetadata
class CodingA : NSObject, NSCoding {
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
@@ -21,7 +21,7 @@
// Nested classes
extension CodingA {
- // CHECK-NOT: class_decl "NestedA"{{.*}}@_staticInitializeObjCMetadata
+ // CHECK-NOT: class_decl{{.*}}"NestedA"{{.*}}@_staticInitializeObjCMetadata
class NestedA : NSObject, NSCoding { // expected-error{{nested class 'CodingA.NestedA' has an unstable name when archiving via 'NSCoding'}}
// expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{3-3=@objc(_TtCC8nscoding7CodingA7NestedA)}}
// expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#prefixed Objective-C class name#>)}}
@@ -36,14 +36,14 @@
func encode(coder: NSCoder) { }
}
- // CHECK-NOT: class_decl "NestedC"{{.*}}@_staticInitializeObjCMetadata
+ // CHECK-NOT: class_decl{{.*}}"NestedC"{{.*}}@_staticInitializeObjCMetadata
@objc(CodingA_NestedC)
class NestedC : NSObject, NSCoding {
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
}
- // CHECK-NOT: class_decl "NestedD"{{.*}}@_staticInitializeObjCMetadata
+ // CHECK-NOT: class_decl{{.*}}"NestedD"{{.*}}@_staticInitializeObjCMetadata
@objc(CodingA_NestedD)
class NestedD : NSObject {
required init(coder: NSCoder) { }
@@ -58,7 +58,7 @@
}
// Generic classes
-// CHECK-NOT: class_decl "CodingB"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"CodingB"{{.*}}@_staticInitializeObjCMetadata
class CodingB<T> : NSObject, NSCoding {
required init(coder: NSCoder) { }
func encode(coder: NSCoder) { }
@@ -72,7 +72,7 @@
}
// Fileprivate classes.
-// CHECK-NOT: class_decl "CodingC"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"CodingC"{{.*}}@_staticInitializeObjCMetadata
fileprivate class CodingC : NSObject, NSCoding { // expected-error{{fileprivate class 'CodingC' has an unstable name when archiving via 'NSCoding'}}
// expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{1-1=@objc(_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingC)}}
// expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#prefixed Objective-C class name#>)}}
@@ -99,7 +99,7 @@
}
// Inherited conformances.
-// CHECK-NOT: class_decl "CodingE"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"CodingE"{{.*}}@_staticInitializeObjCMetadata
class CodingE<T> : CodingB<T> {
required init(coder: NSCoder) { super.init(coder: coder) }
override func encode(coder: NSCoder) { }
@@ -119,24 +119,24 @@
}
extension CodingB {
- // CHECK-NOT: class_decl "GenericViaScope"{{.*}}@_staticInitializeObjCMetadata
+ // CHECK-NOT: class_decl{{.*}}"GenericViaScope"{{.*}}@_staticInitializeObjCMetadata
@objc(GenericViaScope) // expected-error {{generic subclasses of '@objc' classes cannot have an explicit '@objc' because they are not directly visible from Objective-C}}
class GenericViaScope : NSObject { }
}
// Inference of @_staticInitializeObjCMetadata.
-// CHECK-NOT: class_decl "SubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"SubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
class SubclassOfCodingA : CodingA { }
-// CHECK: class_decl "SubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
+// CHECK: class_decl{{.*}}"SubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
class SubclassOfCodingE : CodingE<Int> { }
// Do not warn when simply inheriting from classes that conform to NSCoding.
// The subclass may never be serialized. But do still infer static
// initialization, just in case.
-// CHECK-NOT: class_decl "PrivateSubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"PrivateSubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
private class PrivateSubclassOfCodingA : CodingA { }
-// CHECK: class_decl "PrivateSubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
+// CHECK: class_decl{{.*}}"PrivateSubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
private class PrivateSubclassOfCodingE : CodingE<Int> { }
// But do warn when inherited through a protocol.
diff --git a/test/decl/protocol/conforms/nscoding_availability_osx.swift b/test/decl/protocol/conforms/nscoding_availability_osx.swift
index 91337e7..46ecacb 100644
--- a/test/decl/protocol/conforms/nscoding_availability_osx.swift
+++ b/test/decl/protocol/conforms/nscoding_availability_osx.swift
@@ -17,6 +17,6 @@
@available(OSX 10.51, *)
class OuterCodingJ {
- // CHECK-NOT: class_decl "NestedJ"{{.*}}@_staticInitializeObjCMetadata
+ // CHECK-NOT: class_decl{{.*}}"NestedJ"{{.*}}@_staticInitializeObjCMetadata
class NestedJ : CodingI { }
}
diff --git a/test/decl/subscript/subscripting.swift b/test/decl/subscript/subscripting.swift
index 294f2a4..d02f414 100644
--- a/test/decl/subscript/subscripting.swift
+++ b/test/decl/subscript/subscripting.swift
@@ -246,33 +246,82 @@
}
}
+protocol Protocol {}
+protocol RefinedProtocol: Protocol {}
+class SuperClass {}
+class SubClass: SuperClass {}
+class SubSubClass: SubClass {}
+class ClassConformingToProtocol: Protocol {}
+class ClassConformingToRefinedProtocol: RefinedProtocol {}
+
+struct GenSubscriptFixitTest {
+ subscript<T>(_ arg: T) -> Bool { return true } // expected-note {{declared here}}
+}
+
+func testGenSubscriptFixit(_ s0: GenSubscriptFixitTest) {
+
+ _ = s0.subscript("hello")
+ // expected-error@-1 {{value of type 'GenSubscriptFixitTest' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{27-28=]}}
+}
+
struct SubscriptTest1 {
subscript(keyword:String) -> Bool { return true } // expected-note 2 {{found this candidate}}
subscript(keyword:String) -> String? {return nil } // expected-note 2 {{found this candidate}}
+
+ subscript(arg: SubClass) -> Bool { return true } // expected-note {{declared here}}
+ subscript(arg: Protocol) -> Bool { return true } // expected-note 2 {{declared here}}
+
+ subscript(arg: (foo: Bool, bar: (Int, baz: SubClass)), arg2: String) -> Bool { return true }
+ // expected-note@-1 2 {{declared here}}
}
func testSubscript1(_ s1 : SubscriptTest1) {
let _ : Int = s1["hello"] // expected-error {{ambiguous subscript with base type 'SubscriptTest1' and index type 'String'}}
-
+
if s1["hello"] {}
-
-
- let _ = s1["hello"] // expected-error {{ambiguous use of 'subscript'}}
+
+ _ = s1.subscript((true, (5, SubClass())), "hello")
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{52-53=]}}
+ _ = s1.subscript((true, (5, baz: SubSubClass())), "hello")
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{60-61=]}}
+ _ = s1.subscript((fo: true, (5, baz: SubClass())), "hello")
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
+ _ = s1.subscript(SubSubClass())
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{33-34=]}}
+ _ = s1.subscript(ClassConformingToProtocol())
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{47-48=]}}
+ _ = s1.subscript(ClassConformingToRefinedProtocol())
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{54-55=]}}
+ _ = s1.subscript(true)
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
+ _ = s1.subscript(SuperClass())
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
+ _ = s1.subscript("hello")
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{27-28=]}}
+ _ = s1.subscript("hello"
+ // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{27-27=]}}
+ // expected-note@-2 {{to match this opening '('}}
+
+ let _ = s1["hello"]
+ // expected-error@-1 {{ambiguous use of 'subscript'}}
+ // expected-error@-2 {{expected ')' in expression list}}
}
struct SubscriptTest2 {
subscript(a : String, b : Int) -> Int { return 0 }
+ // expected-note@-1 {{declared here}}
subscript(a : String, b : String) -> Int { return 0 }
}
func testSubscript1(_ s2 : SubscriptTest2) {
_ = s2["foo"] // expected-error {{cannot subscript a value of type 'SubscriptTest2' with an index of type 'String'}}
// expected-note @-1 {{overloads for 'subscript' exist with these partially matching parameter lists: (String, Int), (String, String)}}
-
+
let a = s2["foo", 1.0] // expected-error {{cannot subscript a value of type 'SubscriptTest2' with an index of type '(String, Double)'}}
// expected-note @-1 {{overloads for 'subscript' exist with these partially matching parameter lists: (String, Int), (String, String)}}
-
-
+
+ _ = s2.subscript("hello", 6)
+ // expected-error@-1 {{value of type 'SubscriptTest2' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{30-31=]}}
let b = s2[1, "foo"] // expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}}
// rdar://problem/27449208
@@ -313,9 +362,10 @@
// SR-2575
struct SR2575 {
- subscript() -> Int {
+ subscript() -> Int { // expected-note {{declared here}}
return 1
}
}
-SR2575().subscript() // expected-error{{type 'SR2575' has no member 'subscript'}}
+SR2575().subscript()
+// expected-error@-1 {{value of type 'SR2575' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{20-21=]}}
diff --git a/test/expr/capture/dynamic_self.swift b/test/expr/capture/dynamic_self.swift
index b2c45a2..c37fbf3 100644
--- a/test/expr/capture/dynamic_self.swift
+++ b/test/expr/capture/dynamic_self.swift
@@ -1,6 +1,6 @@
// RUN: %target-swift-frontend -dump-ast %s 2>&1 | %FileCheck %s
-// CHECK: func_decl "clone()" interface type='(Android) -> () -> Self'
+// CHECK: func_decl{{.*}}"clone()" interface type='(Android) -> () -> Self'
class Android {
func clone() -> Self {
diff --git a/test/expr/capture/generic_params.swift b/test/expr/capture/generic_params.swift
index 27c07cd..ee6590e 100644
--- a/test/expr/capture/generic_params.swift
+++ b/test/expr/capture/generic_params.swift
@@ -2,7 +2,7 @@
func doSomething<T>(_ t: T) {}
-// CHECK: func_decl "outerGeneric(t:x:)" <T> interface type='<T> (t: T, x: AnyObject) -> ()'
+// CHECK: func_decl{{.*}}"outerGeneric(t:x:)" <T> interface type='<T> (t: T, x: AnyObject) -> ()'
func outerGeneric<T>(t: T, x: AnyObject) {
// Simple case -- closure captures outer generic parameter
@@ -20,14 +20,14 @@
// Nested generic functions always capture outer generic parameters, even if
// they're not mentioned in the function body
- // CHECK: func_decl "innerGeneric(u:)" <U> interface type='<T, U> (u: U) -> ()' {{.*}} captures=(<generic> )
+ // CHECK: func_decl{{.*}}"innerGeneric(u:)" <U> interface type='<T, U> (u: U) -> ()' {{.*}} captures=(<generic> )
func innerGeneric<U>(u: U) {}
// Make sure we look through typealiases
typealias TT = (a: T, b: T)
// FIXME: Losing some type sugar here.
- // CHECK: func_decl "localFunction(tt:)" interface type='<T> (tt: (a: T, b: T)) -> ()' {{.*}} captures=(<generic> )
+ // CHECK: func_decl{{.*}}"localFunction(tt:)" interface type='<T> (tt: (a: T, b: T)) -> ()' {{.*}} captures=(<generic> )
func localFunction(tt: TT) {}
// CHECK: closure_expr type='((a: T, b: T)) -> ()' {{.*}} captures=(<generic> )
diff --git a/test/expr/capture/nested.swift b/test/expr/capture/nested.swift
index eee92e2..6d4790a 100644
--- a/test/expr/capture/nested.swift
+++ b/test/expr/capture/nested.swift
@@ -1,6 +1,6 @@
// RUN: %target-swift-frontend -dump-ast %s 2>&1 | %FileCheck %s
-// CHECK: func_decl "foo2(_:)"
+// CHECK: func_decl{{.*}}"foo2(_:)"
func foo2(_ x: Int) -> (Int) -> (Int) -> Int {
// CHECK: closure_expr type='(Int) -> (Int) -> Int' {{.*}} discriminator=0 captures=(x)
return {(bar: Int) -> (Int) -> Int in
diff --git a/test/expr/capture/top-level-guard.swift b/test/expr/capture/top-level-guard.swift
index 45ad1d0..744c896 100644
--- a/test/expr/capture/top-level-guard.swift
+++ b/test/expr/capture/top-level-guard.swift
@@ -15,7 +15,7 @@
// CHECK: (top_level_code_decl
_ = 0 // intervening code
-// CHECK-LABEL: (func_decl "function()" interface type='() -> ()' access=internal captures=(x<direct>)
+// CHECK-LABEL: (func_decl{{.*}}"function()" interface type='() -> ()' access=internal captures=(x<direct>)
func function() {
_ = x
}
@@ -23,7 +23,7 @@
// CHECK-LABEL: (closure_expr
// CHECK: location={{.*}}top-level-guard.swift:[[@LINE+3]]
// CHECK: captures=(x<direct>)
-// CHECK: (var_decl "closure"
+// CHECK: (var_decl{{.*}}"closure"
let closure: () -> Void = {
_ = x
}
@@ -33,13 +33,13 @@
// CHECK: (closure_expr
// CHECK: location={{.*}}top-level-guard.swift:[[@LINE+3]]
// CHECK: captures=(x)
-// CHECK: (var_decl "closureCapture"
+// CHECK: (var_decl{{.*}}"closureCapture"
let closureCapture: () -> Void = { [x] in
_ = x
}
// CHECK-LABEL: (defer_stmt
-// CHECK-NEXT: (func_decl implicit "$defer()" interface type='() -> ()' access=fileprivate captures=(x<direct><noescape>)
+// CHECK-NEXT: (func_decl{{.*}}implicit "$defer()" interface type='() -> ()' access=fileprivate captures=(x<direct><noescape>)
defer {
_ = x
}
diff --git a/test/expr/primary/literal/collection_upcast_opt.swift b/test/expr/primary/literal/collection_upcast_opt.swift
index d105716..78cb647 100644
--- a/test/expr/primary/literal/collection_upcast_opt.swift
+++ b/test/expr/primary/literal/collection_upcast_opt.swift
@@ -11,7 +11,7 @@
init(_: [(T) -> Void]) { }
}
-// CHECK-LABEL: func_decl "arrayUpcast(_:_:)"
+// CHECK-LABEL: func_decl{{.*}}"arrayUpcast(_:_:)"
// CHECK: assign_expr
// CHECK-NOT: collection_upcast_expr
// CHECK: array_expr type='[(X) -> Void]'
@@ -27,7 +27,7 @@
init(_: [Int : (T) -> Void]) { }
}
-// CHECK-LABEL: func_decl "dictionaryUpcast(_:_:)"
+// CHECK-LABEL: func_decl{{.*}}"dictionaryUpcast(_:_:)"
// CHECK: assign_expr
// CHECK-NOT: collection_upcast_expr
// CHECK: paren_expr type='([Int : (X) -> Void])'
diff --git a/test/refactoring/RefactoringKind/basic.swift b/test/refactoring/RefactoringKind/basic.swift
index 436c4f9..e434eeb 100644
--- a/test/refactoring/RefactoringKind/basic.swift
+++ b/test/refactoring/RefactoringKind/basic.swift
@@ -174,21 +174,21 @@
return "abc"
}
-func testCollapseNestedIf() {
+func testCollapseNestedIf1() {
let a = 3
if a > 2 {
if a < 10 {}
}
}
-func testMultiConditionalNestedIf() {
+func testCollapseNestedIf2() {
let a = 3
if a > 2, a != 4 {
if a < 10 {}
}
}
-func testExtraDeclNestedIf() {
+func testCollapseNestedIf3() {
let a = 3
if a > 2 {
if a < 10 {}
@@ -196,11 +196,31 @@
}
}
-func testExtraIfNestedIf() {
+func testCollapseNestedIf4() {
+ let a = 3
+ if a > 2 {
+ let b = 0
+ if a < 10 {}
+ }
+}
+
+func testCollapseNestedIf5() {
let a = 3
if a > 2 {
if a < 10 {}
- let b = 0
+ } else {
+ print("else")
+ }
+}
+
+func testCollapseNestedIf6() {
+ let a = 3
+ if a > 2 {
+ if a < 10 {
+ print("if")
+ } else if a < 5 {
+ print("else")
+ }
}
}
@@ -313,25 +333,27 @@
// RUN: %refactor -source-filename %s -pos=173:3 -end-pos=173:27| %FileCheck %s -check-prefix=CHECK-EXTRCT-METHOD
-// RUN: %refactor -source-filename %s -pos=179:3 | %FileCheck %s -check-prefix=CHECK-COLLAPSE-NESTED-IF-EXPRESSION
-// RUN: %refactor -source-filename %s -pos=186:3 | %FileCheck %s -check-prefix=CHECK-COLLAPSE-NESTED-IF-EXPRESSION
+// RUN: %refactor -source-filename %s -pos=179:3 | %FileCheck %s -check-prefix=CHECK-COLLAPSE-NESTED-IF
+// RUN: %refactor -source-filename %s -pos=186:3 | %FileCheck %s -check-prefix=CHECK-COLLAPSE-NESTED-IF
// RUN: %refactor -source-filename %s -pos=193:3 | %FileCheck %s -check-prefix=CHECK-NONE
// RUN: %refactor -source-filename %s -pos=201:3 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=209:3 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=218:3 | %FileCheck %s -check-prefix=CHECK-NONE
-// RUN: %refactor -source-filename %s -pos=210:11 -end-pos=210:24 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
-// RUN: %refactor -source-filename %s -pos=211:11 -end-pos=211:26 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
-// RUN: %refactor -source-filename %s -pos=212:11 -end-pos=212:21 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
+// RUN: %refactor -source-filename %s -pos=230:11 -end-pos=230:24 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
+// RUN: %refactor -source-filename %s -pos=231:11 -end-pos=231:26 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
+// RUN: %refactor -source-filename %s -pos=232:11 -end-pos=232:21 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
-// RUN: %refactor -source-filename %s -pos=217:11 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
-// RUN: %refactor -source-filename %s -pos=217:12 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
-// RUN: %refactor -source-filename %s -pos=217:13 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
-// RUN: %refactor -source-filename %s -pos=217:14 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
+// RUN: %refactor -source-filename %s -pos=237:11 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
+// RUN: %refactor -source-filename %s -pos=237:12 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
+// RUN: %refactor -source-filename %s -pos=237:13 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
+// RUN: %refactor -source-filename %s -pos=237:14 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
-// RUN: %refactor -source-filename %s -pos=225:3 | %FileCheck %s -check-prefix=CHECK-EXPAND-SWITCH
+// RUN: %refactor -source-filename %s -pos=245:3 | %FileCheck %s -check-prefix=CHECK-EXPAND-SWITCH
-// RUN: %refactor -source-filename %s -pos=231:3 -end-pos=231:24 | %FileCheck %s -check-prefix=CHECK-EXPAND-TERNARY-EXPRESSEXPRESSION
+// RUN: %refactor -source-filename %s -pos=251:3 -end-pos=251:24 | %FileCheck %s -check-prefix=CHECK-EXPAND-TERNARY-EXPRESSEXPRESSION
-// RUN: %refactor -source-filename %s -pos=237:3 -end-pos=242:4 | %FileCheck %s -check-prefix=CHECK-CONVERT-TO-TERNARY-EXPRESSEXPRESSION
+// RUN: %refactor -source-filename %s -pos=257:3 -end-pos=262:4 | %FileCheck %s -check-prefix=CHECK-CONVERT-TO-TERNARY-EXPRESSEXPRESSION
// CHECK1: Action begins
// CHECK1-NEXT: Extract Method
@@ -368,7 +390,7 @@
// CHECK-LOCALIZE-STRING: Localize String
-// CHECK-COLLAPSE-NESTED-IF-EXPRESSION: Collapse Nested If Expression
+// CHECK-COLLAPSE-NESTED-IF: Collapse Nested If Statements
// CHECK-STRINGS-INTERPOLATION: Convert to String Interpolation
diff --git a/test/refactoring/RefactoringKind/extract.swift b/test/refactoring/RefactoringKind/extract.swift
index 1a93f25..f8592c6 100644
--- a/test/refactoring/RefactoringKind/extract.swift
+++ b/test/refactoring/RefactoringKind/extract.swift
@@ -6,6 +6,45 @@
}
}
+func testIf(bool: Bool) {
+ if bool {
+ print(1)
+ } else {
+ print(1)
+ }
+}
+
+func testDoCatch(canThrow: () throws -> Void) {
+ do {
+ try canThrow()
+ } catch {
+ print(error)
+ }
+}
+
+func testSwitchCase(x: Int) {
+ switch x {
+ case 1:
+ print(1)
+ default:
+ print(2)
+ }
+}
+
+
// RUN: %refactor -source-filename %s -pos=4:13 -end-pos=6:4 | %FileCheck %s -check-prefix=CHECK-NONE
+
+// RUN: %refactor -source-filename %s -pos=10:11 -end-pos=12:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=12:5 -end-pos=14:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=12:10 -end-pos=14:4 | %FileCheck %s -check-prefix=CHECK-NONE
+
+// RUN: %refactor -source-filename %s -pos=18:6 -end-pos=20:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=20:5 -end-pos=22:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=20:11 -end-pos=22:4 | %FileCheck %s -check-prefix=CHECK-NONE
+
+// RUN: %refactor -source-filename %s -pos=26:12 -end-pos=31:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=27:5 -end-pos=28:15 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=29:5 -end-pos=30:15 | %FileCheck %s -check-prefix=CHECK-NONE
+
// CHECK-NONE: Action begins
// CHECK-NONE-NEXT: Action ends
diff --git a/test/stdlib/Casts.swift b/test/stdlib/Casts.swift
index a7e44b9..e713720 100644
--- a/test/stdlib/Casts.swift
+++ b/test/stdlib/Casts.swift
@@ -50,6 +50,26 @@
extension Int : P {}
+// Test for SR-7664: Inconsistent optional casting behaviour with generics
+// Runtime failed to unwrap multiple levels of Optional when casting.
+CastsTests.test("Multi-level optionals can be casted") {
+ func testSuccess<From, To>(_ x: From, from: From.Type, to: To.Type) {
+ expectNotNil(x as? To)
+ }
+ func testFailure<From, To>(_ x: From, from: From.Type, to: To.Type) {
+ expectNil(x as? To)
+ }
+ testSuccess(42, from: Int?.self, to: Int.self)
+ testSuccess(42, from: Int??.self, to: Int.self)
+ testSuccess(42, from: Int???.self, to: Int.self)
+ testSuccess(42, from: Int???.self, to: Int?.self)
+ testSuccess(42, from: Int???.self, to: Int??.self)
+ testSuccess(42, from: Int???.self, to: Int???.self)
+ testFailure(42, from: Int?.self, to: String.self)
+ testFailure(42, from: Int??.self, to: String.self)
+ testFailure(42, from: Int???.self, to: String.self)
+}
+
#if _runtime(_ObjC)
extension CFBitVector : P {
static func makeImmutable(from values: Array<UInt8>) -> CFBitVector {
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index 1d5ab13..d8221ce 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -2704,7 +2704,8 @@
bool detectTypeRewritten(SDKNodeType *Node, SDKNodeType *Counter) {
if (IsVisitingLeft &&
- (Node->getName() != Counter->getName()||
+ Node->getPrintedName() != Counter->getPrintedName() &&
+ (Node->getName() != Counter->getName() ||
Node->getChildrenCount() != Counter->getChildrenCount())) {
Node->annotate(NodeAnnotation::TypeRewritten);
Node->annotate(NodeAnnotation::TypeRewrittenLeft, Node->getPrintedName());
@@ -2794,6 +2795,8 @@
R->annotate(HasOptional ?
NodeAnnotation::RevertOptionalDictionaryKeyUpdate :
NodeAnnotation::RevertDictionaryKeyUpdate);
+ R->annotate(NodeAnnotation::RawTypeLeft, KeyChangedTo);
+ R->annotate(NodeAnnotation::RawTypeRight, Raw);
}
return true;
}
@@ -2843,6 +2846,8 @@
R->annotate(HasOptional ?
NodeAnnotation::RevertOptionalArrayMemberUpdate :
NodeAnnotation::RevertArrayMemberUpdate);
+ R->annotate(NodeAnnotation::RawTypeLeft, KeyChangedTo);
+ R->annotate(NodeAnnotation::RawTypeRight, Raw);
}
return true;
}
@@ -2874,6 +2879,8 @@
NodeAnnotation::SimpleOptionalStringRepresentableUpdate:
NodeAnnotation::SimpleStringRepresentableUpdate);
} else {
+ R->annotate(NodeAnnotation::RawTypeLeft, KeyChangedTo);
+ R->annotate(NodeAnnotation::RawTypeRight, Raw);
R->annotate(HasOptional ?
NodeAnnotation::RevertSimpleOptionalStringRepresentableUpdate:
NodeAnnotation::RevertSimpleStringRepresentableUpdate);
@@ -2987,8 +2994,8 @@
}
namespace {
-template<typename T>
+template<typename T>
void removeRedundantAndSort(std::vector<T> &Diffs) {
std::set<T> DiffSet(Diffs.begin(), Diffs.end());
Diffs.assign(DiffSet.begin(), DiffSet.end());
@@ -2997,7 +3004,6 @@
template<typename T>
void serializeDiffs(llvm::raw_ostream &Fs, std::vector<T> &Diffs) {
- removeRedundantAndSort(Diffs);
if (Diffs.empty())
return;
Fs << "\n";
@@ -3052,6 +3058,12 @@
case NodeAnnotation::OptionalDictionaryKeyUpdate:
case NodeAnnotation::SimpleStringRepresentableUpdate:
case NodeAnnotation::SimpleOptionalStringRepresentableUpdate:
+ case NodeAnnotation::RevertArrayMemberUpdate:
+ case NodeAnnotation::RevertOptionalArrayMemberUpdate:
+ case NodeAnnotation::RevertDictionaryKeyUpdate:
+ case NodeAnnotation::RevertOptionalDictionaryKeyUpdate:
+ case NodeAnnotation::RevertSimpleStringRepresentableUpdate:
+ case NodeAnnotation::RevertSimpleOptionalStringRepresentableUpdate:
return Node->getAnnotateComment(NodeAnnotation::RawTypeLeft);
case NodeAnnotation::TypeRewritten:
return Node->getAnnotateComment(NodeAnnotation::TypeRewrittenLeft);
@@ -3070,6 +3082,12 @@
case NodeAnnotation::OptionalDictionaryKeyUpdate:
case NodeAnnotation::SimpleStringRepresentableUpdate:
case NodeAnnotation::SimpleOptionalStringRepresentableUpdate:
+ case NodeAnnotation::RevertArrayMemberUpdate:
+ case NodeAnnotation::RevertOptionalArrayMemberUpdate:
+ case NodeAnnotation::RevertDictionaryKeyUpdate:
+ case NodeAnnotation::RevertOptionalDictionaryKeyUpdate:
+ case NodeAnnotation::RevertSimpleStringRepresentableUpdate:
+ case NodeAnnotation::RevertSimpleOptionalStringRepresentableUpdate:
return Node->getAnnotateComment(NodeAnnotation::RawTypeRight);
case NodeAnnotation::TypeRewritten:
return Node->getAnnotateComment(NodeAnnotation::TypeRewrittenRight);
@@ -3807,6 +3825,22 @@
RefinementPass.pass(LeftModule, RightModule);
DiffVector AllItems;
DiffItemEmitter::collectDiffItems(LeftModule, AllItems);
+
+ auto &AliasMap = Ctx.getTypeAliasUpdateMap();
+ // Find type alias change first.
+ TypeAliasDiffFinder(LeftModule, RightModule, AliasMap).search();
+
+ for (auto Pair: AliasMap) {
+ auto Left = Pair.first->getAs<SDKNodeDeclTypeAlias>()->getUnderlyingType()->
+ getPrintedName();
+ auto Right = AliasMap[(SDKNode*)Pair.first]->getAs<SDKNodeDeclType>()->
+ getRawValueType()->getPrintedName();
+ auto *D = Pair.first->getAs<SDKNodeDecl>();
+ AllItems.emplace_back(SDKNodeKind::DeclTypeAlias,
+ NodeAnnotation::TypeAliasDeclToRawRepresentable, "0",
+ D->getUsr(), "", Left, Right, D->getModuleName());
+ }
+
AllItems.erase(std::remove_if(AllItems.begin(), AllItems.end(),
[&](CommonDiffItem &Item) {
return Item.DiffKind == NodeAnnotation::RemovedDecl &&
@@ -3823,6 +3857,10 @@
auto &typeMemberDiffs = Ctx.getTypeMemberDiffs();
std::error_code EC;
llvm::raw_fd_ostream Fs(DiffPath, EC, llvm::sys::fs::F_None);
+ removeRedundantAndSort(AllItems);
+ removeRedundantAndSort(typeMemberDiffs);
+ removeRedundantAndSort(AllNoEscapingFuncs);
+ removeRedundantAndSort(Overloads);
if (options::OutputInJson) {
std::vector<APIDiffItem*> TotalItems;
std::transform(AllItems.begin(), AllItems.end(),
diff --git a/tools/swift-refactor/swift-refactor.cpp b/tools/swift-refactor/swift-refactor.cpp
index eeceb52..6c9f6b6 100644
--- a/tools/swift-refactor/swift-refactor.cpp
+++ b/tools/swift-refactor/swift-refactor.cpp
@@ -41,7 +41,7 @@
"expand-switch-cases", "Perform switch cases expand refactoring"),
clEnumValN(RefactoringKind::LocalizeString,
"localize-string", "Perform string localization refactoring"),
- clEnumValN(RefactoringKind::CollapseNestedIfExpr,
+ clEnumValN(RefactoringKind::CollapseNestedIfStmt,
"collapse-nested-if", "Perform collapse nested if statements"),
clEnumValN(RefactoringKind::ConvertToDoCatch,
"convert-to-do-catch", "Perform force try to do try catch refactoring"),
diff --git a/tools/swift-reflection-dump/swift-reflection-dump.cpp b/tools/swift-reflection-dump/swift-reflection-dump.cpp
index 8827e50..fea516d 100644
--- a/tools/swift-reflection-dump/swift-reflection-dump.cpp
+++ b/tools/swift-reflection-dump/swift-reflection-dump.cpp
@@ -122,17 +122,17 @@
static ReflectionInfo findReflectionInfo(const ObjectFile *objectFile) {
auto fieldSection = findReflectionSection<FieldSection>(
- objectFile, {"__swift4_fieldmd", ".swift4_fieldmd", "swift4_fieldmd"});
+ objectFile, {"__swift5_fieldmd", ".swift5_fieldmd", "swift5_fieldmd"});
auto associatedTypeSection = findReflectionSection<AssociatedTypeSection>(
- objectFile, {"__swift4_assocty", ".swift4_assocty", "swift4_assocty"});
+ objectFile, {"__swift5_assocty", ".swift5_assocty", "swift5_assocty"});
auto builtinTypeSection = findReflectionSection<BuiltinTypeSection>(
- objectFile, {"__swift4_builtin", ".swift4_builtin", "swift4_builtin"});
+ objectFile, {"__swift5_builtin", ".swift5_builtin", "swift5_builtin"});
auto captureSection = findReflectionSection<CaptureSection>(
- objectFile, {"__swift4_capture", ".swift4_capture", "swift4_capture"});
+ objectFile, {"__swift5_capture", ".swift5_capture", "swift5_capture"});
auto typeRefSection = findReflectionSection<GenericSection>(
- objectFile, {"__swift4_typeref", ".swift4_typeref", "swift4_typeref"});
+ objectFile, {"__swift5_typeref", ".swift5_typeref", "swift5_typeref"});
auto reflectionStringsSection = findReflectionSection<GenericSection>(
- objectFile, {"__swift4_reflstr", ".swift4_reflstr", "swift4_reflstr"});
+ objectFile, {"__swift5_reflstr", ".swift5_reflstr", "swift5_reflstr"});
// The entire object file is mapped into this process's memory, so the
// local/remote mapping is identity.
diff --git a/unittests/runtime/CMakeLists.txt b/unittests/runtime/CMakeLists.txt
index 653486d..69a1c3f 100644
--- a/unittests/runtime/CMakeLists.txt
+++ b/unittests/runtime/CMakeLists.txt
@@ -35,6 +35,7 @@
add_swift_unittest(SwiftRuntimeTests
Array.cpp
CompatibilityOverride.cpp
+ Concurrent.cpp
Exclusivity.cpp
Metadata.cpp
Mutex.cpp
diff --git a/unittests/runtime/Concurrent.cpp b/unittests/runtime/Concurrent.cpp
new file mode 100644
index 0000000..3f78805
--- /dev/null
+++ b/unittests/runtime/Concurrent.cpp
@@ -0,0 +1,44 @@
+//===--- Concurrent.cpp - Concurrent data structure tests -----------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#include "swift/Runtime/Concurrent.h"
+#include "gtest/gtest.h"
+
+using namespace swift;
+
+TEST(ConcurrentReadableArrayTest, SingleThreaded) {
+ ConcurrentReadableArray<size_t> array;
+
+ auto add = [&](size_t limit) {
+ for (size_t i = array.snapshot().count(); i < limit; i++)
+ array.push_back(i);
+ };
+ auto check = [&]{
+ size_t i = 0;
+ for (auto element : array.snapshot()) {
+ ASSERT_EQ(element, i);
+ i++;
+ }
+ };
+
+ check();
+ add(1);
+ check();
+ add(16);
+ check();
+ add(100);
+ check();
+ add(1000);
+ check();
+ add(1000000);
+ check();
+}
diff --git a/unittests/runtime/Metadata.cpp b/unittests/runtime/Metadata.cpp
index c77c203..60d2419 100644
--- a/unittests/runtime/Metadata.cpp
+++ b/unittests/runtime/Metadata.cpp
@@ -507,7 +507,7 @@
EXPECT_EQ(5 * sizeof(void*), ex1->getValueWitnesses()->getSize());
EXPECT_EQ(alignof(void*), ex1->getValueWitnesses()->getAlignment());
EXPECT_FALSE(ex1->getValueWitnesses()->isPOD());
- EXPECT_FALSE(ex1->getValueWitnesses()->isBitwiseTakable());
+ EXPECT_TRUE(ex1->getValueWitnesses()->isBitwiseTakable());
EXPECT_EQ(nullptr,
ex1->getSuperclassConstraint());
return ex1;
@@ -525,7 +525,7 @@
EXPECT_EQ(6 * sizeof(void*), ex2->getValueWitnesses()->getSize());
EXPECT_EQ(alignof(void*), ex2->getValueWitnesses()->getAlignment());
EXPECT_FALSE(ex2->getValueWitnesses()->isPOD());
- EXPECT_FALSE(ex2->getValueWitnesses()->isBitwiseTakable());
+ EXPECT_TRUE(ex2->getValueWitnesses()->isBitwiseTakable());
EXPECT_EQ(nullptr,
ex2->getSuperclassConstraint());
return ex2;
@@ -543,7 +543,7 @@
EXPECT_EQ(7 * sizeof(void*), ex3->getValueWitnesses()->getSize());
EXPECT_EQ(alignof(void*), ex3->getValueWitnesses()->getAlignment());
EXPECT_FALSE(ex3->getValueWitnesses()->isPOD());
- EXPECT_FALSE(ex3->getValueWitnesses()->isBitwiseTakable());
+ EXPECT_TRUE(ex3->getValueWitnesses()->isBitwiseTakable());
EXPECT_EQ(nullptr,
ex3->getSuperclassConstraint());
return ex3;
@@ -658,48 +658,6 @@
ValueWitnessTable *vwtable);
} // namespace swift
-
-TEST(MetadataTest, installCommonValueWitnesses_pod_indirect) {
- ValueWitnessTable testTable;
- FullMetadata<Metadata> testMetadata{{&testTable}, {MetadataKind::Opaque}};
-
- // rdar://problem/21375421 - pod_indirect_initializeBufferWithTakeOfBuffer
- // should move ownership of a fixed-size buffer.
-
- testTable.size = sizeof(ValueBuffer) + 1;
- testTable.flags = ValueWitnessFlags()
- .withAlignment(alignof(ValueBuffer))
- .withPOD(true)
- .withBitwiseTakable(true)
- .withInlineStorage(false);
- testTable.stride = sizeof(ValueBuffer) + alignof(ValueBuffer);
-
- installCommonValueWitnesses(*testTable.getTypeLayout(), &testTable);
-
- // Replace allocateBuffer and destroyBuffer with logging versions.
- struct {
- ValueBuffer buffer;
- uintptr_t canary;
- } buf1{{}, 0x5A5A5A5AU}, buf2{{}, 0xA5A5A5A5U};
- testMetadata.allocateBoxForExistentialIn(&buf1.buffer);
-
- testTable.initializeBufferWithTakeOfBuffer(&buf2.buffer, &buf1.buffer,
- &testMetadata);
-
- // The existential's box reference should be copied.
- EXPECT_EQ(buf1.buffer.PrivateData[0], buf2.buffer.PrivateData[0]);
-
- // Ownership of the box should have been transferred.
- auto *reference = reinterpret_cast<HeapObject *>(buf2.buffer.PrivateData[0]);
- EXPECT_TRUE(swift_isUniquelyReferencedOrPinned_nonNull_native(reference));
-
- EXPECT_EQ(buf1.canary, (uintptr_t)0x5A5A5A5AU);
- EXPECT_EQ(buf2.canary, (uintptr_t)0xA5A5A5A5U);
-
- // Release the buffer.
- swift_release(reference);
-}
-
// We cannot construct RelativeDirectPointer instances, so define
// a "shadow" struct for that purpose
struct GenericWitnessTableStorage {
diff --git a/utils/cmpcodesize/cmpcodesize/compare.py b/utils/cmpcodesize/cmpcodesize/compare.py
index 598b353..51ea7d7 100644
--- a/utils/cmpcodesize/cmpcodesize/compare.py
+++ b/utils/cmpcodesize/cmpcodesize/compare.py
@@ -232,7 +232,7 @@
compare_sizes(old_sizes, new_sizes, "__objc_const", section_title,
csv=csv)
compare_sizes(old_sizes, new_sizes, "__data", section_title, csv=csv)
- compare_sizes(old_sizes, new_sizes, "__swift4_proto", section_title,
+ compare_sizes(old_sizes, new_sizes, "__swift5_proto", section_title,
csv=csv)
compare_sizes(old_sizes, new_sizes, "__common", section_title, csv=csv)
compare_sizes(old_sizes, new_sizes, "__bss", section_title, csv=csv)
diff --git a/validation-test/Evolution/Inputs/bitwise_takable.swift b/validation-test/Evolution/Inputs/bitwise_takable.swift
new file mode 100644
index 0000000..35381eb
--- /dev/null
+++ b/validation-test/Evolution/Inputs/bitwise_takable.swift
@@ -0,0 +1,73 @@
+public protocol Reporter {
+ func report() -> String;
+}
+public class Subject {
+ public var value = 1
+ public init(_ v: Int) {
+ value = v
+ }
+}
+public var s2 = Subject(2)
+public var s3 = Subject(3)
+public var s4 = Subject(4)
+public var s5 = Subject(5)
+
+public struct Container : Reporter {
+#if BEFORE
+ public var v : Subject
+#else
+ weak public var v : Subject?
+#endif
+ public init(_ s: Subject) {
+ v = s
+ }
+
+ public func report() -> String{
+#if BEFORE
+ return "Container(\(v.value))"
+#else
+ return "Container(\(v!.value))"
+#endif
+ }
+}
+public func createContainerReporter() -> Reporter {
+ return Container(s2)
+}
+
+public struct PairContainer: Reporter {
+ public var pair : (Container, Container)
+
+ public init(_ p : (Container, Container)) {
+ pair = p
+ }
+
+ public func report() -> String {
+ return "PairContainer(\(pair.0.report()), \(pair.1.report()))"
+ }
+}
+
+public func createPairContainerReporter() -> Reporter {
+ return PairContainer((Container(s3), Container(s4)))
+}
+
+public enum EnumContainer : Reporter {
+ case Empty
+ case Some(Container)
+
+ public func report() -> String {
+ switch self {
+ case .Empty:
+ return "EnumContainer Empty"
+ case .Some(let c):
+ return "EnumContainer(\(c.report()))"
+ }
+ }
+}
+
+public func createEnumContainerReporter() -> Reporter {
+ return EnumContainer.Some(Container(s5))
+}
+
+public func report(_ r: Reporter) -> String {
+ return r.report()
+}
diff --git a/validation-test/Evolution/test_bitwise_takable.swift b/validation-test/Evolution/test_bitwise_takable.swift
new file mode 100644
index 0000000..638e000
--- /dev/null
+++ b/validation-test/Evolution/test_bitwise_takable.swift
@@ -0,0 +1,29 @@
+// RUN: %target-resilience-test
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import bitwise_takable
+
+
+var BitwiseTakable = TestSuite("BitwiseTakable")
+
+BitwiseTakable.test("test") {
+ let c = createContainerReporter()
+ expectEqual("Container(2)", c.report())
+ let p = createPairContainerReporter()
+ expectEqual("PairContainer(Container(3), Container(4))", p.report())
+ let e = createEnumContainerReporter()
+ expectEqual("EnumContainer(Container(5))", e.report())
+
+ let r : Reporter = Container(s2)
+ expectEqual("Container(2)", report(r))
+
+ let r2 : Reporter = PairContainer((Container(s3), Container(s4)))
+ expectEqual("PairContainer(Container(3), Container(4))", report(r2))
+
+ let r3 : Reporter = EnumContainer.Some(Container(s5))
+ expectEqual("EnumContainer(Container(5))", report(r3))
+
+}
+
+runAllTests()
diff --git a/validation-test/Sema/type_checker_perf/fast/rdar40344044.swift.gyb b/validation-test/Sema/type_checker_perf/fast/rdar40344044.swift.gyb
new file mode 100644
index 0000000..6fcc704
--- /dev/null
+++ b/validation-test/Sema/type_checker_perf/fast/rdar40344044.swift.gyb
@@ -0,0 +1,23 @@
+// RUN: %scale-test --begin 3 --end 20 --step 1 --select incrementScopeCounter %s
+// REQUIRES: OS=macosx
+// REQUIRES: asserts
+
+protocol P {}
+class C : P {}
+class D : P {}
+
+class Test {
+ let c: C! = C()
+ let d: D! = D()
+ var a: [P]! = []
+
+ func test() {
+ a = [
+ c,
+%for i in range(0, N):
+ c,
+%end
+ d
+ ]
+ }
+}