Merge pull request #17026 from aschwaighofer/wip_begin_apply_inlining
SILInliner: Initial support for begin_apply
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f5a833..5064656 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -212,11 +212,14 @@
#
# User-configurable Darwin-specific options.
#
-
option(SWIFT_EMBED_BITCODE_SECTION
"If non-empty, embeds LLVM bitcode binary sections in the standard library and overlay binaries for supported platforms"
FALSE)
+option(SWIFT_EMBED_BITCODE_SECTION_HIDE_SYMBOLS
+ "If non-empty, when embedding the LLVM bitcode binary sections into the relevant binaries, pass in -bitcode_hide_symbols. Does nothing if SWIFT_EMBED_BITCODE_SECTION is set to false."
+ FALSE)
+
option(SWIFT_RUNTIME_CRASH_REPORTER_CLIENT
"Whether to enable CrashReporter integration"
FALSE)
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 6c8949c..80fc41b 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -720,7 +720,11 @@
if(SWIFT_EMBED_BITCODE_SECTION AND NOT SWIFTLIB_SINGLE_DONT_EMBED_BITCODE)
if("${SWIFTLIB_SINGLE_SDK}" STREQUAL "IOS" OR "${SWIFTLIB_SINGLE_SDK}" STREQUAL "TVOS" OR "${SWIFTLIB_SINGLE_SDK}" STREQUAL "WATCHOS")
list(APPEND SWIFTLIB_SINGLE_C_COMPILE_FLAGS "-fembed-bitcode")
- list(APPEND SWIFTLIB_SINGLE_LINK_FLAGS "-Xlinker" "-bitcode_bundle" "-Xlinker" "-bitcode_hide_symbols" "-Xlinker" "-lto_library" "-Xlinker" "${LLVM_LIBRARY_DIR}/libLTO.dylib")
+ list(APPEND SWIFTLIB_SINGLE_LINK_FLAGS "-Xlinker" "-bitcode_bundle" "-Xlinker" "-lto_library" "-Xlinker" "${LLVM_LIBRARY_DIR}/libLTO.dylib")
+ # If we are asked to hide symbols, pass the obfuscation flag to libLTO.
+ if (SWIFT_EMBED_BITCODE_SECTION_HIDE_SYMBOLS)
+ list(APPEND SWIFTLIB_SINGLE_LINK_FLAGS "-Xlinker" "-bitcode_hide_symbols")
+ endif()
set(embed_bitcode_arg EMBED_BITCODE)
endif()
endif()
diff --git a/docs/HighLevelSILOptimizations.rst b/docs/HighLevelSILOptimizations.rst
index eccc247..dfe9068 100644
--- a/docs/HighLevelSILOptimizations.rst
+++ b/docs/HighLevelSILOptimizations.rst
@@ -313,19 +313,19 @@
~~~~~~~~~~
TBD.
-@effects attribute
+@_effects attribute
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The @effects attribute describes how a function affects "the state of the world".
+The @_effects attribute describes how a function affects "the state of the world".
More practically how the optimizer can modify the program based on information
that is provided by the attribute.
Usage:
- @effects(readonly) func foo() { .. }
+ @_effects(readonly) func foo() { .. }
-The @effects attribute supports the following tags:
+The @_effects attribute supports the following tags:
readnone
@@ -363,13 +363,13 @@
}
}
- @effects(releasenone)
+ @_effects(releasenone)
func validReleaseNoneFunction(x: Int) -> Int {
global.x = 5
return x + 2
}
- @effects(releasenone)
+ @_effects(releasenone)
func validReleaseNoneFunction(x: Int) -> Int {
var notExternallyVisibleObject = SomeObject()
return x + notExternallyVisibleObject.x
diff --git a/docs/proposals/OptimizerEffects.rst b/docs/proposals/OptimizerEffects.rst
index 13529b6..82ef551 100644
--- a/docs/proposals/OptimizerEffects.rst
+++ b/docs/proposals/OptimizerEffects.rst
@@ -96,7 +96,7 @@
release_value operation.
When referring to unspecified state, I will use the syntax
-``@effects(no<effectname>)``. When referring to state reachable via an
+``@_effects(no<effectname>)``. When referring to state reachable via an
argument, ``@no<effectname> arg``.
Naturally, we also need a syntax for associating effects with
@@ -110,7 +110,7 @@
to unspecified state and that the bridged object is always self. That
way we can denote predicated effects as @nonbridged_effects.
-In examples, @effects(argonly) means that there are no effects on
+In examples, @_effects(argonly) means that there are no effects on
unspecified state.
CoW Optimization Requirements
@@ -167,7 +167,7 @@
Note: In terms of low-level SIL attributes such a method will be marked:::
- @effects(argonly)
+ @_effects(argonly)
@selfeffects(make_unique)
func makeUnique() {}
@@ -230,7 +230,7 @@
Note: In terms of low-level SIL attributes such a method will be marked:::
- @effects(argonly)
+ @_effects(argonly)
@selfeffects(preserve_unique, nowrite, nocapture, norelease,
projects_subobject)
func getElement(_ index: Int) -> T {}
@@ -297,7 +297,7 @@
Note: In terms of low-level SIL attributes such a method will be marked:::
- @effects(argonly)
+ @_effects(argonly)
@selfeffects(preserve_unique, nowrite, nocapture, norelease,
projects_subobject_addr)
func getElementAddr(_ index: Int) -> T {}
@@ -320,7 +320,7 @@
Note: In terms of low-level SIL attributes such a method will be marked:::
- @effects(argonly)
+ @_effects(argonly)
@selfeffects(preserve_unique, nocapture, norelease)
func appendElementAssumingUnique(@norelease @nowrite elt: T) {}
@@ -356,7 +356,7 @@
Note: In terms of low-level SIL attributes such a method will be marked:::
- @effects(argonly, T.release)
+ @_effects(argonly, T.release)
@selfeffects(preserve_unique, nocapture)
func setElement(@nowrite e: T, index: Int) {
}
@@ -536,15 +536,15 @@
The optimizer can only take advantage of user-specified effects before
they have been inlined. Consequently, the optimizer initially preserves
-calls to annotated @effects() functions. After optimizing for effects
+calls to annotated @_effects() functions. After optimizing for effects
these functions can be inlined, dropping the effects information.
Without special syntax, specifying a pure function would require::
- @effects(argonly)
+ @_effects(argonly)
func foo(@noread @nowrite arg)
-A shorthand, such as @effects(none) could easily be
+A shorthand, such as @_effects(none) could easily be
introduced. Typically, this shouldn't be needed because the purity of
a function can probably be deduced from its argument types given that
it has no effect on unspecified state. i.e. If the function does not
@@ -576,7 +576,7 @@
Solving this requires a system for polymorphic effects. Language
support for polymorphic effects might look something like this::
- @effects(T.release)
+ @_effects(T.release)
func foo<T>(t: T) { ... }
This would mean that foo's unspecified effects are bounded by the
diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def
index 8378d9b..c3032e6 100644
--- a/include/swift/AST/Attr.def
+++ b/include/swift/AST/Attr.def
@@ -269,7 +269,7 @@
DeclModifier |
NotSerialized, 49)
CONTEXTUAL_DECL_ATTR_ALIAS(unowned, ReferenceOwnership)
-DECL_ATTR(effects, Effects,
+DECL_ATTR(_effects, Effects,
OnAbstractFunction |
UserInaccessible,
50)
diff --git a/include/swift/AST/AttrKind.h b/include/swift/AST/AttrKind.h
index 5c02ce6..eb4cfa6 100644
--- a/include/swift/AST/AttrKind.h
+++ b/include/swift/AST/AttrKind.h
@@ -72,7 +72,7 @@
enum : unsigned { NumInlineKindBits =
countBitsUsed(static_cast<unsigned>(InlineKind::Last_InlineKind)) };
-/// This enum represents the possible values of the @effects attribute.
+/// This enum represents the possible values of the @_effects attribute.
/// These values are ordered from the strongest guarantee to the weakest,
/// so please do not reorder existing values.
enum class EffectsKind : uint8_t {
diff --git a/include/swift/AST/ClangModuleLoader.h b/include/swift/AST/ClangModuleLoader.h
index ccb729b..eafc24b 100644
--- a/include/swift/AST/ClangModuleLoader.h
+++ b/include/swift/AST/ClangModuleLoader.h
@@ -24,6 +24,8 @@
namespace swift {
+class DeclContext;
+
class ClangModuleLoader : public ModuleLoader {
private:
virtual void anchor();
@@ -46,6 +48,16 @@
/// \returns true if there was an error adding the search path.
virtual bool addSearchPath(StringRef newSearchPath, bool isFramework,
bool isSystem) = 0;
+
+ /// Determine whether \c overlayDC is within an overlay module for the
+ /// imported context enclosing \c importedDC.
+ ///
+ /// This routine is used for various hacks that are only permitted within
+ /// overlays of imported modules, e.g., Objective-C bridging conformances.
+ virtual bool isInOverlayModuleForImportedModule(
+ const DeclContext *overlayDC,
+ const DeclContext *importedDC) = 0;
+
};
} // namespace swift
diff --git a/include/swift/AST/DiagnosticsCommon.def b/include/swift/AST/DiagnosticsCommon.def
index d131e0c..bb804a0 100644
--- a/include/swift/AST/DiagnosticsCommon.def
+++ b/include/swift/AST/DiagnosticsCommon.def
@@ -87,6 +87,9 @@
ERROR(generic_signature_not_minimal,none,
"generic requirement '%0' is redundant in %1", (StringRef, StringRef))
+ERROR(attr_only_on_parameters, none,
+ "'%0' may only be used on parameters", (StringRef))
+
#ifndef DIAG_NO_UNDEF
# if defined(DIAG)
# undef DIAG
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 9285e8a..33f2f5a 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -1309,8 +1309,6 @@
ERROR(attr_only_at_non_local_scope, none,
"attribute '%0' can only be used in a non-local scope", (StringRef))
-ERROR(attr_only_on_parameters_parse, none,
- "'%0' may only be used on parameters", (StringRef))
// Access control
ERROR(attr_access_expected_set,none,
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index e081ec0..7df9b81 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -2298,12 +2298,10 @@
ERROR(attr_only_one_decl_kind,none,
"%0 may only be used on '%1' declarations", (DeclAttribute,StringRef))
-ERROR(attr_only_on_parameters,none,
- "%0 may only be used on parameters", (StringRef))
ERROR(attr_not_on_variadic_parameters,none,
- "%0 must not be used on variadic parameters", (StringRef))
+ "'%0' must not be used on variadic parameters", (StringRef))
ERROR(attr_not_on_subscript_parameters,none,
- "%0 must not be used on subscript parameters", (StringRef))
+ "'%0' must not be used on subscript parameters", (StringRef))
ERROR(override_final,none,
"%0 overrides a 'final' %1", (DescriptiveDeclKind, DescriptiveDeclKind))
diff --git a/include/swift/AST/LazyResolver.h b/include/swift/AST/LazyResolver.h
index b23ca8a..597b732 100644
--- a/include/swift/AST/LazyResolver.h
+++ b/include/swift/AST/LazyResolver.h
@@ -65,6 +65,12 @@
/// consistency and provides the value a type.
virtual void resolveDeclSignature(ValueDecl *VD) = 0;
+ /// Resolve the "overridden" declaration of the given declaration.
+ virtual void resolveOverriddenDecl(ValueDecl *VD) = 0;
+
+ /// Resolve the "is Objective-C" bit for the given declaration.
+ virtual void resolveIsObjC(ValueDecl *VD) = 0;
+
/// Resolve the types in the inheritance clause of the given
/// declaration context, which will be a type declaration or
/// extension declaration.
diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h
index 36dcc48..2ec07cd 100644
--- a/include/swift/ClangImporter/ClangImporter.h
+++ b/include/swift/ClangImporter/ClangImporter.h
@@ -143,6 +143,15 @@
ArrayRef<std::pair<Identifier, SourceLoc>> path)
override;
+ /// Determine whether \c overlayDC is within an overlay module for the
+ /// imported context enclosing \c importedDC.
+ ///
+ /// This routine is used for various hacks that are only permitted within
+ /// overlays of imported modules, e.g., Objective-C bridging conformances.
+ bool isInOverlayModuleForImportedModule(
+ const DeclContext *overlayDC,
+ const DeclContext *importedDC) override;
+
/// \brief Look for declarations associated with the given name.
///
/// \param name The name we're searching for.
@@ -350,14 +359,6 @@
ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,
ArrayRef<clang::Module *> Exported);
-/// Determine whether \c overlayDC is within an overlay module for the
-/// imported context enclosing \c importedDC.
-///
-/// This routine is used for various hacks that are only permitted within
-/// overlays of imported modules, e.g., Objective-C bridging conformances.
-bool isInOverlayModuleForImportedModule(const DeclContext *overlayDC,
- const DeclContext *importedDC);
-
} // end namespace swift
#endif
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index f80ee71..b5182bc 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -31,26 +31,30 @@
class FloatLiteralExpr;
class SILGlobalVariable;
-class SILBuilder {
- friend class SILBuilderWithScope;
+/// Manage the state needed for a SIL pass across multiple, independent
+/// SILBuilder invocations.
+///
+/// A SIL pass can instantiate a SILBuilderContext object to track information
+/// across multiple, potentially independent invocations of SILBuilder. This
+/// allows utilities used within the pass to construct a new SILBuilder instance
+/// whenever it is convenient or appropriate. For example, a separate SILBuilder
+/// should be constructed whenever the current debug location or insertion point
+/// changed. Reusing the same SILBuilder and calling setInsertionPoint() easily
+/// leads to incorrect debug information.
+class SILBuilderContext {
+ friend class SILBuilder;
- SILFunction *F;
- SILModule &Mod;
+ SILModule &Module;
/// Allow the SIL module conventions to be overriden within the builder.
/// This supports passes that lower SIL to a new stage.
- SILModuleConventions silConv = SILModuleConventions(Mod);
-
- /// If this is non-null, the instruction is inserted in the specified
- /// basic block, at the specified InsertPt. If null, created instructions
- /// are not auto-inserted.
- SILBasicBlock *BB;
- SILBasicBlock::iterator InsertPt;
- const SILDebugScope *CurDebugScope = nullptr;
- Optional<SILLocation> CurDebugLocOverride = None;
+ SILModuleConventions silConv = SILModuleConventions(Module);
/// If this pointer is non-null, then any inserted instruction is
/// recorded in this list.
+ ///
+ /// TODO: Give this ownership of InsertedInstrs and migrate users that
+ /// currently provide their own InsertedInstrs.
SmallVectorImpl<SILInstruction *> *InsertedInstrs = nullptr;
/// An immutable view on the set of available opened archetypes.
@@ -75,16 +79,63 @@
bool isParsing = false;
public:
- SILBuilder(SILFunction &F, bool isParsing = false)
- : F(&F), Mod(F.getModule()), BB(0), isParsing(isParsing) {}
+ explicit SILBuilderContext(
+ SILModule &M, SmallVectorImpl<SILInstruction *> *InsertedInstrs = 0)
+ : Module(M), InsertedInstrs(InsertedInstrs) {}
+
+ SILModule &getModule() { return Module; }
+
+ // Allow a pass to override the current SIL module conventions. This should
+ // only be done by a pass responsible for lowering SIL to a new stage
+ // (e.g. AddressLowering).
+ void setSILConventions(SILModuleConventions silConv) {
+ this->silConv = silConv;
+ }
+
+protected:
+ /// Notify the context of each new instruction after it is inserted in the
+ /// instruction stream.
+ void notifyInserted(SILInstruction *Inst) {
+ // If the SILBuilder client wants to know about new instructions, record
+ // this.
+ if (InsertedInstrs)
+ InsertedInstrs->push_back(Inst);
+ }
+};
+
+class SILBuilder {
+ friend class SILBuilderWithScope;
+
+ /// Temporary context for clients that don't provide their own.
+ SILBuilderContext TempContext;
+
+ /// Reference to the provided SILBuilderContext.
+ SILBuilderContext &C;
+
+ SILFunction *F;
+
+ /// If this is non-null, the instruction is inserted in the specified
+ /// basic block, at the specified InsertPt. If null, created instructions
+ /// are not auto-inserted.
+ SILBasicBlock *BB;
+ SILBasicBlock::iterator InsertPt;
+ const SILDebugScope *CurDebugScope = nullptr;
+ Optional<SILLocation> CurDebugLocOverride = None;
+
+public:
+ explicit SILBuilder(SILFunction &F, bool isParsing = false)
+ : TempContext(F.getModule()), C(TempContext), F(&F), BB(0) {
+ C.isParsing = isParsing;
+ }
SILBuilder(SILFunction &F, SmallVectorImpl<SILInstruction *> *InsertedInstrs)
- : F(&F), Mod(F.getModule()), BB(0), InsertedInstrs(InsertedInstrs) {}
+ : TempContext(F.getModule(), InsertedInstrs), C(TempContext), F(&F),
+ BB(0) {}
explicit SILBuilder(SILInstruction *I,
SmallVectorImpl<SILInstruction *> *InsertedInstrs = 0)
- : F(I->getFunction()), Mod(I->getFunction()->getModule()),
- InsertedInstrs(InsertedInstrs) {
+ : TempContext(I->getFunction()->getModule(), InsertedInstrs),
+ C(TempContext), F(I->getFunction()) {
setInsertionPoint(I);
}
@@ -94,8 +145,8 @@
explicit SILBuilder(SILBasicBlock *BB,
SmallVectorImpl<SILInstruction *> *InsertedInstrs = 0)
- : F(BB->getParent()), Mod(BB->getParent()->getModule()),
- InsertedInstrs(InsertedInstrs) {
+ : TempContext(BB->getParent()->getModule(), InsertedInstrs),
+ C(TempContext), F(BB->getParent()) {
setInsertionPoint(BB);
}
@@ -104,40 +155,46 @@
SILBuilder(SILBasicBlock *BB, SILBasicBlock::iterator InsertPt,
SmallVectorImpl<SILInstruction *> *InsertedInstrs = 0)
- : F(BB->getParent()), Mod(BB->getParent()->getModule()),
- InsertedInstrs(InsertedInstrs) {
+ : TempContext(BB->getParent()->getModule(), InsertedInstrs),
+ C(TempContext), F(BB->getParent()) {
setInsertionPoint(BB, InsertPt);
}
+ /// Build instructions before the given insertion point, inheriting the debug
+ /// location.
+ ///
+ /// Clients should prefer this constructor.
+ SILBuilder(SILInstruction *I, SILBuilderContext &C)
+ : TempContext(C.getModule()), C(C), F(I->getFunction()) {
+ setInsertionPoint(I);
+ }
+
// Allow a pass to override the current SIL module conventions. This should
// only be done by a pass responsible for lowering SIL to a new stage
// (e.g. AddressLowering).
- void setSILConventions(SILModuleConventions silConv) {
- this->silConv = silConv;
- }
+ void setSILConventions(SILModuleConventions silConv) { C.silConv = silConv; }
SILFunction &getFunction() const {
assert(F && "cannot create this instruction without a function context");
return *F;
}
- SILModule &getModule() const { return Mod; }
+ SILBuilderContext &getBuilderContext() const { return C; }
+ SILModule &getModule() const { return C.Module; }
ASTContext &getASTContext() const { return getModule().getASTContext(); }
const Lowering::TypeLowering &getTypeLowering(SILType T) const {
return getModule().getTypeLowering(T);
}
void setOpenedArchetypesTracker(SILOpenedArchetypesTracker *Tracker) {
- this->OpenedArchetypesTracker = Tracker;
- this->OpenedArchetypes.setOpenedArchetypesTracker(OpenedArchetypesTracker);
+ C.OpenedArchetypesTracker = Tracker;
+ C.OpenedArchetypes.setOpenedArchetypesTracker(C.OpenedArchetypesTracker);
}
SILOpenedArchetypesTracker *getOpenedArchetypesTracker() const {
- return OpenedArchetypesTracker;
+ return C.OpenedArchetypesTracker;
}
- SILOpenedArchetypesState &getOpenedArchetypes() {
- return OpenedArchetypes;
- }
+ SILOpenedArchetypesState &getOpenedArchetypes() { return C.OpenedArchetypes; }
void setCurrentDebugScope(const SILDebugScope *DS) { CurDebugScope = DS; }
const SILDebugScope *getCurrentDebugScope() const { return CurDebugScope; }
@@ -229,11 +286,11 @@
/// Clients of SILBuilder who want to know about any newly created
/// instructions can install a SmallVector into the builder to collect them.
void setTrackingList(SmallVectorImpl<SILInstruction *> *II) {
- InsertedInstrs = II;
+ C.InsertedInstrs = II;
}
SmallVectorImpl<SILInstruction *> *getTrackingList() {
- return InsertedInstrs;
+ return C.InsertedInstrs;
}
//===--------------------------------------------------------------------===//
@@ -302,9 +359,9 @@
AllocStackInst *createAllocStack(SILLocation Loc, SILType elementType,
Optional<SILDebugVariable> Var = None) {
Loc.markAsPrologue();
- return insert(AllocStackInst::create(getSILDebugLocation(Loc),
- elementType, getFunction(),
- OpenedArchetypes, Var));
+ return insert(AllocStackInst::create(getSILDebugLocation(Loc), elementType,
+ getFunction(), C.OpenedArchetypes,
+ Var));
}
AllocRefInst *createAllocRef(SILLocation Loc, SILType ObjectType,
@@ -314,10 +371,10 @@
// AllocRefInsts expand to function calls and can therefore not be
// counted towards the function prologue.
assert(!Loc.isInPrologue());
- return insert(AllocRefInst::create(getSILDebugLocation(Loc),
- getFunction(), ObjectType, objc, canAllocOnStack,
+ return insert(AllocRefInst::create(getSILDebugLocation(Loc), getFunction(),
+ ObjectType, objc, canAllocOnStack,
ElementTypes, ElementCountOperands,
- OpenedArchetypes));
+ C.OpenedArchetypes));
}
AllocRefDynamicInst *createAllocRefDynamic(SILLocation Loc, SILValue operand,
@@ -327,24 +384,22 @@
// AllocRefDynamicInsts expand to function calls and can therefore
// not be counted towards the function prologue.
assert(!Loc.isInPrologue());
- return insert(AllocRefDynamicInst::create(getSILDebugLocation(Loc), *F,
- operand, type, objc,
- ElementTypes,
- ElementCountOperands,
- OpenedArchetypes));
+ return insert(AllocRefDynamicInst::create(
+ getSILDebugLocation(Loc), *F, operand, type, objc, ElementTypes,
+ ElementCountOperands, C.OpenedArchetypes));
}
AllocValueBufferInst *
createAllocValueBuffer(SILLocation Loc, SILType valueType, SILValue operand) {
return insert(AllocValueBufferInst::create(
- getSILDebugLocation(Loc), valueType, operand, *F, OpenedArchetypes));
+ getSILDebugLocation(Loc), valueType, operand, *F, C.OpenedArchetypes));
}
AllocBoxInst *createAllocBox(SILLocation Loc, CanSILBoxType BoxType,
Optional<SILDebugVariable> Var = None) {
Loc.markAsPrologue();
return insert(AllocBoxInst::create(getSILDebugLocation(Loc), BoxType, *F,
- OpenedArchetypes, Var));
+ C.OpenedArchetypes, Var));
}
AllocExistentialBoxInst *
@@ -353,7 +408,7 @@
ArrayRef<ProtocolConformanceRef> Conformances) {
return insert(AllocExistentialBoxInst::create(
getSILDebugLocation(Loc), ExistentialType, ConcreteType, Conformances,
- F, OpenedArchetypes));
+ F, C.OpenedArchetypes));
}
ApplyInst *createApply(
@@ -361,8 +416,8 @@
ArrayRef<SILValue> Args, bool isNonThrowing,
const GenericSpecializationInformation *SpecializationInfo = nullptr) {
return insert(ApplyInst::create(getSILDebugLocation(Loc), Fn, Subs, Args,
- isNonThrowing, silConv, *F,
- OpenedArchetypes, SpecializationInfo));
+ isNonThrowing, C.silConv, *F,
+ C.OpenedArchetypes, SpecializationInfo));
}
ApplyInst *createApply(
@@ -378,30 +433,27 @@
SILLocation Loc, SILValue fn, SubstitutionMap subs,
ArrayRef<SILValue> args, SILBasicBlock *normalBB, SILBasicBlock *errorBB,
const GenericSpecializationInformation *SpecializationInfo = nullptr) {
- return insertTerminator(TryApplyInst::create(getSILDebugLocation(Loc),
- fn, subs, args,
- normalBB, errorBB, *F,
- OpenedArchetypes,
- SpecializationInfo));
+ return insertTerminator(TryApplyInst::create(
+ getSILDebugLocation(Loc), fn, subs, args, normalBB, errorBB, *F,
+ C.OpenedArchetypes, SpecializationInfo));
}
PartialApplyInst *createPartialApply(
SILLocation Loc, SILValue Fn, SubstitutionMap Subs,
ArrayRef<SILValue> Args, ParameterConvention CalleeConvention,
const GenericSpecializationInformation *SpecializationInfo = nullptr) {
- return insert(PartialApplyInst::create(getSILDebugLocation(Loc), Fn,
- Args, Subs, CalleeConvention, *F,
- OpenedArchetypes,
- SpecializationInfo));
+ return insert(PartialApplyInst::create(
+ getSILDebugLocation(Loc), Fn, Args, Subs, CalleeConvention, *F,
+ C.OpenedArchetypes, SpecializationInfo));
}
BeginApplyInst *createBeginApply(
SILLocation Loc, SILValue Fn, SubstitutionMap Subs,
ArrayRef<SILValue> Args, bool isNonThrowing,
const GenericSpecializationInformation *SpecializationInfo = nullptr) {
- return insert(BeginApplyInst::create(getSILDebugLocation(Loc), Fn, Subs,
- Args, isNonThrowing, silConv, *F,
- OpenedArchetypes, SpecializationInfo));
+ return insert(BeginApplyInst::create(
+ getSILDebugLocation(Loc), Fn, Subs, Args, isNonThrowing, C.silConv, *F,
+ C.OpenedArchetypes, SpecializationInfo));
}
AbortApplyInst *createAbortApply(SILLocation loc, SILValue beginApply) {
@@ -789,20 +841,21 @@
BindMemoryInst *createBindMemory(SILLocation Loc, SILValue base,
SILValue index, SILType boundType) {
return insert(BindMemoryInst::create(getSILDebugLocation(Loc), base, index,
- boundType, getFunction(), OpenedArchetypes));
+ boundType, getFunction(),
+ C.OpenedArchetypes));
}
ConvertFunctionInst *createConvertFunction(SILLocation Loc, SILValue Op,
SILType Ty) {
- return insert(ConvertFunctionInst::create(getSILDebugLocation(Loc), Op, Ty,
- getFunction(), OpenedArchetypes));
+ return insert(ConvertFunctionInst::create(
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
}
ConvertEscapeToNoEscapeInst *
createConvertEscapeToNoEscape(SILLocation Loc, SILValue Op, SILType Ty,
bool isEscapedByUser, bool lifetimeGuaranteed) {
return insert(ConvertEscapeToNoEscapeInst::create(
- getSILDebugLocation(Loc), Op, Ty, getFunction(), OpenedArchetypes,
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes,
isEscapedByUser, lifetimeGuaranteed));
}
@@ -815,12 +868,12 @@
PointerToThinFunctionInst *
createPointerToThinFunction(SILLocation Loc, SILValue Op, SILType Ty) {
return insert(PointerToThinFunctionInst::create(
- getSILDebugLocation(Loc), Op, Ty, getFunction(), OpenedArchetypes));
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
}
UpcastInst *createUpcast(SILLocation Loc, SILValue Op, SILType Ty) {
return insert(UpcastInst::create(getSILDebugLocation(Loc), Op, Ty,
- getFunction(), OpenedArchetypes));
+ getFunction(), C.OpenedArchetypes));
}
AddressToPointerInst *createAddressToPointer(SILLocation Loc, SILValue Op,
@@ -839,8 +892,8 @@
UncheckedRefCastInst *createUncheckedRefCast(SILLocation Loc, SILValue Op,
SILType Ty) {
- return insert(UncheckedRefCastInst::create(getSILDebugLocation(Loc), Op, Ty,
- getFunction(), OpenedArchetypes));
+ return insert(UncheckedRefCastInst::create(
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
}
UncheckedRefCastAddrInst *
@@ -852,20 +905,20 @@
UncheckedAddrCastInst *createUncheckedAddrCast(SILLocation Loc, SILValue Op,
SILType Ty) {
- return insert(UncheckedAddrCastInst::create(getSILDebugLocation(Loc), Op,
- Ty, getFunction(), OpenedArchetypes));
+ return insert(UncheckedAddrCastInst::create(
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
}
UncheckedTrivialBitCastInst *
createUncheckedTrivialBitCast(SILLocation Loc, SILValue Op, SILType Ty) {
return insert(UncheckedTrivialBitCastInst::create(
- getSILDebugLocation(Loc), Op, Ty, getFunction(), OpenedArchetypes));
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
}
UncheckedBitwiseCastInst *
createUncheckedBitwiseCast(SILLocation Loc, SILValue Op, SILType Ty) {
- return insert(UncheckedBitwiseCastInst::create(getSILDebugLocation(Loc), Op,
- Ty, getFunction(), OpenedArchetypes));
+ return insert(UncheckedBitwiseCastInst::create(
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
}
RefToBridgeObjectInst *createRefToBridgeObject(SILLocation Loc, SILValue Ref,
@@ -914,8 +967,8 @@
ThinToThickFunctionInst *createThinToThickFunction(SILLocation Loc,
SILValue Op, SILType Ty) {
- return insert(ThinToThickFunctionInst::create(getSILDebugLocation(Loc), Op,
- Ty, getFunction(), OpenedArchetypes));
+ return insert(ThinToThickFunctionInst::create(
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
}
ThickToObjCMetatypeInst *createThickToObjCMetatype(SILLocation Loc,
@@ -963,7 +1016,8 @@
UnconditionalCheckedCastInst *
createUnconditionalCheckedCast(SILLocation Loc, SILValue op, SILType destTy) {
return insert(UnconditionalCheckedCastInst::create(
- getSILDebugLocation(Loc), op, destTy, getFunction(), OpenedArchetypes));
+ getSILDebugLocation(Loc), op, destTy, getFunction(),
+ C.OpenedArchetypes));
}
UnconditionalCheckedCastAddrInst *
@@ -978,12 +1032,13 @@
createUnconditionalCheckedCastValue(SILLocation Loc,
SILValue op, SILType destTy) {
return insert(UnconditionalCheckedCastValueInst::create(
- getSILDebugLocation(Loc), op, destTy, getFunction(), OpenedArchetypes));
+ getSILDebugLocation(Loc), op, destTy, getFunction(),
+ C.OpenedArchetypes));
}
RetainValueInst *createRetainValue(SILLocation Loc, SILValue operand,
Atomicity atomicity) {
- assert(isParsing || !getFunction().hasQualifiedOwnership());
+ assert(C.isParsing || !getFunction().hasQualifiedOwnership());
assert(operand->getType().isLoadableOrOpaque(getModule()));
return insert(new (getModule()) RetainValueInst(getSILDebugLocation(Loc),
operand, atomicity));
@@ -991,14 +1046,14 @@
RetainValueAddrInst *createRetainValueAddr(SILLocation Loc, SILValue operand,
Atomicity atomicity) {
- assert(isParsing || !getFunction().hasQualifiedOwnership());
+ assert(C.isParsing || !getFunction().hasQualifiedOwnership());
return insert(new (getModule()) RetainValueAddrInst(
getSILDebugLocation(Loc), operand, atomicity));
}
ReleaseValueInst *createReleaseValue(SILLocation Loc, SILValue operand,
Atomicity atomicity) {
- assert(isParsing || !getFunction().hasQualifiedOwnership());
+ assert(C.isParsing || !getFunction().hasQualifiedOwnership());
assert(operand->getType().isLoadableOrOpaque(getModule()));
return insert(new (getModule()) ReleaseValueInst(getSILDebugLocation(Loc),
operand, atomicity));
@@ -1007,7 +1062,7 @@
ReleaseValueAddrInst *createReleaseValueAddr(SILLocation Loc,
SILValue operand,
Atomicity atomicity) {
- assert(isParsing || !getFunction().hasQualifiedOwnership());
+ assert(C.isParsing || !getFunction().hasQualifiedOwnership());
return insert(new (getModule()) ReleaseValueAddrInst(
getSILDebugLocation(Loc), operand, atomicity));
}
@@ -1305,9 +1360,9 @@
ObjCMethodInst *createObjCMethod(SILLocation Loc, SILValue Operand,
SILDeclRef Member, SILType MethodTy) {
- return insert(ObjCMethodInst::create(
- getSILDebugLocation(Loc), Operand, Member, MethodTy,
- &getFunction(), OpenedArchetypes));
+ return insert(ObjCMethodInst::create(getSILDebugLocation(Loc), Operand,
+ Member, MethodTy, &getFunction(),
+ C.OpenedArchetypes));
}
ObjCSuperMethodInst *createObjCSuperMethod(SILLocation Loc, SILValue Operand,
@@ -1321,7 +1376,7 @@
SILDeclRef Member, SILType MethodTy) {
return insert(WitnessMethodInst::create(
getSILDebugLocation(Loc), LookupTy, Conformance, Member, MethodTy,
- &getFunction(), OpenedArchetypes));
+ &getFunction(), C.OpenedArchetypes));
}
OpenExistentialAddrInst *
@@ -1329,8 +1384,8 @@
OpenedExistentialAccess ForAccess) {
auto *I = insert(new (getModule()) OpenExistentialAddrInst(
getSILDebugLocation(Loc), Operand, SelfTy, ForAccess));
- if (OpenedArchetypesTracker)
- OpenedArchetypesTracker->registerOpenedArchetypes(I);
+ if (C.OpenedArchetypesTracker)
+ C.OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}
@@ -1339,8 +1394,8 @@
SILType SelfTy) {
auto *I = insert(new (getModule()) OpenExistentialValueInst(
getSILDebugLocation(Loc), Operand, SelfTy));
- if (OpenedArchetypesTracker)
- OpenedArchetypesTracker->registerOpenedArchetypes(I);
+ if (C.OpenedArchetypesTracker)
+ C.OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}
@@ -1349,8 +1404,8 @@
SILType selfTy) {
auto *I = insert(new (getModule()) OpenExistentialMetatypeInst(
getSILDebugLocation(Loc), operand, selfTy));
- if (OpenedArchetypesTracker)
- OpenedArchetypesTracker->registerOpenedArchetypes(I);
+ if (C.OpenedArchetypesTracker)
+ C.OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}
@@ -1358,8 +1413,8 @@
createOpenExistentialRef(SILLocation Loc, SILValue Operand, SILType Ty) {
auto *I = insert(new (getModule()) OpenExistentialRefInst(
getSILDebugLocation(Loc), Operand, Ty));
- if (OpenedArchetypesTracker)
- OpenedArchetypesTracker->registerOpenedArchetypes(I);
+ if (C.OpenedArchetypesTracker)
+ C.OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}
@@ -1367,8 +1422,8 @@
createOpenExistentialBox(SILLocation Loc, SILValue Operand, SILType Ty) {
auto *I = insert(new (getModule()) OpenExistentialBoxInst(
getSILDebugLocation(Loc), Operand, Ty));
- if (OpenedArchetypesTracker)
- OpenedArchetypesTracker->registerOpenedArchetypes(I);
+ if (C.OpenedArchetypesTracker)
+ C.OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}
@@ -1376,8 +1431,8 @@
createOpenExistentialBoxValue(SILLocation Loc, SILValue Operand, SILType Ty) {
auto *I = insert(new (getModule()) OpenExistentialBoxValueInst(
getSILDebugLocation(Loc), Operand, Ty));
- if (OpenedArchetypesTracker)
- OpenedArchetypesTracker->registerOpenedArchetypes(I);
+ if (C.OpenedArchetypesTracker)
+ C.OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}
@@ -1388,7 +1443,7 @@
ArrayRef<ProtocolConformanceRef> Conformances) {
return insert(InitExistentialAddrInst::create(
getSILDebugLocation(Loc), Existential, FormalConcreteType,
- LoweredConcreteType, Conformances, &getFunction(), OpenedArchetypes));
+ LoweredConcreteType, Conformances, &getFunction(), C.OpenedArchetypes));
}
InitExistentialValueInst *
@@ -1397,7 +1452,7 @@
ArrayRef<ProtocolConformanceRef> Conformances) {
return insert(InitExistentialValueInst::create(
getSILDebugLocation(Loc), ExistentialType, FormalConcreteType, Concrete,
- Conformances, &getFunction(), OpenedArchetypes));
+ Conformances, &getFunction(), C.OpenedArchetypes));
}
InitExistentialMetatypeInst *
@@ -1406,7 +1461,7 @@
ArrayRef<ProtocolConformanceRef> conformances) {
return insert(InitExistentialMetatypeInst::create(
getSILDebugLocation(Loc), existentialType, metatype, conformances,
- &getFunction(), OpenedArchetypes));
+ &getFunction(), C.OpenedArchetypes));
}
InitExistentialRefInst *
@@ -1415,7 +1470,7 @@
ArrayRef<ProtocolConformanceRef> Conformances) {
return insert(InitExistentialRefInst::create(
getSILDebugLocation(Loc), ExistentialType, FormalConcreteType, Concrete,
- Conformances, &getFunction(), OpenedArchetypes));
+ Conformances, &getFunction(), C.OpenedArchetypes));
}
DeinitExistentialAddrInst *createDeinitExistentialAddr(SILLocation Loc,
@@ -1454,7 +1509,7 @@
MetatypeInst *createMetatype(SILLocation Loc, SILType Metatype) {
return insert(MetatypeInst::create(getSILDebugLocation(Loc), Metatype,
- &getFunction(), OpenedArchetypes));
+ &getFunction(), C.OpenedArchetypes));
}
ObjCMetatypeToObjectInst *
@@ -1493,13 +1548,13 @@
StrongRetainInst *createStrongRetain(SILLocation Loc, SILValue Operand,
Atomicity atomicity) {
- assert(isParsing || !getFunction().hasQualifiedOwnership());
+ assert(C.isParsing || !getFunction().hasQualifiedOwnership());
return insert(new (getModule()) StrongRetainInst(getSILDebugLocation(Loc),
Operand, atomicity));
}
StrongReleaseInst *createStrongRelease(SILLocation Loc, SILValue Operand,
Atomicity atomicity) {
- assert(isParsing || !getFunction().hasQualifiedOwnership());
+ assert(C.isParsing || !getFunction().hasQualifiedOwnership());
return insert(new (getModule()) StrongReleaseInst(
getSILDebugLocation(Loc), Operand, atomicity));
}
@@ -1827,7 +1882,7 @@
ProfileCounter Target2Count = ProfileCounter()) {
return insertTerminator(CheckedCastBranchInst::create(
getSILDebugLocation(Loc), isExact, op, destTy, successBB, failureBB,
- getFunction(), OpenedArchetypes, Target1Count, Target2Count));
+ getFunction(), C.OpenedArchetypes, Target1Count, Target2Count));
}
CheckedCastValueBranchInst *
@@ -1836,7 +1891,7 @@
SILBasicBlock *failureBB) {
return insertTerminator(CheckedCastValueBranchInst::create(
getSILDebugLocation(Loc), op, destTy, successBB, failureBB,
- getFunction(), OpenedArchetypes));
+ getFunction(), C.OpenedArchetypes));
}
CheckedCastAddrBranchInst *
@@ -2030,12 +2085,10 @@
if (BB == 0)
return;
- // If the SILBuilder client wants to know about new instructions, record
- // this.
- if (InsertedInstrs)
- InsertedInstrs->push_back(TheInst);
-
BB->insert(InsertPt, TheInst);
+
+ C.notifyInserted(TheInst);
+
// TODO: We really shouldn't be creating instructions unless we are going to
// insert them into a block... This failed in SimplifyCFG.
#ifndef NDEBUG
@@ -2070,6 +2123,16 @@
}
public:
+ /// Build instructions before the given insertion point, inheriting the debug
+ /// location.
+ ///
+ /// Clients should prefer this constructor.
+ SILBuilderWithScope(SILInstruction *I, SILBuilderContext &C)
+ : SILBuilder(I, C) {
+ assert(I->getDebugScope() && "instruction has no debug scope");
+ setCurrentDebugScope(I->getDebugScope());
+ }
+
explicit SILBuilderWithScope(
SILInstruction *I,
SmallVectorImpl<SILInstruction *> *InsertedInstrs = nullptr)
diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h
index 7fc2cf2..2d68d46 100644
--- a/include/swift/SIL/SILFunction.h
+++ b/include/swift/SIL/SILFunction.h
@@ -587,7 +587,7 @@
/// \return the function side effects information.
EffectsKind getEffectsKind() const { return EffectsKindAttr; }
- /// \return True if the function is annotated with the @effects attribute.
+ /// \return True if the function is annotated with the @_effects attribute.
bool hasEffectsKind() const {
return EffectsKindAttr != EffectsKind::Unspecified;
}
diff --git a/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h b/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h
index 7fc56cb..8862207 100644
--- a/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h
@@ -406,8 +406,8 @@
}
protected:
- /// Set the side-effects of a function, which has an @effects attribute.
- /// Returns true if \a F has an @effects attribute which could be handled.
+ /// Set the side-effects of a function, which has an @_effects attribute.
+ /// Returns true if \a F has an @_effects attribute which could be handled.
bool setDefinedEffects(SILFunction *F);
/// Set the side-effects of a semantic call.
diff --git a/lib/AST/ConformanceLookupTable.cpp b/lib/AST/ConformanceLookupTable.cpp
index e3c9b9d..7e5e1f8 100644
--- a/lib/AST/ConformanceLookupTable.cpp
+++ b/lib/AST/ConformanceLookupTable.cpp
@@ -161,8 +161,6 @@
SmallVector<ProtocolConformance *, 2> conformances;
loader.first->loadAllConformances(nominal, loader.second, conformances);
loadAllConformances(nominal, conformances);
- } else if (nominal->getParentSourceFile() && resolver) {
- resolver->resolveDeclSignature(nominal);
}
nominalFunc(nominal);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 70041fa..0d1672d 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3495,19 +3495,7 @@
if (isObjC())
return true;
- // Resolve the protocol's type.
- if (resolver && !hasInterfaceType())
- resolver->resolveDeclSignature(this);
-
for (auto member : getMembers()) {
- if (auto vd = dyn_cast<ValueDecl>(member)) {
- if (resolver && !vd->hasInterfaceType())
- resolver->resolveDeclSignature(vd);
- }
-
- if (member->isInvalid())
- continue;
-
// Check for associated types.
if (isa<AssociatedTypeDecl>(member)) {
// An existential type cannot be used if the protocol has an
@@ -3524,6 +3512,9 @@
continue;
}
+ if (resolver && !valueMember->hasInterfaceType())
+ resolver->resolveDeclSignature(valueMember);
+
if (!isAvailableInExistential(valueMember)) {
Bits.ProtocolDecl.ExistentialTypeSupported = false;
return false;
@@ -4375,8 +4366,9 @@
/*IsCaptureList*/false, parameterNameLoc, parameterName, ty, dc),
ArgumentName(argumentName), ArgumentNameLoc(argumentNameLoc),
SpecifierLoc(specifierLoc) {
- assert(specifier != Specifier::Var &&
- "'var' cannot appear on parameters; you meant 'inout'");
+
+ assert(specifier != Specifier::Var &&
+ "'var' cannot appear on parameters; you meant 'inout'");
Bits.ParamDecl.IsTypeLocImplicit = false;
Bits.ParamDecl.defaultArgumentKind =
static_cast<unsigned>(DefaultArgumentKind::None);
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index c87c4bc..a3f613b 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -7465,6 +7465,12 @@
ProtocolDecl *proto) {
GenericSignatureBuilder builder(proto->getASTContext());
+ if (!proto->hasInterfaceType()) {
+ // FIXME: Overkill.
+ if (auto lazyResolver = proto->getASTContext().getLazyResolver())
+ lazyResolver->resolveDeclSignature(proto);
+ }
+
// Add the 'self' parameter.
auto selfType =
proto->getSelfInterfaceType()->castTo<GenericTypeParamType>();
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index 3b9a38a..d82c7c2 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -15,11 +15,11 @@
//===----------------------------------------------------------------------===//
#include "NameLookupImpl.h"
-#include "swift/ClangImporter/ClangImporter.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTScope.h"
#include "swift/AST/ASTVisitor.h"
+#include "swift/AST/ClangModuleLoader.h"
#include "swift/AST/DebuggerClient.h"
#include "swift/AST/ExistentialLayout.h"
#include "swift/AST/LazyResolver.h"
@@ -81,11 +81,16 @@
}
bool swift::removeOverriddenDecls(SmallVectorImpl<ValueDecl*> &decls) {
- if (decls.empty())
+ if (decls.size() < 2)
return false;
+ auto lazyResolver = decls.front()->getASTContext().getLazyResolver();
llvm::SmallPtrSet<ValueDecl*, 8> overridden;
for (auto decl : decls) {
+ // Compute enough information to make the overridden-declaration available.
+ if (lazyResolver)
+ lazyResolver->resolveOverriddenDecl(decl);
+
while (auto overrides = decl->getOverriddenDecl()) {
overridden.insert(overrides);
@@ -100,6 +105,10 @@
/// cause instead (incomplete circularity detection).
assert(decl != overrides && "Circular class inheritance?");
decl = overrides;
+
+ if (lazyResolver)
+ lazyResolver->resolveOverriddenDecl(decl);
+
continue;
}
@@ -299,13 +308,18 @@
// Prefer declarations in an overlay to similar declarations in
// the Clang module it customizes.
if (firstDecl->hasClangNode() != secondDecl->hasClangNode()) {
- if (isInOverlayModuleForImportedModule(firstDecl->getDeclContext(),
- secondDecl->getDeclContext())){
+ auto clangLoader = ctx.getClangModuleLoader();
+ if (!clangLoader) continue;
+
+ if (clangLoader->isInOverlayModuleForImportedModule(
+ firstDecl->getDeclContext(),
+ secondDecl->getDeclContext())) {
shadowed.insert(secondDecl);
continue;
}
- if (isInOverlayModuleForImportedModule(secondDecl->getDeclContext(),
+ if (clangLoader->isInOverlayModuleForImportedModule(
+ secondDecl->getDeclContext(),
firstDecl->getDeclContext())) {
shadowed.insert(firstDecl);
break;
@@ -1755,13 +1769,6 @@
// criteria.
bool onlyCompleteObjectInits = false;
auto isAcceptableDecl = [&](NominalTypeDecl *current, ValueDecl *decl) -> bool {
- // If the decl is currently being type checked, then we have something
- // cyclic going on. Instead of poking at parts that are potentially not
- // set up, just assume it is acceptable. This will make sure we produce an
- // error later.
- if (!decl->hasValidSignature())
- return true;
-
// Filter out designated initializers, if requested.
if (onlyCompleteObjectInits) {
if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
@@ -1780,8 +1787,12 @@
}
// Check access.
- if (!(options & NL_IgnoreAccessControl))
+ if (!(options & NL_IgnoreAccessControl)) {
+ if (typeResolver)
+ typeResolver->resolveAccessControl(decl);
+
return decl->isAccessibleFrom(this);
+ }
return true;
};
@@ -1823,11 +1834,6 @@
if ((options & NL_OnlyTypes) && !isa<TypeDecl>(decl))
continue;
- // Resolve the declaration signature when we find the
- // declaration.
- if (typeResolver)
- typeResolver->resolveDeclSignature(decl);
-
if (isAcceptableDecl(current, decl))
decls.push_back(decl);
}
@@ -1892,17 +1898,20 @@
if ((options & NL_OnlyTypes) && !isa<TypeDecl>(decl))
continue;
+ // If the declaration is not @objc, it cannot be called dynamically.
if (typeResolver)
- typeResolver->resolveDeclSignature(decl);
+ typeResolver->resolveIsObjC(decl);
+
+ if (!decl->isObjC())
+ continue;
// If the declaration has an override, name lookup will also have
// found the overridden method. Skip this declaration, because we
// prefer the overridden method.
- if (decl->getOverriddenDecl())
- continue;
+ if (typeResolver)
+ typeResolver->resolveOverriddenDecl(decl);
- // If the declaration is not @objc, it cannot be called dynamically.
- if (!decl->isObjC())
+ if (decl->getOverriddenDecl())
continue;
auto dc = decl->getDeclContext();
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 29d6f45..d64e2bd 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1835,7 +1835,7 @@
if (auto classDecl = type->getClassOrBoundGenericClass()) {
auto &ctx = classDecl->getASTContext();
if (auto resolver = ctx.getLazyResolver())
- resolver->resolveDeclSignature(classDecl);
+ resolver->resolveIsObjC(classDecl);
if (classDecl->isObjC())
return ForeignRepresentableKind::Object;
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index d431891..456a1c1 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -3539,7 +3539,7 @@
// Resolve the type.
if (auto typeResolver = getTypeResolver())
- typeResolver->resolveDeclSignature(const_cast<NominalTypeDecl *>(nominal));
+ typeResolver->resolveIsObjC(const_cast<NominalTypeDecl *>(nominal));
// If it's an @objc entity, go look for it.
if (nominal->isObjC()) {
@@ -3598,7 +3598,8 @@
getDeclName();
}
-bool swift::isInOverlayModuleForImportedModule(const DeclContext *overlayDC,
+bool ClangImporter::isInOverlayModuleForImportedModule(
+ const DeclContext *overlayDC,
const DeclContext *importedDC) {
overlayDC = overlayDC->getModuleScopeContext();
importedDC = importedDC->getModuleScopeContext();
@@ -3613,7 +3614,7 @@
// Is this a private module that's re-exported to the public (overlay) name?
auto clangModule =
- importedClangModuleUnit->getClangModule()->getTopLevelModule();
+ importedClangModuleUnit->getClangModule()->getTopLevelModule();
return !clangModule->ExportAsModule.empty() &&
clangModule->ExportAsModule == overlayModule->getName().str();
}
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 3071be1..3c3daaf 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -4395,9 +4395,6 @@
T *found = nullptr;
for (auto result : results) {
if (auto singleResult = dyn_cast<T>(result)) {
- if (auto typeResolver = Impl.getTypeResolver())
- typeResolver->resolveDeclSignature(singleResult);
-
// Skip versioned variants.
const DeclAttributes &attrs = singleResult->getAttrs();
if (attrs.isUnavailableInSwiftVersion(languageVersion))
@@ -5620,7 +5617,7 @@
// argument label
auto *paramDecl =
new (Impl.SwiftContext) ParamDecl(
- VarDecl::Specifier::Let, SourceLoc(), SourceLoc(), argNames.front(),
+ VarDecl::Specifier::Default, SourceLoc(), SourceLoc(), argNames.front(),
SourceLoc(), argNames.front(), Impl.SwiftContext.TheEmptyTupleType,
dc);
paramDecl->setInterfaceType(Impl.SwiftContext.TheEmptyTupleType);
diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp
index fc58c94..e9076ec 100644
--- a/lib/ClangImporter/ImportType.cpp
+++ b/lib/ClangImporter/ImportType.cpp
@@ -2364,8 +2364,6 @@
NLKind::UnqualifiedLookup, results);
if (results.size() == 1) {
if (auto nominalDecl = dyn_cast<NominalTypeDecl>(results.front())) {
- if (auto *typeResolver = getTypeResolver())
- typeResolver->resolveDeclSignature(nominalDecl);
if (auto params = nominalDecl->getGenericParams()) {
if (params->size() == args.size()) {
// When we form the bound generic type, make sure we get the
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 10db2ee..094f204 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2222,7 +2222,7 @@
}
/// Return True if the function \p f is a 'readonly' function. Checking
-/// for the SIL @effects(readonly) attribute is not enough because this
+/// for the SIL @_effects(readonly) attribute is not enough because this
/// definition does not match the definition of the LLVM readonly function
/// attribute. In this function we do the actual check.
static bool isReadOnlyFunction(SILFunction *f) {
@@ -2235,11 +2235,11 @@
auto Eff = f->getEffectsKind();
// Swift's readonly does not automatically match LLVM's readonly.
- // Swift SIL optimizer relies on @effects(readonly) to remove e.g.
+ // Swift SIL optimizer relies on @_effects(readonly) to remove e.g.
// dead code remaining from initializers of strings or dictionaries
// of variables that are not used. But those initializers are often
// not really readonly in terms of LLVM IR. For example, the
- // Dictionary.init() is marked as @effects(readonly) in Swift, but
+ // Dictionary.init() is marked as @_effects(readonly) in Swift, but
// it does invoke reference-counting operations.
if (Eff == EffectsKind::ReadOnly || Eff == EffectsKind::ReadNone) {
// TODO: Analyze the body of function f and return true if it is
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 2f3ebae..31b0700 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -2648,7 +2648,7 @@
for (auto &F : *getModule())
runOnFunction(&F);
- if (modFuncs.empty()) {
+ if (modFuncs.empty() && modApplies.empty()) {
return;
}
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index 95fea25..6e16b3e 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -425,7 +425,7 @@
Identifier argName, SourceLoc argNameLoc,
Identifier paramName, SourceLoc paramNameLoc)
-> ParamDecl * {
- auto param = new (ctx) ParamDecl(paramInfo.SpecifierKind,
+ auto param = new (ctx) ParamDecl(VarDecl::Specifier::Default,
paramInfo.SpecifierLoc,
argNameLoc, argName,
paramNameLoc, paramName, Type(),
diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp
index ad69d3f..ed5b8ea 100644
--- a/lib/Parse/ParseType.cpp
+++ b/lib/Parse/ParseType.cpp
@@ -181,7 +181,7 @@
Tok.getRawText().equals("__owned")))) {
// Type specifier should already be parsed before here. This only happens
// for construct like 'P1 & inout P2'.
- diagnose(Tok.getLoc(), diag::attr_only_on_parameters_parse, Tok.getText());
+ diagnose(Tok.getLoc(), diag::attr_only_on_parameters, Tok.getRawText());
consumeToken();
}
diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp
index 4409ab1..a6ff85e 100644
--- a/lib/SIL/SILBuilder.cpp
+++ b/lib/SIL/SILBuilder.cpp
@@ -23,7 +23,8 @@
SILBuilder::SILBuilder(SILGlobalVariable *GlobVar,
SmallVectorImpl<SILInstruction *> *InsertedInstrs)
- : F(nullptr), Mod(GlobVar->getModule()), InsertedInstrs(InsertedInstrs) {
+ : TempContext(GlobVar->getModule(), InsertedInstrs), C(TempContext),
+ F(nullptr) {
setInsertionPoint(&GlobVar->StaticInitializerBlock);
}
@@ -100,7 +101,8 @@
return nullptr;
return insert(UncheckedRefCastInst::create(getSILDebugLocation(Loc), Op,
- ResultTy, getFunction(), OpenedArchetypes));
+ ResultTy, getFunction(),
+ C.OpenedArchetypes));
}
ClassifyBridgeObjectInst *
@@ -120,15 +122,15 @@
assert(Ty.isLoadableOrOpaque(getModule()));
if (Ty.isTrivial(getModule()))
return insert(UncheckedTrivialBitCastInst::create(
- getSILDebugLocation(Loc), Op, Ty, getFunction(), OpenedArchetypes));
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
if (auto refCast = tryCreateUncheckedRefCast(Loc, Op, Ty))
return refCast;
// The destination type is nontrivial, and may be smaller than the source
// type, so RC identity cannot be assumed.
- return insert(UncheckedBitwiseCastInst::create(getSILDebugLocation(Loc), Op,
- Ty, getFunction(), OpenedArchetypes));
+ return insert(UncheckedBitwiseCastInst::create(
+ getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
}
BranchInst *SILBuilder::createBranch(SILLocation Loc,
@@ -420,7 +422,7 @@
void SILBuilder::addOpenedArchetypeOperands(SILInstruction *I) {
// The list of archetypes from the previous instruction needs
// to be replaced, because it may reference a removed instruction.
- OpenedArchetypes.addOpenedArchetypeOperands(I->getTypeDependentOperands());
+ C.OpenedArchetypes.addOpenedArchetypeOperands(I->getTypeDependentOperands());
if (I && I->getNumTypeDependentOperands() > 0)
return;
@@ -447,18 +449,19 @@
I = SVI;
continue;
}
- auto Def = OpenedArchetypes.getOpenedArchetypeDef(Archetype);
+ auto Def = C.OpenedArchetypes.getOpenedArchetypeDef(Archetype);
// Return if it is a known open archetype.
if (Def)
return;
// Otherwise register it and return.
- if (OpenedArchetypesTracker)
- OpenedArchetypesTracker->addOpenedArchetypeDef(Archetype, SVI);
+ if (C.OpenedArchetypesTracker)
+ C.OpenedArchetypesTracker->addOpenedArchetypeDef(Archetype, SVI);
return;
}
if (I && I->getNumTypeDependentOperands() > 0) {
- OpenedArchetypes.addOpenedArchetypeOperands(I->getTypeDependentOperands());
+ C.OpenedArchetypes.addOpenedArchetypeOperands(
+ I->getTypeDependentOperands());
}
}
diff --git a/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
index 1952a4c..720f21d 100644
--- a/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
@@ -334,7 +334,7 @@
case EffectsKind::ReadNone:
return true;
case EffectsKind::ReadOnly:
- // @effects(readonly) is worthless if we have owned parameters, because
+ // @_effects(readonly) is worthless if we have owned parameters, because
// the release inside the callee may call a deinit, which itself can do
// anything.
if (!F->hasOwnedParameters()) {
@@ -356,7 +356,7 @@
if (!F->empty())
ParamEffects.resize(F->getArguments().size());
- // Handle @effects attributes
+ // Handle @_effects attributes
if (setDefinedEffects(F)) {
DEBUG(llvm::dbgs() << " -- has defined effects " << F->getName() << '\n');
return true;
@@ -463,7 +463,7 @@
}
if (SILFunction *SingleCallee = fullApply.getReferencedFunction()) {
- // Does the function have any @effects?
+ // Does the function have any @_effects?
if (setDefinedEffects(SingleCallee))
return true;
}
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index 9788b31..a20c11b 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -828,7 +828,7 @@
namespace {
class SILClosureSpecializerTransform : public SILFunctionTransform {
- void gatherCallSites(SILFunction *Caller,
+ bool gatherCallSites(SILFunction *Caller,
llvm::SmallVectorImpl<ClosureInfo*> &ClosureCandidates,
llvm::DenseSet<FullApplySite> &MultipleClosureAI);
bool specialize(SILFunction *Caller,
@@ -904,7 +904,7 @@
llvm_unreachable("Unexpect instruction");
}
-void SILClosureSpecializerTransform::gatherCallSites(
+bool SILClosureSpecializerTransform::gatherCallSites(
SILFunction *Caller,
llvm::SmallVectorImpl<ClosureInfo*> &ClosureCandidates,
llvm::DenseSet<FullApplySite> &MultipleClosureAI) {
@@ -917,6 +917,8 @@
// up using as an argument that we specialize on.
llvm::DenseSet<SingleValueInstruction *> UsedReabstractionClosure;
+ bool CFGChanged = false;
+
// For each basic block BB in Caller...
for (auto &BB : *Caller) {
@@ -1010,7 +1012,7 @@
// We could fix this by inserting new arguments more carefully, or
// changing how we model dynamic Self altogether.
if (mayBindDynamicSelf(ApplyCallee))
- return;
+ return CFGChanged;
// Ok, we know that we can perform the optimization but not whether or
// not the optimization is profitable. Find the index of the argument
@@ -1096,12 +1098,15 @@
}
if (CInfo) {
ValueLifetimeAnalysis VLA(CInfo->Closure, UsePoints);
- VLA.computeFrontier(CInfo->LifetimeFrontier,
- ValueLifetimeAnalysis::AllowToModifyCFG);
+ if (!VLA.computeFrontier(CInfo->LifetimeFrontier,
+ ValueLifetimeAnalysis::AllowToModifyCFG)) {
+ CFGChanged = true;
+ }
ClosureCandidates.push_back(CInfo);
}
}
}
+ return CFGChanged;
}
bool SILClosureSpecializerTransform::specialize(SILFunction *Caller,
@@ -1113,7 +1118,9 @@
// ApplyInsts. Check the profitability of specializing the closure argument.
llvm::SmallVector<ClosureInfo*, 8> ClosureCandidates;
llvm::DenseSet<FullApplySite> MultipleClosureAI;
- gatherCallSites(Caller, ClosureCandidates, MultipleClosureAI);
+ if (gatherCallSites(Caller, ClosureCandidates, MultipleClosureAI)) {
+ invalidateAnalysis(SILAnalysis::InvalidationKind::Branches);
+ }
bool Changed = false;
for (auto *CInfo : ClosureCandidates) {
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp
index 6d49c6e..b26e423 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp
@@ -1399,6 +1399,8 @@
if (auto *MI = dyn_cast<MetatypeInst>(MDVal)) {
auto &Mod = ARDI->getModule();
auto SILInstanceTy = MI->getType().getMetatypeInstanceType(Mod);
+ if (!SILInstanceTy.getClassOrBoundGenericClass())
+ return nullptr;
NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
ARDI->isObjC(), false,
@@ -1420,6 +1422,8 @@
if (CCBI && CCBI->isExact() && ARDI->getParent() == CCBI->getSuccessBB()) {
auto &Mod = ARDI->getModule();
auto SILInstanceTy = CCBI->getCastType().getMetatypeInstanceType(Mod);
+ if (!SILInstanceTy.getClassOrBoundGenericClass())
+ return nullptr;
NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
ARDI->isObjC(), false,
ARDI->getTailAllocatedTypes(),
diff --git a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
index 6ca65fd..97137b9 100644
--- a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
+++ b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
@@ -924,7 +924,7 @@
} // end anonymous namespace
/// Create an inliner pass that does not inline functions that are marked with
-/// the @_semantics, @effects or global_init attributes.
+/// the @_semantics, @_effects or global_init attributes.
SILTransform *swift::createEarlyInliner() {
return new SILPerformanceInlinerPass(
InlineSelection::NoSemanticsAndGlobalInit, "Early");
@@ -937,7 +937,7 @@
}
/// Create an inliner pass that inlines all functions that are marked with
-/// the @_semantics, @effects or global_init attributes.
+/// the @_semantics, @_effects or global_init attributes.
SILTransform *swift::createLateInliner() {
return new SILPerformanceInlinerPass(InlineSelection::Everything, "Late");
}
diff --git a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
index fbda97f..37ec91c 100644
--- a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
+++ b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
@@ -664,7 +664,7 @@
auto ModuleName = Callee->getModule().getSwiftModule()->getName().str();
bool IsInStdlib = (ModuleName == STDLIB_NAME || ModuleName == SWIFT_ONONE_SUPPORT);
- // Don't inline functions that are marked with the @_semantics or @effects
+ // Don't inline functions that are marked with the @_semantics or @_effects
// attribute if the inliner is asked not to inline them.
if (Callee->hasSemanticsAttrs() || Callee->hasEffectsKind()) {
if (WhatToInline == InlineSelection::NoSemanticsAndGlobalInit) {
diff --git a/lib/Sema/NameBinding.cpp b/lib/Sema/NameBinding.cpp
index 248ca97..33ebde4 100644
--- a/lib/Sema/NameBinding.cpp
+++ b/lib/Sema/NameBinding.cpp
@@ -347,9 +347,10 @@
/// performNameBinding - Once parsing is complete, this walks the AST to
/// resolve names and do other top-level validation.
///
-/// At this parsing has been performed, but we still have UnresolvedDeclRefExpr
-/// nodes for unresolved value names, and we may have unresolved type names as
-/// well. This handles import directives and forward references.
+/// At this point parsing has been performed, but we still have
+/// UnresolvedDeclRefExpr nodes for unresolved value names, and we may have
+/// unresolved type names as well. This handles import directives and forward
+/// references.
void swift::performNameBinding(SourceFile &SF, unsigned StartElem) {
SharedTimer timer("Name binding");
// Make sure we skip adding the standard library imports if the
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index c858ccd..06e3e68 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -18,11 +18,11 @@
#include "MiscDiagnostics.h"
#include "swift/AST/GenericSignatureBuilder.h"
#include "swift/AST/ASTVisitor.h"
+#include "swift/AST/ClangModuleLoader.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/Types.h"
-#include "swift/ClangImporter/ClangImporter.h"
#include "swift/Parse/Lexer.h"
#include "llvm/Support/Debug.h"
@@ -1413,7 +1413,9 @@
if (!classDecl)
return false;
- return isInOverlayModuleForImportedModule(ext, classDecl);
+ auto clangLoader = dc->getASTContext().getClangModuleLoader();
+ if (!clangLoader) return false;
+ return clangLoader->isInOverlayModuleForImportedModule(ext, classDecl);
}
void AttributeChecker::visitRequiredAttr(RequiredAttr *attr) {
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 7d365cb..f427c15 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3792,6 +3792,51 @@
if (isInvalid) PGD->setInvalid();
}
+void TypeChecker::resolveOverriddenDecl(ValueDecl *VD) {
+ // Only members of classes can override other declarations.
+ if (!VD->getDeclContext()->getAsClassOrClassExtensionContext())
+ return;
+
+ // Types that aren't associated types cannot be overridden.
+ if (isa<TypeDecl>(VD) && !isa<AssociatedTypeDecl>(VD))
+ return;
+
+ // FIXME: We should check for the 'override' or 'required' keywords
+ // here, to short-circuit checking in the common case.
+
+ // FIXME: We should perform more minimal validation.
+ validateDeclForNameLookup(VD);
+}
+
+void TypeChecker::resolveIsObjC(ValueDecl *VD) {
+ // Short-circuit this operation if we already know that the entity is @objc.
+ if (VD->isObjC()) return;
+
+ auto dc = VD->getDeclContext();
+ if (dc->getAsClassOrClassExtensionContext()) {
+ // Members of classes can be @objc.
+
+ // FIXME: We
+ validateDeclForNameLookup(VD);
+ }
+ else if (isa<ClassDecl>(VD)) {
+ // Classes can be @objc.
+
+ // Protocols and enums can also be @objc, but this is covered by the
+ // isObjC() check at the beginning.
+ }
+ else if (isa<ProtocolDecl>(dc) && cast<ProtocolDecl>(dc)->isObjC()) {
+ // Members of @objc protocols are @objc.
+ }
+ else {
+ // Cannot be @objc; do nothing.
+ return;
+ }
+
+ // FIXME: Narrow this computation to just the @objc bits.
+ validateDeclForNameLookup(VD);
+}
+
PrecedenceGroupDecl *TypeChecker::lookupPrecedenceGroup(DeclContext *dc,
Identifier name,
SourceLoc nameLoc) {
diff --git a/lib/Sema/TypeCheckError.cpp b/lib/Sema/TypeCheckError.cpp
index c768835..6cf8938 100644
--- a/lib/Sema/TypeCheckError.cpp
+++ b/lib/Sema/TypeCheckError.cpp
@@ -875,6 +875,14 @@
llvm_unreachable("invalid classify result");
}
+ static Context getContextForPatternBinding(PatternBindingDecl *pbd) {
+ if (!pbd->isStatic() && pbd->getDeclContext()->isTypeContext()) {
+ return Context(Kind::IVarInitializer);
+ } else {
+ return Context(Kind::GlobalVarInitializer);
+ }
+ }
+
Kind TheKind;
bool DiagnoseErrorOnTry = false;
DeclContext *RethrowsDC = nullptr;
@@ -897,6 +905,23 @@
result.RethrowsDC = D;
return result;
}
+
+ // HACK: If the decl is the synthesized getter for a 'lazy' property, then
+ // treat the context as a property initializer in order to produce a better
+ // diagnostic; the only code we should be diagnosing on is within the
+ // initializer expression that has been transplanted from the var's pattern
+ // binding decl. We don't perform the analysis on the initializer while it's
+ // still a part of that PBD, as it doesn't get a solution applied there.
+ if (auto *accessor = dyn_cast<AccessorDecl>(D)) {
+ if (auto *var = dyn_cast<VarDecl>(accessor->getStorage())) {
+ if (accessor->isGetter() && var->getAttrs().hasAttribute<LazyAttr>()) {
+ auto *pbd = var->getParentPatternBinding();
+ assert(pbd && "lazy var didn't have a pattern binding decl");
+ return getContextForPatternBinding(pbd);
+ }
+ }
+ }
+
return Context(getKindForFunctionBody(
D->getInterfaceType(), D->getNumParameterLists()));
}
@@ -906,14 +931,10 @@
return Context(Kind::DefaultArgument);
}
- auto binding = cast<PatternBindingInitializer>(init)->getBinding();
+ auto *binding = cast<PatternBindingInitializer>(init)->getBinding();
assert(!binding->getDeclContext()->isLocalContext() &&
"setting up error context for local pattern binding?");
- if (!binding->isStatic() && binding->getDeclContext()->isTypeContext()) {
- return Context(Kind::IVarInitializer);
- } else {
- return Context(Kind::GlobalVarInitializer);
- }
+ return getContextForPatternBinding(binding);
}
static Context forEnumElementInitializer(EnumElementDecl *elt) {
@@ -1411,7 +1432,8 @@
// HACK: functions can get queued multiple times in
// definedFunctions, so be sure to be idempotent.
- if (!E->isThrowsSet()) {
+ if (!E->isThrowsSet() &&
+ classification.getResult() != ThrowingKind::Invalid) {
E->setThrows(classification.getResult() == ThrowingKind::RethrowingOnly ||
classification.getResult() == ThrowingKind::Throws);
}
@@ -1485,6 +1507,9 @@
Flags.set(ContextFlags::HasAnyThrowSite);
if (requiresTry) Flags.set(ContextFlags::HasTryThrowSite);
+ // We set the throwing bit of an apply expr after performing this
+ // analysis, so ensure we don't emit duplicate diagnostics for functions
+ // that have been queued multiple times.
if (auto expr = E.dyn_cast<Expr*>())
if (auto apply = dyn_cast<ApplyExpr>(expr))
if (apply->isThrowsSet())
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index a85f440..af45fa8 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -27,6 +27,7 @@
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTMangler.h"
#include "swift/AST/ASTPrinter.h"
+#include "swift/AST/ClangModuleLoader.h"
#include "swift/AST/Decl.h"
#include "swift/AST/ExistentialLayout.h"
#include "swift/AST/GenericEnvironment.h"
@@ -3628,8 +3629,10 @@
if (Proto->isSpecificProtocol(KnownProtocolKind::ObjectiveCBridgeable)) {
auto nominal = Adoptee->getAnyNominal();
if (!TC.Context.isTypeBridgedInExternalModule(nominal)) {
+ auto clangLoader = TC.Context.getClangModuleLoader();
if (nominal->getParentModule() != DC->getParentModule() &&
- !isInOverlayModuleForImportedModule(DC, nominal)) {
+ !(clangLoader &&
+ clangLoader->isInOverlayModuleForImportedModule(DC, nominal))) {
auto nominalModule = nominal->getParentModule();
TC.diagnose(Loc, diag::nonlocal_bridged_to_objc, nominal->getName(),
Proto->getName(), nominalModule->getName());
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 0a1fc60..f8e1547 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -2193,11 +2193,7 @@
options -= TypeResolutionFlags::ImmediateFunctionInput;
options -= TypeResolutionFlags::FunctionInput;
options -= TypeResolutionFlags::TypeAliasUnderlyingType;
- // FIXME: Until we remove the IUO type from the type system, we
- // need to continue to parse IUOs in SIL tests so that we can
- // match the types we generate from the importer.
- if (!options.contains(TypeResolutionFlags::SILMode))
- options -= TypeResolutionFlags::AllowIUO;
+ options -= TypeResolutionFlags::AllowIUO;
Type inputTy = resolveType(repr->getArgsTypeRepr(),
options | TypeResolutionFlags::ImmediateFunctionInput);
@@ -2712,13 +2708,13 @@
StringRef name;
switch (repr->getKind()) {
case TypeReprKind::InOut:
- name = "'inout'";
+ name = "inout";
break;
case TypeReprKind::Shared:
- name = "'__shared'";
+ name = "__shared";
break;
case TypeReprKind::Owned:
- name = "'__owned'";
+ name = "__owned";
break;
default:
llvm_unreachable("unknown SpecifierTypeRepr kind");
@@ -2863,11 +2859,7 @@
auto elementOptions = options;
if (repr->isParenType()) {
// We also want to disallow IUO within even a paren.
- // FIXME: Until we remove the IUO type from the type system, we
- // need to continue to parse IUOs in SIL tests so that we can
- // match the types we generate from the importer.
- if (!options.contains(TypeResolutionFlags::SILMode))
- elementOptions -= TypeResolutionFlags::AllowIUO;
+ elementOptions -= TypeResolutionFlags::AllowIUO;
// If we have a single ParenType, don't clear the context bits; we
// still want to parse the type contained therein as if it were in
@@ -2876,7 +2868,7 @@
// `FunctionInput` so that e.g. ((foo: Int)) -> Int is considered a
// tuple argument rather than a labeled Int argument.
if (isImmediateFunctionInput) {
- elementOptions -= TypeResolutionFlags::ImmediateFunctionInput;
+ elementOptions = withoutContext(elementOptions, true);
elementOptions |= TypeResolutionFlags::FunctionInput;
}
} else {
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index d863aa1..aead3fd 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -585,7 +585,7 @@
// Make sure we have a type checker.
//
- // FIXME: We should never have a type checker here, but currently do when
+ // FIXME: We should never have a type checker here, but currently we do when
// we're using immediate together with -enable-source-import.
//
// This possibility should be eliminated, since it results in duplicated
@@ -596,7 +596,7 @@
// Make sure that name binding has been completed before doing any type
// checking.
- performNameBinding(SF, StartElem);
+ performNameBinding(SF, StartElem);
{
// NOTE: The type checker is scoped to be torn down before AST
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index aa14f6f..fee35bc 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -581,6 +581,7 @@
options -= TypeResolutionFlags::FunctionInput;
options -= TypeResolutionFlags::VariadicFunctionInput;
options -= TypeResolutionFlags::EnumCase;
+ options -= TypeResolutionFlags::SubscriptParameters;
options -= TypeResolutionFlags::ImmediateOptionalTypeArgument;
options -= TypeResolutionFlags::AllowIUO;
if (!preserveSIL) options -= TypeResolutionFlags::SILType;
@@ -1378,6 +1379,12 @@
validateDeclForNameLookup(VD);
}
+ /// Resolve the "overridden" declaration of the given declaration.
+ virtual void resolveOverriddenDecl(ValueDecl *VD) override;
+
+ /// Resolve the "is Objective-C" bit for the given declaration.
+ virtual void resolveIsObjC(ValueDecl *VD) override;
+
virtual void bindExtension(ExtensionDecl *ext) override;
virtual void resolveExtension(ExtensionDecl *ext) override {
diff --git a/stdlib/public/core/Character.swift b/stdlib/public/core/Character.swift
index f868b18..8549333 100644
--- a/stdlib/public/core/Character.swift
+++ b/stdlib/public/core/Character.swift
@@ -130,7 +130,7 @@
}
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
public init(_builtinUnicodeScalarLiteral value: Builtin.Int32) {
self.init(Unicode.Scalar(_builtinUnicodeScalarLiteral: value))
}
@@ -139,7 +139,7 @@
// integer constant in case of small character literals.
@inlinable // FIXME(sil-serialize-all)
@inline(__always)
- @effects(readonly)
+ @_effects(readonly)
public init(
_builtinExtendedGraphemeClusterLiteral start: Builtin.RawPointer,
utf8CodeUnitCount: Builtin.Word,
@@ -194,7 +194,7 @@
// integer constant in case of small character literals.
@inlinable // FIXME(sil-serialize-all)
@inline(__always)
- @effects(readonly)
+ @_effects(readonly)
public init(
_builtinExtendedGraphemeClusterLiteral start: Builtin.RawPointer,
utf16CodeUnitCount: Builtin.Word
@@ -483,7 +483,7 @@
///
/// - Parameter hasher: The hasher to use when combining the components
/// of this instance.
- @effects(releasenone)
+ @_effects(releasenone)
public func hash(into hasher: inout Hasher) {
// FIXME(performance): constructing a temporary string is extremely
// wasteful and inefficient.
diff --git a/stdlib/public/core/Dictionary.swift b/stdlib/public/core/Dictionary.swift
index f6aa4fa..48227cd 100644
--- a/stdlib/public/core/Dictionary.swift
+++ b/stdlib/public/core/Dictionary.swift
@@ -798,7 +798,7 @@
/// - Parameter elements: The key-value pairs that will make up the new
/// dictionary. Each key in `elements` must be unique.
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
public init(dictionaryLiteral elements: (Key, Value)...) {
self.init(_nativeBuffer: _NativeDictionaryBuffer.fromArray(elements))
}
diff --git a/stdlib/public/core/Hasher.swift b/stdlib/public/core/Hasher.swift
index 877c3cf..0aaf1a1 100644
--- a/stdlib/public/core/Hasher.swift
+++ b/stdlib/public/core/Hasher.swift
@@ -281,14 +281,14 @@
/// Initialize a new hasher. The hasher uses a per-execution seed value that
/// is set during process startup, usually from a high-quality random source.
- @effects(releasenone)
+ @_effects(releasenone)
public init() {
self._core = Core(seed: Hasher._seed)
}
/// Initialize a new hasher using the specified seed value.
@usableFromInline
- @effects(releasenone)
+ @_effects(releasenone)
internal init(_seed seed: (UInt64, UInt64)) {
self._core = Core(seed: seed)
}
@@ -331,37 +331,37 @@
value.hash(into: &self)
}
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal mutating func _combine(_ value: UInt) {
_core.combine(value)
}
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal mutating func _combine(_ value: UInt64) {
_core.combine(value)
}
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal mutating func _combine(_ value: UInt32) {
_core.combine(value)
}
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal mutating func _combine(_ value: UInt16) {
_core.combine(value)
}
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal mutating func _combine(_ value: UInt8) {
_core.combine(value)
}
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal mutating func _combine(bytes value: UInt64, count: Int) {
_core.combine(bytes: value, count: count)
@@ -369,7 +369,7 @@
/// Feed the contents of `buffer` into this hasher, mixing it into the hasher
/// state.
- @effects(releasenone)
+ @_effects(releasenone)
public mutating func combine(bytes: UnsafeRawBufferPointer) {
_core.combine(bytes: bytes)
}
@@ -377,7 +377,7 @@
/// Finalize the hasher state and return the hash value.
/// Finalizing invalidates the hasher; additional bits cannot be combined
/// into it, and it cannot be finalized again.
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal mutating func _finalize() -> Int {
return Int(truncatingIfNeeded: _core.finalize())
@@ -391,7 +391,7 @@
///
/// Hash values are not guaranteed to be equal across different executions of
/// your program. Do not save hash values to use during a future execution.
- @effects(releasenone)
+ @_effects(releasenone)
public __consuming func finalize() -> Int {
var core = _core
return Int(truncatingIfNeeded: core.finalize())
@@ -399,13 +399,13 @@
// Generate a seed value from the current state of this hasher.
// FIXME(hasher): Remove
- @effects(readnone)
+ @_effects(readnone)
@usableFromInline
internal func _generateSeed() -> (UInt64, UInt64) {
return _core._generateSeed()
}
- @effects(readnone)
+ @_effects(readnone)
@usableFromInline
internal static func _hash(seed: (UInt64, UInt64), _ value: UInt64) -> Int {
var core = RawCore(seed: seed)
@@ -414,7 +414,7 @@
return Int(truncatingIfNeeded: core.finalize(tailAndByteCount: tbc.value))
}
- @effects(readnone)
+ @_effects(readnone)
@usableFromInline
internal static func _hash(seed: (UInt64, UInt64), _ value: UInt) -> Int {
var core = RawCore(seed: seed)
@@ -431,7 +431,7 @@
return Int(truncatingIfNeeded: core.finalize(tailAndByteCount: tbc.value))
}
- @effects(readnone)
+ @_effects(readnone)
@usableFromInline
internal static func _hash(
seed: (UInt64, UInt64),
@@ -442,7 +442,7 @@
return Int(truncatingIfNeeded: core.finalize(tailAndByteCount: tbc.value))
}
- @effects(readnone)
+ @_effects(readnone)
@usableFromInline
internal static func _hash(
seed: (UInt64, UInt64),
diff --git a/stdlib/public/core/KeyPath.swift b/stdlib/public/core/KeyPath.swift
index 48ef660..a42c431 100644
--- a/stdlib/public/core/KeyPath.swift
+++ b/stdlib/public/core/KeyPath.swift
@@ -57,7 +57,7 @@
///
/// - Parameter hasher: The hasher to use when combining the components
/// of this instance.
- @effects(releasenone)
+ @_effects(releasenone)
final public func hash(into hasher: inout Hasher) {
return withBuffer {
var buffer = $0
@@ -594,7 +594,7 @@
}
}
- @effects(releasenone)
+ @_effects(releasenone)
internal func hash(into hasher: inout Hasher) {
var hasher = hasher
func appendHashFromArgument(
diff --git a/stdlib/public/core/OutputStream.swift b/stdlib/public/core/OutputStream.swift
index c7f060c..8e85703 100644
--- a/stdlib/public/core/OutputStream.swift
+++ b/stdlib/public/core/OutputStream.swift
@@ -415,7 +415,7 @@
///
/// This function is forbidden from being inlined because when building the
/// standard library inlining makes us drop the special semantics.
-@inline(never) @effects(readonly)
+@inline(never) @_effects(readonly)
@usableFromInline
internal func _toStringReadOnlyStreamable<
T : TextOutputStreamable
@@ -425,7 +425,7 @@
return result
}
-@inline(never) @effects(readonly)
+@inline(never) @_effects(readonly)
@usableFromInline
internal func _toStringReadOnlyPrintable<
T : CustomStringConvertible
diff --git a/stdlib/public/core/SmallString.swift b/stdlib/public/core/SmallString.swift
index 5b9652b..290968d 100644
--- a/stdlib/public/core/SmallString.swift
+++ b/stdlib/public/core/SmallString.swift
@@ -129,7 +129,7 @@
@inline(__always)
@inlinable
- @effects(readonly)
+ @_effects(readonly)
public // @testable
init?(_ codeUnits: UnsafeBufferPointer<UInt8>) {
#if arch(i386) || arch(arm)
diff --git a/stdlib/public/core/StaticString.swift b/stdlib/public/core/StaticString.swift
index afa995a..9c41e66 100644
--- a/stdlib/public/core/StaticString.swift
+++ b/stdlib/public/core/StaticString.swift
@@ -196,7 +196,7 @@
}
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
@_transparent
public init(_builtinUnicodeScalarLiteral value: Builtin.Int32) {
self = StaticString(unicodeScalar: value)
@@ -207,14 +207,14 @@
/// Do not call this initializer directly. It may be used by the compiler
/// when you initialize a static string with a Unicode scalar.
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
@_transparent
public init(unicodeScalarLiteral value: StaticString) {
self = value
}
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
@_transparent
public init(
_builtinExtendedGraphemeClusterLiteral start: Builtin.RawPointer,
@@ -234,14 +234,14 @@
/// Do not call this initializer directly. It may be used by the compiler
/// when you initialize a static string using an extended grapheme cluster.
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
@_transparent
public init(extendedGraphemeClusterLiteral value: StaticString) {
self = value
}
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
@_transparent
public init(
_builtinStringLiteral start: Builtin.RawPointer,
@@ -259,7 +259,7 @@
/// Do not call this initializer directly. It may be used by the compiler
/// when you initialize a static string using a string literal.
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
@_transparent
public init(stringLiteral value: StaticString) {
self = value
diff --git a/stdlib/public/core/String.swift b/stdlib/public/core/String.swift
index 243dff7..ecc4915 100644
--- a/stdlib/public/core/String.swift
+++ b/stdlib/public/core/String.swift
@@ -668,7 +668,7 @@
extension String : _ExpressibleByBuiltinUnicodeScalarLiteral {
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
public // @testable
init(_builtinUnicodeScalarLiteral value: Builtin.Int32) {
self.init(Unicode.Scalar(_value: UInt32(value)))
@@ -699,7 +699,7 @@
extension String : _ExpressibleByBuiltinExtendedGraphemeClusterLiteral {
@inlinable
- @effects(readonly)
+ @_effects(readonly)
@_semantics("string.makeUTF8")
public init(
_builtinExtendedGraphemeClusterLiteral start: Builtin.RawPointer,
@@ -715,7 +715,7 @@
extension String : _ExpressibleByBuiltinUTF16StringLiteral {
@inlinable
- @effects(readonly)
+ @_effects(readonly)
@_semantics("string.makeUTF16")
public init(
_builtinUTF16StringLiteral start: Builtin.RawPointer,
@@ -736,7 +736,7 @@
extension String : _ExpressibleByBuiltinStringLiteral {
@inline(__always)
@inlinable
- @effects(readonly)
+ @_effects(readonly)
@_semantics("string.makeUTF8")
public init(
_builtinStringLiteral start: Builtin.RawPointer,
@@ -922,7 +922,7 @@
extension String {
@inlinable // FIXME(sil-serialize-all)
- @effects(readonly)
+ @_effects(readonly)
@_semantics("string.concat")
public static func + (lhs: String, rhs: String) -> String {
var lhs = lhs
diff --git a/stdlib/public/core/StringBridge.swift b/stdlib/public/core/StringBridge.swift
index 405cc83..43e1818 100644
--- a/stdlib/public/core/StringBridge.swift
+++ b/stdlib/public/core/StringBridge.swift
@@ -30,7 +30,7 @@
}
@inlinable // FIXME(sil-serialize-all)
-@effects(readonly)
+@_effects(readonly)
public // @testable
func _stdlib_binary_CFStringGetLength(
_ source: _CocoaString
diff --git a/stdlib/public/core/StringComparison.swift b/stdlib/public/core/StringComparison.swift
index 1327f56..0719ab4 100644
--- a/stdlib/public/core/StringComparison.swift
+++ b/stdlib/public/core/StringComparison.swift
@@ -33,7 +33,7 @@
// HACK: This gets rid of some retains/releases that was slowing down the
// memcmp fast path for comparing ascii strings. rdar://problem/37473470
@inline(never) // @outlined
-@effects(readonly)
+@_effects(readonly)
@usableFromInline // @opaque
internal
func _compareUnicode(
@@ -70,7 +70,7 @@
}
@inline(never) // @outlined
-@effects(readonly)
+@_effects(readonly)
@usableFromInline // @opaque
internal
func _compareUnicode(
diff --git a/stdlib/public/core/StringGuts.swift b/stdlib/public/core/StringGuts.swift
index 203fece..d86a552 100644
--- a/stdlib/public/core/StringGuts.swift
+++ b/stdlib/public/core/StringGuts.swift
@@ -228,7 +228,7 @@
// FIXME(TODO: JIRA): HACK HACK HACK: Work around for ARC :-(
//
@usableFromInline
- @effects(readonly)
+ @_effects(readonly)
internal static func getCocoaLength(_unsafeBitPattern: UInt) -> Int {
return _stdlib_binary_CFStringGetLength(
Builtin.reinterpretCast(_unsafeBitPattern))
@@ -399,7 +399,7 @@
@inlinable
internal
var _unmanagedASCIIView: _UnmanagedString<UInt8> {
- @effects(readonly)
+ @_effects(readonly)
get {
_sanityCheck(_object.isContiguousASCII)
if _object.isUnmanaged {
@@ -420,7 +420,7 @@
@inlinable
internal
var _unmanagedUTF16View: _UnmanagedString<UTF16.CodeUnit> {
- @effects(readonly)
+ @_effects(readonly)
get {
_sanityCheck(_object.isContiguousUTF16)
if _object.isUnmanaged {
@@ -807,7 +807,7 @@
@usableFromInline
internal
var _nonStoredCount: Int {
- @effects(readonly)
+ @_effects(readonly)
get {
if _object.isSmall {
return _object.smallUTF8Count
diff --git a/stdlib/public/core/StringGutsVisitor.swift b/stdlib/public/core/StringGutsVisitor.swift
index 41fb9ee..e86eb2e 100644
--- a/stdlib/public/core/StringGutsVisitor.swift
+++ b/stdlib/public/core/StringGutsVisitor.swift
@@ -54,7 +54,7 @@
}
@usableFromInline
- @effects(readonly)
+ @_effects(readonly)
@inline(never) // @_outlined
func _visitOpaque<Result>(
range: (Range<Int>, performBoundsCheck: Bool)? = nil,
@@ -141,7 +141,7 @@
}
@usableFromInline // @opaque
- @effects(readonly)
+ @_effects(readonly)
@inline(never)
func _visitOpaque<T, Result>(
range: (Range<Int>, performBoundsCheck: Bool)?,
diff --git a/stdlib/public/core/StringHashable.swift b/stdlib/public/core/StringHashable.swift
index d9ffbfa..6b69e3e 100644
--- a/stdlib/public/core/StringHashable.swift
+++ b/stdlib/public/core/StringHashable.swift
@@ -107,7 +107,7 @@
}
extension _StringGuts {
- @effects(releasenone) // FIXME: Is this valid in the opaque case?
+ @_effects(releasenone) // FIXME: Is this valid in the opaque case?
@usableFromInline
internal func hash(into hasher: inout Hasher) {
if _isSmall {
@@ -127,7 +127,7 @@
_unmanagedUTF16View.hash(into: &hasher)
}
- @effects(releasenone) // FIXME: Is this valid in the opaque case?
+ @_effects(releasenone) // FIXME: Is this valid in the opaque case?
@usableFromInline
internal func hash(_ range: Range<Int>, into hasher: inout Hasher) {
if _isSmall {
@@ -147,7 +147,7 @@
_unmanagedUTF16View[range].hash(into: &hasher)
}
- @effects(releasenone) // FIXME: Is this valid in the opaque case?
+ @_effects(releasenone) // FIXME: Is this valid in the opaque case?
@usableFromInline
internal func _rawHashValue(seed: (UInt64, UInt64)) -> Int {
if _isSmall {
@@ -164,7 +164,7 @@
return _unmanagedUTF16View._rawHashValue(seed: seed)
}
- @effects(releasenone) // FIXME: Is this valid in the opaque case?
+ @_effects(releasenone) // FIXME: Is this valid in the opaque case?
@usableFromInline
internal func _rawHashValue(
_ range: Range<Int>,
diff --git a/stdlib/public/core/StringInterpolation.swift b/stdlib/public/core/StringInterpolation.swift
index c25312a..ca9a332 100644
--- a/stdlib/public/core/StringInterpolation.swift
+++ b/stdlib/public/core/StringInterpolation.swift
@@ -26,7 +26,7 @@
/// print(message)
/// // Prints "If one cookie costs 2 dollars, 3 cookies cost 6 dollars."
@inlinable
- @effects(readonly)
+ @_effects(readonly)
public init(stringInterpolation strings: String...) {
self.init()
for str in strings {
diff --git a/stdlib/public/core/StringUTF8.swift b/stdlib/public/core/StringUTF8.swift
index ecd789c..1b4143a 100644
--- a/stdlib/public/core/StringUTF8.swift
+++ b/stdlib/public/core/StringUTF8.swift
@@ -168,7 +168,7 @@
}
@inline(never)
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal func _nonASCIIIndex(atEncodedOffset n: Int) -> Index {
_sanityCheck(!_guts._isASCIIOrSmallASCII)
@@ -233,7 +233,7 @@
}
@inline(never)
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal func _nonASCIIIndex(after i: Index) -> Index {
_sanityCheck(!_guts._isASCIIOrSmallASCII)
@@ -293,7 +293,7 @@
}
@inline(never)
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal func _nonASCIIIndex(before i: Index) -> Index {
_sanityCheck(!_guts._isASCIIOrSmallASCII)
@@ -326,7 +326,7 @@
}
@inline(never)
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal func _nonASCIIDistance(from i: Index, to j: Index) -> Int {
let forwards = j >= i
@@ -375,7 +375,7 @@
}
@inline(never)
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal func _nonASCIISubscript(position: Index) -> UTF8.CodeUnit {
_sanityCheck(!_guts._isASCIIOrSmallASCII)
@@ -648,7 +648,7 @@
}
@inline(never)
- @effects(releasenone)
+ @_effects(releasenone)
@usableFromInline
internal func _gutsNonASCIIUTF8Count(
_ range: Range<Int>
diff --git a/test/IRGen/big_types_corner_cases.swift b/test/IRGen/big_types_corner_cases.swift
index fb4171d..f2a878b 100644
--- a/test/IRGen/big_types_corner_cases.swift
+++ b/test/IRGen/big_types_corner_cases.swift
@@ -254,3 +254,20 @@
private func callMethod(ptr: ((BigStruct) -> Void)?) -> () {
}
}
+
+struct BiggerString {
+ var str: String
+ var double: Double
+}
+
+struct LoadableStructWithBiggerString {
+ public var a1: BiggerString
+ public var a2: [String]
+ public var a3: [String]
+}
+
+class ClassWithLoadableStructWithBiggerString {
+ public func f() -> LoadableStructWithBiggerString {
+ return LoadableStructWithBiggerString(a1: BiggerString(str:"", double:0.0), a2: [], a3: [])
+ }
+}
diff --git a/test/IRGen/big_types_corner_cases_tiny.swift b/test/IRGen/big_types_corner_cases_tiny.swift
new file mode 100644
index 0000000..33f1263
--- /dev/null
+++ b/test/IRGen/big_types_corner_cases_tiny.swift
@@ -0,0 +1,11 @@
+
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -enable-large-loadable-types -primary-file %s %S/big_types_corner_cases.swift -emit-ir | %FileCheck %s --check-prefix=CHECK
+// REQUIRES: optimized_stdlib
+
+// DO NOT ADD ANY MORE CODE TO THIS FILE!
+
+// CHECK-LABEL: define internal void @globalinit
+// CHECK: [[ALLOC:%.*]] = alloca %T27big_types_corner_cases_tiny30LoadableStructWithBiggerStringV
+// CHECK: call swiftcc void {{.*}}(%T27big_types_corner_cases_tiny30LoadableStructWithBiggerStringV* noalias nocapture sret [[ALLOC]]
+let model = ClassWithLoadableStructWithBiggerString().f()
+
diff --git a/test/Parse/errors.swift b/test/Parse/errors.swift
index 628ae9d..54506ab 100644
--- a/test/Parse/errors.swift
+++ b/test/Parse/errors.swift
@@ -86,20 +86,6 @@
takesThrowingAutoclosure(genNoError())
}
-struct IllegalContext {
- var x: Int = genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
-
- func foo(_ x: Int = genError()) {} // expected-error {{call can throw, but errors cannot be thrown out of a default argument}}
-
- func catcher() throws {
- do {
- _ = try genError()
- } catch MSV.CarriesInt(genError()) { // expected-error {{call can throw, but errors cannot be thrown out of a catch pattern}}
- } catch MSV.CarriesInt(let i) where i == genError() { // expected-error {{call can throw, but errors cannot be thrown out of a catch guard expression}}
- }
- }
-}
-
func illformed() throws {
do {
_ = try genError()
diff --git a/test/SILGen/effectsattr.swift b/test/SILGen/effectsattr.swift
index 3ca8597..a7cd2e0 100644
--- a/test/SILGen/effectsattr.swift
+++ b/test/SILGen/effectsattr.swift
@@ -2,13 +2,13 @@
//CHECK: [readonly] @func1
-@effects(readonly) @_silgen_name("func1") func func1() { }
+@_effects(readonly) @_silgen_name("func1") func func1() { }
//CHECK: [readnone] @func2
-@effects(readnone) @_silgen_name("func2") func func2() { }
+@_effects(readnone) @_silgen_name("func2") func func2() { }
//CHECK: [readwrite] @func3
-@effects(readwrite) @_silgen_name("func3") func func3() { }
+@_effects(readwrite) @_silgen_name("func3") func func3() { }
//CHECK: [releasenone] @func4
-@effects(releasenone) @_silgen_name("func4") func func4() { }
+@_effects(releasenone) @_silgen_name("func4") func func4() { }
diff --git a/test/SILOptimizer/closure_specialize_and_cfg.sil b/test/SILOptimizer/closure_specialize_and_cfg.sil
new file mode 100644
index 0000000..c59f441
--- /dev/null
+++ b/test/SILOptimizer/closure_specialize_and_cfg.sil
@@ -0,0 +1,49 @@
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -sil-verify-without-invalidation -enable-sil-verify-all -simplify-cfg -closure-specialize %s
+
+// Test if the ClosureSpecializer correctly invalidates the dominator tree
+// even if there are no functions specialized.
+// The test just checks if the compiler does not crash.
+// First running SimplifyCFG creates the dominator tree, which should then be
+// invalidated by the ClosureSpecializer.
+// If this is not done correctly the verification will complain that the
+// dominator tree is not up to date.
+
+import Builtin
+import Swift
+
+sil @closure : $@convention(thin) () -> ()
+
+sil @use_closure : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+
+sil hidden [noinline] @use_closure2 : $@convention(thin) (@owned @callee_owned () -> (), @owned @callee_owned () -> ()) -> () {
+bb0(%0 : $@callee_owned () -> (), %1 : $@callee_owned () -> ()):
+ %2 = apply %0() : $@callee_owned () -> ()
+ %3 = apply %1() : $@callee_owned () -> ()
+ %4 = tuple ()
+ return %3 : $()
+}
+
+sil @insert_release_in_liferange_exit_block : $@convention(thin) () -> () {
+bb0:
+ %2 = function_ref @closure : $@convention(thin) () -> ()
+ %3 = partial_apply %2() : $@convention(thin) () -> ()
+ %8 = function_ref @use_closure : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %5 = partial_apply %8(%3) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+
+ // There is a critical edge from bb0 to bb2 which is broken by ValueLifetimeAnalysis.
+ cond_br undef, bb2, bb1
+
+bb1:
+ strong_retain %3 : $@callee_owned () -> ()
+ strong_retain %3 : $@callee_owned () -> ()
+ %10 = function_ref @use_closure2 : $@convention(thin) (@owned @callee_owned () -> (), @owned @callee_owned () -> ()) -> ()
+
+ // Passing two closures actually prevents closure specialization.
+ %17 = apply %10(%3, %3) : $@convention(thin) (@owned @callee_owned () -> (), @owned @callee_owned () -> ()) -> ()
+ br bb2
+
+bb2:
+ strong_release %5 : $@callee_owned () -> ()
+ %11 = tuple ()
+ return %11 : $()
+}
diff --git a/test/SILOptimizer/inline_semantics.sil b/test/SILOptimizer/inline_semantics.sil
index c025b87..dbec397 100644
--- a/test/SILOptimizer/inline_semantics.sil
+++ b/test/SILOptimizer/inline_semantics.sil
@@ -89,7 +89,7 @@
return %1 : $Int32
}
-// A function annotated with the @effects(readonly) attribute.
+// A function annotated with the @_effects(readonly) attribute.
sil [readonly] @callee_func2 : $@convention(thin) () -> Int32 {
bb0:
%0 = integer_literal $Builtin.Int32, 3
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index 8cd14ab..8490683 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -2431,6 +2431,20 @@
return %4 : $()
}
+// CHECK: sil @alloc_ref_dynamic_with_metatype_genneric
+// CHECK: metatype
+// CHECK: upcast
+// CHECK: alloc_ref_dynamic
+// CHECK: return
+sil @alloc_ref_dynamic_with_metatype_genneric : $<T where T : B>() -> () {
+ %1 = metatype $@thick T.Type
+ %2 = upcast %1 : $@thick T.Type to $@thick B.Type
+ %3 = alloc_ref_dynamic %2 : $@thick B.Type, $B
+ strong_release %3 : $B
+ %4 = tuple()
+ return %4 : $()
+}
+
// CHECK-LABEL: sil @alloc_ref_dynamic_with_upcast_metatype
// CHECK: bb0
// CHECK-NOT: alloc_ref_dynamic
diff --git a/test/SourceKit/InterfaceGen/gen_stdlib.swift b/test/SourceKit/InterfaceGen/gen_stdlib.swift
index 291e390..4de1153 100644
--- a/test/SourceKit/InterfaceGen/gen_stdlib.swift
+++ b/test/SourceKit/InterfaceGen/gen_stdlib.swift
@@ -22,7 +22,7 @@
// CHECK-MUTATING-ATTR: mutating func
-// CHECK-HIDE-ATTR-NOT: @effects
+// CHECK-HIDE-ATTR-NOT: @_effects
// CHECK-HIDE-ATTR-NOT: @semantics
// CHECK-HIDE-ATTR-NOT: @inline
diff --git a/test/attr/attr_autoclosure.swift b/test/attr/attr_autoclosure.swift
index 9f4aa11..7c1bd0e 100644
--- a/test/attr/attr_autoclosure.swift
+++ b/test/attr/attr_autoclosure.swift
@@ -1,7 +1,7 @@
// RUN: %target-typecheck-verify-swift
// Simple case.
-var fn : @autoclosure () -> Int = 4 // expected-error {{@autoclosure may only be used on parameters}} expected-error {{cannot convert value of type 'Int' to specified type '() -> Int'}}
+var fn : @autoclosure () -> Int = 4 // expected-error {{'@autoclosure' may only be used on parameters}} expected-error {{cannot convert value of type 'Int' to specified type '() -> Int'}}
@autoclosure func func1() {} // expected-error {{attribute can only be applied to types, not declarations}}
@@ -15,7 +15,7 @@
func func6(_: @autoclosure () -> Int) {func6(0)}
// autoclosure + inout doesn't make sense.
-func func8(_ x: inout @autoclosure () -> Bool) -> Bool { // expected-error {{@autoclosure may only be used on parameters}}
+func func8(_ x: inout @autoclosure () -> Bool) -> Bool { // expected-error {{'@autoclosure' may only be used on parameters}}
}
func func9(_ x: @autoclosure (Int) -> Bool) {} // expected-error {{argument type of @autoclosure parameter must be '()'}}
@@ -157,7 +157,7 @@
takesAutoclosure(fn()) // ok
}
-// expected-error @+1 {{@autoclosure must not be used on variadic parameters}}
+// expected-error @+1 {{'@autoclosure' must not be used on variadic parameters}}
func variadicAutoclosure(_ fn: @autoclosure () -> ()...) {
for _ in fn {}
}
diff --git a/test/decl/enum/enumtest.swift b/test/decl/enum/enumtest.swift
index 6659ad7..80ac3b5 100644
--- a/test/decl/enum/enumtest.swift
+++ b/test/decl/enum/enumtest.swift
@@ -322,4 +322,7 @@
enum Lens<T> {
case foo(inout T) // expected-error {{'inout' may only be used on parameters}}
case bar(inout T, Int) // expected-error {{'inout' may only be used on parameters}}
+
+ case baz((inout T) -> ()) // ok
+ case quux((inout T, inout T) -> ()) // ok
}
diff --git a/test/decl/func/throwing_functions.swift b/test/decl/func/throwing_functions.swift
index cf4d179..db76400 100644
--- a/test/decl/func/throwing_functions.swift
+++ b/test/decl/func/throwing_functions.swift
@@ -153,3 +153,108 @@
// expected-note@-1 {{did you mean to use 'try'?}} {{9-9=try }}
// expected-note@-2 {{did you mean to handle error as optional value?}} {{9-9=try? }}
// expected-note@-3 {{did you mean to disable error propagation?}} {{9-9=try! }}
+
+enum MSV : Error {
+ case Foo, Bar, Baz
+ case CarriesInt(Int)
+}
+
+func genError() throws -> Int { throw MSV.Foo }
+
+struct IllegalContext {
+ var x1: Int = genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ let x2 = genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ var x3 = try genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ let x4: Int = try genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ var x5 = B() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ var x6 = try B() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ var x7 = { // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+ return try genError()
+ }()
+
+ var x8: Int = {
+ do {
+ return genError() // expected-error {{call can throw but is not marked with 'try'}}
+ // expected-note@-1 {{did you mean to use 'try'?}}
+ // expected-note@-2 {{did you mean to handle error as optional value?}}
+ // expected-note@-3 {{did you mean to disable error propagation?}}
+ } catch {
+ return 0
+ }
+ }()
+
+ var x9: Int = {
+ do {
+ return try genError()
+ } catch {
+ return 0
+ }
+ }()
+
+ var x10: B = {
+ do {
+ return try B()
+ } catch {
+ return B(foo: 0)
+ }
+ }()
+
+ lazy var y1: Int = genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ lazy var y2 = genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ lazy var y3 = try genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ lazy var y4: Int = try genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ lazy var y5 = B() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ lazy var y6 = try B() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+
+ lazy var y7 = { // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
+ return try genError()
+ }()
+
+ lazy var y8: Int = {
+ do {
+ return genError() // expected-error {{call can throw but is not marked with 'try'}}
+ // expected-note@-1 {{did you mean to use 'try'?}}
+ // expected-note@-2 {{did you mean to handle error as optional value?}}
+ // expected-note@-3 {{did you mean to disable error propagation?}}
+ } catch {
+ return 0
+ }
+ }()
+
+ lazy var y9: Int = {
+ do {
+ return try genError()
+ } catch {
+ return 0
+ }
+ }()
+
+ lazy var y10: B = {
+ do {
+ return try B()
+ } catch {
+ return B(foo: 0)
+ }
+ }()
+
+ func foo(_ x: Int = genError()) {} // expected-error {{call can throw, but errors cannot be thrown out of a default argument}}
+
+ func catcher() throws {
+ do {
+ _ = try genError()
+ } catch MSV.CarriesInt(genError()) { // expected-error {{call can throw, but errors cannot be thrown out of a catch pattern}}
+ } catch MSV.CarriesInt(let i) where i == genError() { // expected-error {{call can throw, but errors cannot be thrown out of a catch guard expression}}
+ }
+ }
+}
diff --git a/test/decl/subscript/subscripting.swift b/test/decl/subscript/subscripting.swift
index d02f414..211dba6 100644
--- a/test/decl/subscript/subscripting.swift
+++ b/test/decl/subscript/subscripting.swift
@@ -369,3 +369,20 @@
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=]}}
+
+// SR-7890
+
+struct InOutSubscripts {
+ subscript(x1: inout Int) -> Int { return 0 }
+ // expected-error@-1 {{'inout' must not be used on subscript parameters}}
+
+ subscript(x2: inout Int, y2: inout Int) -> Int { return 0 }
+ // expected-error@-1 2{{'inout' must not be used on subscript parameters}}
+
+ subscript(x3: (inout Int) -> ()) -> Int { return 0 } // ok
+ subscript(x4: (inout Int, inout Int) -> ()) -> Int { return 0 } // ok
+
+ subscript(inout x5: Int) -> Int { return 0 }
+ // expected-error@-1 {{'inout' before a parameter name is not allowed, place it before the parameter type instead}}
+ // expected-error@-2 {{'inout' must not be used on subscript parameters}}
+}
diff --git a/test/stdlib/DictionaryUnchecked.swift b/test/stdlib/DictionaryUnchecked.swift
index db48231..ce7a5fd 100644
--- a/test/stdlib/DictionaryUnchecked.swift
+++ b/test/stdlib/DictionaryUnchecked.swift
@@ -15,7 +15,7 @@
func createDict() -> Dictionary<Int, Bool> {
// CSE should not be able to combine both Dictionary.init() calls.
// This did happen and resulted in a crash because Dictionary.init()
- // was defined with @effects(readnone).
+ // was defined with @_effects(readnone).
// But this was wrong because it actually reads the array buffer (from
// the literal).
var Dict: Dictionary<Int, Bool> = [:]