Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3a47087
[Parser] Don't resolve decl references in the parser if the declaration
hborla Aug 25, 2020
9b2cd5e
[NameLookup] Teach unqualified lookup to resolve backing property wra…
hborla Aug 26, 2020
b33dbed
[SILGen] Teach SIlGen to emit local property wrappers
hborla Sep 27, 2020
0842b42
[SILGen] Only use assign_by_wrapper for wrapped instance properties i…
hborla Sep 28, 2020
9bd3d0b
[Property Wrappers] Make sure captures are computed for synthesized p…
hborla Sep 29, 2020
d8df621
[Property Wrappers] Allow property wrappers on local variables.
hborla Sep 29, 2020
21cbdfa
[Property Wrappers] Add a VarDecl helper method for visiting synthesized
hborla Sep 29, 2020
26b5230
Remove stray character.
adrian-prantl Sep 28, 2020
2a67c65
[Property Wrappers] Generalize a few property wrapper decl context
hborla Sep 29, 2020
9e373a2
[Name Lookup] Remove property wrapper name lookup flags and generalize
hborla Sep 29, 2020
4bb98ba
[SILGen] Add a new CaptureEmission kind specifically for emitting
hborla Sep 30, 2020
176391f
[Test] Start to add SILGen tests for local property wrappers.
hborla Sep 30, 2020
fcb51dc
[windows] XFAIL crash-in-user-code test in MSVC 2017
drodriguez Sep 30, 2020
c02c2bc
[NFC] Add an iterator template for walking singly-linked lists.
rjmccall Oct 1, 2020
8ccee27
ModuleInterface: refactor ModuleInterfaceChecker out of ModuleInterfa…
nkcsgexi Sep 29, 2020
e254f1c
[ConstraintSystem] Infer whether locator is related to return of a si…
xedin Oct 1, 2020
d576b4e
Sema: Move preCheckExpression() into its own file
slavapestov Sep 23, 2020
229cc3b
Merge pull request #34152 from slavapestov/pre-check-is-kind-of-big
slavapestov Oct 2, 2020
2765df6
Merge pull request #34148 from xedin/simplify-contextual-type-element
xedin Oct 2, 2020
af71c5d
[Property Wrappers] Ban non-member property wrappers with observers,
hborla Oct 2, 2020
2c8c9da
Merge pull request #34155 from adrian-prantl/straychar
swift-ci Oct 2, 2020
763bcf9
[SILGen] Don't use assign_by_wrapper for local property wrappers if
hborla Oct 2, 2020
e2a9bf2
Fix use-after-free in SILCombine (#34145)
meg-gupta Oct 2, 2020
f2eb9a5
Merge pull request #34144 from rjmccall/linked-list-iterator
rjmccall Oct 2, 2020
355fbb3
Merge pull request #34109 from hborla/local-property-wrappers
hborla Oct 2, 2020
ac06148
[Docs] Update the documentation contents and index (#34157)
benrimmington Oct 2, 2020
ded29c5
Merge pull request #34143 from drodriguez/windows-xfail-msvc-2017-test
drodriguez Oct 2, 2020
a71e4fb
Merge pull request #34121 from nkcsgexi/refactor-module-interface-loader
nkcsgexi Oct 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ documentation, please create a thread on the Swift forums under the
Describes how the "Omit Needless Words" algorithm works,
making imported names more idiomatic.
- Type-checking and inference:
- [TypeChecker.rst](/docs/TypeChecker.rst):
- [TypeChecker.md](/docs/TypeChecker.md):
Provides an overview of how type-checking and inference work.
- [RequestEvaluator.md](/docs/RequestEvaluator.md):
Describes the request evaluator architecture, which is used for
Expand Down
1 change: 0 additions & 1 deletion docs/contents.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ Contents
Generics
StoredAndComputedVariables
SIL
TypeChecker
OptimizationTips
ABI: TypeMetadata <ABI/TypeMetadata>
ABI: TypeLayout <ABI/TypeLayout>
Expand Down
9 changes: 6 additions & 3 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,12 @@ class ASTContext final {
bool isClang = false, bool isDWARF = false,
bool IsInterface = false);

/// Add a module interface checker to use for this AST context.
void addModuleInterfaceChecker(std::unique_ptr<ModuleInterfaceChecker> checker);

/// Retrieve the module interface checker associated with this AST context.
ModuleInterfaceChecker *getModuleInterfaceChecker() const;

/// Retrieve the module dependencies for the module with the given name.
///
/// \param isUnderlyingClangModule When true, only look for a Clang module
Expand Down Expand Up @@ -839,9 +845,6 @@ class ASTContext final {
/// If there is no Clang module loader, returns a null pointer.
/// The loader is owned by the AST context.
ClangModuleLoader *getDWARFModuleLoader() const;

/// Retrieve the module interface loader for this ASTContext.
ModuleLoader *getModuleInterfaceLoader() const;
public:
namelookup::ImportCache &getImportCache() const;

Expand Down
8 changes: 8 additions & 0 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4842,6 +4842,14 @@ class VarDecl : public AbstractStorageDecl {
/// property wrapper with a \c projectedValue .
VarDecl *getPropertyWrapperProjectionVar() const;

/// Visit all auxiliary declarations to this VarDecl.
///
/// An auxiliary declaration is a declaration synthesized by the compiler to support
/// this VarDecl, such as synthesized property wrapper variables.
///
/// \note this function only visits auxiliary decls that are not part of the AST.
void visitAuxiliaryDecls(llvm::function_ref<void(VarDecl *)>) const;

/// Retrieve the backing storage property for a lazy property.
VarDecl *getLazyStorageProperty() const;

Expand Down
2 changes: 0 additions & 2 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -5216,8 +5216,6 @@ ERROR(property_wrapper_mutating_get_composed_to_get_only,none,
"property wrapper %0 with a mutating getter cannot be composed inside "
"get-only property wrapper %1", (TypeLoc, TypeLoc))

ERROR(property_wrapper_local,none,
"property wrappers are not yet supported on local properties", ())
ERROR(property_wrapper_top_level,none,
"property wrappers are not yet supported in top-level code", ())
ERROR(property_wrapper_let, none,
Expand Down
17 changes: 17 additions & 0 deletions include/swift/AST/ModuleLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,23 @@ struct SubCompilerInstanceInfo {
ArrayRef<StringRef> ExtraPCMArgs;
};

/// Abstract interface for a checker of module interfaces and prebuilt modules.
class ModuleInterfaceChecker {
public:
virtual std::vector<std::string>
getCompiledModuleCandidatesForInterface(StringRef moduleName,
StringRef interfacePath) = 0;

/// Given a list of potential ready-to-use compiled modules for \p interfacePath,
/// check if any one of them is up-to-date. If so, emit a forwarding module
/// to the candidate binary module to \p outPath.
virtual bool tryEmitForwardingModule(StringRef moduleName,
StringRef interfacePath,
ArrayRef<std::string> candidates,
StringRef outPath) = 0;
virtual ~ModuleInterfaceChecker() = default;
};

/// Abstract interface to run an action in a sub ASTContext.
struct InterfaceSubContextDelegate {
virtual std::error_code runInSubContext(StringRef moduleName,
Expand Down
41 changes: 41 additions & 0 deletions include/swift/Basic/STLExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,47 @@ inline Iterator prev_or_begin(Iterator it, Iterator begin) {

/// @}

/// An iterator that walks a linked list of objects until it reaches
/// a null pointer.
template <class T, T* (&getNext)(T*)>
class LinkedListIterator {
T *Pointer;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = T *;
using reference = T *;
using pointer = void;

/// Returns an iterator range starting from the given pointer and
/// running until it reaches a null pointer.
static llvm::iterator_range<LinkedListIterator> rangeBeginning(T *pointer) {
return {pointer, nullptr};
}

constexpr LinkedListIterator(T *pointer) : Pointer(pointer) {}

T *operator*() const {
assert(Pointer && "dereferencing a null iterator");
return Pointer;
}

LinkedListIterator &operator++() {
Pointer = getNext(Pointer);
return *this;
}
LinkedListIterator operator++(int) {
auto copy = *this;
Pointer = getNext(Pointer);
return copy;
}

friend bool operator==(LinkedListIterator lhs, LinkedListIterator rhs) {
return lhs.Pointer == rhs.Pointer;
}
friend bool operator!=(LinkedListIterator lhs, LinkedListIterator rhs) {
return lhs.Pointer != rhs.Pointer;
}
};

/// An iterator that transforms the result of an underlying bidirectional
/// iterator with a given operation.
Expand Down
68 changes: 39 additions & 29 deletions include/swift/Frontend/ModuleInterfaceLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,27 +309,52 @@ struct ModuleInterfaceLoaderOptions {
ModuleInterfaceLoaderOptions() = default;
};

class ModuleInterfaceCheckerImpl: public ModuleInterfaceChecker {
friend class ModuleInterfaceLoader;
ASTContext &Ctx;
std::string CacheDir;
std::string PrebuiltCacheDir;
ModuleInterfaceLoaderOptions Opts;

public:
explicit ModuleInterfaceCheckerImpl(ASTContext &Ctx,
StringRef cacheDir,
StringRef prebuiltCacheDir,
ModuleInterfaceLoaderOptions Opts)
: Ctx(Ctx), CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir),
Opts(Opts) {}

std::vector<std::string>
getCompiledModuleCandidatesForInterface(StringRef moduleName,
StringRef interfacePath) override;

/// Given a list of potential ready-to-use compiled modules for \p interfacePath,
/// check if any one of them is up-to-date. If so, emit a forwarding module
/// to the candidate binary module to \p outPath.
bool tryEmitForwardingModule(StringRef moduleName,
StringRef interfacePath,
ArrayRef<std::string> candidates,
StringRef outPath) override;
bool isCached(StringRef DepPath);
};

/// A ModuleLoader that runs a subordinate \c CompilerInvocation and
/// \c CompilerInstance to convert .swiftinterface files to .swiftmodule
/// files on the fly, caching the resulting .swiftmodules in the module cache
/// directory, and loading the serialized .swiftmodules from there.
class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
friend class unittest::ModuleInterfaceLoaderTest;
explicit ModuleInterfaceLoader(
ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
ASTContext &ctx, ModuleInterfaceCheckerImpl &InterfaceChecker,
DependencyTracker *tracker, ModuleLoadingMode loadMode,
ArrayRef<std::string> PreferInterfaceForModules,
bool IgnoreSwiftSourceInfoFile, ModuleInterfaceLoaderOptions Opts)
: SerializedModuleLoaderBase(ctx, tracker, loadMode,
IgnoreSwiftSourceInfoFile),
CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir),
PreferInterfaceForModules(PreferInterfaceForModules),
Opts(Opts) {}
bool IgnoreSwiftSourceInfoFile)
: SerializedModuleLoaderBase(ctx, tracker, loadMode, IgnoreSwiftSourceInfoFile),
InterfaceChecker(InterfaceChecker),
PreferInterfaceForModules(PreferInterfaceForModules){}

std::string CacheDir;
std::string PrebuiltCacheDir;
ModuleInterfaceCheckerImpl &InterfaceChecker;
ArrayRef<std::string> PreferInterfaceForModules;
ModuleInterfaceLoaderOptions Opts;

std::error_code findModuleFilesInDirectory(
ImportPath::Element ModuleID,
Expand All @@ -343,17 +368,14 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
bool isCached(StringRef DepPath) override;
public:
static std::unique_ptr<ModuleInterfaceLoader>
create(ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
create(ASTContext &ctx, ModuleInterfaceCheckerImpl &InterfaceChecker,
DependencyTracker *tracker, ModuleLoadingMode loadMode,
ArrayRef<std::string> PreferInterfaceForModules = {},
ModuleInterfaceLoaderOptions Opts = ModuleInterfaceLoaderOptions(),
bool IgnoreSwiftSourceInfoFile = false) {
return std::unique_ptr<ModuleInterfaceLoader>(
new ModuleInterfaceLoader(ctx, cacheDir, prebuiltCacheDir,
tracker, loadMode,
PreferInterfaceForModules,
IgnoreSwiftSourceInfoFile,
Opts));
new ModuleInterfaceLoader(ctx, InterfaceChecker, tracker, loadMode,
PreferInterfaceForModules,
IgnoreSwiftSourceInfoFile));
}

/// Append visible module names to \p names. Note that names are possibly
Expand All @@ -373,18 +395,6 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
StringRef ModuleName, StringRef InPath, StringRef OutPath,
bool SerializeDependencyHashes, bool TrackSystemDependencies,
ModuleInterfaceLoaderOptions Opts);

std::vector<std::string>
getCompiledModuleCandidatesForInterface(StringRef moduleName,
StringRef interfacePath) override;

/// Given a list of potential ready-to-use compiled modules for \p interfacePath,
/// check if any one of them is up-to-date. If so, emit a forwarding module
/// to the candidate binary module to \p outPath.
bool tryEmitForwardingModule(StringRef moduleName,
StringRef interfacePath,
ArrayRef<std::string> candidates,
StringRef outPath) override;
};

struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
Expand Down
6 changes: 6 additions & 0 deletions include/swift/SILOptimizer/Utils/InstOptUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@ void getConsumedPartialApplyArgs(PartialApplyInst *pai,
SmallVectorImpl<Operand *> &argOperands,
bool includeTrivialAddrArgs);

/// Emit destroy operation for \p operand, and call appropriate functions from
/// \p callbacks for newly created instructions and deleted instructions.
void emitDestroyOperation(SILBuilder &builder, SILLocation loc,
SILValue operand, InstModCallbacks callbacks);

/// Collect all (transitive) users of \p inst which just copy or destroy \p
/// inst.
///
Expand All @@ -366,6 +371,7 @@ void getConsumedPartialApplyArgs(PartialApplyInst *pai,
/// destroys, i.e. if \p inst can be considered as "dead".
bool collectDestroys(SingleValueInstruction *inst,
SmallVectorImpl<SILInstruction *> &destroys);

/// If Closure is a partial_apply or thin_to_thick_function with only local
/// ref count users and a set of post-dominating releases:
///
Expand Down
12 changes: 0 additions & 12 deletions include/swift/Serialization/SerializedModuleLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,6 @@ class SerializedModuleLoaderBase : public ModuleLoader {
virtual Optional<ModuleDependencies> getModuleDependencies(
StringRef moduleName, ModuleDependenciesCache &cache,
InterfaceSubContextDelegate &delegate) override;

virtual std::vector<std::string>
getCompiledModuleCandidatesForInterface(StringRef moduleName,
StringRef interfacePath) {
return std::vector<std::string>();
}
virtual bool tryEmitForwardingModule(StringRef moduleName,
StringRef interfacePath,
ArrayRef<std::string> candidates,
StringRef outPath) {
return false;
}
};

/// Imports serialized Swift modules into an ASTContext.
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_UNSAFEVALUEBUFFER =
{"Builtin.UnsafeValueBuffer"};
/// The name of the Builtin type for UnknownObject
///
/// This no longer exists as an AST-accessible type, but it's still used for 
/// This no longer exists as an AST-accessible type, but it's still used for
/// fields shaped like AnyObject when ObjC interop is enabled.
constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_UNKNOWNOBJECT = {
"Builtin.UnknownObject"};
Expand Down
20 changes: 13 additions & 7 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,9 @@ struct ASTContext::Implementation {
/// The set of known protocols, lazily populated as needed.
ProtocolDecl *KnownProtocols[NumKnownProtocols] = { };

/// The module interface checker owned by the ASTContext.
std::unique_ptr<ModuleInterfaceChecker> InterfaceChecker;

/// The various module loaders that import external modules into this
/// ASTContext.
SmallVector<std::unique_ptr<swift::ModuleLoader>, 4> ModuleLoaders;
Expand All @@ -268,9 +271,6 @@ struct ASTContext::Implementation {
/// The module loader used to load Clang modules from DWARF.
ClangModuleLoader *TheDWARFModuleLoader = nullptr;

/// The module loader used to load Swift textual interface.
ModuleLoader *TheModuleInterfaceLoader = nullptr;

/// Map from Swift declarations to raw comments.
llvm::DenseMap<const Decl *, RawComment> RawComments;

Expand Down Expand Up @@ -1522,11 +1522,15 @@ void ASTContext::addModuleLoader(std::unique_ptr<ModuleLoader> loader,
if (IsClang && IsDwarf && !getImpl().TheDWARFModuleLoader)
getImpl().TheDWARFModuleLoader =
static_cast<ClangModuleLoader *>(loader.get());
if (IsInterface && !getImpl().TheModuleInterfaceLoader)
getImpl().TheModuleInterfaceLoader = loader.get();
getImpl().ModuleLoaders.push_back(std::move(loader));
}

void ASTContext::addModuleInterfaceChecker(
std::unique_ptr<ModuleInterfaceChecker> checker) {
assert(!getImpl().InterfaceChecker && "Checker has been set already");
getImpl().InterfaceChecker = std::move(checker);
}

Optional<ModuleDependencies> ASTContext::getModuleDependencies(
StringRef moduleName, bool isUnderlyingClangModule,
ModuleDependenciesCache &cache, InterfaceSubContextDelegate &delegate) {
Expand Down Expand Up @@ -1613,8 +1617,10 @@ ClangModuleLoader *ASTContext::getDWARFModuleLoader() const {
return getImpl().TheDWARFModuleLoader;
}

ModuleLoader *ASTContext::getModuleInterfaceLoader() const {
return getImpl().TheModuleInterfaceLoader;
ModuleInterfaceChecker *ASTContext::getModuleInterfaceChecker() const {
auto *result = getImpl().InterfaceChecker.get();
assert(result);
return result;
}

ModuleDecl *ASTContext::getLoadedModule(
Expand Down
11 changes: 11 additions & 0 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5835,6 +5835,17 @@ VarDecl *VarDecl::getPropertyWrapperProjectionVar() const {
return getPropertyWrapperBackingPropertyInfo().projectionVar;
}

void VarDecl::visitAuxiliaryDecls(llvm::function_ref<void(VarDecl *)> visit) const {
if (getDeclContext()->isTypeContext())
return;

if (auto *backingVar = getPropertyWrapperBackingProperty())
visit(backingVar);

if (auto *projectionVar = getPropertyWrapperProjectionVar())
visit(projectionVar);
}

VarDecl *VarDecl::getLazyStorageProperty() const {
auto &ctx = getASTContext();
auto mutableThis = const_cast<VarDecl *>(this);
Expand Down
19 changes: 17 additions & 2 deletions lib/AST/UnqualifiedLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "swift/AST/ModuleNameLookup.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/NameLookupRequests.h"
#include "swift/AST/PropertyWrappers.h"
#include "swift/Basic/Debug.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Basic/SourceManager.h"
Expand Down Expand Up @@ -564,8 +565,22 @@ bool ASTScopeDeclConsumerForUnqualifiedLookup::consume(
}
}

if (!value->getName().matchesRef(factory.Name.getFullName()))
continue;
auto fullName = factory.Name.getFullName();
if (!value->getName().matchesRef(fullName)) {
bool foundMatch = false;
if (auto *varDecl = dyn_cast<VarDecl>(value)) {
// Check if the name matches any auxiliary decls not in the AST
varDecl->visitAuxiliaryDecls([&](VarDecl *auxiliaryVar) {
if (auxiliaryVar->ValueDecl::getName().matchesRef(fullName)) {
value = auxiliaryVar;
foundMatch = true;
}
});
}

if (!foundMatch)
continue;
}

// In order to preserve the behavior of the existing context-based lookup,
// which finds all results for non-local variables at the top level instead
Expand Down
Loading