diff --git a/SwiftCompilerSources/CMakeLists.txt b/SwiftCompilerSources/CMakeLists.txt index 410a8938f3bd5..b4c66e32aeaf9 100644 --- a/SwiftCompilerSources/CMakeLists.txt +++ b/SwiftCompilerSources/CMakeLists.txt @@ -87,6 +87,10 @@ function(add_swift_compiler_modules_library name) list(APPEND swift_compile_options "-O" "-cross-module-optimization") endif() + if(NOT LLVM_ENABLE_ASSERTIONS) + list(APPEND swift_compile_options "-Xcc" "-DNDEBUG") + endif() + if(NOT SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT) list(APPEND swift_compile_options "-Xfrontend" "-disable-legacy-type-info") endif() diff --git a/include/swift-c/DependencyScan/DependencyScan.h b/include/swift-c/DependencyScan/DependencyScan.h index c08a6fb7482c3..07d6b2217e841 100644 --- a/include/swift-c/DependencyScan/DependencyScan.h +++ b/include/swift-c/DependencyScan/DependencyScan.h @@ -25,7 +25,7 @@ /// SWIFTSCAN_VERSION_MINOR should increase when there are API additions. /// SWIFTSCAN_VERSION_MAJOR is intended for "major" source/ABI breaking changes. #define SWIFTSCAN_VERSION_MAJOR 0 -#define SWIFTSCAN_VERSION_MINOR 3 +#define SWIFTSCAN_VERSION_MINOR 4 SWIFTSCAN_BEGIN_DECLS @@ -139,6 +139,10 @@ SWIFTSCAN_PUBLIC swiftscan_string_set_t * swiftscan_swift_textual_detail_get_command_line( swiftscan_module_details_t details); +SWIFTSCAN_PUBLIC swiftscan_string_set_t * +swiftscan_swift_textual_detail_get_bridging_pch_command_line( + swiftscan_module_details_t details); + SWIFTSCAN_PUBLIC swiftscan_string_set_t * swiftscan_swift_textual_detail_get_extra_pcm_args( swiftscan_module_details_t details); @@ -154,6 +158,14 @@ SWIFTSCAN_PUBLIC swiftscan_string_set_t * swiftscan_swift_textual_detail_get_swift_overlay_dependencies( swiftscan_module_details_t details); +SWIFTSCAN_PUBLIC swiftscan_string_ref_t +swiftscan_swift_textual_detail_get_cas_fs_root_id( + swiftscan_module_details_t details); + +SWIFTSCAN_PUBLIC swiftscan_string_ref_t +swiftscan_swift_textual_detail_get_module_cache_key( + swiftscan_module_details_t details); + //=== Swift Binary Module Details query APIs ------------------------------===// SWIFTSCAN_PUBLIC swiftscan_string_ref_t @@ -168,10 +180,18 @@ SWIFTSCAN_PUBLIC swiftscan_string_ref_t swiftscan_swift_binary_detail_get_module_source_info_path( swiftscan_module_details_t details); +SWIFTSCAN_PUBLIC swiftscan_string_set_t * +swiftscan_swift_binary_detail_get_header_dependencies( + swiftscan_module_details_t details); + SWIFTSCAN_PUBLIC bool swiftscan_swift_binary_detail_get_is_framework( swiftscan_module_details_t details); +SWIFTSCAN_PUBLIC swiftscan_string_ref_t +swiftscan_swift_binary_detail_get_module_cache_key( + swiftscan_module_details_t details); + //=== Swift Placeholder Module Details query APIs -------------------------===// SWIFTSCAN_PUBLIC swiftscan_string_ref_t @@ -200,6 +220,12 @@ swiftscan_clang_detail_get_command_line(swiftscan_module_details_t details); SWIFTSCAN_PUBLIC swiftscan_string_set_t * swiftscan_clang_detail_get_captured_pcm_args(swiftscan_module_details_t details); +SWIFTSCAN_PUBLIC swiftscan_string_ref_t +swiftscan_clang_detail_get_cas_fs_root_id(swiftscan_module_details_t details); + +SWIFTSCAN_PUBLIC swiftscan_string_ref_t +swiftscan_clang_detail_get_module_cache_key(swiftscan_module_details_t details); + //=== Batch Scan Input Functions ------------------------------------------===// /// Create an \c swiftscan_batch_scan_input_t instance. @@ -402,6 +428,40 @@ swiftscan_scanner_cache_reset(swiftscan_scanner_t scanner); /// An entry point to invoke the compiler via a library call. SWIFTSCAN_PUBLIC int invoke_swift_compiler(int argc, const char **argv); +//=== Scanner CAS Operations ----------------------------------------------===// + +/// Opaque container for a CAS instance that includes both ObjectStore and +/// ActionCache. +typedef struct swiftscan_cas_s *swiftscan_cas_t; + +/// Enum types for output types for cache key computation. +/// TODO: complete the list. +typedef enum { + SWIFTSCAN_OUTPUT_TYPE_OBJECT = 0, + SWIFTSCAN_OUTPUT_TYPE_SWIFTMODULE = 1, + SWIFTSCAN_OUTPUT_TYPE_SWIFTINTERFACE = 2, + SWIFTSCAN_OUTPUT_TYPE_SWIFTPRIAVEINTERFACE = 3, + SWIFTSCAN_OUTPUT_TYPE_CLANG_MODULE = 4, + SWIFTSCAN_OUTPUT_TYPE_CLANG_PCH = 5 +} swiftscan_output_kind_t; + +/// Create a \c cas instance that points to path. +SWIFTSCAN_PUBLIC swiftscan_cas_t swiftscan_cas_create(const char *path); + +/// Dispose the \c cas instance. +SWIFTSCAN_PUBLIC void swiftscan_cas_dispose(swiftscan_cas_t cas); + +/// Store content into CAS. Return \c CASID as string. +SWIFTSCAN_PUBLIC swiftscan_string_ref_t swiftscan_cas_store(swiftscan_cas_t cas, + uint8_t *data, + unsigned size); + +/// Compute \c CacheKey for output of \c kind from the compiler invocation \c +/// argc and \c argv with \c input. Return \c CacheKey as string. +SWIFTSCAN_PUBLIC swiftscan_string_ref_t +swiftscan_compute_cache_key(swiftscan_cas_t cas, int argc, const char **argv, + const char *input, swiftscan_output_kind_t kind); + //===----------------------------------------------------------------------===// SWIFTSCAN_END_DECLS diff --git a/include/swift/AST/ASTScope.h b/include/swift/AST/ASTScope.h index 5ebe70dcef3be..3411bed70fbf9 100644 --- a/include/swift/AST/ASTScope.h +++ b/include/swift/AST/ASTScope.h @@ -218,6 +218,10 @@ class ASTScopeImpl : public ASTAllocated { return nullptr; } + virtual NullablePtr getFreestandingMacro() const { + return nullptr; + } + #pragma mark - debugging and printing public: @@ -278,6 +282,10 @@ class ASTScopeImpl : public ASTAllocated { static std::pair lookupFallthroughSourceAndDest(SourceFile *sourceFile, SourceLoc loc); + static void lookupEnclosingMacroScope( + SourceFile *sourceFile, SourceLoc loc, + llvm::function_ref consume); + /// Scopes that cannot bind variables may set this to true to create more /// compact scope tree in the debug info. virtual bool ignoreInDebugInfo() const { return false; } @@ -840,24 +848,20 @@ class DefaultArgumentInitializerScope final : public ASTScopeImpl { bool ignoreInDebugInfo() const override { return true; } }; -/// Consider: -/// @_propertyWrapper -/// struct WrapperWithInitialValue { -/// } -/// struct HasWrapper { -/// @WrapperWithInitialValue var y = 17 -/// } -/// Lookup has to be able to find the use of WrapperWithInitialValue, that's -/// what this scope is for. Because the source positions are screwy. - -class AttachedPropertyWrapperScope final : public ASTScopeImpl { +/// The scope for custom attributes and their arguments, such as for +/// attached property wrappers and for attached macros. +/// +/// Source locations for the attribute name and its arguments are in the +/// custom attribute, so lookup is invoked from within the attribute +/// itself. +class CustomAttributeScope final : public ASTScopeImpl { public: CustomAttr *attr; - VarDecl *decl; + Decl *decl; - AttachedPropertyWrapperScope(CustomAttr *attr, VarDecl *decl) + CustomAttributeScope(CustomAttr *attr,Decl *decl) : attr(attr), decl(decl) {} - virtual ~AttachedPropertyWrapperScope() {} + virtual ~CustomAttributeScope() {} protected: ASTScopeImpl *expandSpecifically(ScopeCreator &) override; @@ -871,7 +875,8 @@ class AttachedPropertyWrapperScope final : public ASTScopeImpl { NullablePtr getDeclAttributeIfAny() const override { return attr; } - bool ignoreInDebugInfo() const override { return true; } + bool ignoreInDebugInfo() const override { return true; } + private: void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &); }; @@ -1134,9 +1139,9 @@ class SpecializeAttributeScope final : public ASTScopeImpl { class DifferentiableAttributeScope final : public ASTScopeImpl { public: DifferentiableAttr *const differentiableAttr; - ValueDecl *const attributedDeclaration; + Decl *const attributedDeclaration; - DifferentiableAttributeScope(DifferentiableAttr *diffAttr, ValueDecl *decl) + DifferentiableAttributeScope(DifferentiableAttr *diffAttr, Decl *decl) : differentiableAttr(diffAttr), attributedDeclaration(decl) {} virtual ~DifferentiableAttributeScope() {} @@ -1270,6 +1275,10 @@ class MacroExpansionDeclScope final : public ASTScopeImpl { SourceRange getSourceRangeOfThisASTNode(bool omitAssertions = false) const override; + NullablePtr getFreestandingMacro() const override { + return decl; + } + protected: void printSpecifics(llvm::raw_ostream &out) const override; diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 92f150e7b3715..891f8c1a46427 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -3902,7 +3902,7 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext { /// protocols to which the nominal type conforms. Furthermore, the resulting /// set of declarations has not been filtered for visibility, nor have /// overridden declarations been removed. - TinyPtrVector lookupDirect(DeclName name, + TinyPtrVector lookupDirect(DeclName name, SourceLoc loc = SourceLoc(), OptionSet flags = OptionSet()); @@ -4457,7 +4457,8 @@ class ClassDecl final : public NominalTypeDecl { // Force loading all the members, which will add this attribute if any of // members are determined to be missing while loading. auto mutableThis = const_cast(this); - (void)mutableThis->lookupDirect(DeclBaseName::createConstructor()); + (void)mutableThis->lookupDirect(DeclBaseName::createConstructor(), + getStartLoc()); } if (Bits.ClassDecl.ComputedHasMissingDesignatedInitializers) diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h index d6e21e3167959..8de5bd8494950 100644 --- a/include/swift/AST/DeclContext.h +++ b/include/swift/AST/DeclContext.h @@ -598,7 +598,8 @@ class alignas(1 << DeclContextAlignInBits) DeclContext /// lookup. /// /// \returns true if anything was found. - bool lookupQualified(Type type, DeclNameRef member, NLOptions options, + bool lookupQualified(Type type, DeclNameRef member, + SourceLoc loc, NLOptions options, SmallVectorImpl &decls) const; /// Look for the set of declarations with the given name within the @@ -616,12 +617,12 @@ class alignas(1 << DeclContextAlignInBits) DeclContext /// /// \returns true if anything was found. bool lookupQualified(ArrayRef types, DeclNameRef member, - NLOptions options, + SourceLoc loc, NLOptions options, SmallVectorImpl &decls) const; /// Perform qualified lookup for the given member in the given module. bool lookupQualified(ModuleDecl *module, DeclNameRef member, - NLOptions options, + SourceLoc loc, NLOptions options, SmallVectorImpl &decls) const; /// Look up all Objective-C methods with the given selector visible diff --git a/include/swift/AST/DiagnosticsSIL.def b/include/swift/AST/DiagnosticsSIL.def index df082a3ce52fd..896d472d69029 100644 --- a/include/swift/AST/DiagnosticsSIL.def +++ b/include/swift/AST/DiagnosticsSIL.def @@ -766,9 +766,10 @@ ERROR(sil_movechecking_borrowed_parameter_captured_by_closure, none, "parameter", (StringRef)) ERROR(sil_movechecking_capture_consumed, none, - "noncopyable '%0' cannot be consumed when captured by a closure", (StringRef)) -ERROR(sil_movechecking_inout_not_reinitialized_before_end_of_function, none, - "missing reinitialization of inout parameter '%0' after consume", (StringRef)) + "noncopyable '%0' cannot be consumed when captured by an escaping closure", (StringRef)) +ERROR(sil_movechecking_not_reinitialized_before_end_of_function, none, + "missing reinitialization of %select{inout parameter|closure capture}1 '%0' " + "after consume", (StringRef, bool)) ERROR(sil_movechecking_value_consumed_in_a_loop, none, "'%0' consumed in a loop", (StringRef)) ERROR(sil_movechecking_use_after_partial_consume, none, diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index ca4751062633a..98a58ce0f3f02 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -7194,6 +7194,10 @@ ERROR(macro_accessor_missing_from_expansion,none, ERROR(macro_init_accessor_not_documented,none, "expansion of macro %0 produced an unexpected 'init' accessor", (DeclName)) +ERROR(global_arbitrary_name,none, + "'%0' macros are not allowed to introduce arbitrary names " + "at global scope", + (StringRef)) ERROR(macro_resolve_circular_reference, none, "circular reference resolving %select{freestanding|attached}0 macro %1", diff --git a/include/swift/AST/Evaluator.h b/include/swift/AST/Evaluator.h index 7e42e727eb61f..2ff80cd6419d5 100644 --- a/include/swift/AST/Evaluator.h +++ b/include/swift/AST/Evaluator.h @@ -208,18 +208,6 @@ class Evaluator { /// is treated as a stack and is used to detect cycles. llvm::SetVector activeRequests; - /// How many `ResolveMacroRequest` requests are active. - /// - /// This allows us to quickly determine whether there is any - /// `ResolveMacroRequest` active in the active request stack. - /// It saves us from a linear scan through `activeRequests` when - /// we need to determine this information. - /// - /// Why on earth would we need to determine this information? - /// Please see the extended comment that goes with the constructor - /// of `UnqualifiedLookupRequest`. - unsigned numActiveResolveMacroRequests = 0; - /// A cache that stores the results of requests. evaluator::RequestCache cache; @@ -342,16 +330,6 @@ class Evaluator { return activeRequests.count(ActiveRequest(request)); } - /// Determine whether there is any active "resolve macro" request - /// on the request stack. - /// - /// Why on earth would we need to determine this information? - /// Please see the extended comment that goes with the constructor - /// of `UnqualifiedLookupRequest`. - bool hasActiveResolveMacroRequest() const { - return numActiveResolveMacroRequests > 0; - } - private: /// Diagnose a cycle detected in the evaluation of the given /// request. diff --git a/include/swift/AST/ModuleDependencies.h b/include/swift/AST/ModuleDependencies.h index 8fb3c39faa1da..dde8b9ef26984 100644 --- a/include/swift/AST/ModuleDependencies.h +++ b/include/swift/AST/ModuleDependencies.h @@ -23,9 +23,16 @@ #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSet.h" +#include "llvm/CAS/CASProvidingFileSystem.h" +#include "llvm/CAS/CASReference.h" +#include "llvm/CAS/CachingOnDiskFileSystem.h" +#include "llvm/CAS/ObjectStore.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/VirtualFileSystem.h" #include #include #include @@ -99,8 +106,15 @@ class ModuleDependencyInfoStorageBase { const ModuleDependencyKind dependencyKind; ModuleDependencyInfoStorageBase(ModuleDependencyKind dependencyKind, - bool resolved = false) - : dependencyKind(dependencyKind), resolved(resolved) { } + StringRef moduleCacheKey = "") + : dependencyKind(dependencyKind), moduleCacheKey(moduleCacheKey.str()), + resolved(false) { } + + ModuleDependencyInfoStorageBase(ModuleDependencyKind dependencyKind, + const std::vector &moduleImports, + StringRef moduleCacheKey = "") + : dependencyKind(dependencyKind), moduleImports(moduleImports), + moduleCacheKey(moduleCacheKey.str()), resolved(false) {} virtual ModuleDependencyInfoStorageBase *clone() const = 0; @@ -117,12 +131,20 @@ class ModuleDependencyInfoStorageBase { /// The set of modules on which this module depends, resolved /// to Module IDs, qualified by module kind: Swift, Clang, etc. std::vector resolvedModuleDependencies; + + /// The cache key for the produced module. + std::string moduleCacheKey; + bool resolved; }; struct CommonSwiftTextualModuleDependencyDetails { - CommonSwiftTextualModuleDependencyDetails(ArrayRef extraPCMArgs) - : extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()) {} + CommonSwiftTextualModuleDependencyDetails( + ArrayRef extraPCMArgs, ArrayRef buildCommandLine, + const std::string &CASFileSystemRootID) + : extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()), + buildCommandLine(buildCommandLine.begin(), buildCommandLine.end()), + CASFileSystemRootID(CASFileSystemRootID) {} /// To build a PCM to be used by this Swift module, we need to append these /// arguments to the generic PCM build arguments reported from the dependency @@ -141,6 +163,16 @@ struct CommonSwiftTextualModuleDependencyDetails { /// Dependencies comprised of Swift overlay modules of direct and /// transitive Clang dependencies. std::vector swiftOverlayDependencies; + + /// The Swift frontend invocation arguments to build the Swift module from the + /// interface. + std::vector buildCommandLine; + + /// CASID for the Root of CASFS. Empty if CAS is not used. + std::string CASFileSystemRootID; + + /// CASID for the Root of bridgingHeaderClangIncludeTree. Empty if not used. + std::string CASBridgingHeaderIncludeTreeRootID; }; /// Describes the dependencies of a Swift module described by an Swift interface file. @@ -158,10 +190,6 @@ class SwiftInterfaceModuleDependenciesStorage : /// Potentially ready-to-use compiled modules for the interface file. const std::vector compiledModuleCandidates; - /// The Swift frontend invocation arguments to build the Swift module from the - /// interface. - std::vector buildCommandLine; - /// The hash value that will be used for the generated module const std::string contextHash; @@ -172,22 +200,20 @@ class SwiftInterfaceModuleDependenciesStorage : CommonSwiftTextualModuleDependencyDetails textualModuleDetails; SwiftInterfaceModuleDependenciesStorage( - const std::string moduleOutputPath, - const std::string swiftInterfaceFile, + const std::string &moduleOutputPath, + const std::string &swiftInterfaceFile, ArrayRef compiledModuleCandidates, - ArrayRef buildCommandLine, - ArrayRef extraPCMArgs, - StringRef contextHash, - bool isFramework - ) : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftInterface), - moduleOutputPath(moduleOutputPath), - swiftInterfaceFile(swiftInterfaceFile), - compiledModuleCandidates(compiledModuleCandidates.begin(), - compiledModuleCandidates.end()), - buildCommandLine(buildCommandLine.begin(), buildCommandLine.end()), - contextHash(contextHash), isFramework(isFramework), - textualModuleDetails(extraPCMArgs) - {} + ArrayRef buildCommandLine, ArrayRef extraPCMArgs, + StringRef contextHash, bool isFramework, const std::string &RootID, + const std::string &moduleCacheKey) + : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftInterface, + moduleCacheKey), + moduleOutputPath(moduleOutputPath), + swiftInterfaceFile(swiftInterfaceFile), + compiledModuleCandidates(compiledModuleCandidates.begin(), + compiledModuleCandidates.end()), + contextHash(contextHash), isFramework(isFramework), + textualModuleDetails(extraPCMArgs, buildCommandLine, RootID) {} ModuleDependencyInfoStorageBase *clone() const override { return new SwiftInterfaceModuleDependenciesStorage(*this); @@ -198,7 +224,7 @@ class SwiftInterfaceModuleDependenciesStorage : } void updateCommandLine(const std::vector &newCommandLine) { - buildCommandLine = newCommandLine; + textualModuleDetails.buildCommandLine = newCommandLine; } }; @@ -218,11 +244,18 @@ class SwiftSourceModuleDependenciesStorage : /// Collection of module imports that were detected to be `@Testable` llvm::StringSet<> testableImports; + /// The Swift frontend invocation arguments to build bridging header. + std::vector bridgingHeaderBuildCommandLine; + SwiftSourceModuleDependenciesStorage( - ArrayRef extraPCMArgs - ) : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftSource), - textualModuleDetails(extraPCMArgs), - testableImports(llvm::StringSet<>()) {} + const std::string &RootID, ArrayRef buildCommandLine, + ArrayRef bridgingHeaderBuildCommandLine, + ArrayRef extraPCMArgs) + : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftSource), + textualModuleDetails(extraPCMArgs, buildCommandLine, RootID), + testableImports(llvm::StringSet<>()), + bridgingHeaderBuildCommandLine(bridgingHeaderBuildCommandLine.begin(), + bridgingHeaderBuildCommandLine.end()) {} ModuleDependencyInfoStorageBase *clone() const override { return new SwiftSourceModuleDependenciesStorage(*this); @@ -232,6 +265,15 @@ class SwiftSourceModuleDependenciesStorage : return base->dependencyKind == ModuleDependencyKind::SwiftSource; } + void updateCommandLine(const std::vector &newCommandLine) { + textualModuleDetails.buildCommandLine = newCommandLine; + } + + void updateBridgingHeaderCommandLine( + const std::vector &newCommandLine) { + bridgingHeaderBuildCommandLine = newCommandLine; + } + void addTestableImport(ImportPath::Module module) { testableImports.insert(module.front().Item.str()); } @@ -245,11 +287,14 @@ class SwiftBinaryModuleDependencyStorage : public ModuleDependencyInfoStorageBas SwiftBinaryModuleDependencyStorage(const std::string &compiledModulePath, const std::string &moduleDocPath, const std::string &sourceInfoPath, - const bool isFramework) - : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftBinary), - compiledModulePath(compiledModulePath), - moduleDocPath(moduleDocPath), - sourceInfoPath(sourceInfoPath), + const std::vector &moduleImports, + const std::vector &headerImports, + const bool isFramework, + const std::string &moduleCacheKey) + : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftBinary, + moduleImports, moduleCacheKey), + compiledModulePath(compiledModulePath), moduleDocPath(moduleDocPath), + sourceInfoPath(sourceInfoPath), preCompiledBridgingHeaderPaths(headerImports), isFramework(isFramework) {} ModuleDependencyInfoStorageBase *clone() const override { @@ -265,6 +310,9 @@ class SwiftBinaryModuleDependencyStorage : public ModuleDependencyInfoStorageBas /// The path to the .swiftSourceInfo file. const std::string sourceInfoPath; + /// The paths of all the .pch dependencies of this module. + const std::vector preCompiledBridgingHeaderPaths; + /// A flag that indicates this dependency is a framework const bool isFramework; @@ -288,7 +336,7 @@ class ClangModuleDependencyStorage : public ModuleDependencyInfoStorageBase { const std::string contextHash; /// Partial (Clang) command line that can be used to build this module. - const std::vector nonPathCommandLine; + std::vector buildCommandLine; /// The file dependencies const std::vector fileDependencies; @@ -297,20 +345,28 @@ class ClangModuleDependencyStorage : public ModuleDependencyInfoStorageBase { /// as found by the scanning action that discovered it const std::vector capturedPCMArgs; - ClangModuleDependencyStorage( - const std::string &pcmOutputPath, - const std::string &moduleMapFile, - const std::string &contextHash, - const std::vector &nonPathCommandLine, - const std::vector &fileDependencies, - const std::vector &capturedPCMArgs - ) : ModuleDependencyInfoStorageBase(ModuleDependencyKind::Clang), - pcmOutputPath(pcmOutputPath), - moduleMapFile(moduleMapFile), - contextHash(contextHash), - nonPathCommandLine(nonPathCommandLine), - fileDependencies(fileDependencies), - capturedPCMArgs(capturedPCMArgs) {} + /// CASID for the Root of CASFS. Empty if CAS is not used. + std::string CASFileSystemRootID; + + /// CASID for the Root of ClangIncludeTree. Empty if not used. + std::string CASClangIncludeTreeRootID; + + ClangModuleDependencyStorage(const std::string &pcmOutputPath, + const std::string &moduleMapFile, + const std::string &contextHash, + const std::vector &buildCommandLine, + const std::vector &fileDependencies, + const std::vector &capturedPCMArgs, + const std::string &CASFileSystemRootID, + const std::string &clangIncludeTreeRoot, + const std::string &moduleCacheKey) + : ModuleDependencyInfoStorageBase(ModuleDependencyKind::Clang, + moduleCacheKey), + pcmOutputPath(pcmOutputPath), moduleMapFile(moduleMapFile), + contextHash(contextHash), buildCommandLine(buildCommandLine), + fileDependencies(fileDependencies), capturedPCMArgs(capturedPCMArgs), + CASFileSystemRootID(CASFileSystemRootID), + CASClangIncludeTreeRootID(clangIncludeTreeRoot) {} ModuleDependencyInfoStorageBase *clone() const override { return new ClangModuleDependencyStorage(*this); @@ -319,6 +375,10 @@ class ClangModuleDependencyStorage : public ModuleDependencyInfoStorageBase { static bool classof(const ModuleDependencyInfoStorageBase *base) { return base->dependencyKind == ModuleDependencyKind::Clang; } + + void updateCommandLine(const std::vector &newCommandLine) { + buildCommandLine = newCommandLine; + } }; /// Describes an placeholder Swift module dependency module stub. @@ -381,18 +441,20 @@ class ModuleDependencyInfo { /// Describe the module dependencies for a Swift module that can be /// built from a Swift interface file (\c .swiftinterface). - static ModuleDependencyInfo forSwiftInterfaceModule( - const std::string &moduleOutputPath, - const std::string &swiftInterfaceFile, - ArrayRef compiledCandidates, - ArrayRef buildCommands, - ArrayRef extraPCMArgs, - StringRef contextHash, - bool isFramework) { + static ModuleDependencyInfo + forSwiftInterfaceModule(const std::string &moduleOutputPath, + const std::string &swiftInterfaceFile, + ArrayRef compiledCandidates, + ArrayRef buildCommands, + ArrayRef extraPCMArgs, + StringRef contextHash, bool isFramework, + const std::string &CASFileSystemRootID, + const std::string &moduleCacheKey) { return ModuleDependencyInfo( std::make_unique( - moduleOutputPath, swiftInterfaceFile, compiledCandidates, buildCommands, - extraPCMArgs, contextHash, isFramework)); + moduleOutputPath, swiftInterfaceFile, compiledCandidates, + buildCommands, extraPCMArgs, contextHash, isFramework, + CASFileSystemRootID, moduleCacheKey)); } /// Describe the module dependencies for a serialized or parsed Swift module. @@ -400,16 +462,25 @@ class ModuleDependencyInfo { const std::string &compiledModulePath, const std::string &moduleDocPath, const std::string &sourceInfoPath, - bool isFramework) { + const std::vector &moduleImports, + const std::vector &headerImports, + bool isFramework, const std::string &moduleCacheKey) { return ModuleDependencyInfo( std::make_unique( - compiledModulePath, moduleDocPath, sourceInfoPath, isFramework)); + compiledModulePath, moduleDocPath, sourceInfoPath, + moduleImports, headerImports, isFramework, moduleCacheKey)); } /// Describe the main Swift module. - static ModuleDependencyInfo forSwiftSourceModule(ArrayRef extraPCMArgs) { + static ModuleDependencyInfo + forSwiftSourceModule(const std::string &CASFileSystemRootID, + ArrayRef buildCommands, + ArrayRef bridgingHeaderBuildCommands, + ArrayRef extraPCMArgs) { return ModuleDependencyInfo( - std::make_unique(extraPCMArgs)); + std::make_unique( + CASFileSystemRootID, buildCommands, bridgingHeaderBuildCommands, + extraPCMArgs)); } /// Describe the module dependencies for a Clang module that can be @@ -420,11 +491,15 @@ class ModuleDependencyInfo { const std::string &contextHash, const std::vector &nonPathCommandLine, const std::vector &fileDependencies, - const std::vector &capturedPCMArgs) { + const std::vector &capturedPCMArgs, + const std::string &CASFileSystemRootID, + const std::string &clangIncludeTreeRoot, + const std::string &moduleCacheKey) { return ModuleDependencyInfo( std::make_unique( pcmOutputPath, moduleMapFile, contextHash, - nonPathCommandLine, fileDependencies, capturedPCMArgs)); + nonPathCommandLine, fileDependencies, capturedPCMArgs, + CASFileSystemRootID, clangIncludeTreeRoot, moduleCacheKey)); } /// Describe a placeholder dependency swift module. @@ -453,6 +528,15 @@ class ModuleDependencyInfo { return storage->resolvedModuleDependencies; } + std::string getModuleCacheKey() const { + assert(storage->resolved); + return storage->moduleCacheKey; + } + + void updateModuleCacheKey(const std::string &key) { + storage->moduleCacheKey = key; + } + /// Resolve a dependency's set of `imports` with qualified Module IDs void resolveDependencies(const ArrayRef dependencyIDs) { assert(!storage->resolved && "Resolving an already-resolved dependency"); @@ -474,9 +558,41 @@ class ModuleDependencyInfo { textualModuleDetails->swiftOverlayDependencies.assign(dependencyIDs.begin(), dependencyIDs.end()); } + std::vector getCommandline() const { + if (auto *detail = getAsClangModule()) + return detail->buildCommandLine; + else if (auto *detail = getAsSwiftInterfaceModule()) + return detail->textualModuleDetails.buildCommandLine; + else if (auto *detail = getAsSwiftSourceModule()) + return detail->textualModuleDetails.buildCommandLine; + return {}; + } + void updateCommandLine(const std::vector &newCommandLine) { - assert(isSwiftInterfaceModule() && "Can only update command line on Swift interface dependency"); - cast(storage.get())->updateCommandLine(newCommandLine); + if (isSwiftInterfaceModule()) + return cast(storage.get()) + ->updateCommandLine(newCommandLine); + else if (isSwiftSourceModule()) + return cast(storage.get()) + ->updateCommandLine(newCommandLine); + else if (isClangModule()) + return cast(storage.get()) + ->updateCommandLine(newCommandLine); + llvm_unreachable("Unexpected type"); + } + + std::vector getBridgingHeaderCommandline() const { + if (auto *detail = getAsSwiftSourceModule()) + return detail->bridgingHeaderBuildCommandLine; + return {}; + } + + void updateBridgingHeaderCommandLine( + const std::vector &newCommandLine) { + if (isSwiftSourceModule()) + return cast(storage.get()) + ->updateBridgingHeaderCommandLine(newCommandLine); + llvm_unreachable("Unexpected type"); } bool isResolved() const { @@ -568,6 +684,18 @@ class ModuleDependencyInfo { /// Get the bridging header. Optional getBridgingHeader() const; + /// Get CAS Filesystem RootID. + Optional getCASFSRootID() const; + + /// Get Clang Include Tree ID. + Optional getClangIncludeTree() const; + + /// Get bridging header Include Tree ID. + Optional getBridgingHeaderIncludeTree() const; + + /// Get module output path. + std::string getModuleOutputPath() const; + /// Add a bridging header to a Swift module's dependencies. void addBridgingHeader(StringRef bridgingHeader); @@ -581,6 +709,9 @@ class ModuleDependencyInfo { void addBridgingModuleDependency(StringRef module, llvm::StringSet<> &alreadyAddedModules); + /// Add bridging header include tree. + void addBridgingHeaderIncludeTree(StringRef ID); + /// Collect a map from a secondary module name to a list of cross-import /// overlays, when this current module serves as the primary module. llvm::StringMap> @@ -597,6 +728,23 @@ using ModuleDependenciesKindRefMap = llvm::StringMap, ModuleDependencyKindHash>; +// MARK: SwiftDependencyTracker +/// Track swift dependency +class SwiftDependencyTracker { +public: + SwiftDependencyTracker(llvm::cas::CachingOnDiskFileSystem &FS, + const std::vector &CommonFiles) + : FS(FS.createProxyFS()), Files(CommonFiles) {} + + void startTracking(); + void trackFile(const Twine &path) { (void)FS->status(path); } + llvm::Expected createTreeFromDependencies(); + +private: + llvm::IntrusiveRefCntPtr FS; + const std::vector &Files; +}; + // MARK: SwiftDependencyScanningService /// A carrier of state shared among possibly multiple invocations of the dependency /// scanner. Acts as a global cache of discovered module dependencies and @@ -620,7 +768,21 @@ class SwiftDependencyScanningService { }; /// The persistent Clang dependency scanner service - clang::tooling::dependencies::DependencyScanningService ClangScanningService; + Optional + ClangScanningService; + + /// CachingOnDiskFileSystem for dependency tracking. + llvm::IntrusiveRefCntPtr CacheFS; + + /// If use clang include tree. + bool UseClangIncludeTree = false; + + /// CAS ObjectStore Instance. + std::shared_ptr CAS; + + /// The common dependencies that is needed for every swift compiler instance. + std::vector CommonDependencyFiles; + /// The global file system cache. Optional< clang::tooling::dependencies::DependencyScanningFilesystemSharedCache> @@ -671,9 +833,37 @@ class SwiftDependencyScanningService { return getCacheForScanningContextHash(scanningContextHash)->alreadySeenClangModules; } + bool usingCachingFS() const { return !UseClangIncludeTree && (bool)CacheFS; } + + llvm::cas::CachingOnDiskFileSystem &getSharedCachingFS() const { + assert(CacheFS && "Expect CachingOnDiskFileSystem"); + return *CacheFS; + } + + Optional createSwiftDependencyTracker() const { + if (!CacheFS) + return None; + + return SwiftDependencyTracker(*CacheFS, CommonDependencyFiles); + } + + llvm::IntrusiveRefCntPtr getClangScanningFS() const { + if (usingCachingFS()) + return CacheFS->createProxyFS(); + + if (UseClangIncludeTree) + return llvm::cas::createCASProvidingFileSystem( + CAS, llvm::vfs::createPhysicalFileSystem()); + + return llvm::vfs::createPhysicalFileSystem(); + } + /// Wrap the filesystem on the specified `CompilerInstance` with a /// caching `DependencyScanningWorkerFilesystem` void overlaySharedFilesystemCacheForCompilation(CompilerInstance &Instance); + + /// Setup caching service. + void setupCachingDependencyScanningService(CompilerInstance &Instance); private: /// Enforce clients not being allowed to query this cache directly, it must be /// wrapped in an instance of `ModuleDependenciesCache`. @@ -769,6 +959,9 @@ class ModuleDependenciesCache { clang::tooling::dependencies::DependencyScanningTool& getClangScannerTool() { return clangScanningTool; } + SwiftDependencyScanningService &getScanService() { + return globalScanningService; + } llvm::StringSet<>& getAlreadySeenClangModules() { return globalScanningService.getAlreadySeenClangModules(scannerContextHash); } diff --git a/include/swift/AST/ModuleNameLookup.h b/include/swift/AST/ModuleNameLookup.h index bb09a801f3d66..18283f44dd518 100644 --- a/include/swift/AST/ModuleNameLookup.h +++ b/include/swift/AST/ModuleNameLookup.h @@ -62,7 +62,7 @@ void lookupInModule(const DeclContext *moduleOrFile, DeclName name, SmallVectorImpl &decls, NLKind lookupKind, ResolutionKind resolutionKind, const DeclContext *moduleScopeContext, - NLOptions options); + SourceLoc loc, NLOptions options); /// Performs a qualified lookup into the given module and, if necessary, its /// reexports, observing proper shadowing rules. diff --git a/include/swift/AST/NameLookup.h b/include/swift/AST/NameLookup.h index a4b8a0a3c14f4..5d3898d43283e 100644 --- a/include/swift/AST/NameLookup.h +++ b/include/swift/AST/NameLookup.h @@ -513,7 +513,7 @@ void lookupVisibleDecls(VisibleDeclConsumer &Consumer, /// /// \param CurrDC the DeclContext from which the lookup is done. void lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer, - Type BaseTy, + Type BaseTy, SourceLoc loc, const DeclContext *CurrDC, bool includeInstanceMembers, bool includeDerivedRequirements, @@ -545,6 +545,15 @@ template void filterForDiscriminator(SmallVectorImpl &results, DebuggerClient *debugClient); +/// \returns The set of macro declarations with the given name that +/// fulfill any of the given macro roles. +SmallVector +lookupMacros(DeclContext *dc, DeclNameRef macroName, MacroRoles roles); + +/// \returns Whether the given source location is inside an attached +/// or freestanding macro argument. +bool isInMacroArgument(SourceFile *sourceFile, SourceLoc loc); + /// Call the given function body with each macro declaration and its associated /// role attribute for the given role. /// @@ -816,6 +825,22 @@ class ASTScope : public ASTAllocated { static std::pair lookupFallthroughSourceAndDest(SourceFile *sourceFile, SourceLoc loc); + using PotentialMacro = + llvm::PointerUnion; + + /// Look up the scope tree for the nearest enclosing macro scope at + /// the given source location. + /// + /// \param sourceFile The source file containing the given location. + /// \param loc The source location to start lookup from. + /// \param consume A function that is called when a potential macro + /// scope is found. If \c consume returns \c true, lookup + /// will stop. If \c consume returns \c false, lookup will + /// continue up the scope tree. + static void lookupEnclosingMacroScope( + SourceFile *sourceFile, SourceLoc loc, + llvm::function_ref consume); + SWIFT_DEBUG_DUMP; void print(llvm::raw_ostream &) const; void dumpOneScopeMapLocation(std::pair); diff --git a/include/swift/AST/NameLookupRequests.h b/include/swift/AST/NameLookupRequests.h index 39fe9d7dc2a3b..7aa1c47ee83a5 100644 --- a/include/swift/AST/NameLookupRequests.h +++ b/include/swift/AST/NameLookupRequests.h @@ -461,7 +461,7 @@ class LookupInModuleRequest LookupInModuleRequest( const DeclContext *, DeclName, NLKind, namelookup::ResolutionKind, const DeclContext *, - NLOptions); + SourceLoc, NLOptions); private: friend SimpleRequest; @@ -511,7 +511,7 @@ class ModuleQualifiedLookupRequest public: ModuleQualifiedLookupRequest(const DeclContext *, ModuleDecl *, DeclNameRef, - NLOptions); + SourceLoc, NLOptions); private: friend SimpleRequest; @@ -537,7 +537,7 @@ class QualifiedLookupRequest public: QualifiedLookupRequest(const DeclContext *, SmallVector, - DeclNameRef, NLOptions); + DeclNameRef, SourceLoc, NLOptions); private: friend SimpleRequest; @@ -588,7 +588,7 @@ class DirectLookupRequest TinyPtrVector(DirectLookupDescriptor), RequestFlags::Uncached|RequestFlags::DependencySink> { public: - DirectLookupRequest(DirectLookupDescriptor); + DirectLookupRequest(DirectLookupDescriptor, SourceLoc); private: friend SimpleRequest; diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h index 8574c38fa42f1..0dd81a6b654cf 100644 --- a/include/swift/AST/TypeCheckRequests.h +++ b/include/swift/AST/TypeCheckRequests.h @@ -3249,6 +3249,9 @@ class UnresolvedMacroReference { public: UnresolvedMacroReference(FreestandingMacroExpansion *exp) : pointer(exp) {} UnresolvedMacroReference(CustomAttr *attr) : pointer(attr) {} + UnresolvedMacroReference( + llvm::PointerUnion pointer) + : pointer(pointer) {} FreestandingMacroExpansion *getFreestanding() const { return pointer.dyn_cast(); diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 8f77bc68ae512..ccd39bb2a26cd 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -822,6 +822,9 @@ namespace swift { /// clang CASOptions. std::string CASPath; + /// Cache key for imported bridging header. + std::string BridgingHeaderPCHCacheKey; + /// Disable validating the persistent PCH. bool PCHDisableValidation = false; @@ -891,6 +894,9 @@ namespace swift { /// built and provided to the compiler invocation. bool DisableImplicitClangModules = false; + /// Enable ClangIncludeTree for explicit module builds. + bool UseClangIncludeTree = false; + /// Return a hash code of any components from these options that should /// contribute to a Swift Bridging PCH hash. llvm::hash_code getPCHHashComponents() const { diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index 70fe747dd012f..7b6d817c107c3 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -54,6 +54,7 @@ namespace clang { namespace tooling { namespace dependencies { struct ModuleDeps; + struct TranslationUnitDeps; using ModuleDepsGraph = std::vector; } } @@ -431,6 +432,10 @@ class ClangImporter final : public ClangModuleLoader { ModuleDependenciesCache &cache, const clang::tooling::dependencies::ModuleDepsGraph &clangDependencies); + void recordBridgingHeaderOptions( + ModuleDependencyInfo &MDI, + const clang::tooling::dependencies::TranslationUnitDeps &deps); + Optional getModuleDependencies( StringRef moduleName, ModuleDependenciesCache &cache, InterfaceSubContextDelegate &delegate, diff --git a/include/swift/DependencyScan/DependencyScanImpl.h b/include/swift/DependencyScan/DependencyScanImpl.h index dd0463e502e44..a0ac5751d298f 100644 --- a/include/swift/DependencyScan/DependencyScanImpl.h +++ b/include/swift/DependencyScan/DependencyScanImpl.h @@ -86,6 +86,9 @@ typedef struct { /// Options to the compile command required to build this module interface swiftscan_string_set_t *command_line; + /// Options to the compile command required to build bridging header. + swiftscan_string_set_t *bridging_pch_command_line; + /// To build a PCM to be used by this Swift module, we need to append these /// arguments to the generic PCM build arguments reported from the dependency /// graph. @@ -96,6 +99,15 @@ typedef struct { /// A flag to indicate whether or not this module is a framework. bool is_framework; + + /// The CASID for CASFileSystemRoot + swiftscan_string_ref_t cas_fs_root_id; + + /// The CASID for bridging header include tree + swiftscan_string_ref_t bridging_header_include_tree; + + /// ModuleCacheKey + swiftscan_string_ref_t module_cache_key; } swiftscan_swift_textual_details_t; /// Swift modules with only a binary module file. @@ -109,8 +121,15 @@ typedef struct { /// The path to the .swiftSourceInfo file. swiftscan_string_ref_t module_source_info_path; + /// (Clang) header dependencies of this binary module. + /// Typically pre-compiled bridging header. + swiftscan_string_set_t *header_dependencies; + /// A flag to indicate whether or not this module is a framework. bool is_framework; + + /// ModuleCacheKey + swiftscan_string_ref_t module_cache_key; } swiftscan_swift_binary_details_t; /// Swift placeholder modules carry additional details that specify their @@ -139,6 +158,15 @@ typedef struct { /// The swift-specific PCM arguments captured by this dependencies object swiftscan_string_set_t *captured_pcm_args; + + /// The CASID for CASFileSystemRoot + swiftscan_string_ref_t cas_fs_root_id; + + /// The CASID for CASFileSystemRoot + swiftscan_string_ref_t clang_include_tree; + + /// ModuleCacheKey + swiftscan_string_ref_t module_cache_key; } swiftscan_clang_details_t; struct swiftscan_module_details_s { diff --git a/include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h b/include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h index bad67c1e43bf1..b702b07d79739 100644 --- a/include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h +++ b/include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h @@ -140,7 +140,10 @@ using SwiftInterfaceModuleDetailsLayout = FileIDArrayIDField, // sourceFiles FileIDArrayIDField, // bridgingSourceFiles FileIDArrayIDField, // bridgingModuleDependencies - DependencyIDArrayIDField // swiftOverlayDependencies + DependencyIDArrayIDField, // swiftOverlayDependencies + IdentifierIDField, // CASFileSystemRootID + IdentifierIDField, // bridgingHeaderIncludeTree + IdentifierIDField // moduleCacheKey >; using SwiftSourceModuleDetailsLayout = @@ -150,7 +153,11 @@ using SwiftSourceModuleDetailsLayout = FileIDArrayIDField, // sourceFiles FileIDArrayIDField, // bridgingSourceFiles FileIDArrayIDField, // bridgingModuleDependencies - DependencyIDArrayIDField // swiftOverlayDependencies + DependencyIDArrayIDField, // swiftOverlayDependencies + IdentifierIDField, // CASFileSystemRootID + IdentifierIDField, // bridgingHeaderIncludeTree + FlagIDArrayIDField, // buildCommandLine + FlagIDArrayIDField // bridgingHeaderBuildCommandLine >; using SwiftBinaryModuleDetailsLayout = @@ -158,7 +165,9 @@ using SwiftBinaryModuleDetailsLayout = FileIDField, // compiledModulePath FileIDField, // moduleDocPath FileIDField, // moduleSourceInfoPath - IsFrameworkField // isFramework + ImportArrayIDField, // headerImports + IsFrameworkField, // isFramework + IdentifierIDField // moduleCacheKey >; using SwiftPlaceholderModuleDetailsLayout = @@ -175,7 +184,10 @@ using ClangModuleDetailsLayout = ContextHashIDField, // contextHash FlagIDArrayIDField, // commandLine FileIDArrayIDField, // fileDependencies - FlagIDArrayIDField // capturedPCMArgs + FlagIDArrayIDField, // capturedPCMArgs + IdentifierIDField, // CASFileSystemRootID + IdentifierIDField, // clangIncludeTreeRoot + IdentifierIDField // moduleCacheKey >; } // namespace graph_block diff --git a/include/swift/Frontend/CachingUtils.h b/include/swift/Frontend/CachingUtils.h index 36709d8c3a38e..501a65415d38e 100644 --- a/include/swift/Frontend/CachingUtils.h +++ b/include/swift/Frontend/CachingUtils.h @@ -19,6 +19,7 @@ #include "llvm/CAS/ActionCache.h" #include "llvm/CAS/ObjectStore.h" #include "llvm/CAS/CASReference.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/VirtualOutputBackend.h" #include @@ -54,6 +55,32 @@ llvm::Error storeCachedCompilerOutput(llvm::cas::ObjectStore &CAS, StringRef CorrespondingInput, file_types::ID OutputKind); +llvm::Expected> +createCASFileSystem(llvm::cas::ObjectStore &CAS, ArrayRef FSRoots, + ArrayRef IncludeTreeRoots); + +namespace cas { +/// Helper class to manage CAS/Caching from libSwiftScan C APIs. +class CachingTool { +public: + // Create the tool with a list of arguments from compiler invocation. + CachingTool(llvm::StringRef Path); + + // Compute the CASID for PCH output from invocation. + std::string computeCacheKey(llvm::ArrayRef Args, + StringRef InputPath, file_types::ID OutputKind); + + // Store content into CAS. + std::string storeContent(llvm::StringRef Content); + + // Check if the tool is correctly initialized. + bool isValid() const { return CAS && Cache; } + +private: + std::unique_ptr CAS; + std::unique_ptr Cache; +}; +} // namespace cas } #endif diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 8809316ee9ca9..d19af926aafc8 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -129,7 +129,10 @@ class FrontendOptions { std::string CASPath; /// CASFS Root. - std::string CASFSRootID; + std::vector CASFSRootIDs; + + /// Clang Include Trees. + std::vector ClangIncludeTrees; /// Number of retry opening an input file if the previous opening returns /// bad file descriptor error. diff --git a/include/swift/Frontend/ModuleInterfaceLoader.h b/include/swift/Frontend/ModuleInterfaceLoader.h index d5533b10ec14e..4d61b939be13e 100644 --- a/include/swift/Frontend/ModuleInterfaceLoader.h +++ b/include/swift/Frontend/ModuleInterfaceLoader.h @@ -111,9 +111,17 @@ #include "swift/Frontend/Frontend.h" #include "swift/Frontend/ModuleInterfaceSupport.h" #include "swift/Serialization/SerializedModuleLoader.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/YAMLTraits.h" +namespace llvm { +namespace cas { +class ObjectStore; +class ActionCache; +} // namespace cas +} // namespace llvm + namespace clang { class CompilerInstance; } @@ -178,29 +186,86 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase { ~ExplicitSwiftModuleLoader(); }; +class ExplicitCASModuleLoader : public SerializedModuleLoaderBase { + explicit ExplicitCASModuleLoader(ASTContext &ctx, llvm::cas::ObjectStore &CAS, + llvm::cas::ActionCache &cache, + DependencyTracker *tracker, + ModuleLoadingMode loadMode, + bool IgnoreSwiftSourceInfoFile); + + bool findModule(ImportPath::Element moduleID, + SmallVectorImpl *moduleInterfacePath, + SmallVectorImpl *moduleInterfaceSourcePath, + std::unique_ptr *moduleBuffer, + std::unique_ptr *moduleDocBuffer, + std::unique_ptr *moduleSourceInfoBuffer, + bool skipBuildingInterface, bool isTestableDependencyLookup, + bool &isFramework, bool &isSystemModule) override; + + std::error_code findModuleFilesInDirectory( + ImportPath::Element ModuleID, const SerializedModuleBaseName &BaseName, + SmallVectorImpl *ModuleInterfacePath, + SmallVectorImpl *ModuleInterfaceSourcePath, + std::unique_ptr *ModuleBuffer, + std::unique_ptr *ModuleDocBuffer, + std::unique_ptr *ModuleSourceInfoBuffer, + bool SkipBuildingInterface, bool IsFramework, + bool IsTestableDependencyLookup = false) override; + + bool canImportModule(ImportPath::Module named, + ModuleVersionInfo *versionInfo, + bool isTestableDependencyLookup = false) override; + + struct Implementation; + Implementation &Impl; + +public: + static std::unique_ptr + create(ASTContext &ctx, llvm::cas::ObjectStore &CAS, + llvm::cas::ActionCache &cache, DependencyTracker *tracker, + ModuleLoadingMode loadMode, StringRef ExplicitSwiftModuleMap, + const std::vector> + &ExplicitSwiftModuleInputs, + bool IgnoreSwiftSourceInfoFile); + + /// Append visible module names to \p names. Note that names are possibly + /// duplicated, and not guaranteed to be ordered in any way. + void collectVisibleTopLevelModuleNames( + SmallVectorImpl &names) const override; + + ~ExplicitCASModuleLoader(); +}; // Explicitly-specified Swift module inputs struct ExplicitSwiftModuleInputInfo { ExplicitSwiftModuleInputInfo(std::string modulePath, llvm::Optional moduleDocPath, llvm::Optional moduleSourceInfoPath, + llvm::Optional> headerDependencyPaths, bool isFramework = false, - bool isSystem = false) + bool isSystem = false, + llvm::Optional moduleCacheKey = None) : modulePath(modulePath), moduleDocPath(moduleDocPath), moduleSourceInfoPath(moduleSourceInfoPath), + headerDependencyPaths(headerDependencyPaths), isFramework(isFramework), - isSystem(isSystem) {} + isSystem(isSystem), + moduleCacheKey(moduleCacheKey) {} // Path of the .swiftmodule file. std::string modulePath; // Path of the .swiftmoduledoc file. llvm::Optional moduleDocPath; // Path of the .swiftsourceinfo file. llvm::Optional moduleSourceInfoPath; + // Paths of the precompiled header dependencies of this module. + llvm::Optional> headerDependencyPaths; // A flag that indicates whether this module is a framework bool isFramework = false; // A flag that indicates whether this module is a system module bool isSystem = false; + // The cache key for clang module. + llvm::Optional moduleCacheKey; }; // Explicitly-specified Clang module inputs @@ -208,11 +273,13 @@ struct ExplicitClangModuleInputInfo { ExplicitClangModuleInputInfo(std::string moduleMapPath, std::string modulePath, bool isFramework = false, - bool isSystem = false) + bool isSystem = false, + llvm::Optional moduleCacheKey = None) : moduleMapPath(moduleMapPath), modulePath(modulePath), isFramework(isFramework), - isSystem(isSystem) {} + isSystem(isSystem), + moduleCacheKey(moduleCacheKey) {} // Path of the Clang module map file. std::string moduleMapPath; // Path of a compiled Clang explicit module file (pcm). @@ -221,6 +288,8 @@ struct ExplicitClangModuleInputInfo { bool isFramework = false; // A flag that indicates whether this module is a system module bool isSystem = false; + // The cache key for clang module. + llvm::Optional moduleCacheKey; }; /// Parser of explicit module maps passed into the compiler. @@ -233,6 +302,8 @@ struct ExplicitClangModuleInputInfo { // "isFramework": false, // "clangModuleMapPath": "A/module.modulemap", // "clangModulePath": "A.pcm", +// "moduleCacheKey": "llvmcas://", +// "clangModuleCacheKey": "llvmcas://", // }, // { // "moduleName": "B", @@ -242,6 +313,8 @@ struct ExplicitClangModuleInputInfo { // "isFramework": false, // "clangModuleMapPath": "B/module.modulemap", // "clangModulePath": "B.pcm", +// "moduleCacheKey": "llvmcas://", +// "clangModuleCacheKey": "llvmcas://", // } // ] class ExplicitModuleMapParser { @@ -249,21 +322,14 @@ class ExplicitModuleMapParser { ExplicitModuleMapParser(llvm::BumpPtrAllocator &Allocator) : Saver(Allocator) {} std::error_code - parseSwiftExplicitModuleMap(llvm::StringRef fileName, + parseSwiftExplicitModuleMap(llvm::MemoryBufferRef BufferRef, llvm::StringMap &swiftModuleMap, llvm::StringMap &clangModuleMap) { using namespace llvm::yaml; - // Load the input file. - llvm::ErrorOr> fileBufOrErr = - llvm::MemoryBuffer::getFile(fileName); - if (!fileBufOrErr) { - return std::make_error_code(std::errc::no_such_file_or_directory); - } - StringRef Buffer = fileBufOrErr->get()->getBuffer(); // Use a new source manager instead of the one from ASTContext because we // don't want the JSON file to be persistent. llvm::SourceMgr SM; - Stream Stream(llvm::MemoryBufferRef(Buffer, fileName), SM); + Stream Stream(BufferRef, SM); for (auto DI = Stream.begin(); DI != Stream.end(); ++DI) { assert(DI != Stream.end() && "Failed to read a document"); if (auto *MN = dyn_cast_or_null(DI->getRoot())) { @@ -305,31 +371,41 @@ class ExplicitModuleMapParser { return true; StringRef moduleName; llvm::Optional swiftModulePath, swiftModuleDocPath, - swiftModuleSourceInfoPath; + swiftModuleSourceInfoPath, swiftModuleCacheKey, + clangModuleCacheKey; + llvm::Optional> headerDependencyPaths; std::string clangModuleMapPath = "", clangModulePath = ""; bool isFramework = false, isSystem = false; for (auto &entry : *mapNode) { auto key = getScalaNodeText(entry.getKey()); - auto val = getScalaNodeText(entry.getValue()); - if (key == "moduleName") { - moduleName = val; - } else if (key == "modulePath") { - swiftModulePath = val.str(); - } else if (key == "docPath") { - swiftModuleDocPath = val.str(); - } else if (key == "sourceInfoPath") { - swiftModuleSourceInfoPath = val.str(); - } else if (key == "isFramework") { - isFramework = parseBoolValue(val); - } else if (key == "isSystem") { - isSystem = parseBoolValue(val); - } else if (key == "clangModuleMapPath") { - clangModuleMapPath = val.str(); - } else if (key == "clangModulePath") { - clangModulePath = val.str(); - } else { - // Being forgiving for future fields. + if (key == "prebuiltHeaderDependencyPaths") { continue; + } else { + auto val = getScalaNodeText(entry.getValue()); + if (key == "moduleName") { + moduleName = val; + } else if (key == "modulePath") { + swiftModulePath = val.str(); + } else if (key == "docPath") { + swiftModuleDocPath = val.str(); + } else if (key == "sourceInfoPath") { + swiftModuleSourceInfoPath = val.str(); + } else if (key == "isFramework") { + isFramework = parseBoolValue(val); + } else if (key == "isSystem") { + isSystem = parseBoolValue(val); + } else if (key == "clangModuleMapPath") { + clangModuleMapPath = val.str(); + } else if (key == "clangModulePath") { + clangModulePath = val.str(); + } else if (key == "moduleCacheKey") { + swiftModuleCacheKey = val.str(); + } else if (key == "clangModuleCacheKey") { + clangModuleCacheKey = val.str(); + } else { + // Being forgiving for future fields. + continue; + } } } if (moduleName.empty()) @@ -342,8 +418,10 @@ class ExplicitModuleMapParser { ExplicitSwiftModuleInputInfo entry(swiftModulePath.value(), swiftModuleDocPath, swiftModuleSourceInfoPath, + headerDependencyPaths, isFramework, - isSystem); + isSystem, + swiftModuleCacheKey); swiftModuleMap.try_emplace(moduleName, std::move(entry)); } else { assert((!clangModuleMapPath.empty() || @@ -352,7 +430,8 @@ class ExplicitModuleMapParser { ExplicitClangModuleInputInfo entry(clangModuleMapPath, clangModulePath, isFramework, - isSystem); + isSystem, + clangModuleCacheKey); clangModuleMap.try_emplace(moduleName, std::move(entry)); } diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 984d69949697f..1069d3ea2b10f 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -1829,6 +1829,15 @@ def allow_unstable_cache_key_for_testing: Flag<["-"], "allow-unstable-cache-key- Flags<[FrontendOption, HelpHidden, NoDriverOption]>, HelpText<"Allow compilation caching with unstable inputs for testing purpose">; +def bridging_header_pch_key : Separate<["-"], "bridging-header-pch-key">, + Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>, + HelpText<"Cache Key for bridging header pch">; + +def clang_include_tree: Flag<["-"], "clang-include-tree">, + Flags<[FrontendOption, NoDriverOption]>, + HelpText<"Use clang include tree">; + + // END ONLY SUPPORTED IN NEW DRIVER def enable_cas: Flag<["-"], "enable-cas">, @@ -1839,6 +1848,10 @@ def cas_fs: Separate<["-"], "cas-fs">, Flags<[FrontendOption, NoDriverOption]>, HelpText<"Root CASID for CAS FileSystem">, MetaVarName<"">; +def clang_include_tree_root: Separate<["-"], "clang-include-tree-root">, + Flags<[FrontendOption, NoDriverOption]>, + HelpText<"Clang Include Tree CASID">, MetaVarName<"">; + def load_plugin_library: Separate<["-"], "load-plugin-library">, Flags<[FrontendOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>, diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h index 557d7530c90ea..07094ef23e7bc 100644 --- a/include/swift/Runtime/Metadata.h +++ b/include/swift/Runtime/Metadata.h @@ -666,6 +666,36 @@ void swift_initStructMetadataWithLayoutString(StructMetadata *self, const uint8_t *fieldTags, uint32_t *fieldOffsets); +SWIFT_RUNTIME_STDLIB_INTERNAL +size_t _swift_refCountBytesForMetatype(const Metadata *type); + +enum LayoutStringFlags : uint64_t { + Empty = 0, + // TODO: Track other useful information tha can be used to optimize layout + // strings, like different reference kinds contained in the string + // number of ref counting operations (maybe up to 4), so we can + // use witness functions optimized for these cases. + HasRelativePointers = (1ULL << 63), +}; + +inline bool operator&(LayoutStringFlags a, LayoutStringFlags b) { + return (uint64_t(a) & uint64_t(b)) != 0; +} +inline LayoutStringFlags operator|(LayoutStringFlags a, LayoutStringFlags b) { + return LayoutStringFlags(uint64_t(a) | uint64_t(b)); +} +inline LayoutStringFlags &operator|=(LayoutStringFlags &a, LayoutStringFlags b) { + return a = (a | b); +} + +SWIFT_RUNTIME_STDLIB_INTERNAL +void _swift_addRefCountStringForMetatype(uint8_t *layoutStr, + size_t &layoutStrOffset, + LayoutStringFlags &flags, + const Metadata *fieldType, + size_t &fullOffset, + size_t &previousFieldOffset); + /// Allocate the metadata for a class and copy fields from the given pattern. /// The final size of the metadata is calculated at runtime from the metadata /// bounds in the class descriptor. diff --git a/include/swift/Sema/ConstraintSystem.h b/include/swift/Sema/ConstraintSystem.h index 6d6bb23a2712c..e003098aa03ab 100644 --- a/include/swift/Sema/ConstraintSystem.h +++ b/include/swift/Sema/ConstraintSystem.h @@ -2910,7 +2910,8 @@ class ConstraintSystem { /// and no new names are introduced after that point. /// /// \returns A reference to the member-lookup result. - LookupResult &lookupMember(Type base, DeclNameRef name); + LookupResult &lookupMember(Type base, DeclNameRef name, + SourceLoc loc); /// Retrieve the set of "alternative" literal types that we'll explore /// for a given literal protocol kind. diff --git a/include/swift/Serialization/ModuleDependencyScanner.h b/include/swift/Serialization/ModuleDependencyScanner.h index 0132c7ce58920..1567d63995281 100644 --- a/include/swift/Serialization/ModuleDependencyScanner.h +++ b/include/swift/Serialization/ModuleDependencyScanner.h @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "swift/AST/ASTContext.h" +#include "swift/AST/ModuleDependencies.h" #include "swift/Frontend/ModuleInterfaceLoader.h" #include "swift/Serialization/SerializedModuleLoader.h" @@ -41,18 +42,22 @@ namespace swift { /// Location where pre-built moduels are to be built into. std::string moduleCachePath; + + Optional dependencyTracker; public: Optional dependencies; ModuleDependencyScanner(ASTContext &ctx, ModuleLoadingMode LoadMode, Identifier moduleName, InterfaceSubContextDelegate &astDelegate, - ScannerKind kind = MDS_plain) + ScannerKind kind = MDS_plain, + Optional tracker = None) : SerializedModuleLoaderBase(ctx, nullptr, LoadMode, /*IgnoreSwiftSourceInfoFile=*/true), kind(kind), moduleName(moduleName), astDelegate(astDelegate), moduleCachePath(getModuleCachePathFromClang( - ctx.getClangModuleLoader()->getClangInstance())) {} + ctx.getClangModuleLoader()->getClangInstance())), + dependencyTracker(tracker) {} std::error_code findModuleFilesInDirectory( ImportPath::Element ModuleID, @@ -87,9 +92,16 @@ namespace swift { void parsePlaceholderModuleMap(StringRef fileName) { ExplicitModuleMapParser parser(Allocator); llvm::StringMap ClangDependencyModuleMap; - auto result = - parser.parseSwiftExplicitModuleMap(fileName, PlaceholderDependencyModuleMap, - ClangDependencyModuleMap); + llvm::ErrorOr> fileBufOrErr = + llvm::MemoryBuffer::getFile(fileName); + if (!fileBufOrErr) { + Ctx.Diags.diagnose(SourceLoc(), + diag::explicit_swift_module_map_missing, fileName); + return; + } + auto result = parser.parseSwiftExplicitModuleMap( + (*fileBufOrErr)->getMemBufferRef(), PlaceholderDependencyModuleMap, + ClangDependencyModuleMap); if (result == std::errc::invalid_argument) { Ctx.Diags.diagnose(SourceLoc(), diag::placeholder_dependency_module_map_corrupted, @@ -109,9 +121,10 @@ namespace swift { PlaceholderSwiftModuleScanner(ASTContext &ctx, ModuleLoadingMode LoadMode, Identifier moduleName, StringRef PlaceholderDependencyModuleMap, - InterfaceSubContextDelegate &astDelegate) + InterfaceSubContextDelegate &astDelegate, + Optional tracker = None) : ModuleDependencyScanner(ctx, LoadMode, moduleName, astDelegate, - MDS_placeholder) { + MDS_placeholder, tracker) { // FIXME: Find a better place for this map to live, to avoid // doing the parsing on every module. diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h index b13b2fb177798..085deabdda8c4 100644 --- a/include/swift/Serialization/SerializedModuleLoader.h +++ b/include/swift/Serialization/SerializedModuleLoader.h @@ -150,15 +150,20 @@ class SerializedModuleLoaderBase : public ModuleLoader { /// Scan the given serialized module file to determine dependencies. llvm::ErrorOr scanModuleFile(Twine modulePath, bool isFramework); - static llvm::ErrorOr> - getModuleImportsOfModule(Twine modulePath, - ModuleLoadingBehavior transitiveBehavior, - bool isFramework, - bool isRequiredOSSAModules, - StringRef SDKName, - StringRef packageName, - llvm::vfs::FileSystem *fileSystem, - PathObfuscator &recoverer); + struct BinaryModuleImports { + llvm::StringSet<> moduleImports; + llvm::StringSet<> headerImports; + }; + + static llvm::ErrorOr + getImportsOfModule(Twine modulePath, + ModuleLoadingBehavior transitiveBehavior, + bool isFramework, + bool isRequiredOSSAModules, + StringRef SDKName, + StringRef packageName, + llvm::vfs::FileSystem *fileSystem, + PathObfuscator &recoverer); /// Load the module file into a buffer and also collect its module name. static std::unique_ptr diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 00bd291f3a025..93c8f0f0959e4 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1072,8 +1072,8 @@ DECLTYPE *ASTContext::get##NAME##Decl() const { \ /* Note: lookupQualified() will search both the Swift overlay \ * and the Clang module it imports. */ \ SmallVector decls; \ - M->lookupQualified(M, DeclNameRef(getIdentifier(#NAME)), NL_OnlyTypes, \ - decls); \ + M->lookupQualified(M, DeclNameRef(getIdentifier(#NAME)), SourceLoc(), \ + NL_OnlyTypes, decls); \ if (decls.size() == 1 && isa(decls[0])) { \ auto decl = cast(decls[0]); \ if (isa(decl) \ @@ -1336,7 +1336,8 @@ ConcreteDeclRef ASTContext::getRegexInitDecl(Type regexType) const { {Id_regexString, Id_version}); SmallVector results; spModule->lookupQualified(getRegexType(), DeclNameRef(name), - NL_IncludeUsableFromInline, results); + SourceLoc(), NL_IncludeUsableFromInline, + results); assert(results.size() == 1); auto *foundDecl = cast(results[0]); auto subs = regexType->getMemberSubstitutionMap(spModule, foundDecl); diff --git a/lib/AST/ASTScope.cpp b/lib/AST/ASTScope.cpp index c4eb1d1370f5f..aa80e71159bf9 100644 --- a/lib/AST/ASTScope.cpp +++ b/lib/AST/ASTScope.cpp @@ -60,6 +60,12 @@ std::pair ASTScope::lookupFallthroughSourceAndDest( return ASTScopeImpl::lookupFallthroughSourceAndDest(sourceFile, loc); } +void ASTScope::lookupEnclosingMacroScope( + SourceFile *sourceFile, SourceLoc loc, + llvm::function_ref body) { + return ASTScopeImpl::lookupEnclosingMacroScope(sourceFile, loc, body); +} + #if SWIFT_COMPILER_IS_MSVC #pragma warning(push) #pragma warning(disable : 4996) @@ -138,7 +144,7 @@ DEFINE_GET_CLASS_NAME(AbstractFunctionDeclScope) DEFINE_GET_CLASS_NAME(ParameterListScope) DEFINE_GET_CLASS_NAME(FunctionBodyScope) DEFINE_GET_CLASS_NAME(DefaultArgumentInitializerScope) -DEFINE_GET_CLASS_NAME(AttachedPropertyWrapperScope) +DEFINE_GET_CLASS_NAME(CustomAttributeScope) DEFINE_GET_CLASS_NAME(PatternEntryDeclScope) DEFINE_GET_CLASS_NAME(PatternEntryInitializerScope) DEFINE_GET_CLASS_NAME(ConditionalClausePatternUseScope) diff --git a/lib/AST/ASTScopeCreation.cpp b/lib/AST/ASTScopeCreation.cpp index 66821d17e6c49..f2bcdedd65f1b 100644 --- a/lib/AST/ASTScopeCreation.cpp +++ b/lib/AST/ASTScopeCreation.cpp @@ -180,7 +180,7 @@ class ScopeCreator final : public ASTAllocated { addChildrenForParsedAccessors(AbstractStorageDecl *asd, ASTScopeImpl *parent); - void addChildrenForKnownAttributes(ValueDecl *decl, + void addChildrenForKnownAttributes(Decl *decl, ASTScopeImpl *parent); /// Add PatternEntryDeclScopes for each pattern binding entry. @@ -569,7 +569,7 @@ void ScopeCreator::addChildrenForParsedAccessors( }); } -void ScopeCreator::addChildrenForKnownAttributes(ValueDecl *decl, +void ScopeCreator::addChildrenForKnownAttributes(Decl *decl, ASTScopeImpl *parent) { SmallVector relevantAttrs; @@ -601,10 +601,8 @@ void ScopeCreator::addChildrenForKnownAttributes(ValueDecl *decl, parent, specAttr, afd); } } else if (auto *customAttr = dyn_cast(attr)) { - if (auto *vd = dyn_cast(decl)) { - constructExpandAndInsert( - parent, customAttr, vd); - } + constructExpandAndInsert( + parent, customAttr, decl); } } } @@ -716,7 +714,7 @@ CREATES_NEW_INSERTION_POINT(ConditionalClausePatternUseScope) NO_NEW_INSERTION_POINT(FunctionBodyScope) NO_NEW_INSERTION_POINT(AbstractFunctionDeclScope) -NO_NEW_INSERTION_POINT(AttachedPropertyWrapperScope) +NO_NEW_INSERTION_POINT(CustomAttributeScope) NO_NEW_INSERTION_POINT(EnumElementScope) NO_NEW_INSERTION_POINT(GuardStmtBodyScope) NO_NEW_INSERTION_POINT(ParameterListScope) @@ -1177,7 +1175,7 @@ void DefaultArgumentInitializerScope:: scopeCreator.addToScopeTree(initExpr, this); } -void AttachedPropertyWrapperScope:: +void CustomAttributeScope:: expandAScopeThatDoesNotCreateANewInsertionPoint( ScopeCreator &scopeCreator) { if (auto *args = attr->getArgs()) { @@ -1192,7 +1190,9 @@ ASTScopeImpl *GenericTypeOrExtensionWholePortion::expandScope( GenericTypeOrExtensionScope *scope, ScopeCreator &scopeCreator) const { // Get now in case recursion emancipates scope auto *const ip = scope->getParent().get(); - + + scopeCreator.addChildrenForKnownAttributes(scope->getDecl(), scope); + auto *context = scope->getGenericContext(); auto *genericParams = (isa(context) ? context->getParsedGenericParams() diff --git a/lib/AST/ASTScopeLookup.cpp b/lib/AST/ASTScopeLookup.cpp index 676e6e9dbdd77..a8168ca096605 100644 --- a/lib/AST/ASTScopeLookup.cpp +++ b/lib/AST/ASTScopeLookup.cpp @@ -675,3 +675,36 @@ std::pair ASTScopeImpl::lookupFallthroughSourceAndDest( return { nullptr, nullptr }; } + +void ASTScopeImpl::lookupEnclosingMacroScope( + SourceFile *sourceFile, SourceLoc loc, + llvm::function_ref consume) { + if (!sourceFile || sourceFile->Kind == SourceFileKind::Interface) + return; + + if (loc.isInvalid()) + return; + + auto *fileScope = sourceFile->getScope().impl; + auto *scope = fileScope->findInnermostEnclosingScope(loc, nullptr); + do { + auto *freestanding = scope->getFreestandingMacro().getPtrOrNull(); + if (freestanding && consume(freestanding)) + return; + + auto *attr = scope->getDeclAttributeIfAny().getPtrOrNull(); + auto *potentialAttached = dyn_cast_or_null(attr); + if (potentialAttached && consume(potentialAttached)) + return; + + // If we've reached a source file scope, we can't be inside of + // a macro argument. Either this is a top-level source file, or + // it's macro expansion buffer. We have to check for this because + // macro expansion buffers for freestanding macros are children of + // MacroExpansionDeclScope, and child scopes of freestanding macros + // are otherwise inside the macro argument. + if (scope->getClassName() == "ASTSourceFileScope") + return; + + } while ((scope = scope->getParent().getPtrOrNull())); +} diff --git a/lib/AST/ASTScopeSourceRange.cpp b/lib/AST/ASTScopeSourceRange.cpp index 0073be55f8e89..1ce85b9319b55 100644 --- a/lib/AST/ASTScopeSourceRange.cpp +++ b/lib/AST/ASTScopeSourceRange.cpp @@ -360,7 +360,7 @@ SourceRange ClosureParametersScope::getSourceRangeOfThisASTNode( return explicitClosureExpr->getSourceRange(); } -SourceRange AttachedPropertyWrapperScope::getSourceRangeOfThisASTNode( +SourceRange CustomAttributeScope::getSourceRangeOfThisASTNode( const bool omitAssertions) const { return attr->getRange(); } diff --git a/lib/AST/AccessRequests.cpp b/lib/AST/AccessRequests.cpp index a32ef4f720acb..4f36950dcbbcc 100644 --- a/lib/AST/AccessRequests.cpp +++ b/lib/AST/AccessRequests.cpp @@ -67,6 +67,13 @@ AccessLevelRequest::evaluate(Evaluator &evaluator, ValueDecl *D) const { } } + // Special case for opaque type decls, which inherit the access of their + // naming decls. + if (auto *opaqueType = dyn_cast(D)) { + if (auto *namingDecl = opaqueType->getNamingDecl()) + return namingDecl->getFormalAccess(); + } + DeclContext *DC = D->getDeclContext(); // Special case for generic parameters; we just give them a dummy diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 14d6a9c2849fe..5cdafc50f6642 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -3749,6 +3749,15 @@ bool ValueDecl::isUsableFromInline() const { return true; } + if (auto *opaqueType = dyn_cast(this)) { + if (auto *namingDecl = opaqueType->getNamingDecl()) { + if (namingDecl->getAttrs().hasAttribute() || + namingDecl->getAttrs().hasAttribute() || + namingDecl->getAttrs().hasAttribute()) + return true; + } + } + if (auto *EED = dyn_cast(this)) if (EED->getParentEnum()->getAttrs().hasAttribute()) return true; @@ -5395,7 +5404,7 @@ NominalTypeDecl::getExecutorOwnedEnqueueFunction() const { llvm::SmallVector results; lookupQualified(getSelfNominalTypeDecl(), DeclNameRef(C.Id_enqueue), - NL_ProtocolMembers, + getLoc(), NL_ProtocolMembers, results); for (auto candidate: results) { @@ -5434,7 +5443,7 @@ NominalTypeDecl::getExecutorLegacyOwnedEnqueueFunction() const { llvm::SmallVector results; lookupQualified(getSelfNominalTypeDecl(), DeclNameRef(C.Id_enqueue), - NL_ProtocolMembers, + getLoc(), NL_ProtocolMembers, results); for (auto candidate: results) { @@ -5473,7 +5482,7 @@ NominalTypeDecl::getExecutorLegacyUnownedEnqueueFunction() const { llvm::SmallVector results; lookupQualified(getSelfNominalTypeDecl(), DeclNameRef(C.Id_enqueue), - NL_ProtocolMembers, + getLoc(), NL_ProtocolMembers, results); for (auto candidate: results) { @@ -9927,7 +9936,7 @@ const VarDecl *ClassDecl::getUnownedExecutorProperty() const { llvm::SmallVector results; this->lookupQualified(getSelfNominalTypeDecl(), DeclNameRef(C.Id_unownedExecutor), - NL_ProtocolMembers, + getLoc(), NL_ProtocolMembers, results); for (auto candidate: results) { diff --git a/lib/AST/DocComment.cpp b/lib/AST/DocComment.cpp index 96bf365ef8745..5c73b29a42959 100644 --- a/lib/AST/DocComment.cpp +++ b/lib/AST/DocComment.cpp @@ -435,7 +435,8 @@ class CommentProviderFinder final { SmallVector members; protocol->lookupQualified(const_cast(protocol), DeclNameRef(VD->getName()), - NLOptions::NL_ProtocolMembers, members); + VD->getLoc(), NLOptions::NL_ProtocolMembers, + members); Optional result; for (auto *member : members) { diff --git a/lib/AST/Evaluator.cpp b/lib/AST/Evaluator.cpp index 49c1fab72b53c..fdc1b5889b912 100644 --- a/lib/AST/Evaluator.cpp +++ b/lib/AST/Evaluator.cpp @@ -63,8 +63,6 @@ Evaluator::Evaluator(DiagnosticEngine &diags, const LangOptions &opts) bool Evaluator::checkDependency(const ActiveRequest &request) { // Record this as an active request. if (activeRequests.insert(request)) { - if (request.getAs()) - ++numActiveResolveMacroRequests; return false; } @@ -74,9 +72,6 @@ bool Evaluator::checkDependency(const ActiveRequest &request) { } void Evaluator::finishedRequest(const ActiveRequest &request) { - if (request.getAs()) - --numActiveResolveMacroRequests; - assert(activeRequests.back() == request); activeRequests.pop_back(); } diff --git a/lib/AST/GenericEnvironment.cpp b/lib/AST/GenericEnvironment.cpp index 88957a6abe737..aecf75826e670 100644 --- a/lib/AST/GenericEnvironment.cpp +++ b/lib/AST/GenericEnvironment.cpp @@ -635,7 +635,6 @@ Type GenericEnvironment::mapTypeIntoContext( assert((!type->hasArchetype() || type->hasLocalArchetype()) && "already have a contextual type"); - type = maybeApplyOuterContextSubstitutions(type); Type result = type.subst(QueryInterfaceTypeSubstitutions(this), lookupConformance, SubstFlags::AllowLoweredTypes | diff --git a/lib/AST/ModuleDependencies.cpp b/lib/AST/ModuleDependencies.cpp index a9f5435d05d34..c3d3a59f590c2 100644 --- a/lib/AST/ModuleDependencies.cpp +++ b/lib/AST/ModuleDependencies.cpp @@ -15,8 +15,14 @@ //===----------------------------------------------------------------------===// #include "swift/AST/ModuleDependencies.h" #include "swift/AST/Decl.h" +#include "swift/AST/DiagnosticsFrontend.h" #include "swift/AST/SourceFile.h" #include "swift/Frontend/Frontend.h" +#include "llvm/CAS/CASProvidingFileSystem.h" +#include "llvm/CAS/CachingOnDiskFileSystem.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include using namespace swift; ModuleDependencyInfoStorageBase::~ModuleDependencyInfoStorageBase() {} @@ -175,6 +181,108 @@ Optional ModuleDependencyInfo::getBridgingHeader() const { } } +Optional ModuleDependencyInfo::getCASFSRootID() const { + std::string Root; + switch (getKind()) { + case swift::ModuleDependencyKind::SwiftInterface: { + auto swiftInterfaceStorage = + cast(storage.get()); + Root = swiftInterfaceStorage->textualModuleDetails.CASFileSystemRootID; + break; + } + case swift::ModuleDependencyKind::SwiftSource: { + auto swiftSourceStorage = + cast(storage.get()); + Root = swiftSourceStorage->textualModuleDetails.CASFileSystemRootID; + break; + } + case swift::ModuleDependencyKind::Clang: { + auto clangModuleStorage = cast(storage.get()); + Root = clangModuleStorage->CASFileSystemRootID; + break; + } + default: + return None; + } + if (Root.empty()) + return None; + + return Root; +} + +Optional ModuleDependencyInfo::getClangIncludeTree() const { + std::string Root; + switch (getKind()) { + case swift::ModuleDependencyKind::Clang: { + auto clangModuleStorage = cast(storage.get()); + Root = clangModuleStorage->CASClangIncludeTreeRootID; + break; + } + default: + return None; + } + if (Root.empty()) + return None; + + return Root; +} + +Optional +ModuleDependencyInfo::getBridgingHeaderIncludeTree() const { + std::string Root; + switch (getKind()) { + case swift::ModuleDependencyKind::SwiftInterface: { + auto swiftInterfaceStorage = + cast(storage.get()); + Root = swiftInterfaceStorage->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID; + break; + } + case swift::ModuleDependencyKind::SwiftSource: { + auto swiftSourceStorage = + cast(storage.get()); + Root = swiftSourceStorage->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID; + break; + } + default: + return None; + } + if (Root.empty()) + return None; + + return Root; +} + +std::string ModuleDependencyInfo::getModuleOutputPath() const { + switch (getKind()) { + case swift::ModuleDependencyKind::SwiftInterface: { + auto swiftInterfaceStorage = + cast(storage.get()); + return swiftInterfaceStorage->moduleOutputPath; + } + case swift::ModuleDependencyKind::SwiftSource: { + return ""; + } + case swift::ModuleDependencyKind::Clang: { + auto clangModuleStorage = cast(storage.get()); + return clangModuleStorage->pcmOutputPath; + } + case swift::ModuleDependencyKind::SwiftBinary: { + auto swiftBinaryStorage = + cast(storage.get()); + return swiftBinaryStorage->compiledModulePath; + } + case swift::ModuleDependencyKind::SwiftPlaceholder: { + auto swiftPlaceholderStorage = + cast(storage.get()); + return swiftPlaceholderStorage->compiledModulePath; + } + default: + llvm_unreachable("Unexpected dependency kind"); + } +} + void ModuleDependencyInfo::addBridgingHeader(StringRef bridgingHeader) { switch (getKind()) { case swift::ModuleDependencyKind::SwiftInterface: { @@ -217,6 +325,27 @@ void ModuleDependencyInfo::addBridgingSourceFile(StringRef bridgingSourceFile) { } } +void ModuleDependencyInfo::addBridgingHeaderIncludeTree(StringRef ID) { + switch (getKind()) { + case swift::ModuleDependencyKind::SwiftInterface: { + auto swiftInterfaceStorage = + cast(storage.get()); + swiftInterfaceStorage->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID = ID.str(); + break; + } + case swift::ModuleDependencyKind::SwiftSource: { + auto swiftSourceStorage = + cast(storage.get()); + swiftSourceStorage->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID = ID.str(); + break; + } + default: + llvm_unreachable("Unexpected dependency kind"); + } +} + void ModuleDependencyInfo::addSourceFile(StringRef sourceFile) { switch (getKind()) { case swift::ModuleDependencyKind::SwiftSource: { @@ -253,25 +382,97 @@ void ModuleDependencyInfo::addBridgingModuleDependency( } } -SwiftDependencyScanningService::SwiftDependencyScanningService() - : ClangScanningService(clang::tooling::dependencies::ScanningMode::DependencyDirectivesScan, - clang::tooling::dependencies::ScanningOutputFormat::Full, - clang::CASOptions(), - /* CAS (llvm::cas::ObjectStore) */ nullptr, - /* Cache (llvm::cas::ActionCache) */ nullptr, - /* SharedFS */ nullptr, - /* OptimizeArgs */ true) { - SharedFilesystemCache.emplace(); +SwiftDependencyScanningService::SwiftDependencyScanningService() { + ClangScanningService.emplace( + clang::tooling::dependencies::ScanningMode::DependencyDirectivesScan, + clang::tooling::dependencies::ScanningOutputFormat::FullTree, + clang::CASOptions(), + /* CAS (llvm::cas::ObjectStore) */ nullptr, + /* Cache (llvm::cas::ActionCache) */ nullptr, + /* SharedFS */ nullptr, + /* OptimizeArgs */ true); + SharedFilesystemCache.emplace(); +} + +void SwiftDependencyTracker::startTracking() { + FS->trackNewAccesses(); + + for (auto &file : Files) + (void)FS->status(file); +} + +llvm::Expected +SwiftDependencyTracker::createTreeFromDependencies() { + return FS->createTreeFromNewAccesses(); } -void SwiftDependencyScanningService::overlaySharedFilesystemCacheForCompilation(CompilerInstance &Instance) { - auto existingFS = Instance.getSourceMgr().getFileSystem(); - llvm::IntrusiveRefCntPtr< - clang::tooling::dependencies::DependencyScanningWorkerFilesystem> - depFS = - new clang::tooling::dependencies::DependencyScanningWorkerFilesystem( - getSharedFilesystemCache(), existingFS); - Instance.getSourceMgr().setFileSystem(depFS); +void SwiftDependencyScanningService::overlaySharedFilesystemCacheForCompilation( + CompilerInstance &Instance) { + auto existingFS = Instance.getSourceMgr().getFileSystem(); + llvm::IntrusiveRefCntPtr< + clang::tooling::dependencies::DependencyScanningWorkerFilesystem> + depFS = + new clang::tooling::dependencies::DependencyScanningWorkerFilesystem( + getSharedFilesystemCache(), existingFS); + Instance.getSourceMgr().setFileSystem(depFS); +} + +void SwiftDependencyScanningService::setupCachingDependencyScanningService( + CompilerInstance &Instance) { + if (!Instance.getInvocation().getFrontendOptions().EnableCAS) + return; + + // Setup CAS. + CAS = Instance.getSharedCASInstance(); + + // Add SDKSetting file. + SmallString<256> SDKSettingPath; + llvm::sys::path::append( + SDKSettingPath, + Instance.getInvocation().getSearchPathOptions().getSDKPath(), + "SDKSettings.json"); + CommonDependencyFiles.emplace_back(SDKSettingPath.data(), + SDKSettingPath.size()); + + // Add Legacy layout file (maybe just hard code instead of searching). + for (auto RuntimeLibPath : + Instance.getInvocation().getSearchPathOptions().RuntimeLibraryPaths) { + auto &FS = Instance.getFileSystem(); + std::error_code EC; + for (auto F = FS.dir_begin(RuntimeLibPath, EC); + !EC && F != llvm::vfs::directory_iterator(); F.increment(EC)) { + if (F->path().endswith(".yaml")) + CommonDependencyFiles.emplace_back(F->path().str()); + } + } + + auto CachingFS = + llvm::cas::createCachingOnDiskFileSystem(Instance.getObjectStore()); + if (!CachingFS) { + Instance.getDiags().diagnose(SourceLoc(), diag::error_create_cas, + "CachingOnDiskFS", + toString(CachingFS.takeError())); + return; + } + CacheFS = std::move(*CachingFS); + + clang::CASOptions CASOpts; + CASOpts.CASPath = Instance.getInvocation().getFrontendOptions().CASPath; + CASOpts.ensurePersistentCAS(); + + UseClangIncludeTree = + Instance.getInvocation().getClangImporterOptions().UseClangIncludeTree; + const clang::tooling::dependencies::ScanningOutputFormat ClangScanningFormat = + UseClangIncludeTree + ? clang::tooling::dependencies::ScanningOutputFormat::FullIncludeTree + : clang::tooling::dependencies::ScanningOutputFormat::FullTree; + + ClangScanningService.emplace( + clang::tooling::dependencies::ScanningMode::DependencyDirectivesScan, + ClangScanningFormat, CASOpts, Instance.getSharedCASInstance(), + Instance.getSharedCacheInstance(), + UseClangIncludeTree ? nullptr : CacheFS, + /* ReuseFileManager */ false, /* OptimizeArgs */ false); } SwiftDependencyScanningService::ContextSpecificGlobalCacheState * @@ -385,12 +586,12 @@ ModuleDependenciesCache::getDependencyReferencesMap( ModuleDependenciesCache::ModuleDependenciesCache( SwiftDependencyScanningService &globalScanningService, - std::string mainScanModuleName, - std::string scannerContextHash) + std::string mainScanModuleName, std::string scannerContextHash) : globalScanningService(globalScanningService), mainScanModuleName(mainScanModuleName), scannerContextHash(scannerContextHash), - clangScanningTool(globalScanningService.ClangScanningService) { + clangScanningTool(*globalScanningService.ClangScanningService, + globalScanningService.getClangScanningFS()) { globalScanningService.configureForContextHash(scannerContextHash); for (auto kind = ModuleDependencyKind::FirstKind; kind != ModuleDependencyKind::LastKind; ++kind) { @@ -399,8 +600,7 @@ ModuleDependenciesCache::ModuleDependenciesCache( } } -Optional -ModuleDependenciesCache::findDependency( +Optional ModuleDependenciesCache::findDependency( StringRef moduleName, Optional kind) const { auto optionalDep = globalScanningService.findDependency(moduleName, kind, scannerContextHash); diff --git a/lib/AST/ModuleLoader.cpp b/lib/AST/ModuleLoader.cpp index 643082931a7dc..5480c40ed6268 100644 --- a/lib/AST/ModuleLoader.cpp +++ b/lib/AST/ModuleLoader.cpp @@ -94,7 +94,9 @@ static bool findOverlayFilesInDirectory(ASTContext &ctx, StringRef path, callback(file); } - if (error && error != std::errc::no_such_file_or_directory) { + // A CAS file list returns operation not permitted on directory iterations. + if (error && error != std::errc::no_such_file_or_directory && + error != std::errc::operation_not_permitted) { ctx.Diags.diagnose(diagLoc, diag::cannot_list_swiftcrossimport_dir, moduleName, error.message(), path); } diff --git a/lib/AST/ModuleNameLookup.cpp b/lib/AST/ModuleNameLookup.cpp index 10ea32c053c17..98ae1381690ce 100644 --- a/lib/AST/ModuleNameLookup.cpp +++ b/lib/AST/ModuleNameLookup.cpp @@ -281,10 +281,10 @@ void namelookup::lookupInModule(const DeclContext *moduleOrFile, NLKind lookupKind, ResolutionKind resolutionKind, const DeclContext *moduleScopeContext, - NLOptions options) { + SourceLoc loc, NLOptions options) { auto &ctx = moduleOrFile->getASTContext(); LookupInModuleRequest req(moduleOrFile, name, lookupKind, resolutionKind, - moduleScopeContext, options); + moduleScopeContext, loc, options); auto results = evaluateOrDefault(ctx.evaluator, req, {}); decls.append(results.begin(), results.end()); } diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp index 77e029d8e3199..ca2162d7e504e 100644 --- a/lib/AST/NameLookup.cpp +++ b/lib/AST/NameLookup.cpp @@ -1594,6 +1594,60 @@ static DeclName adjustLazyMacroExpansionNameKey( return name; } +SmallVector +namelookup::lookupMacros(DeclContext *dc, DeclNameRef macroName, + MacroRoles roles) { + SmallVector choices; + auto moduleScopeDC = dc->getModuleScopeContext(); + ASTContext &ctx = moduleScopeDC->getASTContext(); + + // Macro lookup should always exclude macro expansions; macro + // expansions cannot introduce new macro declarations. Note that + // the source location here doesn't matter. + UnqualifiedLookupDescriptor descriptor{ + macroName, moduleScopeDC, SourceLoc(), + UnqualifiedLookupFlags::ExcludeMacroExpansions + }; + + auto lookup = evaluateOrDefault( + ctx.evaluator, UnqualifiedLookupRequest{descriptor}, {}); + for (const auto &found : lookup.allResults()) { + if (auto macro = dyn_cast(found.getValueDecl())) { + auto candidateRoles = macro->getMacroRoles(); + if ((candidateRoles && roles.contains(candidateRoles)) || + // FIXME: `externalMacro` should have all roles. + macro->getBaseIdentifier().str() == "externalMacro") { + choices.push_back(macro); + } + } + } + return choices; +} + +bool +namelookup::isInMacroArgument(SourceFile *sourceFile, SourceLoc loc) { + bool inMacroArgument = false; + + ASTScope::lookupEnclosingMacroScope( + sourceFile, loc, + [&](auto potentialMacro) -> bool { + UnresolvedMacroReference macro(potentialMacro); + + if (macro.getFreestanding()) { + inMacroArgument = true; + } else if (auto *attr = macro.getAttr()) { + auto *moduleScope = sourceFile->getModuleScopeContext(); + auto results = lookupMacros(moduleScope, macro.getMacroName(), + getAttachedMacroRoles()); + inMacroArgument = !results.empty(); + } + + return inMacroArgument; + }); + + return inMacroArgument; +} + /// Call the given function body with each macro declaration and its associated /// role attribute for the given role. /// @@ -1851,10 +1905,10 @@ maybeFilterOutUnwantedDecls(TinyPtrVector decls, } TinyPtrVector -NominalTypeDecl::lookupDirect(DeclName name, +NominalTypeDecl::lookupDirect(DeclName name, SourceLoc loc, OptionSet flags) { return evaluateOrDefault(getASTContext().evaluator, - DirectLookupRequest({this, name, flags}), {}); + DirectLookupRequest({this, name, flags}, loc), {}); } TinyPtrVector @@ -2195,6 +2249,7 @@ void namelookup::tryExtractDirectlyReferencedNominalTypes( bool DeclContext::lookupQualified(Type type, DeclNameRef member, + SourceLoc loc, NLOptions options, SmallVectorImpl &decls) const { using namespace namelookup; @@ -2209,14 +2264,16 @@ bool DeclContext::lookupQualified(Type type, // Handle lookup in a module. if (auto moduleTy = type->getAs()) - return lookupQualified(moduleTy->getModule(), member, options, decls); + return lookupQualified(moduleTy->getModule(), member, + loc, options, decls); // Figure out which nominal types we will look into. SmallVector nominalTypesToLookInto; namelookup::extractDirectlyReferencedNominalTypes(type, nominalTypesToLookInto); - return lookupQualified(nominalTypesToLookInto, member, options, decls); + return lookupQualified(nominalTypesToLookInto, member, + loc, options, decls); } static void installPropertyWrapperMembersIfNeeded(NominalTypeDecl *target, @@ -2251,11 +2308,11 @@ static void installPropertyWrapperMembersIfNeeded(NominalTypeDecl *target, bool DeclContext::lookupQualified(ArrayRef typeDecls, DeclNameRef member, - NLOptions options, + SourceLoc loc, NLOptions options, SmallVectorImpl &decls) const { assert(decls.empty() && "additive lookup not supported"); QualifiedLookupRequest req{this, {typeDecls.begin(), typeDecls.end()}, - member, options}; + member, loc, options}; decls = evaluateOrDefault(getASTContext().evaluator, req, {}); return !decls.empty(); } @@ -2309,7 +2366,11 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC, flags |= NominalTypeDecl::LookupDirectFlags::IncludeAttrImplements; if (options & NL_ExcludeMacroExpansions) flags |= NominalTypeDecl::LookupDirectFlags::ExcludeMacroExpansions; - for (auto decl : current->lookupDirect(member.getFullName(), flags)) { + + // Note that the source loc argument doesn't matter, because excluding + // macro expansions is already propagated through the lookup flags above. + for (auto decl : current->lookupDirect(member.getFullName(), + SourceLoc(), flags)) { // If we're performing a type lookup, don't even attempt to validate // the decl if its not a type. if ((options & NL_OnlyTypes) && !isa(decl)) @@ -2383,10 +2444,10 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC, } bool DeclContext::lookupQualified(ModuleDecl *module, DeclNameRef member, - NLOptions options, + SourceLoc loc, NLOptions options, SmallVectorImpl &decls) const { assert(decls.empty() && "additive lookup not supported"); - ModuleQualifiedLookupRequest req{this, module, member, options}; + ModuleQualifiedLookupRequest req{this, module, member, loc, options}; decls = evaluateOrDefault(getASTContext().evaluator, req, {}); return !decls.empty(); } @@ -2404,7 +2465,7 @@ ModuleQualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC, auto topLevelScope = DC->getModuleScopeContext(); if (module == topLevelScope->getParentModule()) { lookupInModule(module, member.getFullName(), decls, NLKind::QualifiedLookup, - kind, topLevelScope, options); + kind, topLevelScope, SourceLoc(), options); } else { // Note: This is a lookup into another module. Unless we're compiling // multiple modules at once, or if the other module re-exports this one, @@ -2421,7 +2482,7 @@ ModuleQualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC, })) { lookupInModule(module, member.getFullName(), decls, NLKind::QualifiedLookup, kind, topLevelScope, - options); + SourceLoc(), options); } } @@ -2613,6 +2674,20 @@ directReferencesForUnqualifiedTypeLookup(DeclNameRef name, SourceLoc loc, DeclContext *dc, LookupOuterResults lookupOuter, bool allowUsableFromInline=false) { + UnqualifiedLookupOptions options = + UnqualifiedLookupFlags::TypeLookup | + UnqualifiedLookupFlags::AllowProtocolMembers; + if (lookupOuter == LookupOuterResults::Included) + options |= UnqualifiedLookupFlags::IncludeOuterResults; + + if (allowUsableFromInline) + options |= UnqualifiedLookupFlags::IncludeUsableFromInline; + + // Manually exclude macro expansions here since the source location + // is overridden below. + if (namelookup::isInMacroArgument(dc->getParentSourceFile(), loc)) + options |= UnqualifiedLookupFlags::ExcludeMacroExpansions; + // In a protocol or protocol extension, the 'where' clause can refer to // associated types without 'Self' qualification: // @@ -2640,15 +2715,6 @@ directReferencesForUnqualifiedTypeLookup(DeclNameRef name, DirectlyReferencedTypeDecls results; - UnqualifiedLookupOptions options = - UnqualifiedLookupFlags::TypeLookup | - UnqualifiedLookupFlags::AllowProtocolMembers; - if (lookupOuter == LookupOuterResults::Included) - options |= UnqualifiedLookupFlags::IncludeOuterResults; - - if (allowUsableFromInline) - options |= UnqualifiedLookupFlags::IncludeUsableFromInline; - auto &ctx = dc->getASTContext(); auto descriptor = UnqualifiedLookupDescriptor(name, dc, loc, options); auto lookup = evaluateOrDefault(ctx.evaluator, @@ -2679,6 +2745,7 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator, ArrayRef baseTypes, DeclNameRef name, DeclContext *dc, + SourceLoc loc, bool allowUsableFromInline=false) { DirectlyReferencedTypeDecls result; auto addResults = [&result](ArrayRef found){ @@ -2705,7 +2772,7 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator, resolveTypeDeclsToNominal(ctx.evaluator, ctx, baseTypes, moduleDecls, anyObject); - dc->lookupQualified(nominalTypeDecls, name, options, members); + dc->lookupQualified(nominalTypeDecls, name, loc, options, members); // Search all of the modules. for (auto module : moduleDecls) { @@ -2713,7 +2780,7 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator, innerOptions &= ~NL_RemoveOverridden; innerOptions &= ~NL_RemoveNonVisible; SmallVector moduleMembers; - dc->lookupQualified(module, name, innerOptions, moduleMembers); + dc->lookupQualified(module, name, loc, innerOptions, moduleMembers); members.append(moduleMembers.begin(), moduleMembers.end()); } @@ -2765,6 +2832,7 @@ directReferencesForDeclRefTypeRepr(Evaluator &evaluator, ASTContext &ctx, current = directReferencesForQualifiedTypeLookup(evaluator, ctx, current, component->getNameRef(), dc, + component->getLoc(), allowUsableFromInline); if (current.empty()) return current; @@ -3552,7 +3620,8 @@ bool IsCallAsFunctionNominalRequest::evaluate(Evaluator &evaluator, // member access. SmallVector results; auto opts = NL_QualifiedDefault | NL_ProtocolMembers | NL_IgnoreAccessControl; - dc->lookupQualified(decl, DeclNameRef(ctx.Id_callAsFunction), opts, results); + dc->lookupQualified(decl, DeclNameRef(ctx.Id_callAsFunction), + decl->getLoc(), opts, results); return llvm::any_of(results, [](ValueDecl *decl) -> bool { if (auto *fd = dyn_cast(decl)) diff --git a/lib/AST/NameLookupRequests.cpp b/lib/AST/NameLookupRequests.cpp index 617db015e9040..33b8d86e4a6f2 100644 --- a/lib/AST/NameLookupRequests.cpp +++ b/lib/AST/NameLookupRequests.cpp @@ -519,24 +519,14 @@ swift::extractNearestSourceLoc(CustomRefCountingOperationDescriptor desc) { // macros, because doing so trivially creates a cyclic dependency amongst the // macro expansions that will be detected by the request-evaluator. // -// Our lookup requests don't always have enough information to answer the -// question "is this part of an argument to a macro?", so we do a much simpler, -// more efficient, and not-entirely-sound hack based on the request-evaluator. -// Specifically, if we are in the process of resolving a macro (which is -// determined by checking for the presence of a `ResolveMacroRequest` in the -// request-evaluator stack), then we adjust the options used for the name -// lookup request we are forming to exclude macro expansions. The evaluation -// of that request will then avoid expanding any macros, and not produce any -// results that involve entries in already-expanded macros. By adjusting the -// request itself, we still distinguish between requests that can and cannot -// look into macro expansions, so it doesn't break caching for those immediate -// requests. -// -// Over time, we should seek to replace this heuristic with a location-based -// check, where we use ASTScope to determine whether we are inside a macro -// argument. This existing check might still be useful because it's going to -// be faster than a location-based query, but the location-based query can be -// fully correct. +// We use source locations to answer the question "is this part of an argument +// to a macro?" through `namelookup::isInMacroArgument`. If the answer is yes, +// then we adjust the options used for the name lookup request we are forming +// to exclude macro expansions. The evaluation of that request will then avoid +// expanding any macros, and not produce any results that involve entries in +// already-expanded macros. By adjusting the request itself, we still +// distinguish between requests that can and cannot look into macro expansions, +// so it doesn't break caching for those immediate requests. /// Exclude macros in the unqualified lookup descriptor if we need to. static UnqualifiedLookupDescriptor excludeMacrosIfNeeded( @@ -545,8 +535,10 @@ static UnqualifiedLookupDescriptor excludeMacrosIfNeeded( UnqualifiedLookupFlags::ExcludeMacroExpansions)) return descriptor; - auto &evaluator = descriptor.DC->getASTContext().evaluator; - if (!evaluator.hasActiveResolveMacroRequest()) + auto isInMacroArgument = namelookup::isInMacroArgument( + descriptor.DC->getParentSourceFile(), descriptor.Loc); + + if (!isInMacroArgument) return descriptor; descriptor.Options |= UnqualifiedLookupFlags::ExcludeMacroExpansions; @@ -555,13 +547,15 @@ static UnqualifiedLookupDescriptor excludeMacrosIfNeeded( /// Exclude macros in the direct lookup descriptor if we need to. static DirectLookupDescriptor excludeMacrosIfNeeded( - DirectLookupDescriptor descriptor) { + DirectLookupDescriptor descriptor, SourceLoc loc) { if (descriptor.Options.contains( NominalTypeDecl::LookupDirectFlags::ExcludeMacroExpansions)) return descriptor; - auto &evaluator = descriptor.DC->getASTContext().evaluator; - if (!evaluator.hasActiveResolveMacroRequest()) + auto isInMacroArgument = namelookup::isInMacroArgument( + descriptor.DC->getParentSourceFile(), loc); + + if (!isInMacroArgument) return descriptor; descriptor.Options |= @@ -572,12 +566,15 @@ static DirectLookupDescriptor excludeMacrosIfNeeded( /// Exclude macros in the name lookup options if we need to. static NLOptions -excludeMacrosIfNeeded(const DeclContext *dc, NLOptions options) { +excludeMacrosIfNeeded(const DeclContext *dc, SourceLoc loc, + NLOptions options) { if (options & NL_ExcludeMacroExpansions) return options; - auto &evaluator = dc->getASTContext().evaluator; - if (!evaluator.hasActiveResolveMacroRequest()) + auto isInMacroArgument = namelookup::isInMacroArgument( + dc->getParentSourceFile(), loc); + + if (!isInMacroArgument) return options; return options | NL_ExcludeMacroExpansions; @@ -591,25 +588,27 @@ LookupInModuleRequest::LookupInModuleRequest( const DeclContext *moduleOrFile, DeclName name, NLKind lookupKind, namelookup::ResolutionKind resolutionKind, const DeclContext *moduleScopeContext, - NLOptions options + SourceLoc loc, NLOptions options ) : SimpleRequest(moduleOrFile, name, lookupKind, resolutionKind, moduleScopeContext, - excludeMacrosIfNeeded(moduleOrFile, options)) { } + excludeMacrosIfNeeded(moduleOrFile, loc, options)) { } ModuleQualifiedLookupRequest::ModuleQualifiedLookupRequest( const DeclContext *dc, ModuleDecl *module, DeclNameRef name, - NLOptions options - ) : SimpleRequest(dc, module, name, excludeMacrosIfNeeded(dc, options)) { } + SourceLoc loc, NLOptions options + ) : SimpleRequest(dc, module, name, + excludeMacrosIfNeeded(dc, loc, options)) { } QualifiedLookupRequest::QualifiedLookupRequest( const DeclContext *dc, SmallVector decls, - DeclNameRef name, NLOptions options + DeclNameRef name, + SourceLoc loc, NLOptions options ) : SimpleRequest(dc, std::move(decls), name, - excludeMacrosIfNeeded(dc, options)) { } + excludeMacrosIfNeeded(dc, loc, options)) { } -DirectLookupRequest::DirectLookupRequest(DirectLookupDescriptor descriptor) - : SimpleRequest(excludeMacrosIfNeeded(descriptor)) { } +DirectLookupRequest::DirectLookupRequest(DirectLookupDescriptor descriptor, SourceLoc loc) + : SimpleRequest(excludeMacrosIfNeeded(descriptor, loc)) { } // Implement the clang importer type zone. #define SWIFT_TYPEID_ZONE ClangImporter diff --git a/lib/AST/RequirementMachine/NameLookup.cpp b/lib/AST/RequirementMachine/NameLookup.cpp index ddb218353a656..6a9e83421f37e 100644 --- a/lib/AST/RequirementMachine/NameLookup.cpp +++ b/lib/AST/RequirementMachine/NameLookup.cpp @@ -48,7 +48,7 @@ swift::rewriting::lookupConcreteNestedType( SmallVectorImpl &concreteDecls) { SmallVector foundMembers; decl->getParentModule()->lookupQualified( - decl, DeclNameRef(name), + decl, DeclNameRef(name), decl->getLoc(), NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers, foundMembers); for (auto member : foundMembers) diff --git a/lib/AST/UnqualifiedLookup.cpp b/lib/AST/UnqualifiedLookup.cpp index b48b4abcadc15..6651bbea3322a 100644 --- a/lib/AST/UnqualifiedLookup.cpp +++ b/lib/AST/UnqualifiedLookup.cpp @@ -333,7 +333,8 @@ void UnqualifiedLookupFactory::ResultFinderForTypeContext::findResults( return; SmallVector Lookup; - contextForLookup->lookupQualified(selfBounds, Name, baseNLOptions, Lookup); + contextForLookup->lookupQualified(selfBounds, Name, factory->Loc, + baseNLOptions, Lookup); for (auto Result : Lookup) { auto baseDC = const_cast(whereValueIsMember(Result)); auto baseDecl = getBaseDeclForResult(baseDC); @@ -531,7 +532,8 @@ void UnqualifiedLookupFactory::addImportedResults(const DeclContext *const dc) { if (options.contains(Flags::ExcludeMacroExpansions)) nlOptions |= NL_ExcludeMacroExpansions; lookupInModule(dc, Name.getFullName(), CurModuleResults, - NLKind::UnqualifiedLookup, resolutionKind, dc, nlOptions); + NLKind::UnqualifiedLookup, resolutionKind, dc, + Loc, nlOptions); // Always perform name shadowing for type lookup. if (options.contains(Flags::TypeLookup)) { diff --git a/lib/ClangImporter/ClangDerivedConformances.cpp b/lib/ClangImporter/ClangDerivedConformances.cpp index 89bd5d8ddd66d..59a7a60410aaa 100644 --- a/lib/ClangImporter/ClangDerivedConformances.cpp +++ b/lib/ClangImporter/ClangDerivedConformances.cpp @@ -586,10 +586,33 @@ void swift::conformToCxxSetIfNeeded(ClangImporter::Implementation &impl, if (!valueType || !sizeType) return; + auto insertId = ctx.getIdentifier("__insertUnsafe"); + auto inserts = lookupDirectWithoutExtensions(decl, insertId); + FuncDecl *insert = nullptr; + for (auto candidate : inserts) { + if (auto candidateMethod = dyn_cast(candidate)) { + if (!candidateMethod->hasParameterList()) + continue; + auto params = candidateMethod->getParameters(); + if (params->size() != 1) + continue; + auto param = params->front(); + if (param->getType()->getCanonicalType() != + valueType->getUnderlyingType()->getCanonicalType()) + continue; + insert = candidateMethod; + break; + } + } + if (!insert) + return; + impl.addSynthesizedTypealias(decl, ctx.Id_Element, valueType->getUnderlyingType()); impl.addSynthesizedTypealias(decl, ctx.getIdentifier("Size"), sizeType->getUnderlyingType()); + impl.addSynthesizedTypealias(decl, ctx.getIdentifier("InsertionResult"), + insert->getResultInterfaceType()); impl.addSynthesizedProtocolAttrs(decl, {KnownProtocolKind::CxxSet}); } diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 86ed63dbe3ba8..8dacf49cfd5a2 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -708,6 +708,15 @@ importer::getNormalInvocationArguments( invocationArgStrs.push_back((llvm::Twine(searchPathOpts.RuntimeResourcePath) + llvm::sys::path::get_separator() + "apinotes").str()); + + if (!importerOpts.CASPath.empty()) { + invocationArgStrs.push_back("-Xclang"); + invocationArgStrs.push_back("-fcas-path"); + invocationArgStrs.push_back("-Xclang"); + invocationArgStrs.push_back(importerOpts.CASPath); + invocationArgStrs.push_back("-Xclang"); + invocationArgStrs.push_back("-fno-pch-timestamp"); + } } static void @@ -1721,7 +1730,8 @@ ClangImporter::cloneCompilerInstanceForPrecompiling() { auto &FrontendOpts = invocation->getFrontendOpts(); FrontendOpts.DisableFree = false; - FrontendOpts.Inputs.clear(); + if (FrontendOpts.CASIncludeTreeID.empty()) + FrontendOpts.Inputs.clear(); auto clonedInstance = std::make_unique( Impl.Instance->getPCHContainerOperations(), @@ -1752,7 +1762,8 @@ bool ClangImporter::emitBridgingPCH( auto inputFile = clang::FrontendInputFile(headerPath, language); auto &FrontendOpts = invocation.getFrontendOpts(); - FrontendOpts.Inputs = {inputFile}; + if (invocation.getFrontendOpts().CASIncludeTreeID.empty()) + FrontendOpts.Inputs = {inputFile}; FrontendOpts.OutputFile = outputPCHPath.str(); FrontendOpts.ProgramAction = clang::frontend::GeneratePCH; @@ -1784,7 +1795,8 @@ bool ClangImporter::runPreprocessor( auto inputFile = clang::FrontendInputFile(inputPath, language); auto &FrontendOpts = invocation.getFrontendOpts(); - FrontendOpts.Inputs = {inputFile}; + if (invocation.getFrontendOpts().CASIncludeTreeID.empty()) + FrontendOpts.Inputs = {inputFile}; FrontendOpts.OutputFile = outputPath.str(); FrontendOpts.ProgramAction = clang::frontend::PrintPreprocessedInput; @@ -1807,11 +1819,13 @@ bool ClangImporter::emitPrecompiledModule( auto language = getLanguageFromOptions(LangOpts); auto &FrontendOpts = invocation.getFrontendOpts(); - auto inputFile = clang::FrontendInputFile( - moduleMapPath, clang::InputKind( - language, clang::InputKind::ModuleMap, false), - FrontendOpts.IsSystemModule); - FrontendOpts.Inputs = {inputFile}; + if (invocation.getFrontendOpts().CASIncludeTreeID.empty()) { + auto inputFile = clang::FrontendInputFile( + moduleMapPath, + clang::InputKind(language, clang::InputKind::ModuleMap, false), + FrontendOpts.IsSystemModule); + FrontendOpts.Inputs = {inputFile}; + } FrontendOpts.OriginalModuleMap = moduleMapPath.str(); FrontendOpts.OutputFile = outputPath.str(); FrontendOpts.ProgramAction = clang::frontend::GenerateModule; @@ -1839,7 +1853,8 @@ bool ClangImporter::dumpPrecompiledModule( clang::Language::Unknown, clang::InputKind::Precompiled, false)); auto &FrontendOpts = invocation.getFrontendOpts(); - FrontendOpts.Inputs = {inputFile}; + if (invocation.getFrontendOpts().CASIncludeTreeID.empty()) + FrontendOpts.Inputs = {inputFile}; FrontendOpts.OutputFile = outputPath.str(); auto action = std::make_unique(); diff --git a/lib/ClangImporter/ClangModuleDependencyScanner.cpp b/lib/ClangImporter/ClangModuleDependencyScanner.cpp index 4633a050c18d5..0855acffb882a 100644 --- a/lib/ClangImporter/ClangModuleDependencyScanner.cpp +++ b/lib/ClangImporter/ClangModuleDependencyScanner.cpp @@ -18,11 +18,17 @@ #include "swift/AST/ModuleDependencies.h" #include "swift/Basic/SourceManager.h" #include "swift/ClangImporter/ClangImporter.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/FrontendOptions.h" #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Signals.h" #include "llvm/Support/Path.h" +#include "llvm/Support/StringSaver.h" using namespace swift; @@ -175,18 +181,86 @@ void ClangImporter::recordModuleDependencies( // Swift frontend option for input file path (Foo.modulemap). swiftArgs.push_back(clangModuleDep.ClangModuleMapFile); + // Handle VFSOverlay. + if (!ctx.SearchPathOpts.VFSOverlayFiles.empty()) { + for (auto &overlay : ctx.SearchPathOpts.VFSOverlayFiles) { + swiftArgs.push_back("-vfsoverlay"); + swiftArgs.push_back(overlay); + } + } + // Add args reported by the scanner. - llvm::for_each(clangModuleDep.BuildArguments, addClangArg); + + // Round-trip clang args to canonicalize and clear the options that swift + // compiler doesn't need. + clang::CompilerInvocation depsInvocation; + clang::DiagnosticsEngine clangDiags(new clang::DiagnosticIDs(), + new clang::DiagnosticOptions(), + new clang::IgnoringDiagConsumer()); + + llvm::SmallVector clangArgs; + llvm::for_each(clangModuleDep.BuildArguments, [&](const std::string &Arg) { + clangArgs.push_back(Arg.c_str()); + }); + + bool success = clang::CompilerInvocation::CreateFromArgs( + depsInvocation, clangArgs, clangDiags); + (void)success; + assert(success && "clang option from dep scanner round trip failed"); + + // Clear the cache key for module. The module key is computed from clang + // invocation, not swift invocation. + depsInvocation.getFrontendOpts().ModuleCacheKeys.clear(); + + // FIXME: workaround for rdar://105684525: find the -ivfsoverlay option + // from clang scanner and pass to swift. + for (auto overlay : depsInvocation.getHeaderSearchOpts().VFSOverlayFiles) { + if (llvm::is_contained(ctx.SearchPathOpts.VFSOverlayFiles, overlay)) + continue; + swiftArgs.push_back("-vfsoverlay"); + swiftArgs.push_back(overlay); + } + + llvm::BumpPtrAllocator allocator; + llvm::StringSaver saver(allocator); + clangArgs.clear(); + depsInvocation.generateCC1CommandLine( + clangArgs, + [&saver](const llvm::Twine &T) { return saver.save(T).data(); }); + + llvm::for_each(clangArgs, addClangArg); + + // CASFileSystemRootID. + std::string RootID = clangModuleDep.CASFileSystemRootID + ? clangModuleDep.CASFileSystemRootID->toString() + : ""; + + std::string IncludeTree = + clangModuleDep.IncludeTreeID ? *clangModuleDep.IncludeTreeID : ""; + + if (!RootID.empty() || !IncludeTree.empty()) { + swiftArgs.push_back("-enable-cas"); + swiftArgs.push_back("-cas-path"); + swiftArgs.push_back(ctx.ClangImporterOpts.CASPath); + } + + if (!RootID.empty()) { + swiftArgs.push_back("-cas-fs"); + swiftArgs.push_back(RootID); + } + + if (!IncludeTree.empty()) { + swiftArgs.push_back("-clang-include-tree"); + swiftArgs.push_back("-clang-include-tree-root"); + swiftArgs.push_back(IncludeTree); + } // Module-level dependencies. llvm::StringSet<> alreadyAddedModules; auto dependencies = ModuleDependencyInfo::forClangModule( - pcmPath, - clangModuleDep.ClangModuleMapFile, - clangModuleDep.ID.ContextHash, - swiftArgs, - fileDeps, - capturedPCMArgs); + pcmPath, clangModuleDep.ClangModuleMapFile, + clangModuleDep.ID.ContextHash, swiftArgs, fileDeps, capturedPCMArgs, + RootID, IncludeTree, /*module-cache-key*/ ""); for (const auto &moduleName : clangModuleDep.ClangModuleDeps) { dependencies.addModuleImport(moduleName.ModuleName, &alreadyAddedModules); // It is safe to assume that all dependencies of a Clang module are Clang modules. @@ -200,6 +274,85 @@ void ClangImporter::recordModuleDependencies( } } +void ClangImporter::recordBridgingHeaderOptions( + ModuleDependencyInfo &MDI, + const clang::tooling::dependencies::TranslationUnitDeps &deps) { + auto &ctx = Impl.SwiftContext; + + std::vector swiftArgs; + auto addClangArg = [&](Twine arg) { + swiftArgs.push_back("-Xcc"); + swiftArgs.push_back(arg.str()); + }; + + // We are using Swift frontend mode. + swiftArgs.push_back("-frontend"); + + // Swift frontend action: -emit-pcm + swiftArgs.push_back("-emit-pch"); + + // We pass the entire argument list via -Xcc, so the invocation should + // use extra clang options alone. + swiftArgs.push_back("-only-use-extra-clang-opts"); + + // Ensure that the resulting PCM build invocation uses Clang frontend + // directly + swiftArgs.push_back("-direct-clang-cc1-module-build"); + + // Add args reported by the scanner. + + // Round-trip clang args to canonicalize and clear the options that swift + // compiler doesn't need. + clang::CompilerInvocation depsInvocation; + clang::DiagnosticsEngine clangDiags(new clang::DiagnosticIDs(), + new clang::DiagnosticOptions(), + new clang::IgnoringDiagConsumer()); + + llvm::SmallVector clangArgs; + llvm::for_each(deps.Commands[0].Arguments, [&](const std::string &Arg) { + clangArgs.push_back(Arg.c_str()); + }); + + bool success = clang::CompilerInvocation::CreateFromArgs( + depsInvocation, clangArgs, clangDiags); + (void)success; + assert(success && "clang option from dep scanner round trip failed"); + + // Clear the cache key for module. The module key is computed from clang + // invocation, not swift invocation. + depsInvocation.getFrontendOpts().ProgramAction = + clang::frontend::ActionKind::GeneratePCH; + depsInvocation.getFrontendOpts().ModuleCacheKeys.clear(); + depsInvocation.getFrontendOpts().OutputFile = ""; + + llvm::BumpPtrAllocator allocator; + llvm::StringSaver saver(allocator); + clangArgs.clear(); + depsInvocation.generateCC1CommandLine( + clangArgs, + [&saver](const llvm::Twine &T) { return saver.save(T).data(); }); + + llvm::for_each(clangArgs, addClangArg); + + if (!ctx.ClangImporterOpts.CASPath.empty()) { + swiftArgs.push_back("-enable-cas"); + swiftArgs.push_back("-cas-path"); + swiftArgs.push_back(ctx.ClangImporterOpts.CASPath); + } + + if (auto Tree = deps.IncludeTreeID) { + swiftArgs.push_back("-clang-include-tree"); + swiftArgs.push_back("-clang-include-tree-root"); + swiftArgs.push_back(*Tree); + } + if (auto CASFS = deps.CASFileSystemRootID) { + swiftArgs.push_back("-cas-fs"); + swiftArgs.push_back(*CASFS); + } + + MDI.updateBridgingHeaderCommandLine(swiftArgs); +} + // The Swift compiler does not have a concept of a working directory. // It is instead handled by the Swift driver by resolving relative paths // according to the driver's notion of a working directory. On the other hand, @@ -337,6 +490,11 @@ bool ClangImporter::addBridgingHeaderDependencies( alreadyAddedModules); } + if (auto TreeID = clangModuleDependencies->IncludeTreeID) + targetModule.addBridgingHeaderIncludeTree(*TreeID); + + recordBridgingHeaderOptions(targetModule, *clangModuleDependencies); + // Update the cache with the new information for the module. cache.updateDependency({moduleName.str(), moduleKind}, targetModule); diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index d7d3527a6c7a0..48ef2808303fd 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -2635,30 +2635,38 @@ namespace { } clang::CXXConstructorDecl *copyCtor = nullptr; clang::CXXConstructorDecl *moveCtor = nullptr; + clang::CXXConstructorDecl *defaultCtor = nullptr; if (decl->needsImplicitCopyConstructor()) { copyCtor = clangSema.DeclareImplicitCopyConstructor( const_cast(decl)); - } else if (decl->needsImplicitMoveConstructor()) { + } + if (decl->needsImplicitMoveConstructor()) { moveCtor = clangSema.DeclareImplicitMoveConstructor( const_cast(decl)); - } else { - // We may have a defaulted copy constructor that needs to be defined. - // Try to find it. - for (auto methods : decl->methods()) { - if (auto declCtor = dyn_cast(methods)) { - if (declCtor->isDefaulted() && - declCtor->getAccess() == clang::AS_public && - !declCtor->isDeleted() && - // Note: we use "doesThisDeclarationHaveABody" here because - // that's what "DefineImplicitCopyConstructor" checks. - !declCtor->doesThisDeclarationHaveABody()) { - if (declCtor->isCopyConstructor()) { + } + if (decl->needsImplicitDefaultConstructor()) { + defaultCtor = clangSema.DeclareImplicitDefaultConstructor( + const_cast(decl)); + } + // We may have a defaulted copy/move/default constructor that needs to + // be defined. Try to find it. + for (auto methods : decl->methods()) { + if (auto declCtor = dyn_cast(methods)) { + if (declCtor->isDefaulted() && + declCtor->getAccess() == clang::AS_public && + !declCtor->isDeleted() && + // Note: we use "doesThisDeclarationHaveABody" here because + // that's what "DefineImplicitCopyConstructor" checks. + !declCtor->doesThisDeclarationHaveABody()) { + if (declCtor->isCopyConstructor()) { + if (!copyCtor) copyCtor = declCtor; - break; - } else if (declCtor->isMoveConstructor()) { + } else if (declCtor->isMoveConstructor()) { + if (!moveCtor) moveCtor = declCtor; - break; - } + } else if (declCtor->isDefaultConstructor()) { + if (!defaultCtor) + defaultCtor = declCtor; } } } @@ -2671,6 +2679,10 @@ namespace { clangSema.DefineImplicitMoveConstructor(clang::SourceLocation(), moveCtor); } + if (defaultCtor) { + clangSema.DefineImplicitDefaultConstructor(clang::SourceLocation(), + defaultCtor); + } if (decl->needsImplicitDestructor()) { auto dtor = clangSema.DeclareImplicitDestructor( @@ -6532,7 +6544,7 @@ void SwiftDeclConverter::recordObjCOverride(AbstractFunctionDecl *decl) { // Dig out the Objective-C superclass. SmallVector results; superDecl->lookupQualified(superDecl, DeclNameRef(decl->getName()), - NL_QualifiedDefault, + decl->getLoc(), NL_QualifiedDefault, results); for (auto member : results) { if (member->getKind() != decl->getKind() || @@ -6605,7 +6617,7 @@ void SwiftDeclConverter::recordObjCOverride(SubscriptDecl *subscript) { SmallVector lookup; subscript->getModuleContext()->lookupQualified( superDecl, DeclNameRef(subscript->getName()), - NL_QualifiedDefault, lookup); + subscript->getLoc(), NL_QualifiedDefault, lookup); for (auto result : lookup) { auto parentSub = dyn_cast(result); @@ -8292,7 +8304,8 @@ static void finishTypeWitnesses( NL_OnlyTypes | NL_ProtocolMembers); - dc->lookupQualified(nominal, DeclNameRef(assocType->getName()), options, + dc->lookupQualified(nominal, DeclNameRef(assocType->getName()), + nominal->getLoc(), options, lookupResults); for (auto member : lookupResults) { auto typeDecl = cast(member); diff --git a/lib/DependencyScan/DependencyScanningTool.cpp b/lib/DependencyScan/DependencyScanningTool.cpp index 084922efbcf64..6f67370390588 100644 --- a/lib/DependencyScan/DependencyScanningTool.cpp +++ b/lib/DependencyScan/DependencyScanningTool.cpp @@ -236,9 +236,6 @@ DependencyScanningTool::initCompilerInstanceForScan( auto Instance = std::make_unique(); Instance->addDiagnosticConsumer(&CDC); - // Wrap the filesystem with a caching `DependencyScanningWorkerFilesystem` - ScanningService->overlaySharedFilesystemCacheForCompilation(*Instance); - // Basic error checking on the arguments if (CommandArgs.empty()) { Instance->getDiags().diagnose(SourceLoc(), diag::error_no_frontend_args); @@ -280,6 +277,10 @@ DependencyScanningTool::initCompilerInstanceForScan( if (Instance->setup(Invocation, InstanceSetupError)) { return std::make_error_code(std::errc::not_supported); } + + // Setup the caching service after the instance finishes setup. + ScanningService->setupCachingDependencyScanningService(*Instance); + (void)Instance->getMainModule(); return Instance; diff --git a/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp b/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp index 6cf39b6fb96b9..e8c786323e5c7 100644 --- a/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp +++ b/lib/DependencyScan/ModuleDependencyCacheSerialization.cpp @@ -235,17 +235,19 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi llvm::report_fatal_error( "Unexpected SWIFT_TEXTUAL_MODULE_DETAILS_NODE record"); cache.configureForContextHash(getContextHash()); - unsigned outputPathFileID, interfaceFileID, compiledModuleCandidatesArrayID, - buildCommandLineArrayID, extraPCMArgsArrayID, contextHashID, - isFramework, bridgingHeaderFileID, sourceFilesArrayID, - bridgingSourceFilesArrayID, bridgingModuleDependenciesArrayID, - overlayDependencyIDArrayID; + unsigned outputPathFileID, interfaceFileID, + compiledModuleCandidatesArrayID, buildCommandLineArrayID, + extraPCMArgsArrayID, contextHashID, isFramework, bridgingHeaderFileID, + sourceFilesArrayID, bridgingSourceFilesArrayID, + bridgingModuleDependenciesArrayID, overlayDependencyIDArrayID, + CASFileSystemRootID, bridgingHeaderIncludeTreeID, moduleCacheKeyID; SwiftInterfaceModuleDetailsLayout::readRecord( - Scratch, outputPathFileID, interfaceFileID, compiledModuleCandidatesArrayID, - buildCommandLineArrayID, extraPCMArgsArrayID, contextHashID, - isFramework, bridgingHeaderFileID, sourceFilesArrayID, - bridgingSourceFilesArrayID, bridgingModuleDependenciesArrayID, - overlayDependencyIDArrayID); + Scratch, outputPathFileID, interfaceFileID, + compiledModuleCandidatesArrayID, buildCommandLineArrayID, + extraPCMArgsArrayID, contextHashID, isFramework, bridgingHeaderFileID, + sourceFilesArrayID, bridgingSourceFilesArrayID, + bridgingModuleDependenciesArrayID, overlayDependencyIDArrayID, + CASFileSystemRootID, bridgingHeaderIncludeTreeID, moduleCacheKeyID); auto outputModulePath = getIdentifier(outputPathFileID); if (!outputModulePath) @@ -278,11 +280,18 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi for (auto &arg : *extraPCMArgs) extraPCMRefs.push_back(arg); + auto rootFileSystemID = getIdentifier(CASFileSystemRootID); + if (!rootFileSystemID) + llvm::report_fatal_error("Bad CASFileSystem RootID"); + auto moduleCacheKey = getIdentifier(moduleCacheKeyID); + if (!moduleCacheKeyID) + llvm::report_fatal_error("Bad moduleCacheKey"); + // Form the dependencies storage object auto moduleDep = ModuleDependencyInfo::forSwiftInterfaceModule( - outputModulePath.value(), - optionalSwiftInterfaceFile.value(), *compiledModuleCandidates, - buildCommandRefs, extraPCMRefs, *contextHash, isFramework); + outputModulePath.value(), optionalSwiftInterfaceFile.value(), + *compiledModuleCandidates, buildCommandRefs, extraPCMRefs, + *contextHash, isFramework, *rootFileSystemID, *moduleCacheKey); // Add imports of this module for (const auto &moduleName : *currentModuleImports) @@ -328,6 +337,14 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi llvm::report_fatal_error("Bad overlay dependencies: no qualified dependencies"); moduleDep.setOverlayDependencies(overlayModuleDependencyIDs.value()); + // Add bridging header include tree + auto bridgingHeaderIncludeTree = + getIdentifier(bridgingHeaderIncludeTreeID); + if (!bridgingHeaderIncludeTree) + llvm::report_fatal_error("Bad bridging header include tree"); + if (!bridgingHeaderIncludeTree->empty()) + moduleDep.addBridgingHeaderIncludeTree(*bridgingHeaderIncludeTree); + cache.recordDependency(currentModuleName, std::move(moduleDep), getContextHash()); hasCurrentModule = false; @@ -345,11 +362,15 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi "SWIFT_SOURCE_MODULE_DETAILS_NODE record"); unsigned extraPCMArgsArrayID, bridgingHeaderFileID, sourceFilesArrayID, bridgingSourceFilesArrayID, bridgingModuleDependenciesArrayID, - overlayDependencyIDArrayID; + overlayDependencyIDArrayID, CASFileSystemRootID, + bridgingHeaderIncludeTreeID, buildCommandLineArrayID, + bridgingHeaderBuildCommandLineArrayID; SwiftSourceModuleDetailsLayout::readRecord( Scratch, extraPCMArgsArrayID, bridgingHeaderFileID, sourceFilesArrayID, bridgingSourceFilesArrayID, - bridgingModuleDependenciesArrayID, overlayDependencyIDArrayID); + bridgingModuleDependenciesArrayID, overlayDependencyIDArrayID, + CASFileSystemRootID, bridgingHeaderIncludeTreeID, + buildCommandLineArrayID, bridgingHeaderBuildCommandLineArrayID); auto extraPCMArgs = getStringArray(extraPCMArgsArrayID); if (!extraPCMArgs) @@ -358,8 +379,27 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi for (auto &arg : *extraPCMArgs) extraPCMRefs.push_back(arg); + auto rootFileSystemID = getIdentifier(CASFileSystemRootID); + if (!rootFileSystemID) + llvm::report_fatal_error("Bad CASFileSystem RootID"); + auto commandLine = getStringArray(buildCommandLineArrayID); + if (!commandLine) + llvm::report_fatal_error("Bad command line"); + std::vector buildCommandRefs; + for (auto &arg : *commandLine) + buildCommandRefs.push_back(arg); + std::vector bridgingHeaderBuildCommandRefs; + auto bridgingHeaderCommandLine = + getStringArray(bridgingHeaderBuildCommandLineArrayID); + if (!bridgingHeaderCommandLine) + llvm::report_fatal_error("Bad bridging header command line"); + for (auto &arg : *bridgingHeaderCommandLine) + bridgingHeaderBuildCommandRefs.push_back(arg); + // Form the dependencies storage object - auto moduleDep = ModuleDependencyInfo::forSwiftSourceModule(extraPCMRefs); + auto moduleDep = ModuleDependencyInfo::forSwiftSourceModule( + *rootFileSystemID, buildCommandRefs, bridgingHeaderBuildCommandRefs, + extraPCMRefs); // Add dependencies of this module for (const auto &moduleName : *currentModuleImports) @@ -402,6 +442,14 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi llvm::report_fatal_error("Bad overlay dependencies: no qualified dependencies"); moduleDep.setOverlayDependencies(overlayModuleDependencyIDs.value()); + // Add bridging header include tree + auto bridgingHeaderIncludeTree = + getIdentifier(bridgingHeaderIncludeTreeID); + if (!bridgingHeaderIncludeTree) + llvm::report_fatal_error("Bad bridging header include tree"); + if (!bridgingHeaderIncludeTree->empty()) + moduleDep.addBridgingHeaderIncludeTree(*bridgingHeaderIncludeTree); + cache.recordDependency(currentModuleName, std::move(moduleDep), getContextHash()); hasCurrentModule = false; @@ -414,10 +462,11 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi "Unexpected SWIFT_BINARY_MODULE_DETAILS_NODE record"); cache.configureForContextHash(getContextHash()); unsigned compiledModulePathID, moduleDocPathID, moduleSourceInfoPathID, - isFramework; + headerImportsArrayID, isFramework, moduleCacheKeyID; SwiftBinaryModuleDetailsLayout::readRecord( Scratch, compiledModulePathID, moduleDocPathID, - moduleSourceInfoPathID, isFramework); + moduleSourceInfoPathID, headerImportsArrayID, isFramework, + moduleCacheKeyID); auto compiledModulePath = getIdentifier(compiledModulePathID); if (!compiledModulePath) @@ -428,14 +477,19 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi auto moduleSourceInfoPath = getIdentifier(moduleSourceInfoPathID); if (!moduleSourceInfoPath) llvm::report_fatal_error("Bad module source info path"); + auto moduleCacheKey = getIdentifier(moduleCacheKeyID); + if (!moduleCacheKey) + llvm::report_fatal_error("Bad moduleCacheKey"); + + auto headerImports = getStringArray(headerImportsArrayID); + if (!headerImports) + llvm::report_fatal_error("Bad binary direct dependencies: no header imports"); // Form the dependencies storage object auto moduleDep = ModuleDependencyInfo::forSwiftBinaryModule( - *compiledModulePath, *moduleDocPath, *moduleSourceInfoPath, - isFramework); - // Add dependencies of this module - for (const auto &moduleName : *currentModuleImports) - moduleDep.addModuleImport(moduleName); + *compiledModulePath, *moduleDocPath, *moduleSourceInfoPath, + *currentModuleImports, *headerImports, isFramework, + *moduleCacheKey); cache.recordDependency(currentModuleName, std::move(moduleDep), getContextHash()); @@ -481,11 +535,15 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi llvm::report_fatal_error("Unexpected CLANG_MODULE_DETAILS_NODE record"); cache.configureForContextHash(getContextHash()); unsigned pcmOutputPathID, moduleMapPathID, contextHashID, commandLineArrayID, - fileDependenciesArrayID, capturedPCMArgsArrayID; + fileDependenciesArrayID, capturedPCMArgsArrayID, CASFileSystemRootID, + clangIncludeTreeRootID, moduleCacheKeyID; ClangModuleDetailsLayout::readRecord(Scratch, pcmOutputPathID, moduleMapPathID, contextHashID, commandLineArrayID, fileDependenciesArrayID, - capturedPCMArgsArrayID); + capturedPCMArgsArrayID, + CASFileSystemRootID, + clangIncludeTreeRootID, + moduleCacheKeyID); auto pcmOutputPath = getIdentifier(pcmOutputPathID); if (!pcmOutputPath) llvm::report_fatal_error("Bad pcm output path"); @@ -504,11 +562,21 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi auto capturedPCMArgs = getStringArray(capturedPCMArgsArrayID); if (!capturedPCMArgs) llvm::report_fatal_error("Bad captured PCM Args"); + auto rootFileSystemID = getIdentifier(CASFileSystemRootID); + if (!rootFileSystemID) + llvm::report_fatal_error("Bad CASFileSystem RootID"); + auto clangIncludeTreeRoot = getIdentifier(clangIncludeTreeRootID); + if (!clangIncludeTreeRoot) + llvm::report_fatal_error("Bad clang include tree ID"); + auto moduleCacheKey = getIdentifier(moduleCacheKeyID); + if (!moduleCacheKeyID) + llvm::report_fatal_error("Bad moduleCacheKey"); // Form the dependencies storage object - auto moduleDep = ModuleDependencyInfo::forClangModule(*pcmOutputPath, - *moduleMapPath, *contextHash, *commandLineArgs, *fileDependencies, - *capturedPCMArgs); + auto moduleDep = ModuleDependencyInfo::forClangModule( + *pcmOutputPath, *moduleMapPath, *contextHash, *commandLineArgs, + *fileDependencies, *capturedPCMArgs, *rootFileSystemID, + *clangIncludeTreeRoot, *moduleCacheKey); // Add dependencies of this module for (const auto &moduleName : *currentModuleImports) @@ -639,6 +707,7 @@ bool swift::dependencies::module_dependency_cache_serialization:: enum ModuleIdentifierArrayKind : uint8_t { Empty = 0, DependencyImports, + DependencyHeaders, QualifiedModuleDependencyIDs, CompiledModuleCandidates, BuildCommandLine, @@ -647,6 +716,7 @@ enum ModuleIdentifierArrayKind : uint8_t { BridgingSourceFiles, BridgingModuleDependencies, SwiftOverlayDependencyIDs, + BridgingHeaderBuildCommandLine, NonPathCommandLine, FileDependencies, CapturedPCMArgs, @@ -852,18 +922,23 @@ void ModuleDependenciesCacheSerializer::writeModuleInfo(ModuleDependencyID modul : 0; SwiftInterfaceModuleDetailsLayout::emitRecord( Out, ScratchRecord, AbbrCodes[SwiftInterfaceModuleDetailsLayout::Code], - outputModulePathFileId, - swiftInterfaceFileId, - getArrayID(moduleID, ModuleIdentifierArrayKind::CompiledModuleCandidates), + outputModulePathFileId, swiftInterfaceFileId, + getArrayID(moduleID, + ModuleIdentifierArrayKind::CompiledModuleCandidates), getArrayID(moduleID, ModuleIdentifierArrayKind::BuildCommandLine), getArrayID(moduleID, ModuleIdentifierArrayKind::ExtraPCMArgs), - getIdentifier(swiftTextDeps->contextHash), - swiftTextDeps->isFramework, + getIdentifier(swiftTextDeps->contextHash), swiftTextDeps->isFramework, bridgingHeaderFileId, getArrayID(moduleID, ModuleIdentifierArrayKind::SourceFiles), getArrayID(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles), - getArrayID(moduleID, ModuleIdentifierArrayKind::BridgingModuleDependencies), - getArrayID(moduleID, ModuleIdentifierArrayKind::SwiftOverlayDependencyIDs)); + getArrayID(moduleID, + ModuleIdentifierArrayKind::BridgingModuleDependencies), + getArrayID(moduleID, + ModuleIdentifierArrayKind::SwiftOverlayDependencyIDs), + getIdentifier(swiftTextDeps->textualModuleDetails.CASFileSystemRootID), + getIdentifier(swiftTextDeps->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID), + getIdentifier(swiftTextDeps->moduleCacheKey)); break; } case swift::ModuleDependencyKind::SwiftSource: { @@ -882,8 +957,17 @@ void ModuleDependenciesCacheSerializer::writeModuleInfo(ModuleDependencyID modul bridgingHeaderFileId, getArrayID(moduleID, ModuleIdentifierArrayKind::SourceFiles), getArrayID(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles), - getArrayID(moduleID, ModuleIdentifierArrayKind::BridgingModuleDependencies), - getArrayID(moduleID, ModuleIdentifierArrayKind::SwiftOverlayDependencyIDs)); + getArrayID(moduleID, + ModuleIdentifierArrayKind::BridgingModuleDependencies), + getArrayID(moduleID, + ModuleIdentifierArrayKind::SwiftOverlayDependencyIDs), + getIdentifier( + swiftSourceDeps->textualModuleDetails.CASFileSystemRootID), + getIdentifier(swiftSourceDeps->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID), + getArrayID(moduleID, ModuleIdentifierArrayKind::BuildCommandLine), + getArrayID(moduleID, + ModuleIdentifierArrayKind::BridgingHeaderBuildCommandLine)); break; } case swift::ModuleDependencyKind::SwiftBinary: { @@ -895,7 +979,9 @@ void ModuleDependenciesCacheSerializer::writeModuleInfo(ModuleDependencyID modul getIdentifier(swiftBinDeps->compiledModulePath), getIdentifier(swiftBinDeps->moduleDocPath), getIdentifier(swiftBinDeps->sourceInfoPath), - swiftBinDeps->isFramework); + getArrayID(moduleID, ModuleIdentifierArrayKind::DependencyHeaders), + swiftBinDeps->isFramework, + getIdentifier(swiftBinDeps->moduleCacheKey)); break; } @@ -922,7 +1008,10 @@ void ModuleDependenciesCacheSerializer::writeModuleInfo(ModuleDependencyID modul getIdentifier(clangDeps->contextHash), getArrayID(moduleID, ModuleIdentifierArrayKind::NonPathCommandLine), getArrayID(moduleID, ModuleIdentifierArrayKind::FileDependencies), - getArrayID(moduleID, ModuleIdentifierArrayKind::CapturedPCMArgs)); + getArrayID(moduleID, ModuleIdentifierArrayKind::CapturedPCMArgs), + getIdentifier(clangDeps->CASFileSystemRootID), + getIdentifier(clangDeps->CASClangIncludeTreeRootID), + getIdentifier(clangDeps->moduleCacheKey)); break; } @@ -1035,26 +1124,30 @@ void ModuleDependenciesCacheSerializer::collectStringsAndArrays( addIdentifier(swiftTextDeps->moduleOutputPath); addIdentifier(swiftTextDeps->swiftInterfaceFile); addStringArray(moduleID, - ModuleIdentifierArrayKind::CompiledModuleCandidates, - swiftTextDeps->compiledModuleCandidates); + ModuleIdentifierArrayKind::CompiledModuleCandidates, + swiftTextDeps->compiledModuleCandidates); addStringArray(moduleID, ModuleIdentifierArrayKind::BuildCommandLine, - swiftTextDeps->buildCommandLine); + swiftTextDeps->textualModuleDetails.buildCommandLine); addStringArray(moduleID, ModuleIdentifierArrayKind::ExtraPCMArgs, - swiftTextDeps->textualModuleDetails.extraPCMArgs); + swiftTextDeps->textualModuleDetails.extraPCMArgs); addIdentifier(swiftTextDeps->contextHash); if (swiftTextDeps->textualModuleDetails.bridgingHeaderFile.has_value()) - addIdentifier( - swiftTextDeps->textualModuleDetails.bridgingHeaderFile.value()); + addIdentifier(swiftTextDeps->textualModuleDetails.bridgingHeaderFile + .value()); addStringArray(moduleID, ModuleIdentifierArrayKind::SourceFiles, - std::vector()); + std::vector()); addStringArray(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles, - swiftTextDeps->textualModuleDetails.bridgingSourceFiles); + swiftTextDeps->textualModuleDetails.bridgingSourceFiles); addStringArray( - moduleID, ModuleIdentifierArrayKind::BridgingModuleDependencies, - swiftTextDeps->textualModuleDetails.bridgingModuleDependencies); + moduleID, ModuleIdentifierArrayKind::BridgingModuleDependencies, + swiftTextDeps->textualModuleDetails.bridgingModuleDependencies); addDependencyIDArray( moduleID, ModuleIdentifierArrayKind::SwiftOverlayDependencyIDs, swiftTextDeps->textualModuleDetails.swiftOverlayDependencies); + addIdentifier(swiftTextDeps->textualModuleDetails.CASFileSystemRootID); + addIdentifier(swiftTextDeps->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID); + addIdentifier(swiftTextDeps->moduleCacheKey); break; } case swift::ModuleDependencyKind::SwiftBinary: { @@ -1063,6 +1156,9 @@ void ModuleDependenciesCacheSerializer::collectStringsAndArrays( addIdentifier(swiftBinDeps->compiledModulePath); addIdentifier(swiftBinDeps->moduleDocPath); addIdentifier(swiftBinDeps->sourceInfoPath); + addIdentifier(swiftBinDeps->moduleCacheKey); + addStringArray(moduleID, ModuleIdentifierArrayKind::DependencyHeaders, + swiftBinDeps->preCompiledBridgingHeaderPaths); break; } case swift::ModuleDependencyKind::SwiftPlaceholder: { @@ -1093,6 +1189,14 @@ void ModuleDependenciesCacheSerializer::collectStringsAndArrays( addDependencyIDArray( moduleID, ModuleIdentifierArrayKind::SwiftOverlayDependencyIDs, swiftSourceDeps->textualModuleDetails.swiftOverlayDependencies); + addStringArray( + moduleID, ModuleIdentifierArrayKind::BuildCommandLine, + swiftSourceDeps->textualModuleDetails.buildCommandLine); + addStringArray( + moduleID, ModuleIdentifierArrayKind::BridgingHeaderBuildCommandLine, + swiftSourceDeps->bridgingHeaderBuildCommandLine); + addIdentifier( + swiftSourceDeps->textualModuleDetails.CASFileSystemRootID); break; } case swift::ModuleDependencyKind::Clang: { @@ -1102,11 +1206,14 @@ void ModuleDependenciesCacheSerializer::collectStringsAndArrays( addIdentifier(clangDeps->moduleMapFile); addIdentifier(clangDeps->contextHash); addStringArray(moduleID, ModuleIdentifierArrayKind::NonPathCommandLine, - clangDeps->nonPathCommandLine); + clangDeps->buildCommandLine); addStringArray(moduleID, ModuleIdentifierArrayKind::FileDependencies, clangDeps->fileDependencies); addStringArray(moduleID, ModuleIdentifierArrayKind::CapturedPCMArgs, clangDeps->capturedPCMArgs); + addIdentifier(clangDeps->CASFileSystemRootID); + addIdentifier(clangDeps->CASClangIncludeTreeRootID); + addIdentifier(clangDeps->moduleCacheKey); break; } default: diff --git a/lib/DependencyScan/ScanDependencies.cpp b/lib/DependencyScan/ScanDependencies.cpp index 9d94da4e784dd..396a965d1e4d1 100644 --- a/lib/DependencyScan/ScanDependencies.cpp +++ b/lib/DependencyScan/ScanDependencies.cpp @@ -12,14 +12,12 @@ #include "swift/Basic/PrettyStackTrace.h" -#include "swift/DependencyScan/ScanDependencies.h" -#include "swift/DependencyScan/SerializedModuleDependencyCacheFormat.h" #include "swift/AST/ASTContext.h" #include "swift/AST/Decl.h" #include "swift/AST/DiagnosticEngine.h" +#include "swift/AST/DiagnosticsDriver.h" #include "swift/AST/DiagnosticsFrontend.h" #include "swift/AST/DiagnosticsSema.h" -#include "swift/AST/DiagnosticsDriver.h" #include "swift/AST/FileSystem.h" #include "swift/AST/Module.h" #include "swift/AST/ModuleDependencies.h" @@ -30,28 +28,38 @@ #include "swift/Basic/STLExtras.h" #include "swift/ClangImporter/ClangImporter.h" #include "swift/DependencyScan/DependencyScanImpl.h" +#include "swift/DependencyScan/ScanDependencies.h" +#include "swift/DependencyScan/SerializedModuleDependencyCacheFormat.h" #include "swift/DependencyScan/StringUtils.h" +#include "swift/Frontend/CachingUtils.h" +#include "swift/Frontend/CompileJobCacheKey.h" #include "swift/Frontend/Frontend.h" #include "swift/Frontend/FrontendOptions.h" #include "swift/Frontend/ModuleInterfaceLoader.h" #include "swift/Strings.h" #include "clang/Basic/Module.h" -#include "llvm/ADT/SetVector.h" +#include "clang/Frontend/CompileJobCacheResult.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetOperations.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/CAS/ActionCache.h" +#include "llvm/CAS/CASReference.h" +#include "llvm/CAS/ObjectStore.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/VirtualOutputBackend.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" +#include #include -#include #include -#include +#include using namespace swift; using namespace swift::dependencies; @@ -246,20 +254,63 @@ computeTransitiveClosureOfExplicitDependencies( llvm::set_union(modReachableSet, succReachableSet); } } + // For ease of use down-the-line, remove the node's self from its set of reachable nodes + for (const auto &modID : topologicallySortedModuleList) + result[modID].erase(modID); + return result; } -static void -resolveExplicitModuleInputs(ModuleDependencyID moduleID, - const ModuleDependencyInfo &resolvingDepInfo, - const std::set &dependencies, - ModuleDependenciesCache &cache) { - auto resolvingInterfaceDepDetails = - resolvingDepInfo.getAsSwiftInterfaceModule(); - assert(resolvingInterfaceDepDetails && - "Expected Swift Interface dependency."); +static llvm::Expected +updateModuleCacheKey(ModuleDependencyInfo &depInfo, + llvm::cas::ObjectStore &CAS) { + auto commandLine = depInfo.getCommandline(); + std::vector Args; + if (commandLine.size() > 1) + for (auto &c : ArrayRef(commandLine).drop_front(1)) + Args.push_back(c.c_str()); + + auto base = createCompileJobBaseCacheKey(CAS, Args); + if (!base) + return base.takeError(); + + StringRef InputPath; + file_types::ID OutputType = file_types::ID::TY_INVALID; + if (auto *dep = depInfo.getAsClangModule()) { + OutputType = file_types::ID::TY_ClangModuleFile; + InputPath = dep->moduleMapFile; + } else if (auto *dep = depInfo.getAsSwiftInterfaceModule()) { + OutputType = file_types::ID::TY_SwiftModuleFile; + InputPath = dep->swiftInterfaceFile; + } else + llvm_unreachable("Unhandled dependency kind"); + + auto key = + createCompileJobCacheKeyForOutput(CAS, *base, InputPath, OutputType); + if (!key) + return key.takeError(); + + depInfo.updateModuleCacheKey(CAS.getID(*key).toString()); + return *key; +} + +static llvm::Error resolveExplicitModuleInputs( + ModuleDependencyID moduleID, const ModuleDependencyInfo &resolvingDepInfo, + const std::set &dependencies, + ModuleDependenciesCache &cache, CompilerInstance &instance) { + // Only need to resolve dependency for following dependencies. + if (moduleID.second == ModuleDependencyKind::SwiftPlaceholder) + return llvm::Error::success(); + + std::vector rootIDs; + if (auto ID = resolvingDepInfo.getCASFSRootID()) + rootIDs.push_back(*ID); - auto commandLine = resolvingInterfaceDepDetails->buildCommandLine; + std::vector includeTrees; + if (auto ID = resolvingDepInfo.getClangIncludeTree()) + includeTrees.push_back(*ID); + + std::vector commandLine = resolvingDepInfo.getCommandline(); for (const auto &depModuleID : dependencies) { const auto optionalDepInfo = cache.findDependency(depModuleID.first, depModuleID.second); @@ -269,14 +320,26 @@ resolveExplicitModuleInputs(ModuleDependencyID moduleID, case swift::ModuleDependencyKind::SwiftInterface: { auto interfaceDepDetails = depInfo->getAsSwiftInterfaceModule(); assert(interfaceDepDetails && "Expected Swift Interface dependency."); + auto &path = interfaceDepDetails->moduleCacheKey.empty() + ? interfaceDepDetails->moduleOutputPath + : interfaceDepDetails->moduleCacheKey; commandLine.push_back("-swift-module-file=" + depModuleID.first + "=" + - interfaceDepDetails->moduleOutputPath); + path); } break; case swift::ModuleDependencyKind::SwiftBinary: { auto binaryDepDetails = depInfo->getAsSwiftBinaryModule(); assert(binaryDepDetails && "Expected Swift Binary Module dependency."); + auto &path = binaryDepDetails->moduleCacheKey.empty() + ? binaryDepDetails->compiledModulePath + : binaryDepDetails->moduleCacheKey; commandLine.push_back("-swift-module-file=" + depModuleID.first + "=" + - binaryDepDetails->compiledModulePath); + path); + for (const auto &headerDep : binaryDepDetails->preCompiledBridgingHeaderPaths) { + commandLine.push_back("-Xcc"); + commandLine.push_back("-include-pch"); + commandLine.push_back("-Xcc"); + commandLine.push_back(headerDep); + } } break; case swift::ModuleDependencyKind::SwiftPlaceholder: { auto placeholderDetails = depInfo->getAsPlaceholderDependencyModule(); @@ -287,13 +350,65 @@ resolveExplicitModuleInputs(ModuleDependencyID moduleID, case swift::ModuleDependencyKind::Clang: { auto clangDepDetails = depInfo->getAsClangModule(); assert(clangDepDetails && "Expected Clang Module dependency."); - commandLine.push_back("-Xcc"); - commandLine.push_back("-fmodule-file=" + depModuleID.first + "=" + - clangDepDetails->pcmOutputPath); - commandLine.push_back("-Xcc"); - commandLine.push_back("-fmodule-map-file=" + - clangDepDetails->moduleMapFile); + if (!resolvingDepInfo.isClangModule()) { + commandLine.push_back("-Xcc"); + commandLine.push_back("-fmodule-file=" + depModuleID.first + "=" + + clangDepDetails->pcmOutputPath); + if (!instance.getInvocation() + .getClangImporterOptions() + .UseClangIncludeTree) { + commandLine.push_back("-Xcc"); + commandLine.push_back("-fmodule-map-file=" + + clangDepDetails->moduleMapFile); + } + } + if (!clangDepDetails->moduleCacheKey.empty()) { + auto appendXclang = [&]() { + if (!resolvingDepInfo.isClangModule()) { + // clang module build using cc1 arg so this is not needed. + commandLine.push_back("-Xcc"); + commandLine.push_back("-Xclang"); + } + commandLine.push_back("-Xcc"); + }; + appendXclang(); + commandLine.push_back("-fmodule-file-cache-key"); + appendXclang(); + commandLine.push_back(clangDepDetails->pcmOutputPath); + appendXclang(); + commandLine.push_back(clangDepDetails->moduleCacheKey); + } + + // Only need to merge the CASFS from clang importer. + if (auto ID = depInfo->getCASFSRootID()) + rootIDs.push_back(*ID); + if (auto ID = depInfo->getClangIncludeTree()) + includeTrees.push_back(*ID); } break; + case swift::ModuleDependencyKind::SwiftSource: { + auto sourceDepDetails = depInfo->getAsSwiftSourceModule(); + assert(sourceDepDetails && "Expected source dependency"); + if (sourceDepDetails->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID.empty()) { + if (!sourceDepDetails->textualModuleDetails.bridgingSourceFiles + .empty()) { + if (auto tracker = + cache.getScanService().createSwiftDependencyTracker()) { + tracker->startTracking(); + for (auto &file : + sourceDepDetails->textualModuleDetails.bridgingSourceFiles) + tracker->trackFile(file); + auto bridgeRoot = tracker->createTreeFromDependencies(); + if (!bridgeRoot) + return bridgeRoot.takeError(); + rootIDs.push_back(bridgeRoot->getID().toString()); + } + } + } else + includeTrees.push_back(sourceDepDetails->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID); + break; + } default: llvm_unreachable("Unhandled dependency kind."); } @@ -301,8 +416,88 @@ resolveExplicitModuleInputs(ModuleDependencyID moduleID, // Update the dependency in the cache with the modified command-line. auto dependencyInfoCopy = resolvingDepInfo; - dependencyInfoCopy.updateCommandLine(commandLine); + if (resolvingDepInfo.isSwiftInterfaceModule() || + resolvingDepInfo.isClangModule()) + dependencyInfoCopy.updateCommandLine(commandLine); + + // Handle CAS options. + if (instance.getInvocation().getFrontendOptions().EnableCAS) { + // Merge CASFS from clang dependency. + auto &CASFS = cache.getScanService().getSharedCachingFS(); + auto &CAS = CASFS.getCAS(); + + // Update build command line. + if (resolvingDepInfo.isSwiftInterfaceModule() || + resolvingDepInfo.isSwiftSourceModule()) { + // Update with casfs option. + std::vector newCommandLine = + dependencyInfoCopy.getCommandline(); + for (auto rootID : rootIDs) { + newCommandLine.push_back("-cas-fs"); + newCommandLine.push_back(rootID); + } + + for (auto tree : includeTrees) { + newCommandLine.push_back("-clang-include-tree-root"); + newCommandLine.push_back(tree); + } + dependencyInfoCopy.updateCommandLine(newCommandLine); + } + + if (auto *sourceDep = resolvingDepInfo.getAsSwiftSourceModule()) { + std::vector newCommandLine = + dependencyInfoCopy.getBridgingHeaderCommandline(); + for (auto bridgingDep : + sourceDep->textualModuleDetails.bridgingModuleDependencies) { + auto dep = + cache.findDependency(bridgingDep, ModuleDependencyKind::Clang); + assert(dep && "unknown clang dependency"); + auto *clangDep = (*dep)->getAsClangModule(); + assert(clangDep && "wrong module dependency kind"); + if (!clangDep->moduleCacheKey.empty()) { + newCommandLine.push_back("-Xcc"); + newCommandLine.push_back("-fmodule-file-cache-key"); + newCommandLine.push_back("-Xcc"); + newCommandLine.push_back(clangDep->pcmOutputPath); + newCommandLine.push_back("-Xcc"); + newCommandLine.push_back(clangDep->moduleCacheKey); + } + dependencyInfoCopy.updateBridgingHeaderCommandLine(newCommandLine); + } + } + + if (resolvingDepInfo.isClangModule() || + resolvingDepInfo.isSwiftInterfaceModule()) { + // Compute and update module cache key. + auto Key = updateModuleCacheKey(dependencyInfoCopy, CAS); + if (!Key) + return Key.takeError(); + } + + // For binary module, we need to make sure the lookup key is setup here in + // action cache. We just use the CASID of the binary module itself as key. + if (auto *binaryDep = dependencyInfoCopy.getAsSwiftBinaryModule()) { + auto Ref = + CASFS.getObjectRefForFileContent(binaryDep->compiledModulePath); + if (!Ref) + return llvm::errorCodeToError(Ref.getError()); + assert(*Ref && "Binary module should be loaded into CASFS already"); + dependencyInfoCopy.updateModuleCacheKey(CAS.getID(**Ref).toString()); + + clang::cas::CompileJobCacheResult::Builder Builder; + Builder.addOutput( + clang::cas::CompileJobCacheResult::OutputKind::MainOutput, **Ref); + auto Result = Builder.build(CAS); + if (!Result) + return Result.takeError(); + if (auto E = instance.getActionCache().put(CAS.getID(**Ref), + CAS.getID(*Result))) + return E; + } + } cache.updateDependency(moduleID, dependencyInfoCopy); + + return llvm::Error::success(); } /// Resolve the direct dependencies of the given module. @@ -363,11 +558,11 @@ resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID moduleI // A record of all of the Clang modules referenced from this Swift module. std::vector allClangModules; llvm::StringSet<> knownModules; + auto clangImporter = + static_cast(ctx.getClangModuleLoader()); // If the Swift module has a bridging header, add those dependencies. if (knownDependencies->getBridgingHeader()) { - auto clangImporter = - static_cast(ctx.getClangModuleLoader()); if (!clangImporter->addBridgingHeaderDependencies(moduleID.first, moduleID.second, cache)) { // Grab the updated module dependencies. @@ -477,7 +672,8 @@ static void discoverCrossImportOverlayDependencies( // Construct a dummy main to resolve the newly discovered cross import // overlays. StringRef dummyMainName = "DummyMainModuleForResolvingCrossImportOverlays"; - auto dummyMainDependencies = ModuleDependencyInfo::forSwiftSourceModule({}); + auto dummyMainDependencies = + ModuleDependencyInfo::forSwiftSourceModule({}, {}, {}, {}); std::for_each(newOverlays.begin(), newOverlays.end(), [&](Identifier modName) { dummyMainDependencies.addModuleImport(modName.str()); @@ -858,6 +1054,16 @@ static void writeJSON(llvm::raw_ostream &out, bool commaAfterFramework = swiftTextualDeps->extra_pcm_args->count != 0 || hasBridgingHeaderPath; + if (swiftTextualDeps->cas_fs_root_id.length != 0) { + writeJSONSingleField(out, "casFSRootID", + swiftTextualDeps->cas_fs_root_id, 5, + /*trailingComma=*/true); + } + if (swiftTextualDeps->module_cache_key.length != 0) { + writeJSONSingleField(out, "moduleCacheKey", + swiftTextualDeps->module_cache_key, 5, + /*trailingComma=*/true); + } writeJSONSingleField(out, "isFramework", swiftTextualDeps->is_framework, 5, commaAfterFramework); if (swiftTextualDeps->extra_pcm_args->count != 0) { @@ -886,16 +1092,36 @@ static void writeJSON(llvm::raw_ostream &out, writeJSONSingleField(out, "sourceFiles", swiftTextualDeps->bridging_source_files, 6, /*trailingComma=*/true); + if (swiftTextualDeps->bridging_header_include_tree.length != 0) { + writeJSONSingleField(out, "includeTree", + swiftTextualDeps->bridging_header_include_tree, + 6, /*trailingComma=*/true); + } writeJSONSingleField(out, "moduleDependencies", swiftTextualDeps->bridging_module_dependencies, 6, - /*trailingComma=*/false); + /*trailingComma=*/true); + out.indent(6 * 2); + out << "\"commandLine\": [\n"; + for (int i = 0, + count = swiftTextualDeps->bridging_pch_command_line->count; + i < count; ++i) { + const auto &arg = get_C_string( + swiftTextualDeps->bridging_pch_command_line->strings[i]); + out.indent(7 * 2); + out << "\"" << quote(arg) << "\""; + if (i != count - 1) + out << ","; + out << "\n"; + } + out.indent(6 * 2); + out << "]\n"; out.indent(5 * 2); out << (hasOverlayDependencies ? "},\n" : "}\n"); } if (hasOverlayDependencies) { writeDependencies(out, swiftTextualDeps->swift_overlay_module_dependencies, "swiftOverlayDependencies", 5, - /*trailingComma=*/true); + /*trailingComma=*/false); } } else if (swiftPlaceholderDeps) { out << "\"swiftPlaceholder\": {\n"; @@ -942,6 +1168,18 @@ static void writeJSON(llvm::raw_ostream &out, swiftBinaryDeps->module_source_info_path, /*indentLevel=*/5, /*trailingComma=*/true); + if (swiftBinaryDeps->module_cache_key.length != 0) { + writeJSONSingleField(out, "moduleCacheKey", + swiftBinaryDeps->module_cache_key, 5, + /*trailingComma=*/true); + } + + // Module Header Dependencies + if (swiftBinaryDeps->header_dependencies->count != 0) + writeJSONSingleField(out, "headerDependencies", + swiftBinaryDeps->header_dependencies, 5, + /*trailingComma=*/true); + writeJSONSingleField(out, "isFramework", swiftBinaryDeps->is_framework, 5, /*trailingComma=*/false); } else { @@ -959,9 +1197,22 @@ static void writeJSON(llvm::raw_ostream &out, writeJSONSingleField(out, "commandLine", clangDeps->command_line, 5, /*trailingComma=*/true); + if (clangDeps->cas_fs_root_id.length != 0) + writeJSONSingleField(out, "casFSRootID", clangDeps->cas_fs_root_id, 5, + /*trailingComma=*/true); + if (clangDeps->clang_include_tree.length != 0) + writeJSONSingleField(out, "clangIncludeTree", + clangDeps->clang_include_tree, 5, + /*trailingComma=*/true); + if (clangDeps->module_cache_key.length != 0) + writeJSONSingleField(out, "moduleCacheKey", clangDeps->module_cache_key, + 5, + /*trailingComma=*/true); + // Captured PCM arguments. writeJSONSingleField(out, "capturedPCMArgs", clangDeps->captured_pcm_args, 5, /*trailingComma=*/false, /*nested=*/true); + } out.indent(4 * 2); @@ -1104,13 +1355,21 @@ generateFullDependencyGraph(CompilerInstance &instance, moduleInterfacePath, create_set(swiftTextualDeps->compiledModuleCandidates), bridgingHeaderPath, - create_set(swiftTextualDeps->textualModuleDetails.bridgingSourceFiles), - create_set(swiftTextualDeps->textualModuleDetails.bridgingModuleDependencies), + create_set( + swiftTextualDeps->textualModuleDetails.bridgingSourceFiles), + create_set(swiftTextualDeps->textualModuleDetails + .bridgingModuleDependencies), create_set(bridgedOverlayDependencyNames), - create_set(swiftTextualDeps->buildCommandLine), + create_set(swiftTextualDeps->textualModuleDetails.buildCommandLine), + /*bridgingHeaderBuildCommand*/ create_set({}), create_set(swiftTextualDeps->textualModuleDetails.extraPCMArgs), create_clone(swiftTextualDeps->contextHash.c_str()), - swiftTextualDeps->isFramework}; + swiftTextualDeps->isFramework, + create_clone(swiftTextualDeps->textualModuleDetails + .CASFileSystemRootID.c_str()), + create_clone(swiftTextualDeps->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID.c_str()), + create_clone(swiftTextualDeps->moduleCacheKey.c_str())}; } else if (swiftSourceDeps) { swiftscan_string_ref_t moduleInterfacePath = create_null(); swiftscan_string_ref_t bridgingHeaderPath = @@ -1128,13 +1387,23 @@ generateFullDependencyGraph(CompilerInstance &instance, moduleInterfacePath, create_empty_set(), bridgingHeaderPath, - create_set(swiftSourceDeps->textualModuleDetails.bridgingSourceFiles), - create_set(swiftSourceDeps->textualModuleDetails.bridgingModuleDependencies), + create_set( + swiftSourceDeps->textualModuleDetails.bridgingSourceFiles), + create_set(swiftSourceDeps->textualModuleDetails + .bridgingModuleDependencies), create_set(bridgedOverlayDependencyNames), - create_empty_set(), + create_set(swiftSourceDeps->textualModuleDetails.buildCommandLine), + create_set(swiftSourceDeps->bridgingHeaderBuildCommandLine), create_set(swiftSourceDeps->textualModuleDetails.extraPCMArgs), - /*contextHash*/create_null(), - /*isFramework*/false}; + /*contextHash*/ create_null(), + /*isFramework*/ false, + /*CASFS*/ + create_clone(swiftSourceDeps->textualModuleDetails + .CASFileSystemRootID.c_str()), + /*IncludeTree*/ + create_clone(swiftSourceDeps->textualModuleDetails + .CASBridgingHeaderIncludeTreeRootID.c_str()), + /*CacheKey*/ create_clone("")}; } else if (swiftPlaceholderDeps) { details->kind = SWIFTSCAN_DEPENDENCY_INFO_SWIFT_PLACEHOLDER; details->swift_placeholder_details = { @@ -1147,16 +1416,20 @@ generateFullDependencyGraph(CompilerInstance &instance, create_clone(swiftBinaryDeps->compiledModulePath.c_str()), create_clone(swiftBinaryDeps->moduleDocPath.c_str()), create_clone(swiftBinaryDeps->sourceInfoPath.c_str()), - swiftBinaryDeps->isFramework}; + create_set(swiftBinaryDeps->preCompiledBridgingHeaderPaths), + swiftBinaryDeps->isFramework, + create_clone(swiftBinaryDeps->moduleCacheKey.c_str())}; } else { // Clang module details details->kind = SWIFTSCAN_DEPENDENCY_INFO_CLANG; details->clang_details = { create_clone(clangDeps->moduleMapFile.c_str()), create_clone(clangDeps->contextHash.c_str()), - create_set(clangDeps->nonPathCommandLine), - create_set(clangDeps->capturedPCMArgs) - }; + create_set(clangDeps->buildCommandLine), + create_set(clangDeps->capturedPCMArgs), + create_clone(clangDeps->CASFileSystemRootID.c_str()), + create_clone(clangDeps->CASClangIncludeTreeRootID.c_str()), + create_clone(clangDeps->moduleCacheKey.c_str())}; } return details; }; @@ -1353,8 +1626,9 @@ forEachBatchEntry(CompilerInstance &invocationInstance, return false; } -static ModuleDependencyInfo -identifyMainModuleDependencies(CompilerInstance &instance) { +static ModuleDependencyInfo identifyMainModuleDependencies( + CompilerInstance &instance, + Optional tracker = None) { ModuleDecl *mainModule = instance.getMainModule(); // Main module file name. auto newExt = file_types::getExtension(file_types::TY_SwiftModuleFile); @@ -1375,7 +1649,22 @@ identifyMainModuleDependencies(CompilerInstance &instance) { ExtraPCMArgs.insert(ExtraPCMArgs.begin(), {"-Xcc", "-target", "-Xcc", instance.getASTContext().LangOpts.Target.str()}); - auto mainDependencies = ModuleDependencyInfo::forSwiftSourceModule(ExtraPCMArgs); + + std::string rootID; + if (tracker) { + tracker->startTracking(); + for (auto fileUnit : mainModule->getFiles()) { + auto sf = dyn_cast(fileUnit); + if (!sf) + continue; + tracker->trackFile(sf->getFilename()); + } + auto root = cantFail(tracker->createTreeFromDependencies()); + rootID = root.getID().toString(); + } + + auto mainDependencies = + ModuleDependencyInfo::forSwiftSourceModule(rootID, {}, {}, ExtraPCMArgs); // Compute Implicit dependencies of the main module { @@ -1475,6 +1764,7 @@ bool swift::dependencies::scanDependencies(CompilerInstance &instance) { deserializeDependencyCache(instance, service); // Wrap the filesystem with a caching `DependencyScanningWorkerFilesystem` service.overlaySharedFilesystemCacheForCompilation(instance); + service.setupCachingDependencyScanningService(instance); ModuleDependenciesCache cache(service, instance.getMainModule()->getNameStr().str(), instance.getInvocation().getModuleScanningHash()); @@ -1542,6 +1832,7 @@ bool swift::dependencies::batchScanDependencies( SwiftDependencyScanningService singleUseService; singleUseService.overlaySharedFilesystemCacheForCompilation(instance); + singleUseService.setupCachingDependencyScanningService(instance); ModuleDependenciesCache cache(singleUseService, instance.getMainModule()->getNameStr().str(), instance.getInvocation().getModuleScanningHash()); @@ -1630,7 +1921,8 @@ swift::dependencies::performModuleScan(CompilerInstance &instance, ModuleDependenciesCache &cache) { ModuleDecl *mainModule = instance.getMainModule(); // First, identify the dependencies of the main module - auto mainDependencies = identifyMainModuleDependencies(instance); + auto mainDependencies = identifyMainModuleDependencies( + instance, cache.getScanService().createSwiftDependencyTracker()); auto &ctx = instance.getASTContext(); // Add the main module. @@ -1702,17 +1994,18 @@ swift::dependencies::performModuleScan(CompilerInstance &instance, auto moduleTransitiveClosures = computeTransitiveClosureOfExplicitDependencies(topoSortedModuleList, cache); - for (const auto &dependencyClosure : moduleTransitiveClosures) { - auto &modID = dependencyClosure.first; + for (const auto &modID : llvm::reverse(topoSortedModuleList)) { + auto dependencyClosure = moduleTransitiveClosures[modID]; // For main module or binary modules, no command-line to resolve. // For Clang modules, their dependencies are resolved by the clang Scanner // itself for us. - if (modID.second != ModuleDependencyKind::SwiftInterface) - continue; auto optionalDeps = cache.findDependency(modID.first, modID.second); assert(optionalDeps.has_value()); auto deps = optionalDeps.value(); - resolveExplicitModuleInputs(modID, *deps, dependencyClosure.second, cache); + if (auto E = resolveExplicitModuleInputs(modID, *deps, dependencyClosure, + cache, instance)) + instance.getDiags().diagnose(SourceLoc(), diag::error_cas, + toString(std::move(E))); } auto dependencyGraph = generateFullDependencyGraph( diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index 4074acd56a570..b7ff8bb6fb712 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -354,8 +354,11 @@ bool ArgsToFrontendOptionsConverter::convert( Opts.EnableCAS = Args.hasArg(OPT_enable_cas); Opts.CASPath = Args.getLastArgValue(OPT_cas_path, llvm::cas::getDefaultOnDiskCASPath()); - Opts.CASFSRootID = Args.getLastArgValue(OPT_cas_fs); - if (Opts.EnableCAS && Opts.CASFSRootID.empty() && + Opts.CASFSRootIDs = Args.getAllArgValues(OPT_cas_fs); + Opts.ClangIncludeTrees = Args.getAllArgValues(OPT_clang_include_tree_root); + + if (Opts.EnableCAS && Opts.CASFSRootIDs.empty() && + Opts.ClangIncludeTrees.empty() && FrontendOptions::supportCompilationCaching(Opts.RequestedAction)) { if (!Args.hasArg(OPT_allow_unstable_cache_key_for_testing)) { Diags.diagnose(SourceLoc(), diag::error_caching_no_cas_fs); diff --git a/lib/Frontend/CachingUtils.cpp b/lib/Frontend/CachingUtils.cpp index 721158a735701..cb6435d887120 100644 --- a/lib/Frontend/CachingUtils.cpp +++ b/lib/Frontend/CachingUtils.cpp @@ -15,13 +15,19 @@ #include "swift/AST/DiagnosticsFrontend.h" #include "swift/Basic/FileTypes.h" #include "swift/Frontend/CompileJobCacheKey.h" +#include "clang/CAS/IncludeTree.h" #include "clang/Frontend/CompileJobCacheResult.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CAS/BuiltinUnifiedCASDatabases.h" +#include "llvm/CAS/CASFileSystem.h" +#include "llvm/CAS/HierarchicalTreeBuilder.h" #include "llvm/CAS/ObjectStore.h" +#include "llvm/CAS/TreeEntry.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Path.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/VirtualOutputBackends.h" #include "llvm/Support/VirtualOutputFile.h" #include @@ -342,4 +348,121 @@ Error storeCachedCompilerOutput(llvm::cas::ObjectStore &CAS, return Error::success(); } +static llvm::Error createCASObjectNotFoundError(const llvm::cas::CASID &ID) { + return createStringError(llvm::inconvertibleErrorCode(), + "CASID missing from Object Store " + ID.toString()); +} + +static Expected mergeCASFileSystem(ObjectStore &CAS, + ArrayRef FSRoots) { + llvm::cas::HierarchicalTreeBuilder Builder; + for (auto &Root : FSRoots) { + auto ID = CAS.parseID(Root); + if (!ID) + return ID.takeError(); + + auto Ref = CAS.getReference(*ID); + if (!Ref) + return createCASObjectNotFoundError(*ID); + Builder.pushTreeContent(*Ref, ""); + } + + auto NewRoot = Builder.create(CAS); + if (!NewRoot) + return NewRoot.takeError(); + + return NewRoot->getRef(); +} + +Expected> +createCASFileSystem(ObjectStore &CAS, ArrayRef FSRoots, + ArrayRef IncludeTrees) { + assert(!FSRoots.empty() || !IncludeTrees.empty() && "no root ID provided"); + if (FSRoots.size() == 1 && IncludeTrees.empty()) { + auto ID = CAS.parseID(FSRoots.front()); + if (!ID) + return ID.takeError(); + auto Ref = CAS.getReference(*ID); + if (!Ref) + return createCASObjectNotFoundError(*ID); + } + + auto NewRoot = mergeCASFileSystem(CAS, FSRoots); + if (!NewRoot) + return NewRoot.takeError(); + + auto FS = createCASFileSystem(CAS, CAS.getID(*NewRoot)); + if (!FS) + return FS.takeError(); + + auto CASFS = makeIntrusiveRefCnt(std::move(*FS)); + // Push all Include File System onto overlay. + for (auto &Tree : IncludeTrees) { + auto ID = CAS.parseID(Tree); + if (!ID) + return ID.takeError(); + + auto Ref = CAS.getReference(*ID); + if (!Ref) + return createCASObjectNotFoundError(*ID); + auto IT = clang::cas::IncludeTreeRoot::get(CAS, *Ref); + if (!IT) + return IT.takeError(); + + auto ITFS = clang::cas::createIncludeTreeFileSystem(*IT); + if (!ITFS) + return ITFS.takeError(); + CASFS->pushOverlay(std::move(*ITFS)); + } + + return CASFS; +} + +namespace cas { + +CachingTool::CachingTool(StringRef Path) { + auto DB = llvm::cas::createOnDiskUnifiedCASDatabases(Path); + if (!DB) { + llvm::errs() << "Failed to create CAS at " << Path << ": " + << toString(DB.takeError()) << "\n"; + return; + } + + CAS = std::move(DB->first); + Cache = std::move(DB->second); +} + +std::string CachingTool::computeCacheKey(ArrayRef Args, + StringRef InputPath, + file_types::ID OutputKind) { + auto BaseKey = createCompileJobBaseCacheKey(*CAS, Args); + if (!BaseKey) { + llvm::errs() << "Failed to create cache key: " + << toString(BaseKey.takeError()) << "\n"; + return ""; + } + + auto Key = + createCompileJobCacheKeyForOutput(*CAS, *BaseKey, InputPath, OutputKind); + if (!Key) { + llvm::errs() << "Failed to create cache key: " << toString(Key.takeError()) + << "\n"; + return ""; + } + + return CAS->getID(*Key).toString(); +} + +std::string CachingTool::storeContent(StringRef Content) { + auto Result = CAS->storeFromString({}, Content); + if (!Result) { + llvm::errs() << "Failed to store to CAS: " << toString(Result.takeError()) + << "\n"; + return ""; + } + + return CAS->getID(*Result).toString(); +} + +} // namespace cas } // namespace swift diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index c75d5a467a4bd..d6c547c76d293 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1438,12 +1438,15 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, Opts.ExtraArgs.push_back("-fdebug-prefix-map=" + Val); } - if (!workingDirectory.empty()) { - // Provide a working directory to Clang as well if there are any -Xcc - // options, in case some of them are search-related. But do it at the - // beginning, so that an explicit -Xcc -working-directory will win. - Opts.ExtraArgs.insert(Opts.ExtraArgs.begin(), - {"-working-directory", workingDirectory.str()}); + if (FrontendOpts.CASFSRootIDs.empty() && + FrontendOpts.ClangIncludeTrees.empty()) { + if (!workingDirectory.empty()) { + // Provide a working directory to Clang as well if there are any -Xcc + // options, in case some of them are search-related. But do it at the + // beginning, so that an explicit -Xcc -working-directory will win. + Opts.ExtraArgs.insert(Opts.ExtraArgs.begin(), + {"-working-directory", workingDirectory.str()}); + } } Opts.DumpClangDiagnostics |= Args.hasArg(OPT_dump_clang_diagnostics); @@ -1463,6 +1466,8 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, if (auto *A = Args.getLastArg(OPT_import_objc_header)) Opts.BridgingHeader = A->getValue(); + Opts.BridgingHeaderPCHCacheKey = + Args.getLastArgValue(OPT_bridging_header_pch_key); Opts.DisableSwiftBridgeAttr |= Args.hasArg(OPT_disable_swift_bridge_attr); Opts.DisableOverlayModules |= Args.hasArg(OPT_emit_imported_modules); @@ -1473,6 +1478,7 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, Opts.ExtraArgsOnly |= Args.hasArg(OPT_extra_clang_options_only); Opts.DirectClangCC1ModuleBuild |= Args.hasArg(OPT_direct_clang_cc1_module_build); + Opts.UseClangIncludeTree |= Args.hasArg(OPT_clang_include_tree); if (const Arg *A = Args.getLastArg(OPT_pch_output_dir)) { Opts.PrecompiledHeaderOutputDir = A->getValue(); diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 461c34938b15c..b65e628b31953 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -439,22 +439,6 @@ bool CompilerInstance::setupCASIfNeeded(ArrayRef Args) { ResultCache = std::move(MaybeCache->second); // create baseline key. - llvm::Optional FSRef; - if (!Opts.CASFSRootID.empty()) { - auto CASFSID = CAS->parseID(Opts.CASFSRootID); - if (!CASFSID) { - Diagnostics.diagnose(SourceLoc(), diag::error_cas, - toString(CASFSID.takeError())); - return true; - } - FSRef = CAS->getReference(*CASFSID); - if (!FSRef) { - Diagnostics.diagnose(SourceLoc(), diag::error_cas, - "-cas-fs value does not exist in CAS"); - return true; - } - } - auto BaseKey = createCompileJobBaseCacheKey(*CAS, Args); if (!BaseKey) { Diagnostics.diagnose(SourceLoc(), diag::error_cas, @@ -561,25 +545,39 @@ bool CompilerInstance::setup(const CompilerInvocation &Invoke, bool CompilerInstance::setUpVirtualFileSystemOverlays() { if (Invocation.getFrontendOptions().EnableCAS && - !Invocation.getFrontendOptions().CASFSRootID.empty()) { + (!Invocation.getFrontendOptions().CASFSRootIDs.empty() || + !Invocation.getFrontendOptions().ClangIncludeTrees.empty())) { // Set up CASFS as BaseFS. - auto RootID = CAS->parseID(Invocation.getFrontendOptions().CASFSRootID); - if (!RootID) { - Diagnostics.diagnose(SourceLoc(), diag::error_invalid_cas_id, - Invocation.getFrontendOptions().CASFSRootID, - toString(RootID.takeError())); - return true; - } - auto FS = llvm::cas::createCASFileSystem(*CAS, *RootID); + const auto &Opts = getInvocation().getFrontendOptions(); + auto FS = + createCASFileSystem(*CAS, Opts.CASFSRootIDs, Opts.ClangIncludeTrees); if (!FS) { - Diagnostics.diagnose(SourceLoc(), diag::error_invalid_cas_id, - Invocation.getFrontendOptions().CASFSRootID, + Diagnostics.diagnose(SourceLoc(), diag::error_cas, toString(FS.takeError())); return true; } SourceMgr.setFileSystem(std::move(*FS)); } + // If we have a bridging header cache key, try load it now and overlay it. + if (!Invocation.getClangImporterOptions().BridgingHeaderPCHCacheKey.empty() && + Invocation.getFrontendOptions().EnableCAS) { + auto loadedBridgingBuffer = loadCachedCompileResultFromCacheKey( + getObjectStore(), getActionCache(), Diagnostics, + Invocation.getClangImporterOptions().BridgingHeaderPCHCacheKey, + Invocation.getClangImporterOptions().BridgingHeader); + if (loadedBridgingBuffer) { + llvm::IntrusiveRefCntPtr PCHFS = + new llvm::vfs::InMemoryFileSystem(); + PCHFS->addFile(Invocation.getClangImporterOptions().BridgingHeader, 0, + std::move(loadedBridgingBuffer)); + llvm::IntrusiveRefCntPtr OverlayVFS = + new llvm::vfs::OverlayFileSystem(SourceMgr.getFileSystem()); + OverlayVFS->pushOverlay(PCHFS); + SourceMgr.setFileSystem(std::move(OverlayVFS)); + } + } + auto ExpectedOverlay = Invocation.getSearchPathOptions().makeOverlayFileSystem( SourceMgr.getFileSystem()); @@ -701,17 +699,24 @@ bool CompilerInstance::setUpModuleLoaders() { // If using `-explicit-swift-module-map-file`, create the explicit loader // before creating `ClangImporter` because the entries in the map influence // the Clang flags. The loader is added to the context below. - std::unique_ptr ESML = nullptr; + std::unique_ptr ESML = nullptr; bool ExplicitModuleBuild = Invocation.getFrontendOptions().DisableImplicitModules; if (ExplicitModuleBuild || !Invocation.getSearchPathOptions().ExplicitSwiftModuleMap.empty() || !Invocation.getSearchPathOptions().ExplicitSwiftModuleInputs.empty()) { - ESML = ExplicitSwiftModuleLoader::create( - *Context, getDependencyTracker(), MLM, - Invocation.getSearchPathOptions().ExplicitSwiftModuleMap, - Invocation.getSearchPathOptions().ExplicitSwiftModuleInputs, - IgnoreSourceInfoFile); + if (Invocation.getFrontendOptions().EnableCAS) + ESML = ExplicitCASModuleLoader::create( + *Context, getObjectStore(), getActionCache(), getDependencyTracker(), + MLM, Invocation.getSearchPathOptions().ExplicitSwiftModuleMap, + Invocation.getSearchPathOptions().ExplicitSwiftModuleInputs, + IgnoreSourceInfoFile); + else + ESML = ExplicitSwiftModuleLoader::create( + *Context, getDependencyTracker(), MLM, + Invocation.getSearchPathOptions().ExplicitSwiftModuleMap, + Invocation.getSearchPathOptions().ExplicitSwiftModuleInputs, + IgnoreSourceInfoFile); } // Wire up the Clang importer. If the user has specified an SDK, use it. @@ -839,6 +844,12 @@ std::string CompilerInstance::getBridgingHeaderPath() const { } bool CompilerInstance::setUpInputs() { + // There is no input file when building PCM using ClangIncludeTree. + if (Invocation.getFrontendOptions().RequestedAction == + FrontendOptions::ActionType::EmitPCM && + Invocation.getClangImporterOptions().UseClangIncludeTree) + return false; + // Adds to InputSourceCodeBufferIDs, so may need to happen before the // per-input setup. const Optional ideInspectionTargetBufferID = diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp index 437fa6090a0df..b12ac463d0efe 100644 --- a/lib/Frontend/ModuleInterfaceLoader.cpp +++ b/lib/Frontend/ModuleInterfaceLoader.cpp @@ -20,6 +20,7 @@ #include "swift/AST/FileSystem.h" #include "swift/AST/Module.h" #include "swift/Basic/Platform.h" +#include "swift/Frontend/CachingUtils.h" #include "swift/Frontend/Frontend.h" #include "swift/Frontend/ModuleInterfaceSupport.h" #include "swift/Parse/ParseVersion.h" @@ -28,6 +29,7 @@ #include "swift/Serialization/Validation.h" #include "swift/Strings.h" #include "clang/Basic/Module.h" +#include "clang/Frontend/CompileJobCacheResult.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" @@ -36,9 +38,12 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/CAS/ActionCache.h" +#include "llvm/CAS/ObjectStore.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" #include "llvm/Support/Path.h" #include "llvm/Support/VirtualOutputBackend.h" #include "llvm/Support/YAMLParser.h" @@ -1572,6 +1577,20 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface( GenericArgs.push_back("-clang-build-session-file"); GenericArgs.push_back(clangImporterOpts.BuildSessionFilePath); } + + if (!clangImporterOpts.CASPath.empty()) { + genericSubInvocation.getClangImporterOptions().CASPath = + clangImporterOpts.CASPath; + GenericArgs.push_back("-enable-cas"); + GenericArgs.push_back("-cas-path"); + GenericArgs.push_back(clangImporterOpts.CASPath); + } + + if (clangImporterOpts.UseClangIncludeTree) { + genericSubInvocation.getClangImporterOptions().UseClangIncludeTree = + clangImporterOpts.UseClangIncludeTree; + GenericArgs.push_back("-clang-include-tree"); + } } bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs( @@ -1661,6 +1680,7 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl( // required by sourcekitd. subClangImporterOpts.DetailedPreprocessingRecord = clangImporterOpts.DetailedPreprocessingRecord; + subClangImporterOpts.CASPath = clangImporterOpts.CASPath; // If the compiler has been asked to be strict with ensuring downstream dependencies // get the parent invocation's context, or this is an Explicit build, inherit the @@ -1941,15 +1961,22 @@ struct ExplicitSwiftModuleLoader::Implementation { void parseSwiftExplicitModuleMap(StringRef fileName) { ExplicitModuleMapParser parser(Allocator); llvm::StringMap ExplicitClangModuleMap; - auto result = - parser.parseSwiftExplicitModuleMap(fileName, ExplicitModuleMap, - ExplicitClangModuleMap); - if (result == std::errc::invalid_argument) - Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted, - fileName); - else if (result == std::errc::no_such_file_or_directory) + // Load the input file. + llvm::ErrorOr> fileBufOrErr = + llvm::MemoryBuffer::getFile(fileName); + if (!fileBufOrErr) { Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_missing, fileName); + return; + } + + auto hasError = parser.parseSwiftExplicitModuleMap( + (*fileBufOrErr)->getMemBufferRef(), ExplicitModuleMap, + ExplicitClangModuleMap); + + if (hasError) + Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted, + fileName); // A single module map can define multiple modules; keep track of the ones // we've seen so that we don't generate duplicate flags. @@ -1977,7 +2004,7 @@ struct ExplicitSwiftModuleLoader::Implementation { const std::vector> &commandLineExplicitInputs) { for (const auto &moduleInput : commandLineExplicitInputs) { - ExplicitSwiftModuleInputInfo entry(moduleInput.second, {}, {}); + ExplicitSwiftModuleInputInfo entry(moduleInput.second, {}, {}, {}); ExplicitModuleMap.try_emplace(moduleInput.first, std::move(entry)); } } @@ -2154,3 +2181,333 @@ ExplicitSwiftModuleLoader::create(ASTContext &ctx, return result; } + +struct ExplicitCASModuleLoader::Implementation { + ASTContext &Ctx; + llvm::BumpPtrAllocator Allocator; + llvm::cas::ObjectStore &CAS; + llvm::cas::ActionCache &Cache; + + llvm::StringMap ExplicitModuleMap; + + Implementation(ASTContext &Ctx, llvm::cas::ObjectStore &CAS, + llvm::cas::ActionCache &Cache) + : Ctx(Ctx), CAS(CAS), Cache(Cache) {} + + llvm::Expected> loadBuffer(StringRef ID) { + auto key = CAS.parseID(ID); + if (!key) + return key.takeError(); + + auto ref = CAS.getReference(*key); + if (!ref) + return nullptr; + + auto loaded = CAS.getProxy(*ref); + if (!loaded) + return loaded.takeError(); + + return loaded->getMemoryBuffer(); + } + + // Same as the regular explicit module map but must be loaded from + // CAS, instead of a file that is not tracked by the dependency. + void parseSwiftExplicitModuleMap(StringRef ID) { + ExplicitModuleMapParser parser(Allocator); + llvm::StringMap ExplicitClangModuleMap; + auto buf = loadBuffer(ID); + if (!buf) { + Ctx.Diags.diagnose(SourceLoc(), diag::error_cas, + toString(buf.takeError())); + return; + } + if (!*buf) { + Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_missing, + ID); + return; + } + llvm::ErrorOr> fileBufOrErr = + llvm::MemoryBuffer::getFile(ID); + + auto hasError = parser.parseSwiftExplicitModuleMap( + (*buf)->getMemBufferRef(), ExplicitModuleMap, ExplicitClangModuleMap); + + if (hasError) + Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted, + ID); + + std::set moduleMapsSeen; + std::vector &extraClangArgs = Ctx.ClangImporterOpts.ExtraArgs; + for (auto &entry : ExplicitClangModuleMap) { + const auto &moduleMapPath = entry.getValue().moduleMapPath; + if (!moduleMapPath.empty() && + !Ctx.ClangImporterOpts.UseClangIncludeTree && + moduleMapsSeen.find(moduleMapPath) == moduleMapsSeen.end()) { + moduleMapsSeen.insert(moduleMapPath); + extraClangArgs.push_back( + (Twine("-fmodule-map-file=") + moduleMapPath).str()); + } + + const auto &modulePath = entry.getValue().modulePath; + if (!modulePath.empty()) { + extraClangArgs.push_back( + (Twine("-fmodule-file=") + entry.getKey() + "=" + modulePath) + .str()); + } + auto cachePath = entry.getValue().moduleCacheKey; + if (cachePath) { + extraClangArgs.push_back("-Xclang"); + extraClangArgs.push_back("-fmodule-file-cache-key"); + extraClangArgs.push_back("-Xclang"); + extraClangArgs.push_back(modulePath); + extraClangArgs.push_back("-Xclang"); + extraClangArgs.push_back(*cachePath); + } + } + } + + void addCommandLineExplicitInputs( + const std::vector> + &commandLineExplicitInputs) { + for (const auto &moduleInput : commandLineExplicitInputs) { + ExplicitSwiftModuleInputInfo entry(moduleInput.second, {}, {}, {}); + ExplicitModuleMap.try_emplace(moduleInput.first, std::move(entry)); + } + } + + llvm::Expected> + loadFileBuffer(StringRef ID, StringRef Name) { + auto key = CAS.parseID(ID); + if (!key) + return key.takeError(); + + auto moduleLookup = Cache.get(*key); + if (!moduleLookup) + return moduleLookup.takeError(); + if (!*moduleLookup) + return nullptr; + + auto moduleRef = CAS.getReference(**moduleLookup); + if (!moduleRef) + return nullptr; + + clang::cas::CompileJobResultSchema schema(CAS); + auto result = schema.load(*moduleRef); + if (!result) + return result.takeError(); + auto output = result->getOutput( + clang::cas::CompileJobCacheResult::OutputKind::MainOutput); + if (!output) + return nullptr; + + auto buf = CAS.getProxy(output->Object); + if (!buf) + return buf.takeError(); + + return buf->getMemoryBuffer(Name); + } + + llvm::Expected> + loadModuleFromPath(StringRef Path, DiagnosticEngine &Diags) { + for (auto &Deps : ExplicitModuleMap) { + if (Deps.second.modulePath == Path) { + if (!Deps.second.moduleCacheKey) + return nullptr; + return loadCachedCompileResultFromCacheKey( + CAS, Cache, Diags, *Deps.second.moduleCacheKey, Path); + } + } + return nullptr; + } +}; + +ExplicitCASModuleLoader::ExplicitCASModuleLoader(ASTContext &ctx, + llvm::cas::ObjectStore &CAS, + llvm::cas::ActionCache &cache, + DependencyTracker *tracker, + ModuleLoadingMode loadMode, + bool IgnoreSwiftSourceInfoFile) + : SerializedModuleLoaderBase(ctx, tracker, loadMode, + IgnoreSwiftSourceInfoFile), + Impl(*new Implementation(ctx, CAS, cache)) {} + +ExplicitCASModuleLoader::~ExplicitCASModuleLoader() { delete &Impl; } + +bool ExplicitCASModuleLoader::findModule( + ImportPath::Element ModuleID, SmallVectorImpl *ModuleInterfacePath, + SmallVectorImpl *ModuleInterfaceSourcePath, + std::unique_ptr *ModuleBuffer, + std::unique_ptr *ModuleDocBuffer, + std::unique_ptr *ModuleSourceInfoBuffer, + bool skipBuildingInterface, bool isTestableDependencyLookup, + bool &IsFramework, bool &IsSystemModule) { + // Find a module with an actual, physical name on disk, in case + // -module-alias is used (otherwise same). + // + // For example, if '-module-alias Foo=Bar' is passed in to the frontend, and + // an input file has 'import Foo', a module called Bar (real name) should be + // searched. + StringRef moduleName = Ctx.getRealModuleName(ModuleID.Item).str(); + + auto it = Impl.ExplicitModuleMap.find(moduleName); + // If no explicit module path is given matches the name, return with an + // error code. + if (it == Impl.ExplicitModuleMap.end()) { + return false; + } + auto &moduleInfo = it->getValue(); + + // Set IsFramework bit according to the moduleInfo + IsFramework = moduleInfo.isFramework; + IsSystemModule = moduleInfo.isSystem; + + // Fallback check for module cache key passed on command-line as module path. + std::string moduleCASID = moduleInfo.moduleCacheKey + ? *moduleInfo.moduleCacheKey + : moduleInfo.modulePath; + + // FIXME: the loaded module buffer doesn't set an identifier so it + // is not tracked in dependency tracker, which doesn't handle modules + // that are not located on disk. + auto moduleBuf = loadCachedCompileResultFromCacheKey(Impl.CAS, Impl.Cache, + Ctx.Diags, moduleCASID); + if (!moduleBuf) { + // We cannot read the module content, diagnose. + Ctx.Diags.diagnose(SourceLoc(), diag::error_opening_explicit_module_file, + moduleInfo.modulePath); + return false; + } + + const bool isForwardingModule = + !serialization::isSerializedAST(moduleBuf->getBuffer()); + // If the module is a forwarding module, read the actual content from the path + // encoded in the forwarding module as the actual module content. + if (isForwardingModule) { + auto forwardingModule = ForwardingModule::load(*moduleBuf.get()); + if (forwardingModule) { + // Look through ExplicitModuleMap for paths. + // TODO: need to have dependency scanner reports forwarded module as + // dependency for this compilation and ingested into CAS. + auto moduleOrErr = Impl.loadModuleFromPath( + forwardingModule->underlyingModulePath, Ctx.Diags); + if (!moduleOrErr) { + llvm::consumeError(moduleOrErr.takeError()); + Ctx.Diags.diagnose(SourceLoc(), + diag::error_opening_explicit_module_file, + moduleInfo.modulePath); + return false; + } + moduleBuf = std::move(*moduleOrErr); + if (!moduleBuf) { + // We cannot read the module content, diagnose. + Ctx.Diags.diagnose(SourceLoc(), + diag::error_opening_explicit_module_file, + moduleInfo.modulePath); + return false; + } + } else { + // We cannot read the module content, diagnose. + Ctx.Diags.diagnose(SourceLoc(), diag::error_opening_explicit_module_file, + moduleInfo.modulePath); + return false; + } + } + assert(moduleBuf); + // Move the opened module buffer to the caller. + *ModuleBuffer = std::move(moduleBuf); + + // TODO: support .swiftdoc file and .swiftsourceinfo file + return true; +} + +std::error_code ExplicitCASModuleLoader::findModuleFilesInDirectory( + ImportPath::Element ModuleID, const SerializedModuleBaseName &BaseName, + SmallVectorImpl *ModuleInterfacePath, + SmallVectorImpl *ModuleInterfaceSourcePath, + std::unique_ptr *ModuleBuffer, + std::unique_ptr *ModuleDocBuffer, + std::unique_ptr *ModuleSourceInfoBuffer, + bool skipBuildingInterface, bool IsFramework, + bool IsTestableDependencyLookup) { + llvm_unreachable("Not supported in the Explicit Swift Module Loader."); + return std::make_error_code(std::errc::not_supported); +} + +bool ExplicitCASModuleLoader::canImportModule( + ImportPath::Module path, ModuleVersionInfo *versionInfo, + bool isTestableDependencyLookup) { + // FIXME: Swift submodules? + if (path.hasSubmodule()) + return false; + ImportPath::Element mID = path.front(); + // Look up the module with the real name (physical name on disk); + // in case `-module-alias` is used, the name appearing in source files + // and the real module name are different. For example, '-module-alias + // Foo=Bar' maps Foo appearing in source files, e.g. 'import Foo', to the real + // module name Bar (on-disk name), which should be searched for loading. + StringRef moduleName = Ctx.getRealModuleName(mID.Item).str(); + auto it = Impl.ExplicitModuleMap.find(moduleName); + // If no provided explicit module matches the name, then it cannot be + // imported. + if (it == Impl.ExplicitModuleMap.end()) { + return false; + } + + // If the caller doesn't want version info we're done. + if (!versionInfo) + return true; + + // Open .swiftmodule file and read out the version + std::string moduleCASID = it->second.moduleCacheKey + ? *it->second.moduleCacheKey + : it->second.modulePath; + auto moduleBuf = Impl.loadFileBuffer(moduleCASID, it->second.modulePath); + if (!moduleBuf) { + Ctx.Diags.diagnose(SourceLoc(), diag::error_cas, + toString(moduleBuf.takeError())); + return false; + } + if (!*moduleBuf) { + Ctx.Diags.diagnose(SourceLoc(), diag::error_opening_explicit_module_file, + it->second.modulePath); + return false; + } + auto metaData = serialization::validateSerializedAST( + (*moduleBuf)->getBuffer(), Ctx.SILOpts.EnableOSSAModules, + Ctx.LangOpts.SDKName, !Ctx.LangOpts.DebuggerSupport); + versionInfo->setVersion(metaData.userModuleVersion, + ModuleVersionSourceKind::SwiftBinaryModule); + return true; +} + +void ExplicitCASModuleLoader::collectVisibleTopLevelModuleNames( + SmallVectorImpl &names) const { + for (auto &entry : Impl.ExplicitModuleMap) { + names.push_back(Ctx.getIdentifier(entry.getKey())); + } +} + +std::unique_ptr ExplicitCASModuleLoader::create( + ASTContext &ctx, llvm::cas::ObjectStore &CAS, llvm::cas::ActionCache &cache, + DependencyTracker *tracker, ModuleLoadingMode loadMode, + StringRef ExplicitSwiftModuleMap, + const std::vector> + &ExplicitSwiftModuleInputs, + bool IgnoreSwiftSourceInfoFile) { + auto result = + std::unique_ptr(new ExplicitCASModuleLoader( + ctx, CAS, cache, tracker, loadMode, IgnoreSwiftSourceInfoFile)); + auto &Impl = result->Impl; + // If the explicit module map is given, try parse it. + if (!ExplicitSwiftModuleMap.empty()) { + // Parse a JSON file to collect explicitly built modules. + Impl.parseSwiftExplicitModuleMap(ExplicitSwiftModuleMap); + } + // If some modules are provided with explicit + // '-swift-module-file' options, add those as well. + if (!ExplicitSwiftModuleInputs.empty()) { + Impl.addCommandLineExplicitInputs(ExplicitSwiftModuleInputs); + } + + return result; +} diff --git a/lib/Frontend/ModuleInterfaceSupport.cpp b/lib/Frontend/ModuleInterfaceSupport.cpp index ee08b89e508c3..3a01ee45af93c 100644 --- a/lib/Frontend/ModuleInterfaceSupport.cpp +++ b/lib/Frontend/ModuleInterfaceSupport.cpp @@ -181,7 +181,7 @@ diagnoseIfModuleImportsShadowingDecl(ModuleInterfaceOptions const &Opts, SmallVector decls; lookupInModule(importedModule, importingModule->getName(), decls, NLKind::UnqualifiedLookup, ResolutionKind::TypesOnly, - importedModule, + importedModule, SourceLoc(), NL_UnqualifiedDefault | NL_IncludeUsableFromInline); for (auto decl : decls) diagnoseDeclShadowsModule(Opts, cast(decl), importingModule, diff --git a/lib/IDE/CompletionLookup.cpp b/lib/IDE/CompletionLookup.cpp index b697641afeba4..b5edc904185fb 100644 --- a/lib/IDE/CompletionLookup.cpp +++ b/lib/IDE/CompletionLookup.cpp @@ -2262,7 +2262,7 @@ bool CompletionLookup::tryUnwrappedCompletions(Type ExprType, bool isIUO) { // unforced IUO. if (isIUO) { if (Type Unwrapped = ExprType->getOptionalObjectType()) { - lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext, + lookupVisibleMemberDecls(*this, Unwrapped, DotLoc, CurrDeclContext, IncludeInstanceMembers, /*includeDerivedRequirements*/ false, /*includeProtocolExtensionMembers*/ true); @@ -2289,7 +2289,8 @@ bool CompletionLookup::tryUnwrappedCompletions(Type ExprType, bool isIUO) { if (NumBytesToEraseForOptionalUnwrap <= CodeCompletionResult::MaxNumBytesToErase) { if (!tryTupleExprCompletions(Unwrapped)) { - lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext, + lookupVisibleMemberDecls(*this, Unwrapped, DotLoc, + CurrDeclContext, IncludeInstanceMembers, /*includeDerivedRequirements*/ false, /*includeProtocolExtensionMembers*/ true); @@ -2370,7 +2371,7 @@ void CompletionLookup::getValueExprCompletions(Type ExprType, ValueDecl *VD) { // Don't check/return so we still add the members of Optional itself below tryUnwrappedCompletions(ExprType, isIUO); - lookupVisibleMemberDecls(*this, ExprType, CurrDeclContext, + lookupVisibleMemberDecls(*this, ExprType, DotLoc, CurrDeclContext, IncludeInstanceMembers, /*includeDerivedRequirements*/ false, /*includeProtocolExtensionMembers*/ true); @@ -2833,7 +2834,7 @@ void CompletionLookup::getUnresolvedMemberCompletions(Type T) { llvm::SaveAndRestore SaveLook(Kind, LookupKind::ValueExpr); llvm::SaveAndRestore SaveType(ExprType, baseType); llvm::SaveAndRestore SaveUnresolved(IsUnresolvedMember, true); - lookupVisibleMemberDecls(consumer, baseType, CurrDeclContext, + lookupVisibleMemberDecls(consumer, baseType, DotLoc, CurrDeclContext, /*includeInstanceMembers=*/false, /*includeDerivedRequirements*/ false, /*includeProtocolExtensionMembers*/ true); @@ -2847,7 +2848,7 @@ void CompletionLookup::getEnumElementPatternCompletions(Type T) { llvm::SaveAndRestore SaveLook(Kind, LookupKind::EnumElement); llvm::SaveAndRestore SaveType(ExprType, baseType); llvm::SaveAndRestore SaveUnresolved(IsUnresolvedMember, true); - lookupVisibleMemberDecls(*this, baseType, CurrDeclContext, + lookupVisibleMemberDecls(*this, baseType, DotLoc, CurrDeclContext, /*includeInstanceMembers=*/false, /*includeDerivedRequirements=*/false, /*includeProtocolExtensionMembers=*/true); @@ -2915,8 +2916,8 @@ void CompletionLookup::getTypeCompletions(Type BaseType) { Kind = LookupKind::Type; this->BaseType = BaseType; NeedLeadingDot = !HaveDot; - lookupVisibleMemberDecls(*this, MetatypeType::get(BaseType), CurrDeclContext, - IncludeInstanceMembers, + lookupVisibleMemberDecls(*this, MetatypeType::get(BaseType), DotLoc, + CurrDeclContext, IncludeInstanceMembers, /*includeDerivedRequirements*/ false, /*includeProtocolExtensionMembers*/ false); if (BaseType->isAnyExistentialType()) { @@ -2951,8 +2952,8 @@ void CompletionLookup::getGenericRequirementCompletions( Kind = LookupKind::GenericRequirement; this->BaseType = selfTy; NeedLeadingDot = false; - lookupVisibleMemberDecls(*this, MetatypeType::get(selfTy), CurrDeclContext, - IncludeInstanceMembers, + lookupVisibleMemberDecls(*this, MetatypeType::get(selfTy), DotLoc, + CurrDeclContext, IncludeInstanceMembers, /*includeDerivedRequirements*/ false, /*includeProtocolExtensionMembers*/ true); // We not only allow referencing nested types/typealiases directly, but also @@ -3214,6 +3215,36 @@ void CompletionLookup::getTypeCompletionsInDeclContext(SourceLoc Loc, RequestedCachedResults.insert(RequestedResultsTy::topLevelResults(filter)); } +namespace { + +/// A \c VisibleDeclConsumer that stores all decls that are found and is able +/// to forward the to another \c VisibleDeclConsumer later. +class StoringDeclConsumer : public VisibleDeclConsumer { + struct FoundDecl { + ValueDecl *VD; + DeclVisibilityKind Reason; + DynamicLookupInfo DynamicLookupInfo; + }; + + std::vector FoundDecls; + + void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason, + DynamicLookupInfo DynamicLookupInfo = {}) override { + FoundDecls.push_back({VD, Reason, DynamicLookupInfo}); + } + +public: + /// Call \c foundDecl for every declaration that this consumer has found. + void forward(VisibleDeclConsumer &Consumer) { + for (auto &FoundDecl : FoundDecls) { + Consumer.foundDecl(FoundDecl.VD, FoundDecl.Reason, + FoundDecl.DynamicLookupInfo); + } + } +}; + +} // namespace + void CompletionLookup::getToplevelCompletions(CodeCompletionFilter Filter) { Kind = (Filter - CodeCompletionFilterFlag::Module) .containsOnly(CodeCompletionFilterFlag::Type) @@ -3221,9 +3252,24 @@ void CompletionLookup::getToplevelCompletions(CodeCompletionFilter Filter) { : LookupKind::ValueInDeclContext; NeedLeadingDot = false; + // If we have 'addinitstotoplevel' enabled, calling `foundDecl` on `this` + // can cause macros to get expanded, which can then cause new members ot get + // added to 'TopLevelValues', invalidating iterator over `TopLevelDecls` in + // `SourceLookupCache::lookupVisibleDecls`. + // + // Technically `foundDecl` should not expand macros or discover new top level + // members in any way because those newly discovered decls will not be added + // to the code completion results. However, it's preferrable to miss results + // than to silently invalidate a collection, resulting in hard-to-diagnose + // crashes. + // Thus, store all the decls found by `CurrModule->lookupVisibleDecls` in a + // vector first and only call `this->foundDecl` once we have left the + // iteration loop over `TopLevelDecls`. + StoringDeclConsumer StoringConsumer; + UsableFilteringDeclConsumer UsableFilteringConsumer( Ctx.SourceMgr, CurrDeclContext, Ctx.SourceMgr.getIDEInspectionTargetLoc(), - *this); + StoringConsumer); AccessFilteringDeclConsumer AccessFilteringConsumer(CurrDeclContext, UsableFilteringConsumer); @@ -3242,6 +3288,8 @@ void CompletionLookup::getToplevelCompletions(CodeCompletionFilter Filter) { CurrModule->lookupVisibleDecls({}, FilteringConsumer, NLKind::UnqualifiedLookup); + + StoringConsumer.forward(*this); } void CompletionLookup::lookupExternalModuleDecls( diff --git a/lib/IDE/CompletionOverrideLookup.cpp b/lib/IDE/CompletionOverrideLookup.cpp index 53320471bfbe7..8a97365271c7e 100644 --- a/lib/IDE/CompletionOverrideLookup.cpp +++ b/lib/IDE/CompletionOverrideLookup.cpp @@ -541,7 +541,7 @@ void CompletionOverrideLookup::getOverrideCompletions(SourceLoc Loc) { if (CurrTy && !CurrTy->is()) { // Look for overridable static members too. Type Meta = MetatypeType::get(CurrTy); - lookupVisibleMemberDecls(*this, Meta, CurrDeclContext, + lookupVisibleMemberDecls(*this, Meta, introducerLoc, CurrDeclContext, /*includeInstanceMembers=*/true, /*includeDerivedRequirements*/ true, /*includeProtocolExtensionMembers*/ false); diff --git a/lib/IDE/ConformingMethodList.cpp b/lib/IDE/ConformingMethodList.cpp index ed5fde99cead9..ef1d355695116 100644 --- a/lib/IDE/ConformingMethodList.cpp +++ b/lib/IDE/ConformingMethodList.cpp @@ -166,7 +166,8 @@ void ConformingMethodListCallbacks::getMatchingMethods( } LocalConsumer(CurDeclContext, T, expectedTypes, result); - lookupVisibleMemberDecls(LocalConsumer, MetatypeType::get(T), CurDeclContext, + lookupVisibleMemberDecls(LocalConsumer, MetatypeType::get(T), + Loc, CurDeclContext, /*includeInstanceMembers=*/false, /*includeDerivedRequirements*/false, /*includeProtocolExtensionMembers*/true); diff --git a/lib/IDE/ExprContextAnalysis.cpp b/lib/IDE/ExprContextAnalysis.cpp index 2aac61940a841..565be3e8d24c4 100644 --- a/lib/IDE/ExprContextAnalysis.cpp +++ b/lib/IDE/ExprContextAnalysis.cpp @@ -372,7 +372,7 @@ class ExprParentFinder : public ASTWalker { /// Collect function (or subscript) members with the given \p name on \p baseTy. static void collectPossibleCalleesByQualifiedLookup( - DeclContext &DC, Type baseTy, DeclNameRef name, + DeclContext &DC, Type baseTy, DeclNameRef name, SourceLoc loc, SmallVectorImpl &candidates) { auto baseInstanceTy = baseTy->getMetatypeInstanceType(); if (!baseInstanceTy->mayHaveMembers()) @@ -395,7 +395,7 @@ static void collectPossibleCalleesByQualifiedLookup( SmallVector decls; if (!DC.lookupQualified(baseInstanceTy, - name.withoutArgumentLabels(), + name.withoutArgumentLabels(), loc, NL_QualifiedDefault | NL_ProtocolMembers, decls)) return; @@ -522,7 +522,9 @@ static void collectPossibleCalleesByQualifiedLookup( } } - collectPossibleCalleesByQualifiedLookup(DC, baseTy, name, candidates); + collectPossibleCalleesByQualifiedLookup(DC, baseTy, name, + baseExpr->getLoc(), + candidates); // Add virtual 'subscript(keyPath: KeyPath) -> Value'. if (name.getBaseName() == DeclBaseName::createSubscript() && @@ -553,6 +555,7 @@ static bool collectPossibleCalleesForUnresolvedMember( return; collectPossibleCalleesByQualifiedLookup(DC, MetatypeType::get(expectedTy), unresolvedMemberExpr->getName(), + unresolvedMemberExpr->getLoc(), candidates); }; diff --git a/lib/IDE/TypeContextInfo.cpp b/lib/IDE/TypeContextInfo.cpp index ffb398ae39b8f..abbc8a88a7bcf 100644 --- a/lib/IDE/TypeContextInfo.cpp +++ b/lib/IDE/TypeContextInfo.cpp @@ -194,7 +194,8 @@ void ContextInfoCallbacks::getImplicitMembers( } LocalConsumer(CurDeclContext, T, Result); - lookupVisibleMemberDecls(LocalConsumer, MetatypeType::get(T), CurDeclContext, + lookupVisibleMemberDecls(LocalConsumer, MetatypeType::get(T), + Loc, CurDeclContext, /*includeInstanceMembers=*/false, /*includeDerivedRequirements*/false, /*includeProtocolExtensionMembers*/true); diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 0e163d85d8dd8..7c62326b4a4f4 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -154,6 +154,9 @@ void Parser::performIDEInspectionSecondPassImpl( // discriminators. Context.evaluator.clearCachedOutput(LocalDiscriminatorsRequest{DC}); + // Clear any ASTScopes that were expanded. + SF.clearScope(); + switch (info.Kind) { case IDEInspectionDelayedDeclKind::TopLevelCodeDecl: { // Re-enter the top-level code decl context. diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 4afc45feb516f..cfe743ad3c3ec 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -1058,7 +1058,7 @@ static CanType getKnownType(Optional &cacheSlot, ASTContext &C, // themselves. SmallVector decls; mod->lookupQualified(mod, DeclNameRef(C.getIdentifier(typeName)), - NL_QualifiedDefault, decls); + SourceLoc(), NL_QualifiedDefault, decls); if (decls.size() != 1) return CanType(); diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index 996d654321465..c70a797ceadc9 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -371,7 +371,7 @@ static FuncDecl *lookupIntrinsic(ModuleDecl &module, return *cache; SmallVector decls; - module.lookupQualified(&module, DeclNameRef(name), + module.lookupQualified(&module, DeclNameRef(name), SourceLoc(), NL_QualifiedDefault | NL_IncludeUsableFromInline, decls); if (decls.size() != 1) { diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index b55b6667eac89..6fb3c14dcded1 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -2174,11 +2174,26 @@ RValue RValueEmitter::visitEnumIsCaseExpr(EnumIsCaseExpr *E, RValue RValueEmitter::visitSingleValueStmtExpr(SingleValueStmtExpr *E, SGFContext C) { + auto emitStmt = [&]() { + SGF.emitStmt(E->getStmt()); + + // A switch of an uninhabited value gets emitted as an unreachable. In that + // case we need to emit a block to emit the rest of the expression code + // into. This block will be unreachable, so will be eliminated by the + // SILOptimizer. This is easier than handling unreachability throughout + // expression emission, as eventually SingleValueStmtExprs ought to be able + // to appear in arbitrary expression position. The rest of the emission + // will reference the uninitialized temporary variable, but that's fine + // because it'll be eliminated. + if (!SGF.B.hasValidInsertionPoint()) + SGF.B.emitBlock(SGF.createBasicBlock()); + }; + // A void SingleValueStmtExpr either only has Void expression branches, or // we've decided that it should have purely statement semantics. In either // case, we can just emit the statement as-is, and produce the void rvalue. if (E->getType()->isVoid()) { - SGF.emitStmt(E->getStmt()); + emitStmt(); return SGF.emitEmptyTupleRValue(E, C); } auto &lowering = SGF.getTypeLowering(E->getType()); @@ -2201,7 +2216,7 @@ RValue RValueEmitter::visitSingleValueStmtExpr(SingleValueStmtExpr *E, // Push the initialization for branches of the statement to initialize into. SGF.SingleValueStmtInitStack.push_back(std::move(initInfo)); SWIFT_DEFER { SGF.SingleValueStmtInitStack.pop_back(); }; - SGF.emitStmt(E->getStmt()); + emitStmt(); return RValue(SGF, E, SGF.emitManagedRValueWithCleanup(resultAddr)); } diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index 6c04a9f890a5e..90d3014bd6109 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -1092,7 +1092,7 @@ void SILGenFunction::emitArtificialTopLevel(Decl *mainDecl) { SmallVector results; UIKit->lookupQualified(UIKit, DeclNameRef(ctx.getIdentifier("UIApplicationMain")), - NL_QualifiedDefault, + SourceLoc(), NL_QualifiedDefault, results); // As the comment above alludes, using a qualified lookup into UIKit is diff --git a/lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp b/lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp index 913c373a26fac..4375ee9631556 100644 --- a/lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp +++ b/lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp @@ -542,6 +542,19 @@ void DiagnosticEmitter::emitObjectDiagnosticsForPartialApplyUses( // MARK: Address Diagnostics //===----------------------------------------------------------------------===// +static bool isClosureCapture(MarkMustCheckInst *markedValue) { + SILValue val = markedValue->getOperand(); + + // look past any project-box + if (auto *pbi = dyn_cast(val)) + val = pbi->getOperand(); + + if (auto *fArg = dyn_cast(val)) + return fArg->isClosureCapture(); + + return false; +} + void DiagnosticEmitter::emitAddressExclusivityHazardDiagnostic( MarkMustCheckInst *markedValue, SILInstruction *consumingUser) { if (!useWithDiagnostic.insert(consumingUser).second) @@ -596,8 +609,8 @@ void DiagnosticEmitter::emitAddressDiagnostic(MarkMustCheckInst *markedValue, diagnose( astContext, markedValue, diag:: - sil_movechecking_inout_not_reinitialized_before_end_of_function, - varName); + sil_movechecking_not_reinitialized_before_end_of_function, + varName, isClosureCapture(markedValue)); diagnose(astContext, violatingUser, diag::sil_movechecking_consuming_use_here); return; @@ -647,8 +660,8 @@ void DiagnosticEmitter::emitInOutEndOfFunctionDiagnostic( // consuming message: diagnose( astContext, markedValue, - diag::sil_movechecking_inout_not_reinitialized_before_end_of_function, - varName); + diag::sil_movechecking_not_reinitialized_before_end_of_function, + varName, isClosureCapture(markedValue)); diagnose(astContext, violatingUser, diag::sil_movechecking_consuming_use_here); } diff --git a/lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp b/lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp index 9d119841216cb..f9fda092cbea2 100644 --- a/lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp +++ b/lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp @@ -522,7 +522,7 @@ void CanonicalizeOSSALifetime::findOriginalBoundary( /// These are the "original" live blocks (originalLiveBlocks). /// [Color these blocks green.] /// - From within that collection, collect the blocks which contain a _final_ -/// consuming, non-destroy use, and their successors. +/// consuming, non-destroy use, and their iterative successors. /// These are the "consumed" blocks (consumedAtExitBlocks). /// [Color these blocks red.] /// - Extend liveness down to the boundary between originalLiveBlocks and @@ -569,8 +569,11 @@ void CanonicalizeOSSALifetime::extendUnconsumedLiveness( } } - // Second, collect the blocks which occur after a _final_ consuming use. + // Second, collect the blocks which contain a _final_ consuming use and their + // iterative successors within the originalLiveBlocks. BasicBlockSet consumedAtExitBlocks(currentDef->getFunction()); + // The subset of consumedAtExitBlocks which do not contain a _final_ consuming + // use, i.e. the subset that is dead. StackList consumedAtEntryBlocks(currentDef->getFunction()); { // Start the forward walk from blocks which contain _final_ non-destroy @@ -596,8 +599,8 @@ void CanonicalizeOSSALifetime::extendUnconsumedLiveness( } } - // Third, find the blocks on the boundary between the originally-live blocks - // and the originally-live-but-consumed blocks. Extend liveness "to the end" + // Third, find the blocks on the boundary between the originalLiveBlocks + // blocks and the consumedAtEntryBlocks blocks. Extend liveness "to the end" // of these blocks. for (auto *block : consumedAtEntryBlocks) { for (auto *predecessor : block->getPredecessorBlocks()) { diff --git a/lib/Sema/BuilderTransform.cpp b/lib/Sema/BuilderTransform.cpp index b6ae98679227c..78a9739cd694e 100644 --- a/lib/Sema/BuilderTransform.cpp +++ b/lib/Sema/BuilderTransform.cpp @@ -1379,6 +1379,7 @@ ResultBuilderOpSupport TypeChecker::checkBuilderOpSupport( SmallVector foundDecls; dc->lookupQualified( builderType, DeclNameRef(fnName), + builderType->getAnyNominal()->getLoc(), NL_QualifiedDefault | NL_ProtocolMembers, foundDecls); for (auto decl : foundDecls) { if (auto func = dyn_cast(decl)) { diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index c2ed909db3352..196217cb62aac 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -2104,7 +2104,8 @@ bool AssignmentFailure::diagnoseAsError() { if (auto typeContext = DC->getInnermostTypeContext()) { SmallVector results; DC->lookupQualified(typeContext->getSelfNominalTypeDecl(), - VD->createNameRef(), NL_QualifiedDefault, results); + VD->createNameRef(), Loc, + NL_QualifiedDefault, results); auto foundProperty = llvm::find_if(results, [&](ValueDecl *decl) { // We're looking for a settable property that is the same type as the diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index c30c94dbc2792..085d178ae2de3 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -1244,7 +1244,7 @@ namespace { auto macroIdent = ctx.getIdentifier(kind); auto macros = lookupMacros( - macroIdent, expr->getLoc(), FunctionRefKind::Unapplied, + macroIdent, FunctionRefKind::Unapplied, MacroRole::Expression); if (!macros.empty()) { // Introduce an overload set for the macro reference. @@ -2949,10 +2949,6 @@ namespace { PreWalkAction walkToDeclPre(Decl *D) override { return Action::VisitChildrenIf(isa(D)); } - - PreWalkResult walkToPatternPre(Pattern *P) override { - return Action::SkipChildren(P); - } } collectVarRefs(CS); // Walk the capture list if this closure has one, because it could @@ -3896,12 +3892,12 @@ namespace { /// Lookup all macros with the given macro name. SmallVector - lookupMacros(Identifier macroName, SourceLoc loc, + lookupMacros(Identifier macroName, FunctionRefKind functionRefKind, MacroRoles roles) { SmallVector choices; - auto results = TypeChecker::lookupMacros( - CurDC, DeclNameRef(macroName), loc, roles); + auto results = namelookup::lookupMacros( + CurDC, DeclNameRef(macroName), roles); for (const auto &result : results) { OverloadChoice choice = OverloadChoice(Type(), result, functionRefKind); choices.push_back(choice); @@ -3926,8 +3922,7 @@ namespace { auto macroIdent = expr->getMacroName().getBaseIdentifier(); FunctionRefKind functionRefKind = FunctionRefKind::SingleApply; auto macros = lookupMacros( - macroIdent, expr->getMacroNameLoc().getBaseNameLoc(), - functionRefKind, expr->getMacroRoles()); + macroIdent, functionRefKind, expr->getMacroRoles()); if (macros.empty()) { ctx.Diags.diagnose(expr->getMacroNameLoc(), diag::macro_undefined, macroIdent) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index da48e9cd8286a..77d02761259a9 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -9307,6 +9307,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, Type baseObjTy = baseTy->getRValueType(); Type instanceTy = baseObjTy; + auto memberNode = simplifyLocatorToAnchor(memberLocator); + auto memberLoc = memberNode ? memberNode.getStartLoc() : SourceLoc(); + if (auto baseObjMeta = baseObjTy->getAs()) { instanceTy = baseObjMeta->getInstanceType(); } @@ -9419,7 +9422,7 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, } // Look for members within the base. - LookupResult &lookup = lookupMember(instanceTy, lookupName); + LookupResult &lookup = lookupMember(instanceTy, lookupName, memberLoc); // If this is true, we're using type construction syntax (Foo()) rather // than an explicit call to `init` (Foo.init()). @@ -9819,7 +9822,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, memberName.getBaseName() == DeclBaseName::createConstructor() && !isImplicitInit) { auto &compatLookup = lookupMember(instanceTy, - DeclNameRef(ctx.getIdentifier("init"))); + DeclNameRef(ctx.getIdentifier("init")), + memberLoc); for (auto result : compatLookup) addChoice(getOverloadChoice(result.getValueDecl(), /*isBridged=*/false, @@ -9829,7 +9833,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, // If the instance type is a bridged to an Objective-C type, perform // a lookup into that Objective-C type. if (bridgedType) { - LookupResult &bridgedLookup = lookupMember(bridgedType, memberName); + LookupResult &bridgedLookup = lookupMember(bridgedType, memberName, + memberLoc); ModuleDecl *foundationModule = nullptr; for (auto result : bridgedLookup) { // Ignore results from the Objective-C "Foundation" @@ -9892,7 +9897,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, // prioritize them and mark any results found on wrapped type // as a fallback results. bool isFallback = !result.ViableCandidates.empty(); - LookupResult &optionalLookup = lookupMember(objectType, memberName); + LookupResult &optionalLookup = lookupMember(objectType, memberName, + memberLoc); for (auto result : optionalLookup) addChoice(getOverloadChoice(result.getValueDecl(), /*bridged*/ false, @@ -9960,7 +9966,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, lookupOptions |= NameLookupFlags::IgnoreAccessControl; auto lookup = - TypeChecker::lookupMember(DC, instanceTy, memberName, lookupOptions); + TypeChecker::lookupMember(DC, instanceTy, memberName, + memberLoc, lookupOptions); for (auto entry : lookup) { auto *cand = entry.getValueDecl(); diff --git a/lib/Sema/CSSyntacticElement.cpp b/lib/Sema/CSSyntacticElement.cpp index 8fdec6b319a5d..e51026474ca67 100644 --- a/lib/Sema/CSSyntacticElement.cpp +++ b/lib/Sema/CSSyntacticElement.cpp @@ -2625,8 +2625,10 @@ void ConjunctionElement::findReferencedVariables( } if (element.is() || element.is() || - element.is() || element.isStmt(StmtKind::Return)) + element.is() || element.isPattern(PatternKind::Expr) || + element.isStmt(StmtKind::Return)) { element.walk(refFinder); + } } Type constraints::isPlaceholderVar(PatternBindingDecl *PB) { diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp index 26e6a088d0cea..30bf38a0771f4 100644 --- a/lib/Sema/CodeSynthesis.cpp +++ b/lib/Sema/CodeSynthesis.cpp @@ -1014,6 +1014,7 @@ static void collectNonOveriddenSuperclassInits( SmallVector lookupResults; subclass->lookupQualified( superclassDecl, DeclNameRef::createConstructor(), + subclass->getStartLoc(), subOptions, lookupResults); for (auto decl : lookupResults) { diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 10563c1fe10f8..35e2e0736721f 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -279,13 +279,15 @@ getDynamicResultSignature(ValueDecl *decl) { llvm_unreachable("Not a valid @objc member"); } -LookupResult &ConstraintSystem::lookupMember(Type base, DeclNameRef name) { +LookupResult &ConstraintSystem::lookupMember(Type base, DeclNameRef name, + SourceLoc loc) { // Check whether we've already performed this lookup. auto &result = MemberLookups[{base, name}]; if (result) return *result; // Lookup the member. - result = TypeChecker::lookupMember(DC, base, name, defaultMemberLookupOptions); + result = TypeChecker::lookupMember(DC, base, name, loc, + defaultMemberLookupOptions); // If we aren't performing dynamic lookup, we're done. if (!*result || !base->isAnyObject()) @@ -1866,11 +1868,14 @@ TypeVariableType *ConstraintSystem::openGenericParameter( auto *paramLocator = getConstraintLocator( locator.withPathElement(LocatorPathElt::GenericParameter(parameter))); - unsigned options = (TVO_PrefersSubtypeBinding | - TVO_CanBindToHole); + unsigned options = TVO_PrefersSubtypeBinding; + if (parameter->isParameterPack()) options |= TVO_CanBindToPack; + if (shouldAttemptFixes()) + options |= TVO_CanBindToHole; + auto typeVar = createTypeVariable(paramLocator, options); auto result = replacements.insert(std::make_pair( cast(parameter->getCanonicalType()), typeVar)); diff --git a/lib/Sema/ImportResolution.cpp b/lib/Sema/ImportResolution.cpp index 520ae263b6a09..5661c3a20ebc2 100644 --- a/lib/Sema/ImportResolution.cpp +++ b/lib/Sema/ImportResolution.cpp @@ -1135,7 +1135,7 @@ ScopedImportLookupRequest::evaluate(Evaluator &evaluator, lookupInModule(topLevelModule, accessPath.front().Item, decls, NLKind::QualifiedLookup, ResolutionKind::Overloadable, import->getDeclContext()->getModuleScopeContext(), - NL_QualifiedDefault); + import->getLoc(), NL_QualifiedDefault); auto importLoc = import->getLoc(); if (decls.empty()) { diff --git a/lib/Sema/LookupVisibleDecls.cpp b/lib/Sema/LookupVisibleDecls.cpp index c089f6767ad2e..ad39282fdea44 100644 --- a/lib/Sema/LookupVisibleDecls.cpp +++ b/lib/Sema/LookupVisibleDecls.cpp @@ -1143,7 +1143,7 @@ struct KeyPathDynamicMemberConsumer : public VisibleDeclConsumer { } // end anonymous namespace static void lookupVisibleDynamicMemberLookupDecls( - Type baseType, KeyPathDynamicMemberConsumer &consumer, + Type baseType, SourceLoc loc, KeyPathDynamicMemberConsumer &consumer, const DeclContext *dc, LookupState LS, DeclVisibilityKind reason, GenericSignature Sig, VisitedSet &visited, llvm::DenseSet &seenDynamicLookup); @@ -1154,13 +1154,14 @@ static void lookupVisibleDynamicMemberLookupDecls( /// \note This is an implementation detail of \c lookupVisibleMemberDecls and /// exists to create the correct recursion for dynamic member lookup. static void lookupVisibleMemberAndDynamicMemberDecls( - Type baseType, VisibleDeclConsumer &consumer, + Type baseType, SourceLoc loc, VisibleDeclConsumer &consumer, KeyPathDynamicMemberConsumer &dynamicMemberConsumer, const DeclContext *DC, LookupState LS, DeclVisibilityKind reason, GenericSignature Sig, VisitedSet &visited, llvm::DenseSet &seenDynamicLookup) { lookupVisibleMemberDeclsImpl(baseType, consumer, DC, LS, reason, Sig, visited); - lookupVisibleDynamicMemberLookupDecls(baseType, dynamicMemberConsumer, DC, LS, - reason, Sig, visited, seenDynamicLookup); + lookupVisibleDynamicMemberLookupDecls(baseType, loc, dynamicMemberConsumer, + DC, LS, reason, Sig, visited, + seenDynamicLookup); } /// Enumerates all keypath dynamic members of \c baseType, as seen from the @@ -1170,7 +1171,7 @@ static void lookupVisibleMemberAndDynamicMemberDecls( /// dynamic member subscripts and looks up the members of the keypath's root /// type. static void lookupVisibleDynamicMemberLookupDecls( - Type baseType, KeyPathDynamicMemberConsumer &consumer, + Type baseType, SourceLoc loc, KeyPathDynamicMemberConsumer &consumer, const DeclContext *dc, LookupState LS, DeclVisibilityKind reason, GenericSignature Sig, VisitedSet &visited, llvm::DenseSet &seenDynamicLookup) { @@ -1187,7 +1188,7 @@ static void lookupVisibleDynamicMemberLookupDecls( { ctx, DeclBaseName::createSubscript(), { ctx.Id_dynamicMember} }); SmallVector subscripts; - dc->lookupQualified(baseType, subscriptName, + dc->lookupQualified(baseType, subscriptName, loc, NL_QualifiedDefault | NL_ProtocolMembers, subscripts); for (ValueDecl *VD : subscripts) { @@ -1209,9 +1210,9 @@ static void lookupVisibleDynamicMemberLookupDecls( KeyPathDynamicMemberConsumer::SubscriptChange sub(consumer, subscript, baseType); - lookupVisibleMemberAndDynamicMemberDecls(memberType, consumer, consumer, dc, - LS, reason, Sig, visited, - seenDynamicLookup); + lookupVisibleMemberAndDynamicMemberDecls(memberType, loc, consumer, + consumer, dc, LS, reason, Sig, + visited, seenDynamicLookup); } } @@ -1222,8 +1223,9 @@ static void lookupVisibleDynamicMemberLookupDecls( /// where 'self' is the type of 'a'. This operation is only valid after name /// binding. static void lookupVisibleMemberDecls( - Type BaseTy, VisibleDeclConsumer &Consumer, const DeclContext *CurrDC, - LookupState LS, DeclVisibilityKind Reason, GenericSignature Sig) { + Type BaseTy, SourceLoc loc, VisibleDeclConsumer &Consumer, + const DeclContext *CurrDC, LookupState LS, + DeclVisibilityKind Reason, GenericSignature Sig) { OverrideFilteringConsumer overrideConsumer(BaseTy, CurrDC); KeyPathDynamicMemberConsumer dynamicConsumer( Consumer, @@ -1232,7 +1234,7 @@ static void lookupVisibleMemberDecls( VisitedSet Visited; llvm::DenseSet seenDynamicLookup; lookupVisibleMemberAndDynamicMemberDecls( - BaseTy, overrideConsumer, dynamicConsumer, CurrDC, LS, Reason, + BaseTy, loc, overrideConsumer, dynamicConsumer, CurrDC, LS, Reason, Sig, Visited, seenDynamicLookup); // Report the declarations we found to the real consumer. @@ -1346,8 +1348,8 @@ static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer, } if (ExtendedType) { - ::lookupVisibleMemberDecls(ExtendedType, Consumer, DC, LS, MemberReason, - nullptr); + ::lookupVisibleMemberDecls(ExtendedType, Loc, Consumer, DC, LS, + MemberReason, nullptr); // Going outside the current type context. MemberReason = DeclVisibilityKind::MemberOfOutsideNominal; @@ -1403,7 +1405,7 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer, } void swift::lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer, Type BaseTy, - const DeclContext *CurrDC, + SourceLoc loc, const DeclContext *CurrDC, bool includeInstanceMembers, bool includeDerivedRequirements, bool includeProtocolExtensionMembers, @@ -1420,7 +1422,7 @@ void swift::lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer, Type BaseTy, ls = ls.withIncludeProtocolExtensionMembers(); } - ::lookupVisibleMemberDecls(BaseTy, Consumer, CurrDC, ls, + ::lookupVisibleMemberDecls(BaseTy, loc, Consumer, CurrDC, ls, DeclVisibilityKind::MemberOfCurrentNominal, Sig); } diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index 4b17e5bfb1859..0c144273096c6 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -4332,7 +4332,8 @@ class ObjCSelectorWalker : public ASTWalker { auto nominal = method->getDeclContext()->getSelfNominalTypeDecl(); auto result = TypeChecker::lookupMember( const_cast(DC), nominal->getDeclaredInterfaceType(), - DeclNameRef(lookupName), defaultMemberLookupOptions); + DeclNameRef(lookupName), method->getLoc(), + defaultMemberLookupOptions); // If we didn't find multiple methods, there is no ambiguity. if (result.size() < 2) return false; diff --git a/lib/Sema/PreCheckExpr.cpp b/lib/Sema/PreCheckExpr.cpp index f634cdf72cdaa..08c56383184cf 100644 --- a/lib/Sema/PreCheckExpr.cpp +++ b/lib/Sema/PreCheckExpr.cpp @@ -602,8 +602,14 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, } TypoCorrectionResults corrections(Name, nameLoc); - TypeChecker::performTypoCorrection(DC, UDRE->getRefKind(), Type(), - lookupOptions, corrections); + + // FIXME: Don't perform typo correction inside macro arguments, because it + // will invoke synthesizing declarations in this scope, which will attempt to + // expand this macro which leads to circular reference errors. + if (!namelookup::isInMacroArgument(DC->getParentSourceFile(), UDRE->getLoc())) { + TypeChecker::performTypoCorrection(DC, UDRE->getRefKind(), Type(), + lookupOptions, corrections); + } if (auto typo = corrections.claimUniqueCorrection()) { auto diag = Context.Diags.diagnose( @@ -1395,7 +1401,7 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) { // See if the type has a member type with this name. auto Result = TypeChecker::lookupMemberType( DC, TD->getDeclaredInterfaceType(), Name, - defaultMemberLookupOptions); + UDE->getLoc(), defaultMemberLookupOptions); // If there is no nested type with this name, we have a lookup of // a non-type member, so leave the expression as-is. @@ -1488,6 +1494,7 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) { if (BaseTy->mayHaveMembers()) { // See if there is a member type with this name. auto Result = TypeChecker::lookupMemberType(DC, BaseTy, Name, + UDE->getLoc(), defaultMemberLookupOptions); // If there is no nested type with this name, we have a lookup of diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index ae66572e3f267..9d1d99b2b2114 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -2328,7 +2328,8 @@ void AttributeChecker::checkApplicationMainAttribute(DeclAttribute *attr, namelookup::lookupInModule(KitModule, Id_ApplicationDelegate, decls, NLKind::QualifiedLookup, namelookup::ResolutionKind::TypesOnly, - SF, NL_QualifiedDefault); + SF, attr->getLocation(), + NL_QualifiedDefault); if (decls.size() == 1) ApplicationDelegateProto = dyn_cast(decls[0]); } @@ -3047,7 +3048,8 @@ static void lookupReplacedDecl(DeclNameRef replacedDeclName, options |= NL_IncludeUsableFromInline; if (typeCtx) - moduleScopeCtxt->lookupQualified({typeCtx}, replacedDeclName, options, + moduleScopeCtxt->lookupQualified({typeCtx}, replacedDeclName, + attr->getLocation(), options, results); } @@ -4057,11 +4059,12 @@ void AttributeChecker::visitResultBuilderAttr(ResultBuilderAttr *attr) { auto builderType = nominal->getDeclaredType(); nominal->lookupQualified(builderType, DeclNameRef(buildPartialBlockFirst), - NL_QualifiedDefault, + attr->getLocation(), NL_QualifiedDefault, buildPartialBlockFirstMatches); nominal->lookupQualified( builderType, DeclNameRef(buildPartialBlockAccumulated), - NL_QualifiedDefault, buildPartialBlockAccumulatedMatches); + attr->getLocation(), NL_QualifiedDefault, + buildPartialBlockAccumulatedMatches); hasAccessibleBuildPartialBlockFirst = llvm::any_of( buildPartialBlockFirstMatches, isBuildMethodAsAccessibleAsType); @@ -7267,7 +7270,8 @@ ValueDecl *RenamedDeclRequest::evaluate(Evaluator &evaluator, SmallVector lookupResults; attachedContext->lookupQualified(attachedContext->getParentModule(), nameRef.withoutArgumentLabels(), - NL_OnlyTypes, lookupResults); + attr->getLocation(), NL_OnlyTypes, + lookupResults); if (lookupResults.size() == 1) return lookupResults[0]; return nullptr; diff --git a/lib/Sema/TypeCheckCodeCompletion.cpp b/lib/Sema/TypeCheckCodeCompletion.cpp index 58acb0c1e1965..9076c7b7f7aef 100644 --- a/lib/Sema/TypeCheckCodeCompletion.cpp +++ b/lib/Sema/TypeCheckCodeCompletion.cpp @@ -767,6 +767,7 @@ bool swift::typeCheckExpression(DeclContext *DC, Expr *&parsedExpr) { LookupResult swift::lookupSemanticMember(DeclContext *DC, Type ty, DeclName name) { - return TypeChecker::lookupMember(DC, ty, DeclNameRef(name), None); + return TypeChecker::lookupMember(DC, ty, DeclNameRef(name), + SourceLoc(), None); } diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index eb566bcde9a3c..4501c282578be 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -266,7 +266,8 @@ VarDecl *GlobalActorInstanceRequest::evaluate( // conformance to the 'GlobalActor' protocol. SmallVector decls; nominal->lookupQualified( - nominal, DeclNameRef(ctx.Id_shared), NL_QualifiedDefault, decls); + nominal, DeclNameRef(ctx.Id_shared), + nominal->getLoc(), NL_QualifiedDefault, decls); for (auto decl : decls) { auto var = dyn_cast(decl); if (!var) diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index dd0f7655608e3..b982f0436f629 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -774,7 +774,7 @@ PrimaryAssociatedTypesRequest::evaluate(Evaluator &evaluator, SmallVector result; decl->lookupQualified(ArrayRef(decl), - DeclNameRef(pair.first), + DeclNameRef(pair.first), decl->getLoc(), NL_QualifiedDefault | NL_OnlyTypes, result); @@ -1609,28 +1609,6 @@ TypeChecker::lookupPrecedenceGroup(DeclContext *dc, Identifier name, return PrecedenceGroupLookupResult(dc, name, std::move(groups)); } -SmallVector -TypeChecker::lookupMacros(DeclContext *dc, DeclNameRef macroName, - SourceLoc loc, MacroRoles roles) { - SmallVector choices; - auto moduleScopeDC = dc->getModuleScopeContext(); - ASTContext &ctx = moduleScopeDC->getASTContext(); - UnqualifiedLookupDescriptor descriptor(macroName, moduleScopeDC); - auto lookup = evaluateOrDefault( - ctx.evaluator, UnqualifiedLookupRequest{descriptor}, {}); - for (const auto &found : lookup.allResults()) { - if (auto macro = dyn_cast(found.getValueDecl())) { - auto candidateRoles = macro->getMacroRoles(); - if ((candidateRoles && roles.contains(candidateRoles)) || - // FIXME: `externalMacro` should have all roles. - macro->getBaseIdentifier().str() == "externalMacro") { - choices.push_back(macro); - } - } - } - return choices; -} - /// Validate the given operator declaration. /// /// This establishes key invariants, such as an InfixOperatorDecl's diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index d4aff7bc2bffc..1ff5390225d7f 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -928,7 +928,7 @@ SmallVector OverrideMatcher::match( ctx->synthesizeSemanticMembersIfNeeded(membersName); } dc->lookupQualified(superContexts, DeclNameRef(membersName), - NL_QualifiedDefault, members); + decl->getLoc(), NL_QualifiedDefault, members); } // Check each member we found. diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index a0ecff79ba60c..7b3283e5b959c 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -1412,6 +1412,7 @@ static void diagnoseClassWithoutInitializers(ClassDecl *classDecl) { { C, DeclBaseName::createConstructor(), { C.Id_from } }); auto result = TypeChecker::lookupMember(superclassDecl, superclassType, initFrom, + classDecl->getLoc(), NameLookupFlags::IgnoreAccessControl); if (!result.empty() && !result.front().getValueDecl()->isImplicit()) diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp index 899d8b017ea0b..82be86ccf35bf 100644 --- a/lib/Sema/TypeCheckGeneric.cpp +++ b/lib/Sema/TypeCheckGeneric.cpp @@ -213,7 +213,6 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator, auto opaqueDecl = OpaqueTypeDecl::get( originatingDecl, genericParams, parentDC, interfaceSignature, opaqueReprs); - opaqueDecl->copyFormalAccessFrom(originatingDecl); if (auto originatingSig = originatingDC->getGenericSignatureOfContext()) { opaqueDecl->setGenericSignature(originatingSig); } else { diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index 90e00f9fb0c78..c7b0f454aca02 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -1470,6 +1470,40 @@ swift::expandConformances(CustomAttr *attr, MacroDecl *macro, return macroSourceFile->getBufferID(); } +/// Emits an error and returns \c true if the maro reference may +/// introduce arbitrary names at global scope. +static bool diagnoseArbitraryGlobalNames(DeclContext *dc, + UnresolvedMacroReference macroRef, + MacroRole macroRole) { + auto &ctx = dc->getASTContext(); + assert(macroRole == MacroRole::Declaration || + macroRole == MacroRole::Peer); + + if (!dc->isModuleScopeContext()) + return false; + + bool isInvalid = false; + namelookup::forEachPotentialResolvedMacro( + dc, macroRef.getMacroName(), macroRole, + [&](MacroDecl *decl, const MacroRoleAttr *attr) { + if (!isInvalid && + attr->hasNameKind(MacroIntroducedDeclNameKind::Arbitrary)) { + ctx.Diags.diagnose(macroRef.getSigilLoc(), + diag::global_arbitrary_name, + getMacroRoleString(macroRole)); + isInvalid = true; + + // If this is an attached macro, mark the attribute as invalid + // to avoid diagnosing an unknown attribute later. + if (auto *attr = macroRef.getAttr()) { + attr->setInvalid(); + } + } + }); + + return isInvalid; +} + ConcreteDeclRef ResolveMacroRequest::evaluate(Evaluator &evaluator, UnresolvedMacroReference macroRef, DeclContext *dc) const { @@ -1486,12 +1520,25 @@ ConcreteDeclRef ResolveMacroRequest::evaluate(Evaluator &evaluator, // When a macro is not found for a custom attribute, it may be a non-macro. // So bail out to prevent diagnostics from the contraint system. if (macroRef.getAttr()) { - auto foundMacros = TypeChecker::lookupMacros( - dc, macroRef.getMacroName(), SourceLoc(), roles); + auto foundMacros = namelookup::lookupMacros( + dc, macroRef.getMacroName(), roles); if (foundMacros.empty()) return ConcreteDeclRef(); } + // Freestanding and peer macros applied at top-level scope cannot introduce + // arbitrary names. Introducing arbitrary names means that any lookup + // into this scope must expand the macro. This is a problem, because + // resolving the macro can invoke type checking other declarations, e.g. + // anything that the macro arguments depend on. If _anything_ the macro + // depends on performs name unqualified name lookup, e.g. type resolution, + // we'll get circularity errors. It's better to prevent this by banning + // these macros at global scope if any of the macro candidates introduce + // arbitrary names. + if (diagnoseArbitraryGlobalNames(dc, macroRef, MacroRole::Declaration) || + diagnoseArbitraryGlobalNames(dc, macroRef, MacroRole::Peer)) + return ConcreteDeclRef(); + // If we already have a MacroExpansionExpr, use that. Otherwise, // create one. MacroExpansionExpr *macroExpansion; diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp index 51b8f416467b3..4cfc994ab296c 100644 --- a/lib/Sema/TypeCheckNameLookup.cpp +++ b/lib/Sema/TypeCheckNameLookup.cpp @@ -314,6 +314,7 @@ TypeChecker::lookupUnqualifiedType(DeclContext *dc, DeclNameRef name, LookupResult TypeChecker::lookupMember(DeclContext *dc, Type type, DeclNameRef name, + SourceLoc loc, NameLookupOptions options) { assert(type->mayHaveMembers()); @@ -331,7 +332,7 @@ LookupResult TypeChecker::lookupMember(DeclContext *dc, LookupResultBuilder builder(result, dc, options); SmallVector lookupResults; - dc->lookupQualified(type, name, subOptions, lookupResults); + dc->lookupQualified(type, name, loc, subOptions, lookupResults); for (auto found : lookupResults) builder.add(found, nullptr, /*baseDecl=*/nullptr, type, /*isOuter=*/false); @@ -407,6 +408,7 @@ TypeChecker::isUnsupportedMemberTypeAccess(Type type, TypeDecl *typeDecl, LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc, Type type, DeclNameRef name, + SourceLoc loc, NameLookupOptions options) { LookupTypeResult result; @@ -422,7 +424,7 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc, // Make sure we've resolved implicit members, if we need them. namelookup::installSemanticMembersIfNeeded(type, name); - if (!dc->lookupQualified(type, name, subOptions, decls)) + if (!dc->lookupQualified(type, name, loc, subOptions, decls)) return result; // Look through the declarations, keeping only the unique type declarations. @@ -615,7 +617,7 @@ void TypeChecker::performTypoCorrection(DeclContext *DC, DeclRefKind refKind, }); if (baseTypeOrNull) { - lookupVisibleMemberDecls(consumer, baseTypeOrNull, DC, + lookupVisibleMemberDecls(consumer, baseTypeOrNull, SourceLoc(), DC, /*includeInstanceMembers*/true, /*includeDerivedRequirements*/false, /*includeProtocolExtensionMembers*/true, diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index 69260e9a0975e..eafc5638c7c13 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -142,7 +142,7 @@ lookupEnumMemberElement(DeclContext *DC, Type ty, // FIXME: We should be able to tell if this is a private lookup. NameLookupOptions lookupOptions = defaultMemberLookupOptions; LookupResult foundElements = - TypeChecker::lookupMember(DC, ty, name, lookupOptions); + TypeChecker::lookupMember(DC, ty, name, UseLoc, lookupOptions); return filterForEnumElement(DC, UseLoc, /*unqualifiedLookup=*/false, foundElements); } diff --git a/lib/Sema/TypeCheckPropertyWrapper.cpp b/lib/Sema/TypeCheckPropertyWrapper.cpp index 8e0717021ef52..8419c276f9d57 100644 --- a/lib/Sema/TypeCheckPropertyWrapper.cpp +++ b/lib/Sema/TypeCheckPropertyWrapper.cpp @@ -38,7 +38,9 @@ static VarDecl *findValueProperty(ASTContext &ctx, NominalTypeDecl *nominal, SmallVector vars; { SmallVector decls; - nominal->lookupQualified(nominal, DeclNameRef(name), NL_QualifiedDefault, + nominal->lookupQualified(nominal, DeclNameRef(name), + nominal->getStartLoc(), + NL_QualifiedDefault, decls); for (const auto &foundDecl : decls) { auto foundVar = dyn_cast(foundDecl); @@ -348,6 +350,7 @@ PropertyWrapperTypeInfoRequest::evaluate( SmallVector decls; nominal->lookupQualified(nominal, DeclNameRef::createConstructor(), + nominal->getStartLoc(), NL_QualifiedDefault, decls); PropertyWrapperTypeInfo result; diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index e8197806b3d10..a2580fe9c680e 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -1306,7 +1306,8 @@ WitnessChecker::lookupValueWitnessesViaImplementsAttr( nominal->synthesizeSemanticMembersIfNeeded(name.getFullName()); SmallVector lookupResults; - DC->lookupQualified(nominal, name, subOptions, lookupResults); + DC->lookupQualified(nominal, name, nominal->getLoc(), + subOptions, lookupResults); for (auto decl : lookupResults) { if (!isa(decl->getDeclContext())) @@ -1387,7 +1388,8 @@ WitnessChecker::lookupValueWitnesses(ValueDecl *req, bool *ignoringNames) { SmallVector lookupResults; bool addedAny = false; - DC->lookupQualified(nominal, reqName, options, lookupResults); + DC->lookupQualified(nominal, reqName, nominal->getLoc(), + options, lookupResults); for (auto *decl : lookupResults) { if (!isa(decl->getDeclContext())) { witnesses.push_back(decl); @@ -1399,7 +1401,8 @@ WitnessChecker::lookupValueWitnesses(ValueDecl *req, bool *ignoringNames) { // again using only the base name. if (!addedAny && ignoringNames) { lookupResults.clear(); - DC->lookupQualified(nominal, reqBaseName, options, lookupResults); + DC->lookupQualified(nominal, reqBaseName, nominal->getLoc(), + options, lookupResults); for (auto *decl : lookupResults) { if (!isa(decl->getDeclContext())) witnesses.push_back(decl); @@ -4754,6 +4757,7 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup( DC->lookupQualified(DC->getSelfNominalTypeDecl(), assocType->createNameRef(), + DC->getSelfNominalTypeDecl()->getLoc(), subOptions, candidates); // If there aren't any candidates, we're done. @@ -6331,7 +6335,8 @@ diagnoseMissingAppendInterpolationMethod(NominalTypeDecl *typeDecl) { DeclNameRef baseName(typeDecl->getASTContext().Id_appendInterpolation); SmallVector lookupResults; - typeDecl->lookupQualified(typeDecl, baseName, subOptions, lookupResults); + typeDecl->lookupQualified(typeDecl, baseName, typeDecl->getLoc(), + subOptions, lookupResults); for (auto decl : lookupResults) { auto method = dyn_cast(decl); if (!method) continue; @@ -7202,6 +7207,7 @@ void TypeChecker::inferDefaultWitnesses(ProtocolDecl *proto) { SmallVector found; module->lookupQualified( proto, DeclNameRef(assocType->getName()), + proto->getLoc(), NL_QualifiedDefault|NL_ProtocolMembers|NL_OnlyTypes, found); if (found.size() == 1 && isa(found[0])) diff --git a/lib/Sema/TypeCheckProtocolInference.cpp b/lib/Sema/TypeCheckProtocolInference.cpp index 89fdacaa6b247..830d1aed3df7a 100644 --- a/lib/Sema/TypeCheckProtocolInference.cpp +++ b/lib/Sema/TypeCheckProtocolInference.cpp @@ -594,6 +594,7 @@ AssociatedTypeInference::inferTypeWitnessesViaAssociatedType( // @_implements attributes. SmallVector lookupResults; dc->lookupQualified(adoptee->getAnyNominal(), defaultName, + adoptee->getAnyNominal()->getStartLoc(), subOptions, lookupResults); InferredAssociatedTypesByWitnesses result; diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp index 6acbee696995c..ae0b89651947f 100644 --- a/lib/Sema/TypeCheckStmt.cpp +++ b/lib/Sema/TypeCheckStmt.cpp @@ -2180,6 +2180,7 @@ static bool checkSuperInit(ConstructorDecl *fromCtor, SmallVector lookupResults; fromCtor->lookupQualified(superclassDecl, DeclNameRef::createConstructor(), + apply->getLoc(), subOptions, lookupResults); for (auto decl : lookupResults) { diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp index c448f4dd90103..979654b18cc1b 100644 --- a/lib/Sema/TypeCheckStorage.cpp +++ b/lib/Sema/TypeCheckStorage.cpp @@ -2730,10 +2730,10 @@ static VarDecl *synthesizePropertyWrapperProjectionVar( auto dc = var->getDeclContext(); if (dc->isTypeContext()) { dc->lookupQualified(dc->getSelfNominalTypeDecl(), projectionName, - NL_QualifiedDefault, declsFound); + var->getLoc(), NL_QualifiedDefault, declsFound); } else if (dc->isModuleScopeContext()) { dc->lookupQualified(dc->getParentModule(), projectionName, - NL_QualifiedDefault, declsFound); + var->getLoc(), NL_QualifiedDefault, declsFound); } else { llvm_unreachable("Property wrappers don't work in local contexts"); } diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 6926bef6593d0..ef53dab93a395 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -1412,7 +1412,8 @@ static Type diagnoseUnknownType(TypeResolution resolution, NameLookupOptions relookupOptions = lookupOptions; relookupOptions |= NameLookupFlags::IgnoreAccessControl; auto inaccessibleMembers = TypeChecker::lookupMemberType( - dc, parentType, repr->getNameRef(), relookupOptions); + dc, parentType, repr->getNameRef(), + repr->getLoc(), relookupOptions); if (inaccessibleMembers) { // FIXME: What if the unviable candidates have different levels of access? const TypeDecl *first = inaccessibleMembers.front().Member; @@ -1443,8 +1444,8 @@ static Type diagnoseUnknownType(TypeResolution resolution, NLOptions memberLookupOptions = (NL_QualifiedDefault | NL_IgnoreAccessControl); SmallVector results; - dc->lookupQualified(parentType, repr->getNameRef(), memberLookupOptions, - results); + dc->lookupQualified(parentType, repr->getNameRef(), repr->getLoc(), + memberLookupOptions, results); // Looks like this is not a member type, but simply a member of parent type. if (!results.empty()) { @@ -1834,7 +1835,7 @@ static Type resolveQualifiedIdentTypeRepr(TypeResolution resolution, LookupTypeResult memberTypes; if (parentTy->mayHaveMembers()) memberTypes = TypeChecker::lookupMemberType( - DC, parentTy, repr->getNameRef(), lookupOptions); + DC, parentTy, repr->getNameRef(), repr->getLoc(), lookupOptions); // Name lookup was ambiguous. Complain. // FIXME: Could try to apply generic arguments first, and see whether diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index 4cba8b17db863..22aed44dd31fc 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -914,6 +914,7 @@ LookupResult lookupUnqualifiedType( /// \returns The result of name lookup. LookupResult lookupMember(DeclContext *dc, Type type, DeclNameRef name, + SourceLoc loc = SourceLoc(), NameLookupOptions options = defaultMemberLookupOptions); /// Look up a member type within the given type. @@ -929,6 +930,7 @@ lookupMember(DeclContext *dc, Type type, DeclNameRef name, /// \returns The result of name lookup. LookupTypeResult lookupMemberType(DeclContext *dc, Type type, DeclNameRef name, + SourceLoc loc = SourceLoc(), NameLookupOptions options = defaultMemberTypeLookupOptions); /// Given an expression that's known to be an infix operator, @@ -939,10 +941,6 @@ lookupPrecedenceGroupForInfixOperator(DeclContext *dc, Expr *op, bool diagnose); PrecedenceGroupLookupResult lookupPrecedenceGroup(DeclContext *dc, Identifier name, SourceLoc nameLoc); -SmallVector -lookupMacros(DeclContext *dc, DeclNameRef macroName, SourceLoc loc, - MacroRoles contexts); - enum class UnsupportedMemberTypeAccessKind : uint8_t { None, TypeAliasOfUnboundGeneric, diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 03fde6bb8ccac..4da0fd88b4d3e 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -1926,7 +1926,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) { getIdentifier(privateDiscriminator)); } else { baseModule->lookupQualified(baseModule, DeclNameRef(name), - NL_QualifiedDefault, + SourceLoc(), NL_QualifiedDefault, values); } filterValues(filterTy, nullptr, nullptr, isType, inProtocolExt, @@ -2113,7 +2113,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) { getIdentifier(privateDiscriminator)); } else { otherModule->lookupQualified(otherModule, DeclNameRef(name), - NL_QualifiedDefault, + SourceLoc(), NL_QualifiedDefault, values); } diff --git a/lib/Serialization/ModuleDependencyScanner.cpp b/lib/Serialization/ModuleDependencyScanner.cpp index 2d3de471e0247..335cfd1e185b4 100644 --- a/lib/Serialization/ModuleDependencyScanner.cpp +++ b/lib/Serialization/ModuleDependencyScanner.cpp @@ -22,6 +22,10 @@ #include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Serialization/ModuleDependencyScanner.h" #include "swift/Subsystems.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/CAS/CachingOnDiskFileSystem.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/VirtualFileSystem.h" #include "ModuleFileSharedCore.h" #include @@ -151,11 +155,6 @@ ErrorOr ModuleDependencyScanner::scanInterfaceFile( Args.push_back("-o"); Args.push_back(outputPathBase.str().str()); - std::vector ArgsRefs(Args.begin(), Args.end()); - Result = ModuleDependencyInfo::forSwiftInterfaceModule( - outputPathBase.str().str(), InPath, compiledCandidates, ArgsRefs, PCMArgs, - Hash, isFramework); - // Open the interface file. auto &fs = *Ctx.SourceMgr.getFileSystem(); auto interfaceBuf = fs.getBufferForFile(moduleInterfacePath); @@ -172,6 +171,21 @@ ErrorOr ModuleDependencyScanner::scanInterfaceFile( *moduleDecl, SourceFileKind::Interface, bufferID, parsingOpts); moduleDecl->addAuxiliaryFile(*sourceFile); + std::string RootID; + if (dependencyTracker) { + dependencyTracker->startTracking(); + dependencyTracker->trackFile(moduleInterfacePath); + auto RootOrError = dependencyTracker->createTreeFromDependencies(); + if (!RootOrError) + return llvm::errorToErrorCode(RootOrError.takeError()); + RootID = RootOrError->getID().toString(); + } + + std::vector ArgsRefs(Args.begin(), Args.end()); + Result = ModuleDependencyInfo::forSwiftInterfaceModule( + outputPathBase.str().str(), InPath, compiledCandidates, ArgsRefs, + PCMArgs, Hash, isFramework, RootID, /*module-cache-key*/ ""); + // Walk the source file to find the import declarations. llvm::StringSet<> alreadyAddedModules; Result->addModuleImport(*sourceFile, alreadyAddedModules); @@ -194,38 +208,41 @@ ErrorOr ModuleDependencyScanner::scanInterfaceFile( }); if (adjacentBinaryModule != compiledCandidates.end()) { // Required modules. - auto adjacentBinaryModuleRequiredImports = getModuleImportsOfModule( + auto adjacentBinaryModuleRequiredImports = getImportsOfModule( *adjacentBinaryModule, ModuleLoadingBehavior::Required, isFramework, isRequiredOSSAModules(), Ctx.LangOpts.SDKName, Ctx.LangOpts.PackageName, Ctx.SourceMgr.getFileSystem().get(), Ctx.SearchPathOpts.DeserializedPathRecoverer); if (!adjacentBinaryModuleRequiredImports) return adjacentBinaryModuleRequiredImports.getError(); - + auto adjacentBinaryModuleRequiredModuleImports = + (*adjacentBinaryModuleRequiredImports).moduleImports; #ifndef NDEBUG // Verify that the set of required modules read out from the binary // module is a super-set of module imports identified in the // textual interface. for (const auto &requiredImport : Result->getModuleImports()) { - assert(adjacentBinaryModuleRequiredImports->contains(requiredImport) && + assert(adjacentBinaryModuleRequiredModuleImports.contains(requiredImport) && "Expected adjacent binary module's import set to contain all " "textual interface imports."); } #endif - for (const auto &requiredImport : *adjacentBinaryModuleRequiredImports) + for (const auto &requiredImport : adjacentBinaryModuleRequiredModuleImports) Result->addModuleImport(requiredImport.getKey(), &alreadyAddedModules); // Optional modules. Will be looked-up on a best-effort basis - auto adjacentBinaryModuleOptionalImports = getModuleImportsOfModule( + auto adjacentBinaryModuleOptionalImports = getImportsOfModule( *adjacentBinaryModule, ModuleLoadingBehavior::Optional, isFramework, isRequiredOSSAModules(), Ctx.LangOpts.SDKName, Ctx.LangOpts.PackageName, Ctx.SourceMgr.getFileSystem().get(), Ctx.SearchPathOpts.DeserializedPathRecoverer); if (!adjacentBinaryModuleOptionalImports) return adjacentBinaryModuleOptionalImports.getError(); - for (const auto &optionalImport : *adjacentBinaryModuleOptionalImports) + auto adjacentBinaryModuleOptionalModuleImports = + (*adjacentBinaryModuleOptionalImports).moduleImports; + for (const auto &optionalImport : adjacentBinaryModuleOptionalModuleImports) Result->addOptionalModuleImport(optionalImport.getKey(), &alreadyAddedModules); } @@ -255,9 +272,10 @@ Optional SerializedModuleLoaderBase::getModuleDepen // FIXME: submodules? scanners.push_back(std::make_unique( Ctx, LoadMode, moduleId, Ctx.SearchPathOpts.PlaceholderDependencyModuleMap, - delegate)); + delegate, cache.getScanService().createSwiftDependencyTracker())); scanners.push_back(std::make_unique( - Ctx, LoadMode, moduleId, delegate)); + Ctx, LoadMode, moduleId, delegate, ModuleDependencyScanner::MDS_plain, + cache.getScanService().createSwiftDependencyTracker())); // Check whether there is a module with this name that we can import. assert(isa(scanners[0].get()) && diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp index 4e7bc7a429dce..98e7cf39b4641 100644 --- a/lib/Serialization/ModuleFile.cpp +++ b/lib/Serialization/ModuleFile.cpp @@ -560,7 +560,7 @@ void ModuleFile::getImportDecls(SmallVectorImpl &Results) { SmallVector Decls; TopLevelModule->lookupQualified( TopLevelModule, DeclNameRef(ScopeID), - NL_QualifiedDefault, Decls); + SourceLoc(), NL_QualifiedDefault, Decls); Optional FoundKind = ImportDecl::findBestImportKind(Decls); assert(FoundKind.has_value() && "deserialized imports should not be ambiguous"); diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 6b952b96295ae..56327b501b71a 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -392,8 +392,8 @@ std::error_code SerializedModuleLoaderBase::openModuleFile( return std::error_code(); } -llvm::ErrorOr> -SerializedModuleLoaderBase::getModuleImportsOfModule( +llvm::ErrorOr +SerializedModuleLoaderBase::getImportsOfModule( Twine modulePath, ModuleLoadingBehavior transitiveBehavior, bool isFramework, bool isRequiredOSSAModules, StringRef SDKName, StringRef packageName, llvm::vfs::FileSystem *fileSystem, @@ -403,6 +403,7 @@ SerializedModuleLoaderBase::getModuleImportsOfModule( return moduleBuf.getError(); llvm::StringSet<> importedModuleNames; + llvm::StringSet<> importedHeaders; // Load the module file without validation. std::shared_ptr loadedModuleFile; serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load( @@ -410,9 +411,10 @@ SerializedModuleLoaderBase::getModuleImportsOfModule( isRequiredOSSAModules, SDKName, recoverer, loadedModuleFile); for (const auto &dependency : loadedModuleFile->getDependencies()) { - // FIXME: Record header dependency? - if (dependency.isHeader()) + if (dependency.isHeader()) { + importedHeaders.insert(dependency.RawPath); continue; + } ModuleLoadingBehavior dependencyTransitiveBehavior = loadedModuleFile->getTransitiveLoadingBehavior( @@ -433,16 +435,13 @@ SerializedModuleLoaderBase::getModuleImportsOfModule( importedModuleNames.insert(moduleName); } - return importedModuleNames; + return SerializedModuleLoaderBase::BinaryModuleImports{importedModuleNames, importedHeaders}; } llvm::ErrorOr SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework) { const std::string moduleDocPath; const std::string sourceInfoPath; - // Map the set of dependencies over to the "module dependencies". - auto dependencies = ModuleDependencyInfo::forSwiftBinaryModule( - modulePath.str(), moduleDocPath, sourceInfoPath, isFramework); // Some transitive dependencies of binary modules are not required to be // imported during normal builds. // TODO: This is worth revisiting for debugger purposes where @@ -451,18 +450,37 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework) { // optional. ModuleLoadingBehavior transitiveLoadingBehavior = ModuleLoadingBehavior::Required; - auto importedModuleNames = getModuleImportsOfModule( + auto binaryModuleImports = getImportsOfModule( modulePath, transitiveLoadingBehavior, isFramework, isRequiredOSSAModules(), Ctx.LangOpts.SDKName, Ctx.LangOpts.PackageName, Ctx.SourceMgr.getFileSystem().get(), Ctx.SearchPathOpts.DeserializedPathRecoverer); - if (!importedModuleNames) - return importedModuleNames.getError(); + if (!binaryModuleImports) + return binaryModuleImports.getError(); + + auto importedModuleSet = binaryModuleImports.get().moduleImports; + std::vector importedModuleNames; + importedModuleNames.reserve(importedModuleSet.size()); + llvm::transform(importedModuleSet.keys(), + std::back_inserter(importedModuleNames), + [](llvm::StringRef N) { + return N.str(); + }); + + auto importedHeaderSet = binaryModuleImports.get().headerImports; + std::vector importedHeaders; + importedHeaders.reserve(importedHeaderSet.size()); + llvm::transform(importedHeaderSet.keys(), + std::back_inserter(importedHeaders), + [](llvm::StringRef N) { + return N.str(); + }); - llvm::StringSet<> addedModuleNames; - for (const auto &importedModuleName : *importedModuleNames) - dependencies.addModuleImport(importedModuleName.getKey(), - &addedModuleNames); + // Map the set of dependencies over to the "module dependencies". + auto dependencies = ModuleDependencyInfo::forSwiftBinaryModule( + modulePath.str(), moduleDocPath, sourceInfoPath, + importedModuleNames, importedHeaders, isFramework, + /*module-cache-key*/ ""); return std::move(dependencies); } diff --git a/stdlib/public/Cxx/CxxSet.swift b/stdlib/public/Cxx/CxxSet.swift index 02dec94fb1193..e3f143da45b60 100644 --- a/stdlib/public/Cxx/CxxSet.swift +++ b/stdlib/public/Cxx/CxxSet.swift @@ -13,11 +13,31 @@ public protocol CxxSet { associatedtype Element associatedtype Size: BinaryInteger + associatedtype InsertionResult // std::pair + + init() + + @discardableResult + mutating func __insertUnsafe(_ element: Element) -> InsertionResult func count(_ element: Element) -> Size } extension CxxSet { + /// Creates a C++ set containing the elements of a Swift Sequence. + /// + /// This initializes the set by copying every element of the sequence. + /// + /// - Complexity: O(*n*), where *n* is the number of elements in the Swift + /// sequence + @inlinable + public init(_ sequence: S) where S.Element == Element { + self.init() + for item in sequence { + self.__insertUnsafe(item) + } + } + @inlinable public func contains(_ element: Element) -> Bool { return count(element) > 0 diff --git a/stdlib/public/Windows/WinSDK.swift b/stdlib/public/Windows/WinSDK.swift index 81ca84b32ecff..ac2319415fcaf 100644 --- a/stdlib/public/Windows/WinSDK.swift +++ b/stdlib/public/Windows/WinSDK.swift @@ -77,6 +77,20 @@ public var FIONBIO: Int32 { public var CW_USEDEFAULT: Int32 { Int32(bitPattern: 2147483648) } + +public var QS_MOUSE: UINT { + UINT(QS_MOUSEMOVE | QS_MOUSEBUTTON) +} +public var QS_INPUT: UINT { + QS_MOUSE | UINT(QS_KEY | QS_RAWINPUT | QS_TOUCH | QS_POINTER) +} +public var QS_ALLEVENTS: UINT { + QS_INPUT | UINT(QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY) +} +public var QS_ALLINPUT: UINT { + QS_INPUT | UINT(QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE) +} + public var WS_OVERLAPPEDWINDOW: UINT { UINT(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) } diff --git a/stdlib/public/core/Duration.swift b/stdlib/public/core/Duration.swift index 737b77971b3e2..5d4319aca0341 100644 --- a/stdlib/public/core/Duration.swift +++ b/stdlib/public/core/Duration.swift @@ -122,7 +122,7 @@ extension Duration { // handle them slightly differently to ensure that integer values are // never rounded if `scale` is representable as Double. let integralPart = duration.rounded(.towardZero) - let fractionalPart = integralPart - duration + let fractionalPart = duration - integralPart self.init(_attoseconds: // This term may trap due to overflow, but it cannot round, so if the // input `seconds` is an exact integer, we get an exact integer result. diff --git a/stdlib/public/runtime/CrashHandlerLinux.cpp b/stdlib/public/runtime/CrashHandlerLinux.cpp index 2913245b97566..526b7a7a3c04e 100644 --- a/stdlib/public/runtime/CrashHandlerLinux.cpp +++ b/stdlib/public/runtime/CrashHandlerLinux.cpp @@ -62,10 +62,12 @@ void resume_other_threads(); void take_thread_lock(); void release_thread_lock(); void notify_paused(); +uint32_t currently_paused(); void wait_paused(uint32_t expected, const struct timespec *timeout); int memserver_start(); int memserver_entry(void *); bool run_backtracer(int fd); +void format_unsigned(unsigned u, char buffer[22]); ssize_t safe_read(int fd, void *buf, size_t len) { uint8_t *ptr = (uint8_t *)buf; @@ -88,7 +90,7 @@ ssize_t safe_read(int fd, void *buf, size_t len) { } ssize_t safe_write(int fd, const void *buf, size_t len) { - const uint8_t *ptr = (uint8_t *)buf; + const uint8_t *ptr = (const uint8_t *)buf; const uint8_t *end = ptr + len; ssize_t total = 0; @@ -308,6 +310,124 @@ getdents(int fd, void *buf, size_t bufsiz) return syscall(SYS_getdents64, fd, buf, bufsiz); } +/* Find the signal to use to suspend the given thread. + + Sadly, libdispatch blocks SIGUSR1, so we can't just use that everywhere; + and on Ubuntu 20.04 *something* is starting a thread with SIGPROF blocked, + so we can't just use that either. + + We also can't modify the signal mask for another thread, since there is + no syscall to do that. + + As a workaround, read /proc//task//status to find the signal + mask so that we can decide which signal to try and send. */ +int +signal_for_suspend(int pid, int tid) +{ + char pid_buffer[22]; + char tid_buffer[22]; + + format_unsigned((unsigned)pid, pid_buffer); + format_unsigned((unsigned)tid, tid_buffer); + + char status_file[6 + 22 + 6 + 22 + 7 + 1]; + + strcpy(status_file, "/proc/"); // 6 + strcat(status_file, pid_buffer); // 22 + strcat(status_file, "/task/"); // 6 + strcat(status_file, tid_buffer); // 22 + strcat(status_file, "/status"); // 7 + 1 for NUL + + int fd = open(status_file, O_RDONLY); + if (fd < 0) + return -1; + + enum match_state { + Matching, + EatLine, + AfterMatch, + InHex, + + // states after this terminate the loop + Done, + Bad + }; + + enum match_state state = Matching; + const char *toMatch = "SigBlk:"; + const char *matchPtr = toMatch; + char buffer[256]; + uint64_t mask = 0; + ssize_t count; + while (state < Done && (count = read(fd, buffer, sizeof(buffer))) > 0) { + char *ptr = buffer; + char *end = buffer + count; + + while (state < Done && ptr < end) { + int ch = *ptr++; + + switch (state) { + case Matching: + if (ch != *matchPtr) { + state = EatLine; + matchPtr = toMatch; + } else if (!*++matchPtr) { + state = AfterMatch; + } + break; + case EatLine: + if (ch == '\n') + state = Matching; + break; + case AfterMatch: + if (ch == ' ' || ch == '\t') { + break; + } + state = InHex; + SWIFT_FALLTHROUGH; + case InHex: + if (ch >= '0' && ch <= '9') { + mask = (mask << 4) | (ch - '0'); + } else if (ch >= 'a' && ch <= 'f') { + mask = (mask << 4) | (ch - 'a' + 10); + } else if (ch >= 'A' && ch <= 'F') { + mask = (mask << 4) | (ch - 'A' + 10); + } else if (ch == '\n') { + state = Done; + break; + } else { + state = Bad; + } + break; + case Done: + case Bad: + break; + } + } + } + + close(fd); + + if (state == Done) { + if (!(mask & (1 << (SIGUSR1 - 1)))) + return SIGUSR1; + else if (!(mask & (1 << (SIGUSR2 - 1)))) + return SIGUSR2; + else if (!(mask & (1 << (SIGPROF - 1)))) + return SIGPROF; + else + return -1; + } + + return -1; +} + +// Write a string to stderr +void +warn(const char *str) { + write(STDERR_FILENO, str, strlen(str)); +} + /* Stop all other threads in this process; we do this by establishing a signal handler for SIGPROF, then iterating through the threads sending SIGPROF. @@ -321,7 +441,7 @@ getdents(int fd, void *buf, size_t bufsiz) void suspend_other_threads(struct thread *self) { - struct sigaction sa, sa_old; + struct sigaction sa, sa_old_prof, sa_old_usr1, sa_old_usr2; // Take the lock take_thread_lock(); @@ -329,13 +449,15 @@ suspend_other_threads(struct thread *self) // Start the thread list with this thread reset_threads(self); - // Swap out the SIGPROF signal handler first + // Swap out the signal handlers first sigfillset(&sa.sa_mask); - sa.sa_flags = SA_NODEFER; + sa.sa_flags = 0; sa.sa_handler = NULL; sa.sa_sigaction = pause_thread; - sigaction(SIGPROF, &sa, &sa_old); + sigaction(SIGPROF, &sa, &sa_old_prof); + sigaction(SIGUSR1, &sa, &sa_old_usr1); + sigaction(SIGUSR2, &sa, &sa_old_usr2); /* Now scan /proc/self/task to get the tids of the threads in this process. We need to ignore our own thread. */ @@ -346,11 +468,14 @@ suspend_other_threads(struct thread *self) size_t offset = 0; size_t count = 0; - uint32_t thread_count = 0; - uint32_t old_thread_count; + unsigned max_loops = 15; + uint32_t pending = 0; do { - old_thread_count = thread_count; + uint32_t paused = currently_paused(); + + pending = 0; + lseek(fd, 0, SEEK_SET); for (;;) { @@ -372,21 +497,35 @@ suspend_other_threads(struct thread *self) int tid = atoi(dp->d_name); if ((int64_t)tid != self->tid && !seen_thread(tid)) { - tgkill(our_pid, tid, SIGPROF); - ++thread_count; + int sig_to_use = signal_for_suspend(our_pid, tid); + + if (sig_to_use > 0) { + tgkill(our_pid, tid, sig_to_use); + ++pending; + } else { + warn("swift-runtime: unable to suspend thread "); + warn(dp->d_name); + warn("\n"); + } } } - // Wait up to 5 seconds for the threads to pause - struct timespec timeout = { 5, 0 }; - wait_paused(thread_count, &timeout); - } while (old_thread_count != thread_count); + // If we find no new threads, we're done + if (!pending) + break; + + // Wait for the threads to suspend + struct timespec timeout = { 2, 0 }; + wait_paused(paused + pending, &timeout); + } while (max_loops--); // Close the directory close(fd); - // Finally, reset the signal handler - sigaction(SIGPROF, &sa_old, NULL); + // Finally, reset the signal handlers + sigaction(SIGPROF, &sa_old_prof, NULL); + sigaction(SIGUSR1, &sa_old_usr1, NULL); + sigaction(SIGUSR2, &sa_old_usr2, NULL); } void @@ -441,6 +580,12 @@ notify_paused() futex(&threads_paused, FUTEX_WAKE, 1, NULL, NULL, 0); } +uint32_t +currently_paused() +{ + return __atomic_load_n(&threads_paused, __ATOMIC_ACQUIRE); +} + void wait_paused(uint32_t expected, const struct timespec *timeout) { diff --git a/stdlib/public/runtime/Enum.cpp b/stdlib/public/runtime/Enum.cpp index 92967e05bd366..f1fdddd3a386e 100644 --- a/stdlib/public/runtime/Enum.cpp +++ b/stdlib/public/runtime/Enum.cpp @@ -214,6 +214,66 @@ swift::swift_initEnumMetadataMultiPayload(EnumMetadata *enumType, vwtable->publishLayout(layout); } +// void +// swift::swift_initEnumMetadataMultiPayloadWithLayoutString(EnumMetadata *enumType, +// EnumLayoutFlags layoutFlags, +// unsigned numPayloads, +// const TypeLayout * const *payloadLayouts) { + // // Accumulate the layout requirements of the payloads. + // size_t payloadSize = 0, alignMask = 0; + // bool isPOD = true, isBT = true; + // for (unsigned i = 0; i < numPayloads; ++i) { + // const TypeLayout *payloadLayout = payloadLayouts[i]; + // payloadSize + // = std::max(payloadSize, (size_t)payloadLayout->size); + // alignMask |= payloadLayout->flags.getAlignmentMask(); + // isPOD &= payloadLayout->flags.isPOD(); + // isBT &= payloadLayout->flags.isBitwiseTakable(); + // } + + // // Store the max payload size in the metadata. + // assignUnlessEqual(enumType->getPayloadSize(), payloadSize); + + // // The total size includes space for the tag. + // auto tagCounts = getEnumTagCounts(payloadSize, + // enumType->getDescription()->getNumEmptyCases(), + // numPayloads); + // unsigned totalSize = payloadSize + tagCounts.numTagBytes; + + // // See whether there are extra inhabitants in the tag. + // unsigned numExtraInhabitants = tagCounts.numTagBytes == 4 + // ? INT_MAX + // : (1 << (tagCounts.numTagBytes * 8)) - tagCounts.numTags; + // numExtraInhabitants = std::min(numExtraInhabitants, + // unsigned(ValueWitnessFlags::MaxNumExtraInhabitants)); + + // auto vwtable = getMutableVWTableForInit(enumType, layoutFlags); + + // // Set up the layout info in the vwtable. + // auto rawStride = (totalSize + alignMask) & ~alignMask; + // TypeLayout layout{totalSize, + // rawStride == 0 ? 1 : rawStride, + // ValueWitnessFlags() + // .withAlignmentMask(alignMask) + // .withPOD(isPOD) + // .withBitwiseTakable(isBT) + // .withEnumWitnesses(true) + // .withInlineStorage(ValueWitnessTable::isValueInline( + // isBT, totalSize, alignMask + 1)), + // numExtraInhabitants}; + + // installCommonValueWitnesses(layout, vwtable); + + // // Unconditionally overwrite the enum-tag witnesses. + // // The compiler does not generate meaningful enum-tag witnesses for + // // enums in this state. + // vwtable->getEnumTagSinglePayload = swift_getMultiPayloadEnumTagSinglePayload; + // vwtable->storeEnumTagSinglePayload = + // swift_storeMultiPayloadEnumTagSinglePayload; + + // vwtable->publishLayout(layout); +//} + namespace { struct MultiPayloadLayout { size_t payloadSize; diff --git a/stdlib/tools/swift-reflection-test/swift-reflection-test.c b/stdlib/tools/swift-reflection-test/swift-reflection-test.c index 5339f0b0c544b..c4f9c0c75d006 100644 --- a/stdlib/tools/swift-reflection-test/swift-reflection-test.c +++ b/stdlib/tools/swift-reflection-test/swift-reflection-test.c @@ -764,10 +764,6 @@ int doDumpHeapInstance(const char *BinaryFilename) { exit(status); } default: { // Parent - for (int i = 5; i > 1; i--) { - fprintf(stderr, "%d\n", i); - sleep(1); - } close(PipeMemoryReader_getChildReadFD(&Pipe)); close(PipeMemoryReader_getChildWriteFD(&Pipe)); SwiftReflectionContextRef RC = diff --git a/test/CAS/Inputs/SwiftDepsExtractor.py b/test/CAS/Inputs/SwiftDepsExtractor.py new file mode 100755 index 0000000000000..9666127c2ed86 --- /dev/null +++ b/test/CAS/Inputs/SwiftDepsExtractor.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# +# Usage: SwiftDepsExtractor.py file.json ModuleName Key + +import json +import sys + +input_json = sys.argv[1] +module_name = sys.argv[2] +key = sys.argv[3] + +mode = 'swift' + +if module_name.startswith('clang:'): + mode = 'clang' + module_name = module_name[6:] +elif module_name.startswith('swiftPrebuiltExternal:'): + mode = 'swiftPrebuiltExternal' + module_name = module_name[22:] + +with open(input_json, 'r') as file: + deps = json.load(file) + module_names = deps['modules'][::2] + module_details = deps['modules'][1::2] + for name, detail in zip(module_names, module_details): + if name.get(mode, '') != module_name: + continue + + if key in detail.keys(): + print(detail[key]) + break + + print(detail['details'][mode][key]) + break diff --git a/test/CAS/binary_module_deps.swift b/test/CAS/binary_module_deps.swift new file mode 100644 index 0000000000000..e59a88e17c09f --- /dev/null +++ b/test/CAS/binary_module_deps.swift @@ -0,0 +1,41 @@ +// REQUIRES: objc_interop + +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/clang-module-cache +// RUN: mkdir -p %t/cas + +// RUN: %target-swift-frontend -emit-module -module-cache-path %t/clang-module-cache %S/../ScanDependencies/Inputs/Swift/E.swiftinterface -o %t/E.swiftmodule -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -swift-version 4 +// RUN: %target-swift-frontend -emit-module -module-cache-path %t/clang-module-cache %S/../ScanDependencies/Inputs/Swift/A.swiftinterface -o %t/A.swiftmodule -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -swift-version 4 +// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %t -swift-version 4 -enable-cas -cas-path %t/cas +// RUN: %FileCheck %s -DTEMP=%t < %t/deps.json + +/// Test binary module key: binary module key is the CASID of itself. +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json swiftPrebuiltExternal:A moduleCacheKey > %t/A.key.casid +// RUN: llvm-cas --cas %t/cas --cat-blob @%t/A.key.casid > %t/Loaded.swiftmodule +// RUN: diff %t/A.swiftmodule %t/Loaded.swiftmodule + +import A +import E + + +/// Main module +// CHECK-LABEL: "swift": "deps" +// CHECK: "directDependencies": [ +// CHECK: "swiftPrebuiltExternal": "A" +// CHECK: "swiftPrebuiltExternal": "E" +// CHECK: "details": { +// CHECK: "casFSRootID" + +/// E.swiftmodule +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}E.swiftmodule", +// CHECK: "details": { +// CHECK: "swiftPrebuiltExternal": { +// CHECK: "compiledModulePath": +// CHECK: "moduleCacheKey": + +/// A.swiftmodule +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}A.swiftmodule", +// CHECK: "details": { +// CHECK: "swiftPrebuiltExternal": { +// CHECK: "compiledModulePath": +// CHECK: "moduleCacheKey": diff --git a/test/CAS/cas-explicit-module-map.swift b/test/CAS/cas-explicit-module-map.swift new file mode 100644 index 0000000000000..fec0dd188d2ec --- /dev/null +++ b/test/CAS/cas-explicit-module-map.swift @@ -0,0 +1,129 @@ +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/cas +// RUN: split-file %s %t +// RUN: %target-swift-emit-pcm -module-cache-path %t/clang-module-cache -module-name SwiftShims %swift-lib-dir/swift/shims/module.modulemap -o %t/SwiftShims.pcm +// RUN: %target-swift-emit-pcm -module-cache-path %t/clang-module-cache -module-name _SwiftConcurrencyShims %swift-lib-dir/swift/shims/module.modulemap -o %t/_SwiftConcurrencyShims.pcm +// RUN: %target-swift-frontend -emit-module -module-cache-path %t/clang-module-cache %t/A.swift -o %t/A.swiftmodule -swift-version 5 +// RUN: %target-swift-frontend -emit-module -module-cache-path %t/clang-module-cache %t/B.swift -o %t/B.swiftmodule -I %t -swift-version 5 +// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %t/Test.swift -o %t/deps.json -I %t -swift-version 5 -enable-cas -cas-path %t/cas + +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json swiftPrebuiltExternal:A moduleCacheKey | tr -d '\n' > %t/A.key +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json swiftPrebuiltExternal:B moduleCacheKey | tr -d '\n' > %t/B.key + +/// Prepare the cas objects that can be used to construct CompileJobResultSchema object. +// RUN: llvm-cas --cas %t/cas --get-cache-result @%t/A.key > %t/A.result +// RUN: llvm-cas --cas %t/cas --ls-node-refs @%t/A.result | tail -n 1 > %t/schema.casid +// RUN: llvm-cas --cas %t/cas --cat-blob @%t/A.result > %t/kind.blob + +/// Make keys for module loads. The result casid construction is tied with the actual structure of CompilerJobResultSchema. +// RUN: llvm-cas --cas %t/cas --make-blob --data %stdlib_module | tr -d '\n' > %t/Swift.key +// RUN: llvm-cas --cas %t/cas --make-node --data %t/kind.blob @%t/Swift.key @%t/schema.casid > %t/Swift.casid +// RUN: llvm-cas --cas %t/cas --put-cache-key @%t/Swift.key @%t/Swift.casid + +// RUN: llvm-cas --cas %t/cas --make-blob --data %ononesupport_module | tr -d '\n' > %t/ONone.key +// RUN: llvm-cas --cas %t/cas --make-node --data %t/kind.blob @%t/ONone.key @%t/schema.casid > %t/ONone.casid +// RUN: llvm-cas --cas %t/cas --put-cache-key @%t/ONone.key @%t/ONone.casid + +// RUN: llvm-cas --cas %t/cas --make-blob --data %concurrency_module | tr -d '\n' > %t/Concurrency.key +// RUN: llvm-cas --cas %t/cas --make-node --data %t/kind.blob @%t/Concurrency.key @%t/schema.casid > %t/Concurrency.casid +// RUN: llvm-cas --cas %t/cas --put-cache-key @%t/Concurrency.key @%t/Concurrency.casid + +// RUN: llvm-cas --cas %t/cas --make-blob --data %string_processing_module | tr -d '\n' > %t/String.key +// RUN: llvm-cas --cas %t/cas --make-node --data %t/kind.blob @%t/String.key @%t/schema.casid > %t/String.casid +// RUN: llvm-cas --cas %t/cas --put-cache-key @%t/String.key @%t/String.casid + +// RUN: llvm-cas --cas %t/cas --make-blob --data %t/SwiftShims.pcm | tr -d '\n' > %t/Shims.key +// RUN: llvm-cas --cas %t/cas --make-node --data %t/kind.blob @%t/Shims.key @%t/schema.casid > %t/Shims.casid +// RUN: llvm-cas --cas %t/cas --put-cache-key @%t/Shims.key @%t/Shims.casid + +// RUN: llvm-cas --cas %t/cas --make-blob --data %t/_SwiftConcurrencyShims.pcm | tr -d '\n' > %t/ConcurrencyShims.key +// RUN: llvm-cas --cas %t/cas --make-node --data %t/kind.blob @%t/ConcurrencyShims.key @%t/schema.casid > %t/ConcurrencyShims.casid +// RUN: llvm-cas --cas %t/cas --put-cache-key @%t/ConcurrencyShims.key @%t/ConcurrencyShims.casid + +// RUN: echo "[{" > %/t/map.json +// RUN: echo "\"moduleName\": \"A\"," >> %/t/map.json +// RUN: echo "\"modulePath\": \"A.swiftmodule\"," >> %/t/map.json +// RUN: echo -n "\"moduleCacheKey\": \"" >> %/t/map.json +// RUN: cat %t/A.key >> %/t/map.json +// RUN: echo "\"," >> %/t/map.json +// RUN: echo "\"isFramework\": false" >> %/t/map.json +// RUN: echo "}," >> %/t/map.json +// RUN: echo "{" >> %/t/map.json +// RUN: echo "\"moduleName\": \"B\"," >> %/t/map.json +// RUN: echo "\"modulePath\": \"B.swiftmodule\"," >> %/t/map.json +// RUN: echo -n "\"moduleCacheKey\": \"" >> %/t/map.json +// RUN: cat %t/B.key >> %/t/map.json +// RUN: echo "\"," >> %/t/map.json +// RUN: echo "\"isFramework\": false" >> %/t/map.json +// RUN: echo "}," >> %/t/map.json +// RUN: echo "{" >> %/t/map.json +// RUN: echo "\"moduleName\": \"Swift\"," >> %/t/map.json +// RUN: echo "\"modulePath\": \"Swift.swiftmodule\"," >> %/t/map.json +// RUN: echo -n "\"moduleCacheKey\": \"" >> %/t/map.json +// RUN: cat %t/Swift.key >> %/t/map.json +// RUN: echo "\"," >> %/t/map.json +// RUN: echo "\"isFramework\": false" >> %/t/map.json +// RUN: echo "}," >> %/t/map.json +// RUN: echo "{" >> %/t/map.json +// RUN: echo "\"moduleName\": \"SwiftOnoneSupport\"," >> %/t/map.json +// RUN: echo "\"modulePath\": \"SwiftOnoneSupport.swiftmodule\"," >> %/t/map.json +// RUN: echo -n "\"moduleCacheKey\": \"" >> %/t/map.json +// RUN: cat %t/ONone.key >> %/t/map.json +// RUN: echo "\"," >> %/t/map.json +// RUN: echo "\"isFramework\": false" >> %/t/map.json +// RUN: echo "}," >> %/t/map.json +// RUN: echo "{" >> %/t/map.json +// RUN: echo "\"moduleName\": \"_Concurrency\"," >> %/t/map.json +// RUN: echo "\"modulePath\": \"_Concurrency.swiftmodule\"," >> %/t/map.json +// RUN: echo -n "\"moduleCacheKey\": \"" >> %/t/map.json +// RUN: cat %t/Concurrency.key >> %/t/map.json +// RUN: echo "\"," >> %/t/map.json +// RUN: echo "\"isFramework\": false" >> %/t/map.json +// RUN: echo "}," >> %/t/map.json +// RUN: echo "{" >> %/t/map.json +// RUN: echo "\"moduleName\": \"_StringProcessing\"," >> %/t/map.json +// RUN: echo "\"modulePath\": \"_StringProcessing.swiftmodule\"," >> %/t/map.json +// RUN: echo -n "\"moduleCacheKey\": \"" >> %/t/map.json +// RUN: cat %t/String.key >> %/t/map.json +// RUN: echo "\"," >> %/t/map.json +// RUN: echo "\"isFramework\": false" >> %/t/map.json +// RUN: echo "}," >> %/t/map.json +// RUN: echo "{" >> %/t/map.json +// RUN: echo "\"moduleName\": \"SwiftShims\"," >> %/t/map.json +// RUN: echo "\"clangModulePath\": \"SwiftShims.pcm\"," >> %/t/map.json +// RUN: echo -n "\"clangModuleCacheKey\": \"" >> %/t/map.json +// RUN: cat %t/Shims.key >> %/t/map.json +// RUN: echo "\"," >> %/t/map.json +// RUN: echo "\"isFramework\": false" >> %/t/map.json +// RUN: echo "}," >> %/t/map.json +// RUN: echo "{" >> %/t/map.json +// RUN: echo "\"moduleName\": \"_SwiftConcurrencyShims\"," >> %/t/map.json +// RUN: echo "\"clangModulePath\": \"_SwiftConcurrency.pcm\"," >> %/t/map.json +// RUN: echo -n "\"clangModuleCacheKey\": \"" >> %/t/map.json +// RUN: cat %t/ConcurrencyShims.key >> %/t/map.json +// RUN: echo "\"," >> %/t/map.json +// RUN: echo "\"isFramework\": false" >> %/t/map.json +// RUN: echo "}]" >> %/t/map.json + +// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid + +// RUN: %target-swift-frontend -emit-module -emit-module-path %t/Foo.swiftmodule -disable-implicit-swift-modules -module-cache-path %t.module-cache -explicit-swift-module-map-file @%t/map.casid -Rmodule-loading -Xcc -Rmodule-import %s -enable-cas -cas-path %t/cas -allow-unstable-cache-key-for-testing 2>&1 | %FileCheck %s + +// CHECK-DAG: loaded module 'A' +// CHECK-DAG: loaded module 'B' +// CHECK-DAG: loaded module 'Swift' +// CHECK-DAG: loaded module '_StringProcessing' +// CHECK-DAG: loaded module '_Concurrency' +// CHECK-DAG: loaded module 'SwiftOnoneSupport' + +//--- A.swift +func test() {} + +//--- B.swift +import A +func myTest() {} + +//--- Test.swift +import B + + diff --git a/test/CAS/cas_fs.swift b/test/CAS/cas_fs.swift index 97bb238ae6c3d..8020d2963abee 100644 --- a/test/CAS/cas_fs.swift +++ b/test/CAS/cas_fs.swift @@ -8,7 +8,6 @@ // RUN: llvm-cas --cas %t/cas --ingest --data %s > %t/source.casid // RUN: not %target-swift-frontend -typecheck -enable-cas -cas-fs @%t/source.casid -cas-path %t/cas %s 2>&1 | %FileCheck %s --check-prefix NO-RESOURCES -// NO-RESOURCES: error: unable to set working directory // NO-RESOURCES: error: unable to load standard library /// Ingest the resource directory to satisfy the file system requirement. Also switch CWD to resource dir. diff --git a/test/CAS/module_deps.swift b/test/CAS/module_deps.swift new file mode 100644 index 0000000000000..4d646ad049415 --- /dev/null +++ b/test/CAS/module_deps.swift @@ -0,0 +1,195 @@ +// REQUIRES: objc_interop + +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/clang-module-cache +// RUN: mkdir -p %t/cas + +// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -enable-cas -cas-path %t/cas +// Check the contents of the JSON output +// RUN: %FileCheck -check-prefix CHECK -check-prefix CHECK_NO_CLANG_TARGET %s < %t/deps.json + +// Check the contents of the JSON output +// RUN: %FileCheck %s -check-prefix CHECK -check-prefix CHECK-NO-SEARCH-PATHS < %t/deps.json + +// Check the make-style dependencies file +// RUN: %FileCheck %s -check-prefix CHECK-MAKE-DEPS < %t/deps.d + +// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -enable-cas -cas-path %t/cas +// RUN: %FileCheck -check-prefix CHECK -check-prefix CHECK_NO_CLANG_TARGET %s < %t/deps.json + +// Ensure that scanning with `-clang-target` makes sure that Swift modules' respective PCM-dependency-build-argument sets do not contain target triples. +// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps_clang_target.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -clang-target %target-cpu-apple-macosx10.14 -enable-cas -cas-path %t/cas +// Check the contents of the JSON output +// RUN: %FileCheck -check-prefix CHECK_CLANG_TARGET %s < %t/deps_clang_target.json + +/// check cas-fs content +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json E casFSRootID > %t/E_fs.casid +// RUN: llvm-cas --cas %t/cas --ls-tree-recursive @%t/E_fs.casid | %FileCheck %s -check-prefix FS_ROOT_E +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json clang:F casFSRootID > %t/F_fs.casid +// RUN: llvm-cas --cas %t/cas --ls-tree-recursive @%t/F_fs.casid | %FileCheck %s -check-prefix FS_ROOT_F + +// FS_ROOT_E-DAG: E.swiftinterface +// FS_ROOT_E-DAG: SDKSettings.json + +// FS_ROOT_F: CHeaders/A.h +// FS_ROOT_F: CHeaders/B.h +// FS_ROOT_F: CHeaders/C.h +// FS_ROOT_F: CHeaders/D.h +// FS_ROOT_F: CHeaders/F.h +// FS_ROOT_F: CHeaders/G.h +// FS_ROOT_F: CHeaders/H.h +// FS_ROOT_F: CHeaders/I.h +// FS_ROOT_F: CHeaders/X.h +// FS_ROOT_F: CHeaders/module.modulemap + +import C +import E +import G +import SubE + +// CHECK: "mainModuleName": "deps" + +/// --------Main module +// CHECK-LABEL: "modulePath": "deps.swiftmodule", +// CHECK-NEXT: sourceFiles +// CHECK-NEXT: module_deps.swift +// CHECK-NEXT: ], +// CHECK-NEXT: "directDependencies": [ +// CHECK-DAG: "swift": "A" +// CHECK-DAG: "clang": "C" +// CHECK-DAG: "swift": "E" +// CHECK-DAG: "swift": "F" +// CHECK-DAG: "swift": "G" +// CHECK-DAG: "swift": "SubE" +// CHECK-DAG: "swift": "Swift" +// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK-DAG: "swift": "_Concurrency" +// CHECK-DAG: "swift": "_cross_import_E" +// CHECK: ], + +// CHECK: "extraPcmArgs": [ +// CHECK-NEXT: "-Xcc", +// CHECK-NEXT: "-target", +// CHECK-NEXT: "-Xcc", +// CHECK: "-fapinotes-swift-version=4" +// CHECK-NOT: "error: cannot open Swift placeholder dependency module map from" +// CHECK: "bridgingHeader": +// CHECK-NEXT: "path": +// CHECK-SAME: Bridging.h + +// CHECK-NEXT: "sourceFiles": +// CHECK-NEXT: Bridging.h +// CHECK-NEXT: BridgingOther.h + +// CHECK: "moduleDependencies": [ +// CHECK-NEXT: "F" +// CHECK-NEXT: ] + +/// --------Swift module A +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}A-{{.*}}.swiftmodule", + +// CHECK: directDependencies +// CHECK-NEXT: { +// CHECK-DAG: "clang": "A" +// CHECK-DAG: "swift": "Swift" +// CHECK-NEXT: }, +// CHECK: "details": +// CHECK: "moduleCacheKey": + +/// --------Swift module F +// CHECK: "modulePath": "{{.*}}{{/|\\}}F-{{.*}}.swiftmodule", +// CHECK-NEXT: "sourceFiles": [ +// CHECK-NEXT: ], +// CHECK-NEXT: "directDependencies": [ +// CHECK-NEXT: { +// CHECK-DAG: "clang": "F" +// CHECK-DAG: "swift": "Swift" +// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK: "details": +// CHECK: "moduleCacheKey": + +/// --------Swift module G +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}G-{{.*}}.swiftmodule" +// CHECK: "directDependencies" +// CHECK-NEXT: { +// CHECK-DAG: "clang": "G" +// CHECK-DAG: "swift": "Swift" +// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK: ], +// CHECK-NEXT: "details": { + +// CHECK: "contextHash": "{{.*}}", +// CHECK: "commandLine": [ +// CHECK: "-compile-module-from-interface" +// CHECK: "-target" +// CHECK: "-module-name" +// CHECK: "G" +// CHECK: "-swift-version" +// CHECK: "5" +// CHECK: ], +// CHECK_NO_CLANG_TARGET: "extraPcmArgs": [ +// CHECK_NO_CLANG_TARGET-NEXT: "-Xcc", +// CHECK_NO_CLANG_TARGET-NEXT: "-target", +// CHECK_CLANG_TARGET: "extraPcmArgs": [ +// CHECK_CLANG_TARGET-NEXT: "-Xcc", +// CHECK_CLANG_TARGET-NEXT: "-fapinotes-swift-version={{.*}}" +// CHECK_CLANG_TARGET-NEXT: ] + +/// --------Swift module E +// CHECK: "swift": "E" +// CHECK-LABEL: modulePath": "{{.*}}{{/|\\}}E-{{.*}}.swiftmodule" +// CHECK: "directDependencies" +// CHECK-NEXT: { +// CHECK-NEXT: "swift": "Swift" + +// CHECK: "moduleInterfacePath" +// CHECK-SAME: E.swiftinterface + +/// --------Swift module Swift +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}Swift-{{.*}}.swiftmodule", + +// CHECK: directDependencies +// CHECK-NEXT: { +// CHECK-NEXT: "clang": "SwiftShims" + +/// --------Clang module SwiftShims +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}SwiftShims-{{.*}}.pcm", +// CHECK: "contextHash": "[[SHIMS_CONTEXT:.*]]", +// CHECK: "-o" +// CHECK-NEXT: SwiftShims-{{.*}}[[SHIMS_CONTEXT]].pcm +// CHECK-NO-SEARCH-PATHS-NOT: "-prebuilt-module-cache-path" + +/// --------Clang module C +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}C-{{.*}}.pcm", + +// CHECK: "sourceFiles": [ +// CHECK-DAG: module.modulemap +// CHECK-DAG: C.h + +// CHECK: directDependencies +// CHECK-NEXT: { +// CHECK-NEXT: "clang": "B" + +// CHECK: "moduleMapPath" +// CHECK-SAME: module.modulemap + +// CHECK: "contextHash" +// CHECK-SAME: "{{.*}}" + +/// --------Clang module B +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}B-{{.*}}.pcm", +// CHECK: "contextHash": "[[B_CONTEXT:.*]]", +// CHECK: "-o" +// CHECK-NEXT: B-{{.*}}[[B_CONTEXT]].pcm + +// Check make-style dependencies +// CHECK-MAKE-DEPS: module_deps.swift +// CHECK-MAKE-DEPS-SAME: A.swiftinterface +// CHECK-MAKE-DEPS-SAME: G.swiftinterface +// CHECK-MAKE-DEPS-SAME: B.h +// CHECK-MAKE-DEPS-SAME: F.h +// CHECK-MAKE-DEPS-SAME: Bridging.h +// CHECK-MAKE-DEPS-SAME: BridgingOther.h +// CHECK-MAKE-DEPS-SAME: module.modulemap diff --git a/test/CAS/module_deps_include_tree.swift b/test/CAS/module_deps_include_tree.swift new file mode 100644 index 0000000000000..85c113e361bd2 --- /dev/null +++ b/test/CAS/module_deps_include_tree.swift @@ -0,0 +1,190 @@ +// REQUIRES: objc_interop + +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/clang-module-cache +// RUN: mkdir -p %t/cas + +// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -enable-cas -cas-path %t/cas -clang-include-tree +// Check the contents of the JSON output +// RUN: %FileCheck -check-prefix CHECK -check-prefix CHECK_NO_CLANG_TARGET %s < %t/deps.json + +// Check the contents of the JSON output +// RUN: %FileCheck %s -check-prefix CHECK -check-prefix CHECK-NO-SEARCH-PATHS < %t/deps.json + +// Check the make-style dependencies file +// RUN: %FileCheck %s -check-prefix CHECK-MAKE-DEPS < %t/deps.d + +// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -enable-cas -cas-path %t/cas -clang-include-tree +// RUN: %FileCheck -check-prefix CHECK -check-prefix CHECK_NO_CLANG_TARGET %s < %t/deps.json + +// Ensure that scanning with `-clang-target` makes sure that Swift modules' respective PCM-dependency-build-argument sets do not contain target triples. +// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps_clang_target.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -clang-target %target-cpu-apple-macosx10.14 -enable-cas -cas-path %t/cas -clang-include-tree +// Check the contents of the JSON output +// RUN: %FileCheck -check-prefix CHECK_CLANG_TARGET %s < %t/deps_clang_target.json + +/// check cas-fs content +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json E casFSRootID > %t/E_fs.casid +// RUN: llvm-cas --cas %t/cas --ls-tree-recursive @%t/E_fs.casid | %FileCheck %s -check-prefix FS_ROOT_E + +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json clang:F clangIncludeTree > %t/F_tree.casid +// RUN: clang-cas-test --cas %t/cas --print-include-tree @%t/F_tree.casid | %FileCheck %s -check-prefix INCLUDE_TREE_F + +// FS_ROOT_E-DAG: E.swiftinterface +// FS_ROOT_E-DAG: SDKSettings.json + +// INCLUDE_TREE_F: +// INCLUDE_TREE_F: +// INCLUDE_TREE_F: Files: +// INCLUDE_TREE_F-NEXT: CHeaders/F.h + +import C +import E +import G +import SubE + +// CHECK: "mainModuleName": "deps" + +/// --------Main module +// CHECK-LABEL: "modulePath": "deps.swiftmodule", +// CHECK-NEXT: sourceFiles +// CHECK-NEXT: module_deps_include_tree.swift +// CHECK-NEXT: ], +// CHECK-NEXT: "directDependencies": [ +// CHECK-DAG: "swift": "A" +// CHECK-DAG: "clang": "C" +// CHECK-DAG: "swift": "E" +// CHECK-DAG: "swift": "F" +// CHECK-DAG: "swift": "G" +// CHECK-DAG: "swift": "SubE" +// CHECK-DAG: "swift": "Swift" +// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK-DAG: "swift": "_Concurrency" +// CHECK-DAG: "swift": "_cross_import_E" +// CHECK: ], + +// CHECK: "extraPcmArgs": [ +// CHECK-NEXT: "-Xcc", +// CHECK-NEXT: "-target", +// CHECK-NEXT: "-Xcc", +// CHECK: "-fapinotes-swift-version=4" +// CHECK-NOT: "error: cannot open Swift placeholder dependency module map from" +// CHECK: "bridgingHeader": +// CHECK-NEXT: "path": +// CHECK-SAME: Bridging.h + +// CHECK-NEXT: "sourceFiles": +// CHECK-NEXT: Bridging.h +// CHECK-NEXT: BridgingOther.h + +// CHECK: "moduleDependencies": [ +// CHECK-NEXT: "F" +// CHECK-NEXT: ] + +/// --------Swift module A +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}A-{{.*}}.swiftmodule", + +// CHECK: directDependencies +// CHECK-NEXT: { +// CHECK-DAG: "clang": "A" +// CHECK-DAG: "swift": "Swift" +// CHECK-NEXT: }, +// CHECK: "details": +// CHECK: "moduleCacheKey": + +/// --------Swift module F +// CHECK: "modulePath": "{{.*}}{{/|\\}}F-{{.*}}.swiftmodule", +// CHECK-NEXT: "sourceFiles": [ +// CHECK-NEXT: ], +// CHECK-NEXT: "directDependencies": [ +// CHECK-NEXT: { +// CHECK-DAG: "clang": "F" +// CHECK-DAG: "swift": "Swift" +// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK: "details": +// CHECK: "moduleCacheKey": + +/// --------Swift module G +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}G-{{.*}}.swiftmodule" +// CHECK: "directDependencies" +// CHECK-NEXT: { +// CHECK-DAG: "clang": "G" +// CHECK-DAG: "swift": "Swift" +// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK: ], +// CHECK-NEXT: "details": { + +// CHECK: "contextHash": "{{.*}}", +// CHECK: "commandLine": [ +// CHECK: "-compile-module-from-interface" +// CHECK: "-target" +// CHECK: "-module-name" +// CHECK: "G" +// CHECK: "-swift-version" +// CHECK: "5" +// CHECK: ], +// CHECK_NO_CLANG_TARGET: "extraPcmArgs": [ +// CHECK_NO_CLANG_TARGET-NEXT: "-Xcc", +// CHECK_NO_CLANG_TARGET-NEXT: "-target", +// CHECK_CLANG_TARGET: "extraPcmArgs": [ +// CHECK_CLANG_TARGET-NEXT: "-Xcc", +// CHECK_CLANG_TARGET-NEXT: "-fapinotes-swift-version={{.*}}" +// CHECK_CLANG_TARGET-NEXT: ] + +/// --------Swift module E +// CHECK: "swift": "E" +// CHECK-LABEL: modulePath": "{{.*}}{{/|\\}}E-{{.*}}.swiftmodule" +// CHECK: "directDependencies" +// CHECK-NEXT: { +// CHECK-NEXT: "swift": "Swift" + +// CHECK: "moduleInterfacePath" +// CHECK-SAME: E.swiftinterface + +/// --------Swift module Swift +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}Swift-{{.*}}.swiftmodule", + +// CHECK: directDependencies +// CHECK-NEXT: { +// CHECK-NEXT: "clang": "SwiftShims" + +/// --------Clang module SwiftShims +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}SwiftShims-{{.*}}.pcm", +// CHECK: "contextHash": "[[SHIMS_CONTEXT:.*]]", +// CHECK: "-o" +// CHECK-NEXT: SwiftShims-{{.*}}[[SHIMS_CONTEXT]].pcm +// CHECK-NO-SEARCH-PATHS-NOT: "-prebuilt-module-cache-path" + +/// --------Clang module C +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}C-{{.*}}.pcm", + +// CHECK: "sourceFiles": [ +// CHECK-DAG: module.modulemap +// CHECK-DAG: C.h + +// CHECK: directDependencies +// CHECK-NEXT: { +// CHECK-NEXT: "clang": "B" + +// CHECK: "moduleMapPath" +// CHECK-SAME: module.modulemap + +// CHECK: "contextHash" +// CHECK-SAME: "{{.*}}" + +/// --------Clang module B +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}B-{{.*}}.pcm", +// CHECK: "contextHash": "[[B_CONTEXT:.*]]", +// CHECK: "-o" +// CHECK-NEXT: B-{{.*}}[[B_CONTEXT]].pcm + +// Check make-style dependencies +// CHECK-MAKE-DEPS: module_deps_include_tree.swift +// CHECK-MAKE-DEPS-SAME: A.swiftinterface +// CHECK-MAKE-DEPS-SAME: G.swiftinterface +// CHECK-MAKE-DEPS-SAME: B.h +// CHECK-MAKE-DEPS-SAME: F.h +// CHECK-MAKE-DEPS-SAME: Bridging.h +// CHECK-MAKE-DEPS-SAME: BridgingOther.h +// CHECK-MAKE-DEPS-SAME: module.modulemap diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 64dbbcaa0df45..cbbfdeffcbe74 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -71,6 +71,7 @@ function(get_test_dependencies SDK result_var_name) c-arcmt-test c-index-test clang + clang-cas-test count dsymutil FileCheck diff --git a/test/Constraints/issue-66561.swift b/test/Constraints/issue-66561.swift new file mode 100644 index 0000000000000..e1293ff0f6c47 --- /dev/null +++ b/test/Constraints/issue-66561.swift @@ -0,0 +1,36 @@ +// RUN: %target-typecheck-verify-swift + +// https://github.com/apple/swift/issues/66561 + +@propertyWrapper +struct WrapperValue { + var value: Value + init(wrappedValue: Value) { + self.value = wrappedValue + } + + var projectedValue: Self { + return self + } + + var wrappedValue: Value { + get { + self.value + } + set { + self.value = newValue + } + } +} + +func test() { + let _ = { + @WrapperValue var value: Bool = false + switch value { + case $value.wrappedValue: + break + default: + break + } + } +} diff --git a/test/Constraints/pack-expansion-expressions.swift b/test/Constraints/pack-expansion-expressions.swift index b773c333cc3c5..a718ed2944acd 100644 --- a/test/Constraints/pack-expansion-expressions.swift +++ b/test/Constraints/pack-expansion-expressions.swift @@ -553,3 +553,11 @@ do { _ = (repeat overloaded(1, each a)) } } + +func configure( + _ item: T, + with configuration: repeat (ReferenceWritableKeyPath, each Element) +) -> T { + repeat item[keyPath: (each configuration).0] = (each configuration).1 + return item +} diff --git a/test/Constraints/rdar110617471.swift b/test/Constraints/rdar110617471.swift new file mode 100644 index 0000000000000..305197320f2ec --- /dev/null +++ b/test/Constraints/rdar110617471.swift @@ -0,0 +1,25 @@ +// RUN: %target-typecheck-verify-swift + +// rdar://110617471: Make sure we can type-check this. +class C { + var prop = 0 +} + +func foo(_ fn: () -> Void) {} + +class D { + let c = C() + + func bar() { + foo { [c] in + foo { + switch 0 { + case c.prop: + break + default: + break + } + } + } + } +} diff --git a/test/IRGen/Inputs/AlwaysInlineIntoWithOpaque.swift b/test/IRGen/Inputs/AlwaysInlineIntoWithOpaque.swift index 09f572bb28ba1..b5ec362ecb8c7 100644 --- a/test/IRGen/Inputs/AlwaysInlineIntoWithOpaque.swift +++ b/test/IRGen/Inputs/AlwaysInlineIntoWithOpaque.swift @@ -14,3 +14,16 @@ public func testInlineWithOpaque() -> some P { } return 2.0 } + +@_alwaysEmitIntoClient +public func testInlineWithOpaqueUsableFromInline() -> some P { + if #available(macOS 9.0, *) { + return usableFromInline() + } + return 4.0 +} + +@usableFromInline +func usableFromInline() -> some P { + return 3 +} diff --git a/test/IRGen/Inputs/AlwaysInlineIntoWithOpaqueReplacement.swift b/test/IRGen/Inputs/AlwaysInlineIntoWithOpaqueReplacement.swift index 8ab8aa865d525..8201c853d1b78 100644 --- a/test/IRGen/Inputs/AlwaysInlineIntoWithOpaqueReplacement.swift +++ b/test/IRGen/Inputs/AlwaysInlineIntoWithOpaqueReplacement.swift @@ -6,3 +6,8 @@ extension Int : P { extension Double : P { } + +@usableFromInline +func usableFromInline() -> some P { + return 3 +} diff --git a/test/IRGen/opaque_result_alwaysInlineIntoClient.swift b/test/IRGen/opaque_result_alwaysInlineIntoClient.swift index 82674435a2fd3..c123861446a22 100644 --- a/test/IRGen/opaque_result_alwaysInlineIntoClient.swift +++ b/test/IRGen/opaque_result_alwaysInlineIntoClient.swift @@ -1,11 +1,11 @@ // RUN: %empty-directory(%t) -// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -parse-as-library -emit-library -emit-module-path %t/AlwaysInlineIntoWithOpaque.swiftmodule -module-name AlwaysInlineIntoWithOpaque %S/Inputs/AlwaysInlineIntoWithOpaque.swift -o %t/%target-library-name(AlwaysInlineIntoWithOpaque) +// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -parse-as-library -emit-library -emit-module-path %t/AlwaysInlineIntoWithOpaque.swiftmodule -module-name AlwaysInlineIntoWithOpaque -enable-library-evolution %S/Inputs/AlwaysInlineIntoWithOpaque.swift -o %t/%target-library-name(AlwaysInlineIntoWithOpaque) // RUN: %target-codesign %t/%target-library-name(AlwaysInlineIntoWithOpaque) // RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -lAlwaysInlineIntoWithOpaque -module-name main -I %t -L %t %s -o %t/a.out // RUN: %target-codesign %t/a.out // RUN: %target-run %t/a.out | %FileCheck %s -// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -parse-as-library -emit-library -emit-module-path %t/AlwaysInlineIntoWithOpaque.swiftmodule -module-name AlwaysInlineIntoWithOpaque %S/Inputs/AlwaysInlineIntoWithOpaqueReplacement.swift -o %t/%target-library-name(AlwaysInlineIntoWithOpaque) +// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -parse-as-library -emit-library -emit-module-path %t/AlwaysInlineIntoWithOpaque.swiftmodule -module-name AlwaysInlineIntoWithOpaque -enable-library-evolution %S/Inputs/AlwaysInlineIntoWithOpaqueReplacement.swift -o %t/%target-library-name(AlwaysInlineIntoWithOpaque) // RUN: %target-codesign %t/a.out // RUN: %target-run %t/a.out | %FileCheck %s @@ -27,3 +27,11 @@ public func test() { test() // CHECK: 1 + +public func testUsableFromInline() { + let p = testInlineWithOpaqueUsableFromInline() + print(p) +} + +testUsableFromInline() +// CHECK: 3 diff --git a/test/Interop/Cxx/class/Inputs/constructors.h b/test/Interop/Cxx/class/Inputs/constructors.h index 4421391fae127..7493fc91cf785 100644 --- a/test/Interop/Cxx/class/Inputs/constructors.h +++ b/test/Interop/Cxx/class/Inputs/constructors.h @@ -10,6 +10,11 @@ struct ImplicitDefaultConstructor { int x = 42; }; +struct DefaultedDefaultConstructor { + int x = 42; + DefaultedDefaultConstructor() = default; +}; + struct MemberOfClassType { ImplicitDefaultConstructor member; }; diff --git a/test/Interop/Cxx/class/constructors-executable.swift b/test/Interop/Cxx/class/constructors-executable.swift index 9a8eb852d46d2..1efbb2556b6cc 100644 --- a/test/Interop/Cxx/class/constructors-executable.swift +++ b/test/Interop/Cxx/class/constructors-executable.swift @@ -19,6 +19,12 @@ CxxConstructorTestSuite.test("ImplicitDefaultConstructor") { expectEqual(42, instance.x) } +CxxConstructorTestSuite.test("DefaultedDefaultConstructor") { + let instance = DefaultedDefaultConstructor() + + expectEqual(42, instance.x) +} + CxxConstructorTestSuite.test("MemberOfClassType") { let instance = MemberOfClassType() diff --git a/test/Interop/Cxx/class/constructors-module-interface.swift b/test/Interop/Cxx/class/constructors-module-interface.swift index fab9918de6771..5f39ea6e8c1aa 100644 --- a/test/Interop/Cxx/class/constructors-module-interface.swift +++ b/test/Interop/Cxx/class/constructors-module-interface.swift @@ -9,6 +9,11 @@ // CHECK-NEXT: init(x: Int32) // CHECK-NEXT: var x: Int32 // CHECK-NEXT: } +// CHECK-NEXT: struct DefaultedDefaultConstructor { +// CHECK-NEXT: init() +// CHECK-NEXT: init(x: Int32) +// CHECK-NEXT: var x: Int32 +// CHECK-NEXT: } // CHECK-NEXT: struct MemberOfClassType { // CHECK-NEXT: init() // CHECK-NEXT: init(member: ImplicitDefaultConstructor) diff --git a/test/Interop/Cxx/stdlib/use-std-map.swift b/test/Interop/Cxx/stdlib/use-std-map.swift index 189ca92c2692d..d3480bbe22db7 100644 --- a/test/Interop/Cxx/stdlib/use-std-map.swift +++ b/test/Interop/Cxx/stdlib/use-std-map.swift @@ -11,13 +11,11 @@ import Cxx var StdMapTestSuite = TestSuite("StdMap") -#if !os(Linux) // https://github.com/apple/swift/issues/61412 StdMapTestSuite.test("init") { let m = Map() expectEqual(m.size(), 0) expectTrue(m.empty()) } -#endif StdMapTestSuite.test("Map.subscript") { // This relies on the `std::map` conformance to `CxxDictionary` protocol. diff --git a/test/Interop/Cxx/stdlib/use-std-set.swift b/test/Interop/Cxx/stdlib/use-std-set.swift index 56f7b7672f166..95f0110908f10 100644 --- a/test/Interop/Cxx/stdlib/use-std-set.swift +++ b/test/Interop/Cxx/stdlib/use-std-set.swift @@ -47,4 +47,18 @@ StdSetTestSuite.test("MultisetOfCInt.contains") { expectFalse(s.contains(3)) } +StdSetTestSuite.test("SetOfCInt.init()") { + let s = SetOfCInt([1, 3, 5]) + expectTrue(s.contains(1)) + expectFalse(s.contains(2)) + expectTrue(s.contains(3)) +} + +StdSetTestSuite.test("UnorderedSetOfCInt.init()") { + let s = UnorderedSetOfCInt([1, 3, 5]) + expectTrue(s.contains(1)) + expectFalse(s.contains(2)) + expectTrue(s.contains(3)) +} + runAllTests() diff --git a/test/Macros/Inputs/syntax_macro_definitions.swift b/test/Macros/Inputs/syntax_macro_definitions.swift index b01cb48da66dc..3b4d17dc27118 100644 --- a/test/Macros/Inputs/syntax_macro_definitions.swift +++ b/test/Macros/Inputs/syntax_macro_definitions.swift @@ -1603,3 +1603,26 @@ extension SelfAlwaysEqualOperator: MemberMacro { ] } } + +public struct InitializableMacro: ConformanceMacro, MemberMacro { + public static func expansion( + of node: AttributeSyntax, + providingConformancesOf decl: some DeclGroupSyntax, + in context: some MacroExpansionContext + ) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] { + return [("Initializable", nil)] + } + + public static func expansion( + of node: AttributeSyntax, + providingMembersOf decl: some DeclGroupSyntax, + in context: some MacroExpansionContext + ) throws -> [DeclSyntax] { + let requirement: DeclSyntax = + """ + init(value: Int) {} + """ + + return [requirement] + } +} diff --git a/test/Macros/macro_expand_peers.swift b/test/Macros/macro_expand_peers.swift index 1f469a088a814..304c621f186fa 100644 --- a/test/Macros/macro_expand_peers.swift +++ b/test/Macros/macro_expand_peers.swift @@ -162,6 +162,16 @@ struct S2 { #endif } +#if TEST_DIAGNOSTICS +// Peer macros cannot introduce arbitrary names at global scope + +//expected-error@+1 {{'peer' macros are not allowed to introduce arbitrary names at global scope}} +@addCompletionHandlerArbitrarily(x) +func h(a: Int, for b: String, _ value: Double) async -> String { + return b +} +#endif + // Stored properties generated by a peer macro @attached(accessor) @attached(peer, names: prefixed(_)) diff --git a/test/Macros/top_level_freestanding.swift b/test/Macros/top_level_freestanding.swift index 3fd9c07c1d6bd..48fe22e78ca51 100644 --- a/test/Macros/top_level_freestanding.swift +++ b/test/Macros/top_level_freestanding.swift @@ -72,13 +72,17 @@ struct HasInnerClosure { #freestandingWithClosure(1) { x in x } } +#if TEST_DIAGNOSTICS // Arbitrary names at global scope #bitwidthNumberedStructs("MyIntGlobal") +// expected-error@-1 {{'declaration' macros are not allowed to introduce arbitrary names at global scope}} func testArbitraryAtGlobal() { _ = MyIntGlobal16() + // expected-error@-1 {{cannot find 'MyIntGlobal16' in scope}} } +#endif // DIAG_BUFFERS-DAG: @__swiftmacro_9MacroUser33_{{.*}}9stringifyfMf1_{{.*}}warning: 'deprecated()' is deprecated // DIAG_BUFFERS-DAG: @__swiftmacro_9MacroUser33_{{.*}}9stringifyfMf2_{{.*}}warning: 'deprecated()' is deprecated @@ -104,3 +108,24 @@ func testGlobalVariable() { } #endif + + +@freestanding(declaration) +macro Empty(_ closure: () -> T) = #externalMacro(module: "MacroDefinition", type: "EmptyDeclarationMacro") + +#Empty { + S(a: 10, b: 10) +} + +@attached(conformance) +@attached(member, names: named(init)) +macro Initializable() = #externalMacro(module: "MacroDefinition", type: "InitializableMacro") + +protocol Initializable { + init(value: Int) +} + +@Initializable +struct S { + init(a: Int, b: Int) {} +} diff --git a/test/SILGen/if_expr.swift b/test/SILGen/if_expr.swift index b85152bccce87..30a87fd3f72da 100644 --- a/test/SILGen/if_expr.swift +++ b/test/SILGen/if_expr.swift @@ -500,3 +500,11 @@ struct TestLValues { opt![keyPath: kp] = if .random() { 1 } else { throw Err() } } } + +func testNever1() -> Never { + if case let x = fatalError() { x } else { fatalError() } +} + +func testNever2() -> Never { + if .random() { fatalError() } else { fatalError() } +} diff --git a/test/SILGen/moveonly_escaping_closure.swift b/test/SILGen/moveonly_escaping_closure.swift index 5492cfad38810..1b20481e0147e 100644 --- a/test/SILGen/moveonly_escaping_closure.swift +++ b/test/SILGen/moveonly_escaping_closure.swift @@ -73,9 +73,9 @@ func testGlobalClosureCaptureVar() { x = SingleElt() globalClosureCaptureVar = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} // expected-error @-1:29 {{overlapping accesses, but deinitialization requires exclusive access}} // expected-note @-2:26 {{conflicting access is here}} } @@ -196,9 +196,9 @@ func testLocalVarClosureCaptureVar() { x = SingleElt() var f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} // expected-error @-1 {{overlapping accesses, but deinitialization requires exclusive access}} // expected-note @-2 {{conflicting access is here}} } @@ -257,9 +257,9 @@ func testInOutVarClosureCaptureVar(_ f: inout () -> ()) { x = SingleElt() f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} // expected-error @-1 {{overlapping accesses, but deinitialization requires exclusive access}} // expected-note @-2 {{conflicting access is here}} } @@ -326,9 +326,9 @@ func testConsumingEscapeClosureCaptureVar(_ f: consuming @escaping () -> ()) { x = SingleElt() f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} // expected-error @-1 {{overlapping accesses, but deinitialization requires exclusive access}} // expected-note @-2 {{conflicting access is here}} } @@ -379,9 +379,9 @@ func testGlobalClosureCaptureLet() { let x = SingleElt() globalClosureCaptureLet = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } globalClosureCaptureLet() } @@ -423,9 +423,9 @@ func testGlobalClosureCaptureLet() { // CHECK: } // end sil function '$s16moveonly_closure026testLocalLetClosureCaptureE0yyFyycfU_' func testLocalLetClosureCaptureLet() { let x = SingleElt() - // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x' cannot be consumed when captured by a closure}} - // expected-error @-3 {{noncopyable 'x' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + // expected-error @-3 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x) consumeVal(x) // expected-note {{consumed here}} @@ -471,9 +471,9 @@ func testLocalVarClosureCaptureLet() { let x = SingleElt() var f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } f = {} f() @@ -519,9 +519,9 @@ func testInOutVarClosureCaptureLet(_ f: inout () -> ()) { let x = SingleElt() f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } f() } @@ -575,9 +575,9 @@ func testConsumingEscapeClosureCaptureLet(_ f: consuming @escaping () -> ()) { let x = SingleElt() f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } f() } @@ -887,9 +887,9 @@ var globalClosureCaptureConsuming: () -> () = {} func testGlobalClosureCaptureConsuming(_ x: consuming SingleElt) { globalClosureCaptureConsuming = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} // expected-error @-1:29 {{overlapping accesses, but deinitialization requires exclusive access}} // expected-note @-2:26 {{conflicting access is here}} } @@ -963,9 +963,9 @@ func testLocalLetClosureCaptureConsuming(_ x: consuming SingleElt) { func testLocalLetClosureCaptureConsuming2(_ x: consuming SingleElt) -> (() -> ()) { let f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} // expected-error @-1 {{overlapping accesses, but deinitialization requires exclusive access}} // expected-note @-2 {{conflicting access is here}} } @@ -1019,9 +1019,9 @@ func testLocalLetClosureCaptureConsuming2(_ x: consuming SingleElt) -> (() -> () func testLocalVarClosureCaptureConsuming(_ x: consuming SingleElt) { var f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} // expected-error @-1 {{overlapping accesses, but deinitialization requires exclusive access}} // expected-note @-2 {{conflicting access is here}} } @@ -1087,9 +1087,9 @@ func testLocalVarClosureCaptureConsuming(_ x: consuming SingleElt) { func testConsumingEscapeClosureCaptureConsuming(_ f: consuming @escaping () -> (), _ x: consuming SingleElt) { f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} // expected-error @-1 {{overlapping accesses, but deinitialization requires exclusive access}} // expected-note @-2 {{conflicting access is here}} } @@ -1139,9 +1139,9 @@ var globalClosureCaptureOwned: () -> () = {} func testGlobalClosureCaptureOwned(_ x: __owned SingleElt) { globalClosureCaptureOwned = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } globalClosureCaptureOwned() } @@ -1182,9 +1182,9 @@ func testGlobalClosureCaptureOwned(_ x: __owned SingleElt) { // CHECK: apply {{%.*}}([[LOADED_READ]], [[LOADED_TAKE]]) // CHECK: } // end sil function '$s16moveonly_closure31testLocalLetClosureCaptureOwnedyyAA9SingleEltVnFyycfU_' func testLocalLetClosureCaptureOwned(_ x: __owned SingleElt) { - // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x' cannot be consumed when captured by a closure}} - // expected-error @-3 {{noncopyable 'x' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + // expected-error @-3 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x) consumeVal(x) // expected-note {{consumed here}} @@ -1229,9 +1229,9 @@ func testLocalLetClosureCaptureOwned(_ x: __owned SingleElt) { func testLocalVarClosureCaptureOwned(_ x: __owned SingleElt) { var f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } f = {} f() @@ -1276,9 +1276,9 @@ func testLocalVarClosureCaptureOwned(_ x: __owned SingleElt) { func testInOutVarClosureCaptureOwned(_ f: inout () -> (), _ x: __owned SingleElt) { f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } f() } @@ -1332,9 +1332,9 @@ func testConsumingEscapeClosureCaptureOwned(_ f: consuming @escaping () -> (), _ x: __owned SingleElt) { f = { borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} - borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} + borrowConsumeVal(x, x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } f() } @@ -1373,7 +1373,7 @@ func closureCoroutineAssignmentLetConsumingArgument(_ e: __owned Empty) { func closureCoroutineAssignmentVarConsumingArgument(_ e: consuming Empty) { let f: () -> () = { - _ = e // expected-error {{noncopyable 'e' cannot be consumed when captured by a closure}} + _ = e // expected-error {{noncopyable 'e' cannot be consumed when captured by an escaping closure}} } var c = ClosureHolder() c.fCoroutine = f @@ -1392,7 +1392,7 @@ func closureCoroutineAssignmentVarBinding() { var e = Empty() e = Empty() let f: () -> () = { - _ = e // expected-error {{noncopyable 'e' cannot be consumed when captured by a closure}} + _ = e // expected-error {{noncopyable 'e' cannot be consumed when captured by an escaping closure}} } var c = ClosureHolder() c.fCoroutine = f diff --git a/test/SILGen/switch_expr.swift b/test/SILGen/switch_expr.swift index 310dc90329ab3..c590be65d2597 100644 --- a/test/SILGen/switch_expr.swift +++ b/test/SILGen/switch_expr.swift @@ -616,3 +616,90 @@ func exprPatternInClosure() { } } } + +func testNeverSwitch1() { + let x = switch fatalError() {} + return x +} + +func testNeverSwitch2() -> Never { + let x = switch fatalError() { + case let x: x + } + return x +} + +func testNeverSwitch3() -> Int { + let x = switch fatalError() { + case fatalError(): 0 + case _ where .random(): 1 + default: 2 + } + return x +} + +func testNeverSwitch4() { + let x: Void + x = switch fatalError() {} + return x +} + +func testNeverSwitch5() -> Never { + let x: Never + x = switch fatalError() { + case let x: x + } + return x +} + +func testNeverSwitch6() -> Int { + let x: Int + x = switch fatalError() { + case fatalError(): 0 + case _ where .random(): 1 + default: 2 + } + return x +} + +func testNeverSwitch7() { + let _ = switch fatalError() {} + let _ = switch fatalError() { case let x: x } + let _ = switch fatalError() { default: "" } +} + +func testNeverSwitch8() { + let _ = switch fatalError() { default: C() } +} + +func testNeverSwitch9() { + let i = switch Bool.random() { + case true: + switch fatalError() {} + case false: + switch fatalError() {} + } + return i +} + +func testNeverSwitch10() -> Never { + switch fatalError() {} +} + +func testNeverSwitch11() { + return switch fatalError() {} +} + +func testNeverSwitch12() -> Never { + return switch fatalError() { case let x: x } +} + +func testNeverSwitch13() { + return switch fatalError() { case let x: x } +} + +extension Never { + init(value: Self) { + self = switch value { case let v: v } + } +} diff --git a/test/SILOptimizer/definite_init_moveonly_controlflowdep_init.sil b/test/SILOptimizer/definite_init_moveonly_controlflowdep_init.sil index f8030b7a933c7..fad9172ba0eec 100644 --- a/test/SILOptimizer/definite_init_moveonly_controlflowdep_init.sil +++ b/test/SILOptimizer/definite_init_moveonly_controlflowdep_init.sil @@ -119,7 +119,7 @@ bb3: %23 = apply %22(%21) : $@convention(thin) (@guaranteed S) -> () destroy_value %21 : $S %25 = mark_must_check [assignable_but_not_consumable] %3 : $*S - // expected-error @-1 {{noncopyable 's' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 's' cannot be consumed when captured by an escaping closure}} %26 = load [take] %25 : $*S %27 = function_ref @consumeVal : $@convention(thin) (@owned S) -> () %28 = apply %27(%26) : $@convention(thin) (@owned S) -> () diff --git a/test/SILOptimizer/discard_checking.swift b/test/SILOptimizer/discard_checking.swift index d8c2ebba5ef57..322c1eb66487c 100644 --- a/test/SILOptimizer/discard_checking.swift +++ b/test/SILOptimizer/discard_checking.swift @@ -388,7 +388,7 @@ struct Basics: ~Copyable { // FIXME move checker is treating the defer like a closure capture (rdar://100468597) // not expecting any errors here - consuming func brokenPositiveTest(_ i: Int) { // expected-error {{missing reinitialization of inout parameter 'self' after consume}} + consuming func brokenPositiveTest(_ i: Int) { // expected-error {{missing reinitialization of closure capture 'self' after consume}} defer { discard self } // expected-note {{consumed here}} switch i { case 0, 1, 2, 3: return diff --git a/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil b/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil index e9fd3072470aa..d8ab032f1d14e 100644 --- a/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil +++ b/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil @@ -359,7 +359,7 @@ bb0(%0 : @closureCapture @guaranteed $<τ_0_0 where τ_0_0 : P> { var AddressOnl end_access %12 : $*AddressOnlyGeneric %17 = begin_access [deinit] [dynamic] %1 : $*AddressOnlyGeneric %18 = mark_must_check [assignable_but_not_consumable] %17 : $*AddressOnlyGeneric - // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} %19 = function_ref @addressOnlyGenericConsume : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in AddressOnlyGeneric<τ_0_0>) -> () %20 = apply %19(%18) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in AddressOnlyGeneric<τ_0_0>) -> () end_access %17 : $*AddressOnlyGeneric @@ -528,4 +528,4 @@ bb0(%0 : @owned $NonTrivialStruct): dealloc_stack %1 : $*NonTrivialStruct %9999 = tuple() return %9999 : $() -} \ No newline at end of file +} diff --git a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift index b8c06c599dcfc..44319d7b967dd 100644 --- a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift +++ b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift @@ -3083,7 +3083,7 @@ public func closureLetClassUseAfterConsumeArg(_ argX: inout Klass) { // We do not support captures of vars by closures today. public func closureLetCaptureClassUseAfterConsume() { - var x2 = Klass() // expected-error {{missing reinitialization of inout parameter 'x2' after consume}} + var x2 = Klass() // expected-error {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-1 {{'x2' consumed more than once}} x2 = Klass() let f = { @@ -3096,7 +3096,7 @@ public func closureLetCaptureClassUseAfterConsume() { } public func closureLetCaptureClassUseAfterConsume2() { - var x2 = Klass() // expected-error {{missing reinitialization of inout parameter 'x2' after consume}} + var x2 = Klass() // expected-error {{missing reinitialization of closure capture 'x2' after consume}} x2 = Klass() let f = { borrowVal(x2) @@ -3106,7 +3106,7 @@ public func closureLetCaptureClassUseAfterConsume2() { } public func closureLetCaptureClassUseAfterConsumeError() { - var x2 = Klass() // expected-error {{missing reinitialization of inout parameter 'x2' after consume}} + var x2 = Klass() // expected-error {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-1 {{'x2' consumed more than once}} // expected-error @-2 {{'x2' consumed more than once}} x2 = Klass() @@ -3143,11 +3143,11 @@ func closureLetStoreClosureInVariableIsEscape() { let f = { borrowVal(s) - consumeVal(s) // expected-error {{noncopyable 's' cannot be consumed when captured by a closure}} + consumeVal(s) // expected-error {{noncopyable 's' cannot be consumed when captured by an escaping closure}} } let c = StoreClosure(f: f) _ = c - consumeVal(s) // expected-error {{noncopyable 's' cannot be consumed when captured by a closure}} + consumeVal(s) // expected-error {{noncopyable 's' cannot be consumed when captured by an escaping closure}} } ///////////////////////////// @@ -3202,8 +3202,8 @@ public func closureVarCaptureClassUseAfterConsume() { var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -3214,7 +3214,7 @@ public func closureVarCaptureClassUseAfterConsume2() { var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -3225,12 +3225,12 @@ public func closureVarCaptureClassUseAfterConsumeError() { var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} x2 = Klass() let _ = x3 } @@ -3254,7 +3254,7 @@ public func closureVarCaptureClassArgUseAfterConsume(_ x2: inout Klass) { public func deferCaptureClassUseAfterConsume() { var x2 = Klass() // expected-error @-1 {{'x2' used after consume}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-3 {{'x2' consumed more than once}} x2 = Klass() defer { // expected-note {{used here}} @@ -3269,7 +3269,7 @@ public func deferCaptureClassUseAfterConsume() { public func deferCaptureClassUseAfterConsume2() { var x2 = Klass() - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-error @-3 {{'x2' used after consume}} x2 = Klass() @@ -3284,7 +3284,7 @@ public func deferCaptureClassUseAfterConsume2() { } public func deferCaptureClassArgUseAfterConsume(_ x2: inout Klass) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} borrowVal(x2) defer { @@ -3298,7 +3298,7 @@ public func deferCaptureClassArgUseAfterConsume(_ x2: inout Klass) { public func closureLetAndDeferCaptureClassUseAfterConsume() { var x2 = Klass() - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} x2 = Klass() let f = { @@ -3316,7 +3316,7 @@ public func closureLetAndDeferCaptureClassUseAfterConsume() { public func closureLetAndDeferCaptureClassUseAfterConsume2() { var x2 = Klass() // expected-error {{'x2' used after consume}} - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} x2 = Klass() let f = { @@ -3335,7 +3335,7 @@ public func closureLetAndDeferCaptureClassUseAfterConsume2() { public func closureLetAndDeferCaptureClassUseAfterConsume3() { var x2 = Klass() // expected-error {{'x2' used after consume}} - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} x2 = Klass() let f = { @@ -3354,7 +3354,7 @@ public func closureLetAndDeferCaptureClassUseAfterConsume3() { } public func closureLetAndDeferCaptureClassArgUseAfterConsume(_ x2: inout Klass) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-note @-3 {{'x2' is declared 'inout'}} let f = { // expected-error {{escaping closure captures 'inout' parameter 'x2'}} @@ -3377,7 +3377,7 @@ public func closureLetAndDeferCaptureClassArgUseAfterConsume(_ x2: inout Klass) public func closureLetAndClosureCaptureClassUseAfterConsume() { var x2 = Klass() // expected-error {{'x2' consumed more than once}} - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} x2 = Klass() let f = { let g = { @@ -3393,7 +3393,7 @@ public func closureLetAndClosureCaptureClassUseAfterConsume() { public func closureLetAndClosureCaptureClassUseAfterConsume2() { var x2 = Klass() // expected-error {{'x2' consumed more than once}} - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} x2 = Klass() let f = { let g = { @@ -3436,7 +3436,7 @@ public func closureLetAndClosureCaptureClassArgUseAfterConsume(_ x2: inout Klass public func closureVarAndDeferCaptureClassUseAfterConsume(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} var x2 = Klass() // expected-error {{'x2' consumed more than once}} - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} x2 = x // expected-note {{consumed here}} var f = {} f = { @@ -3453,12 +3453,12 @@ public func closureVarAndDeferCaptureClassUseAfterConsume(_ x: borrowing Klass) public func closureVarAndDeferCaptureClassUseAfterConsume2(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} var x2 = Klass() - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} x2 = x // expected-note {{consumed here}} var f = {} f = { - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} defer { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -3474,12 +3474,12 @@ public func closureVarAndDeferCaptureClassUseAfterConsume2(_ x: borrowing Klass) public func closureVarAndDeferCaptureClassUseAfterConsume3(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} var x2 = Klass() // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} x2 = x // expected-note @-1 {{consumed here}} var f = {} f = { - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} defer { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -3489,11 +3489,11 @@ public func closureVarAndDeferCaptureClassUseAfterConsume3(_ x: borrowing Klass) print("foo") } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } public func closureVarAndDeferCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} var f = {} f = {// expected-note {{closure capturing 'x2' here}} @@ -3508,7 +3508,7 @@ public func closureVarAndDeferCaptureClassArgUseAfterConsume(_ x2: borrowing Kla } public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} var f = {} f = { defer { @@ -3522,7 +3522,7 @@ public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned } public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming Klass) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} var f = {} f = { @@ -3539,7 +3539,7 @@ public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume2(_ x2: consumi // TODO: MG public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} var f = {} f = { defer { @@ -3550,12 +3550,12 @@ public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned print("foo") } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} var f = {} f = { defer { @@ -3567,7 +3567,7 @@ public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume4(_ x2: consumi print("foo") } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } /////////////////////////////////////////// @@ -3582,11 +3582,11 @@ public func closureVarAndClosureCaptureClassUseAfterConsume(_ x: borrowing Klass var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -3601,14 +3601,14 @@ public func closureVarAndClosureCaptureClassUseAfterConsume2(_ x: borrowing Klas var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} _ = x3 } @@ -3623,19 +3623,19 @@ public func closureVarAndClosureCaptureClassUseAfterConsume3(_ x: borrowing Klas var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} _ = x3 } public func closureVarAndClosureCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} // expected-error @-3 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} var f = {} @@ -3657,8 +3657,8 @@ public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume(_ x2: __owne var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } @@ -3671,8 +3671,8 @@ public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume2(_ x2: consu var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } @@ -3685,13 +3685,13 @@ public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume3(_ x2: __own var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { @@ -3700,13 +3700,13 @@ public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume4(_ x2: consu var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } ///////////////////////////// @@ -4106,14 +4106,14 @@ func inoutCaptureTest() -> (() -> ()) { borrowVal(x) consumeVal(x) - // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} x = NonTrivialStruct() let g = { x = NonTrivialStruct() useInOut(&x) consumeVal(x) - // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } g() @@ -4130,13 +4130,13 @@ func inoutCaptureTestAddressOnlyGeneric(_ t: T.Type) -> (() -> ()) { } borrowVal(x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} x = AddressOnlyGeneric() let g = { x = AddressOnlyGeneric() useInOut(&x) - consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + consumeVal(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } g() diff --git a/test/SILOptimizer/moveonly_nonescaping_closures.swift b/test/SILOptimizer/moveonly_nonescaping_closures.swift index 311b16701c7b7..c2c1bec70ee7e 100644 --- a/test/SILOptimizer/moveonly_nonescaping_closures.swift +++ b/test/SILOptimizer/moveonly_nonescaping_closures.swift @@ -77,12 +77,12 @@ func c2(x: consuming M) { consume(x) } -func d(x: __owned M) { // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} +func d(x: __owned M) { // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} clodger({ consume(x) }) // expected-note @-1 {{consumed here}} } -func d2(x: consuming M) { // expected-error {{missing reinitialization of inout parameter 'x' after consume}} +func d2(x: consuming M) { // expected-error {{missing reinitialization of closure capture 'x' after consume}} clodger({ consume(x) }) // expected-note @-1 {{consumed here}} } @@ -129,7 +129,7 @@ func k(x: borrowing M) { } -func l(x: inout M) { // expected-error {{missing reinitialization of inout parameter 'x' after consume}} +func l(x: inout M) { // expected-error {{missing reinitialization of closure capture 'x' after consume}} clodger({ consume(x) }) // expected-note {{consumed here}} } diff --git a/test/SILOptimizer/moveonly_objectchecker_diagnostics.swift b/test/SILOptimizer/moveonly_objectchecker_diagnostics.swift index 08a73a77e080f..97b95ef1f6934 100644 --- a/test/SILOptimizer/moveonly_objectchecker_diagnostics.swift +++ b/test/SILOptimizer/moveonly_objectchecker_diagnostics.swift @@ -2732,7 +2732,7 @@ public func enumPatternMatchSwitch2WhereClause2OwnedArg2(_ x2: consuming EnumTy) public func closureLetClassUseAfterConsume1(_ x: borrowing Klass) { // expected-error @-1 {{'x' cannot be captured by an escaping closure since it is a borrowed parameter}} - // expected-error @-2 {{noncopyable 'x' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} let f = { // expected-note {{closure capturing 'x' here}} let x2 = x // expected-error {{'x2' consumed more than once}} // expected-note @-1 {{consumed here}} @@ -2764,8 +2764,8 @@ public func closureLetClassUseAfterConsumeArg(_ argX: borrowing Klass) { } public func closureLetCaptureClassUseAfterConsume(_ x: consuming Klass) { - let x2 = x // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + let x2 = x // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -2777,7 +2777,7 @@ public func closureLetCaptureClassUseAfterConsume(_ x: consuming Klass) { public func closureLetCaptureClassUseAfterConsume1(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} var x2 = x // expected-note {{consumed here}} // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} x2 = x // expected-note {{consumed here}} let f = { @@ -2802,7 +2802,7 @@ public func closureLetCaptureClassUseAfterConsume2(_ x2: inout Klass) { // TODO: We are considering this to be an escaping use. public func closureLetCaptureClassUseAfterConsume3(_ x2: inout Klass) { // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} func useClosure(_ x: () -> ()) {} useClosure { @@ -2816,8 +2816,8 @@ public func closureLetCaptureClassUseAfterConsume3(_ x2: inout Klass) { public func closureLetCaptureClassUseAfterConsumeError(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -2829,7 +2829,7 @@ public func closureLetCaptureClassUseAfterConsumeError(_ x: borrowing Klass) { / } public func closureLetCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} let f = { // expected-note {{closure capturing 'x2' here}} borrowVal(x2) @@ -2840,8 +2840,8 @@ public func closureLetCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { } public func closureLetCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -2852,7 +2852,7 @@ public func closureLetCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Klass) { public func closureLetCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming Klass) { // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} let f = { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -2863,8 +2863,8 @@ public func closureLetCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming Klass } public func closureLetCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -2878,7 +2878,7 @@ public func closureLetCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned Klass) public func closureLetCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { // expected-error @-1 {{'x2' consumed more than once}} // expected-error @-2 {{'x2' consumed more than once}} - // expected-error @-3 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-3 {{missing reinitialization of closure capture 'x2' after consume}} let f = { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -2898,7 +2898,7 @@ public func closureLetCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass public func closureVarClassUseAfterConsume1(_ x: borrowing Klass) { // expected-error @-1 {{'x' cannot be captured by an escaping closure since it is a borrowed parameter}} - // expected-error @-2 {{noncopyable 'x' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} var f = {} f = { // expected-note {{closure capturing 'x' here}} let x2 = x // expected-error {{'x2' consumed more than once}} @@ -2937,8 +2937,8 @@ public func closureVarCaptureClassUseAfterConsume(_ x: borrowing Klass) { // exp var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -2950,8 +2950,8 @@ public func closureVarCaptureClassUseAfterConsume1(_ x: borrowing Klass) { // ex var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -2980,7 +2980,7 @@ public func closureVarCaptureClassUseAfterConsume3(_ x2: inout Klass) { public func closureVarCaptureClassUseAfterConsume4(_ x2: inout Klass) { // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} func useClosure(_ x: () -> ()) {} useClosure { @@ -2997,16 +2997,16 @@ public func closureVarCaptureClassUseAfterConsumeError(_ x: borrowing Klass) { / var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let _ = x3 } public func closureVarCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} var f = {} f = { // expected-note {{closure capturing 'x2' here}} @@ -3021,8 +3021,8 @@ public func closureVarCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Klass) { var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -3031,8 +3031,8 @@ public func closureVarCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming Klass var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -3041,11 +3041,11 @@ public func closureVarCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned Klass) var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let _ = x3 } @@ -3053,12 +3053,12 @@ public func closureVarCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass var f = {} f = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} x2 = Klass() let _ = x3 } @@ -3069,7 +3069,7 @@ public func closureVarCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass public func deferCaptureClassUseAfterConsume(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} defer { borrowVal(x2) // TODO: Defer can only run once, so this error shouldn't occur. @@ -3082,7 +3082,7 @@ public func deferCaptureClassUseAfterConsume(_ x: borrowing Klass) { // expected public func deferCaptureClassUseAfterConsume2(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note @-1 {{consumed here}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-3 {{'x2' used after consume}} defer { // expected-note {{used here}} borrowVal(x2) @@ -3094,7 +3094,7 @@ public func deferCaptureClassUseAfterConsume2(_ x: borrowing Klass) { // expecte } public func deferCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} borrowVal(x2) defer { borrowVal(x2) @@ -3105,7 +3105,7 @@ public func deferCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { } public func deferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} defer { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -3115,7 +3115,7 @@ public func deferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Klass) { } public func deferCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming Klass) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} defer { borrowVal(x2) @@ -3127,7 +3127,7 @@ public func deferCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming Klass) { } public func deferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' used after consume}} defer { // expected-note {{used here}} borrowVal(x2) @@ -3138,7 +3138,7 @@ public func deferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned Klass) { } public func deferCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-error @-3 {{'x2' used after consume}} defer { // expected-note {{used here}} @@ -3156,7 +3156,7 @@ public func deferCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { public func closureLetAndDeferCaptureClassUseAfterConsume(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { defer { borrowVal(x2) @@ -3170,9 +3170,9 @@ public func closureLetAndDeferCaptureClassUseAfterConsume(_ x: borrowing Klass) public func closureLetAndDeferCaptureClassUseAfterConsume2(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} // TODO: This is wrong - let x2 = x // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + let x2 = x // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-note @-1 {{consumed here}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { consumeVal(x2) // expected-note {{consumed here}} defer { @@ -3189,8 +3189,8 @@ public func closureLetAndDeferCaptureClassUseAfterConsume2(_ x: borrowing Klass) public func closureLetAndDeferCaptureClassUseAfterConsume3(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note @-1 {{consumed here}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-3 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-3 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { consumeVal(x2) // expected-note {{consumed here}} defer { @@ -3205,7 +3205,7 @@ public func closureLetAndDeferCaptureClassUseAfterConsume3(_ x: borrowing Klass) } public func closureLetAndDeferCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} let f = { // expected-note {{closure capturing 'x2' here}} defer { @@ -3219,7 +3219,7 @@ public func closureLetAndDeferCaptureClassArgUseAfterConsume(_ x2: borrowing Kla } public func closureLetAndDeferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { defer { borrowVal(x2) @@ -3232,7 +3232,7 @@ public func closureLetAndDeferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned } public func closureLetAndDeferCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming Klass) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} let f = { defer { @@ -3248,7 +3248,7 @@ public func closureLetAndDeferCaptureClassOwnedArgUseAfterConsume2(_ x2: consumi // TODO: MG public func closureLetAndDeferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { defer { borrowVal(x2) @@ -3263,7 +3263,7 @@ public func closureLetAndDeferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned public func closureLetAndDeferCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} let f = { defer { borrowVal(x2) @@ -3283,8 +3283,8 @@ public func closureLetAndDeferCaptureClassOwnedArgUseAfterConsume4(_ x2: consumi public func closureLetAndClosureCaptureClassUseAfterConsume(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { let g = { borrowVal(x2) @@ -3299,8 +3299,8 @@ public func closureLetAndClosureCaptureClassUseAfterConsume(_ x: borrowing Klass public func closureLetAndClosureCaptureClassUseAfterConsume2(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note @-1 {{consumed here}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-3 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-3 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-4 {{'x2' consumed more than once}} let f = { @@ -3321,7 +3321,7 @@ public func closureLetAndClosureCaptureClassUseAfterConsume3(_ x: borrowing Klas var x2 = x // expected-note @-1 {{consumed here}} // expected-error @-2 {{'x2' consumed more than once}} - // expected-error @-3 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-3 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-4 {{'x2' consumed more than once}} x2 = x // expected-note @-1 {{consumed here}} @@ -3342,7 +3342,7 @@ public func closureLetAndClosureCaptureClassUseAfterConsume3(_ x: borrowing Klas } public func closureLetAndClosureCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} // expected-error @-3 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} let f = { // expected-note {{closure capturing 'x2' here}} @@ -3357,8 +3357,8 @@ public func closureLetAndClosureCaptureClassArgUseAfterConsume(_ x2: borrowing K } public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { let g = { borrowVal(x2) @@ -3372,7 +3372,7 @@ public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume(_ x2: __owne public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming Klass) { // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} let f = { let g = { borrowVal(x2) @@ -3386,8 +3386,8 @@ public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume2(_ x2: consu } public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { let g = { borrowVal(x2) @@ -3401,7 +3401,7 @@ public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume3(_ x2: __own } public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} let f = { let g = { @@ -3417,7 +3417,7 @@ public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume4(_ x2: consu } public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume5(_ x2: consuming Klass) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-error @-3 {{'x2' used after consume}} let f = { @@ -3440,7 +3440,7 @@ public func closureLetAndClosureCaptureClassOwnedArgUseAfterConsume5(_ x2: consu public func closureVarAndDeferCaptureClassUseAfterConsume(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} var f = {} f = { defer { @@ -3454,11 +3454,11 @@ public func closureVarAndDeferCaptureClassUseAfterConsume(_ x: borrowing Klass) } public func closureVarAndDeferCaptureClassUseAfterConsume2(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} - let x2 = x // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + let x2 = x // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-note @-1 {{consumed here}} var f = {} f = { - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} defer { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -3473,10 +3473,10 @@ public func closureVarAndDeferCaptureClassUseAfterConsume2(_ x: borrowing Klass) public func closureVarAndDeferCaptureClassUseAfterConsume3(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note @-1 {{consumed here}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} var f = {} f = { - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} defer { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -3485,11 +3485,11 @@ public func closureVarAndDeferCaptureClassUseAfterConsume3(_ x: borrowing Klass) print("foo") } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } public func closureVarAndDeferCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} var f = {} f = {// expected-note {{closure capturing 'x2' here}} @@ -3504,7 +3504,7 @@ public func closureVarAndDeferCaptureClassArgUseAfterConsume(_ x2: borrowing Kla } public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} var f = {} f = { defer { @@ -3518,7 +3518,7 @@ public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned } public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming Klass) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} var f = {} f = { @@ -3535,7 +3535,7 @@ public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume2(_ x2: consumi // TODO: MG public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} var f = {} f = { defer { @@ -3546,12 +3546,12 @@ public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned print("foo") } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} var f = {} f = { defer { @@ -3563,7 +3563,7 @@ public func closureVarAndDeferCaptureClassOwnedArgUseAfterConsume4(_ x2: consumi print("foo") } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } /////////////////////////////////////////// @@ -3577,11 +3577,11 @@ public func closureVarAndClosureCaptureClassUseAfterConsume(_ x: borrowing Klass var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -3595,14 +3595,14 @@ public func closureVarAndClosureCaptureClassUseAfterConsume2(_ x: borrowing Klas var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} _ = x3 } @@ -3617,19 +3617,19 @@ public func closureVarAndClosureCaptureClassUseAfterConsume3(_ x: borrowing Klas var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} _ = x3 } public func closureVarAndClosureCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} // expected-error @-3 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} var f = {} @@ -3651,8 +3651,8 @@ public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume(_ x2: __owne var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } @@ -3665,8 +3665,8 @@ public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume2(_ x2: consu var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } @@ -3679,13 +3679,13 @@ public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume3(_ x2: __own var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { @@ -3694,13 +3694,13 @@ public func closureVarAndClosureCaptureClassOwnedArgUseAfterConsume4(_ x2: consu var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } ///////////////////////////////// @@ -3713,11 +3713,11 @@ public func closureVarAndClosureLetCaptureClassUseAfterConsume(_ x: borrowing Kl f = { let g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -3730,14 +3730,14 @@ public func closureVarAndClosureLetCaptureClassUseAfterConsume2(_ x: borrowing K f = { let g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} _ = x3 } @@ -3751,19 +3751,19 @@ public func closureVarAndClosureLetCaptureClassUseAfterConsume3(_ x: borrowing K f = { let g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} _ = x3 } public func closureVarAndClosureLetCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} // expected-error @-3 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} var f = {} @@ -3783,8 +3783,8 @@ public func closureVarAndClosureLetCaptureClassOwnedArgUseAfterConsume(_ x2: __o f = { let g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } @@ -3796,8 +3796,8 @@ public func closureVarAndClosureLetCaptureClassOwnedArgUseAfterConsume2(_ x2: co f = { let g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } @@ -3809,13 +3809,13 @@ public func closureVarAndClosureLetCaptureClassOwnedArgUseAfterConsume3(_ x2: __ f = { let g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } public func closureVarAndClosureLetCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { @@ -3823,13 +3823,13 @@ public func closureVarAndClosureLetCaptureClassOwnedArgUseAfterConsume4(_ x2: co f = { let g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } public func closureLetAndClosureVarCaptureClassUseAfterConsume(_ x: borrowing Klass) { // expected-error {{'x' is borrowed and cannot be consumed}} @@ -3838,11 +3838,11 @@ public func closureLetAndClosureVarCaptureClassUseAfterConsume(_ x: borrowing Kl var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() } @@ -3856,17 +3856,17 @@ public func closureLetAndClosureVarCaptureClassUseAfterConsume2(_ x: borrowing K var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } h() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} _ = x3 } @@ -3880,19 +3880,19 @@ public func closureLetAndClosureVarCaptureClassUseAfterConsume3(_ x: borrowing K var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + let x3 = x2 // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} _ = x3 } public func closureLetAndClosureVarCaptureClassArgUseAfterConsume(_ x2: borrowing Klass) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} // expected-error @-3 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} let f = {// expected-note {{closure capturing 'x2' here}} @@ -3912,8 +3912,8 @@ public func closureLetAndClosureVarCaptureClassOwnedArgUseAfterConsume(_ x2: __o var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } @@ -3925,8 +3925,8 @@ public func closureLetAndClosureVarCaptureClassOwnedArgUseAfterConsume2(_ x2: co var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } @@ -3938,13 +3938,13 @@ public func closureLetAndClosureVarCaptureClassOwnedArgUseAfterConsume3(_ x2: __ var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } public func closureLetAndClosureVarCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming Klass) { @@ -3952,13 +3952,13 @@ public func closureLetAndClosureVarCaptureClassOwnedArgUseAfterConsume4(_ x2: co var g = {} g = { borrowVal(x2) - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } g() } f() - consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by a closure}} + consumeVal(x2) // expected-error {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} } /////////////////////////////////// diff --git a/test/SILOptimizer/moveonly_trivial_addresschecker_diagnostics.swift b/test/SILOptimizer/moveonly_trivial_addresschecker_diagnostics.swift index 284745459fe04..0546c129efeea 100644 --- a/test/SILOptimizer/moveonly_trivial_addresschecker_diagnostics.swift +++ b/test/SILOptimizer/moveonly_trivial_addresschecker_diagnostics.swift @@ -1200,7 +1200,7 @@ public func closureClassUseAfterConsumeArg(_ argX: inout NonTrivialStruct) { // We do not support captures of vars by closures today. public func closureCaptureClassUseAfterConsume() { var x2 = NonTrivialStruct() - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} x2 = NonTrivialStruct() let f = { @@ -1216,7 +1216,7 @@ public func closureCaptureClassUseAfterConsumeError() { var x2 = NonTrivialStruct() // expected-error @-1 {{'x2' consumed more than once}} // expected-error @-2 {{'x2' consumed more than once}} - // expected-error @-3 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-3 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-4 {{'x2' consumed more than once}} // expected-error @-5 {{'x2' consumed more than once}} x2 = NonTrivialStruct() @@ -1251,7 +1251,7 @@ public func closureCaptureClassArgUseAfterConsume(_ x2: inout NonTrivialStruct) // TODO: Improve error msg here to make it clear the use is due to the defer. public func deferCaptureClassUseAfterConsume() { var x2 = NonTrivialStruct() - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-error @-3 {{'x2' used after consume}} x2 = NonTrivialStruct() @@ -1266,7 +1266,7 @@ public func deferCaptureClassUseAfterConsume() { public func deferCaptureClassUseAfterConsume2() { var x2 = NonTrivialStruct() - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-error @-3 {{'x2' used after consume}} x2 = NonTrivialStruct() @@ -1281,7 +1281,7 @@ public func deferCaptureClassUseAfterConsume2() { } public func deferCaptureClassArgUseAfterConsume(_ x2: inout NonTrivialStruct) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} borrowVal(x2) defer { @@ -1295,7 +1295,7 @@ public func deferCaptureClassArgUseAfterConsume(_ x2: inout NonTrivialStruct) { public func closureAndDeferCaptureClassUseAfterConsume() { var x2 = NonTrivialStruct() - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} x2 = NonTrivialStruct() let f = { @@ -1313,7 +1313,7 @@ public func closureAndDeferCaptureClassUseAfterConsume() { public func closureAndDeferCaptureClassUseAfterConsume2() { var x2 = NonTrivialStruct() - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-error @-3 {{'x2' used after consume}} x2 = NonTrivialStruct() @@ -1333,7 +1333,7 @@ public func closureAndDeferCaptureClassUseAfterConsume2() { public func closureAndDeferCaptureClassUseAfterConsume3() { var x2 = NonTrivialStruct() - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-error @-3 {{'x2' used after consume}} x2 = NonTrivialStruct() @@ -1353,7 +1353,7 @@ public func closureAndDeferCaptureClassUseAfterConsume3() { } public func closureAndDeferCaptureClassArgUseAfterConsume(_ x2: inout NonTrivialStruct) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-note @-3 {{'x2' is declared 'inout'}} let f = { // expected-error {{escaping closure captures 'inout' parameter 'x2'}} @@ -1373,7 +1373,7 @@ public func closureAndDeferCaptureClassArgUseAfterConsume(_ x2: inout NonTrivial public func closureAndClosureCaptureClassUseAfterConsume() { var x2 = NonTrivialStruct() // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} x2 = NonTrivialStruct() let f = { let g = { @@ -1390,7 +1390,7 @@ public func closureAndClosureCaptureClassUseAfterConsume() { public func closureAndClosureCaptureClassUseAfterConsume2() { var x2 = NonTrivialStruct() // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} x2 = NonTrivialStruct() let f = { let g = { @@ -1408,7 +1408,7 @@ public func closureAndClosureCaptureClassUseAfterConsume2() { public func closureAndClosureCaptureClassUseAfterConsume3() { var x2 = NonTrivialStruct() // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-3 {{'x2' used after consume}} x2 = NonTrivialStruct() let f = { diff --git a/test/SILOptimizer/moveonly_trivial_objectchecker_diagnostics.swift b/test/SILOptimizer/moveonly_trivial_objectchecker_diagnostics.swift index 720b5082725c9..f08448dbeae24 100644 --- a/test/SILOptimizer/moveonly_trivial_objectchecker_diagnostics.swift +++ b/test/SILOptimizer/moveonly_trivial_objectchecker_diagnostics.swift @@ -1727,7 +1727,7 @@ public func enumPatternMatchSwitch2WhereClause2OwnedArg2(_ x2: consuming EnumTy) ///////////////////////////// public func closureClassUseAfterConsume1(_ x: borrowing NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x' cannot be captured by an escaping closure since it is a borrowed parameter}} let f = { // expected-note {{closure capturing 'x' here}} let x2 = x // expected-error {{'x2' consumed more than once}} @@ -1762,8 +1762,8 @@ public func closureClassUseAfterConsumeArg(_ argX: borrowing NonTrivialStruct) { public func closureCaptureClassUseAfterConsume(_ x: borrowing NonTrivialStruct) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x2) @@ -1775,8 +1775,8 @@ public func closureCaptureClassUseAfterConsume(_ x: borrowing NonTrivialStruct) public func closureCaptureClassUseAfterConsumeError(_ x: borrowing NonTrivialStruct) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -1788,7 +1788,7 @@ public func closureCaptureClassUseAfterConsumeError(_ x: borrowing NonTrivialStr } public func closureCaptureClassArgUseAfterConsume(_ x2: borrowing NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} let f = { // expected-note {{closure capturing 'x2' here}} borrowVal(x2) @@ -1799,8 +1799,8 @@ public func closureCaptureClassArgUseAfterConsume(_ x2: borrowing NonTrivialStru } public func closureCaptureClassOwnedArgUseAfterConsume(_ x2: __owned NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -1810,7 +1810,7 @@ public func closureCaptureClassOwnedArgUseAfterConsume(_ x2: __owned NonTrivialS } public func closureCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming NonTrivialStruct) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} let f = { borrowVal(x2) @@ -1822,8 +1822,8 @@ public func closureCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming NonTrivi } public func closureCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -1835,7 +1835,7 @@ public func closureCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned NonTrivial } public func closureCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming NonTrivialStruct) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} // expected-error @-3 {{'x2' consumed more than once}} let f = { @@ -1852,7 +1852,7 @@ public func closureCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming NonTrivi public func deferCaptureClassUseAfterConsume(_ x: borrowing NonTrivialStruct) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} defer { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -1864,7 +1864,7 @@ public func deferCaptureClassUseAfterConsume(_ x: borrowing NonTrivialStruct) { public func deferCaptureClassUseAfterConsume2(_ x: borrowing NonTrivialStruct) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note @-1 {{consumed here}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-3 {{'x2' used after consume}} defer { // expected-note {{used here}} borrowVal(x2) @@ -1876,7 +1876,7 @@ public func deferCaptureClassUseAfterConsume2(_ x: borrowing NonTrivialStruct) { } public func deferCaptureClassArgUseAfterConsume(_ x2: borrowing NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} borrowVal(x2) defer { borrowVal(x2) @@ -1887,7 +1887,7 @@ public func deferCaptureClassArgUseAfterConsume(_ x2: borrowing NonTrivialStruct } public func deferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} defer { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -1898,7 +1898,7 @@ public func deferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned NonTrivialStr public func deferCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming NonTrivialStruct) { // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} defer { borrowVal(x2) consumeVal(x2) // expected-note {{consumed here}} @@ -1909,7 +1909,7 @@ public func deferCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming NonTrivial } public func deferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' used after consume}} defer { // expected-note {{used here}} borrowVal(x2) @@ -1920,7 +1920,7 @@ public func deferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned NonTrivialSt } public func deferCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming NonTrivialStruct) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' used after consume}} // expected-error @-3 {{'x2' consumed more than once}} defer { // expected-note {{used here}} @@ -1935,7 +1935,7 @@ public func deferCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming NonTrivial public func closureAndDeferCaptureClassUseAfterConsume(_ x: borrowing NonTrivialStruct) { // expected-error @-1 {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { defer { borrowVal(x2) @@ -1949,8 +1949,8 @@ public func closureAndDeferCaptureClassUseAfterConsume(_ x: borrowing NonTrivial public func closureAndDeferCaptureClassUseAfterConsume2(_ x: borrowing NonTrivialStruct) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { consumeVal(x2) // expected-note {{consumed here}} defer { @@ -1966,8 +1966,8 @@ public func closureAndDeferCaptureClassUseAfterConsume2(_ x: borrowing NonTrivia public func closureAndDeferCaptureClassUseAfterConsume3(_ x: borrowing NonTrivialStruct) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note @-1 {{consumed here}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-3 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-3 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { consumeVal(x2) // expected-note {{consumed here}} defer { @@ -1983,7 +1983,7 @@ public func closureAndDeferCaptureClassUseAfterConsume3(_ x: borrowing NonTrivia public func closureAndDeferCaptureClassArgUseAfterConsume(_ x2: borrowing NonTrivialStruct) { // expected-error @-1 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { // expected-note {{closure capturing 'x2' here}} defer { borrowVal(x2) @@ -1996,7 +1996,7 @@ public func closureAndDeferCaptureClassArgUseAfterConsume(_ x2: borrowing NonTri } public func closureAndDeferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { defer { borrowVal(x2) @@ -2009,7 +2009,7 @@ public func closureAndDeferCaptureClassOwnedArgUseAfterConsume(_ x2: __owned Non } public func closureAndDeferCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming NonTrivialStruct) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} let f = { defer { @@ -2024,7 +2024,7 @@ public func closureAndDeferCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming } public func closureAndDeferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { defer { borrowVal(x2) @@ -2038,7 +2038,7 @@ public func closureAndDeferCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned No } public func closureAndDeferCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming NonTrivialStruct) { - // expected-error @-1 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-1 {{missing reinitialization of closure capture 'x2' after consume}} // expected-error @-2 {{'x2' consumed more than once}} let f = { defer { @@ -2055,8 +2055,8 @@ public func closureAndDeferCaptureClassOwnedArgUseAfterConsume4(_ x2: consuming public func closureAndClosureCaptureClassUseAfterConsume(_ x: borrowing NonTrivialStruct) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { let g = { borrowVal(x2) @@ -2070,8 +2070,8 @@ public func closureAndClosureCaptureClassUseAfterConsume(_ x: borrowing NonTrivi public func closureAndClosureCaptureClassUseAfterConsume2(_ x: borrowing NonTrivialStruct) { // expected-error {{'x' is borrowed and cannot be consumed}} let x2 = x // expected-note {{consumed here}} - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { let g = { borrowVal(x2) @@ -2086,7 +2086,7 @@ public func closureAndClosureCaptureClassUseAfterConsume2(_ x: borrowing NonTriv public func closureAndClosureCaptureClassArgUseAfterConsume(_ x2: borrowing NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} // expected-error @-2 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} // expected-error @-3 {{'x2' cannot be captured by an escaping closure since it is a borrowed parameter}} let f = { // expected-note {{closure capturing 'x2' here}} @@ -2101,8 +2101,8 @@ public func closureAndClosureCaptureClassArgUseAfterConsume(_ x2: borrowing NonT } public func closureAndClosureCaptureClassOwnedArgUseAfterConsume(_ x2: __owned NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { let g = { borrowVal(x2) @@ -2116,7 +2116,7 @@ public func closureAndClosureCaptureClassOwnedArgUseAfterConsume(_ x2: __owned N public func closureAndClosureCaptureClassOwnedArgUseAfterConsume2(_ x2: consuming NonTrivialStruct) { // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{missing reinitialization of inout parameter 'x2' after consume}} + // expected-error @-2 {{missing reinitialization of closure capture 'x2' after consume}} let f = { let g = { borrowVal(x2) @@ -2130,8 +2130,8 @@ public func closureAndClosureCaptureClassOwnedArgUseAfterConsume2(_ x2: consumin } public func closureAndClosureCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { let g = { borrowVal(x2) @@ -2145,8 +2145,8 @@ public func closureAndClosureCaptureClassOwnedArgUseAfterConsume3(_ x2: __owned } public func closureAndClosureCaptureClassOwnedArgUseAfterConsume4(_ x2: __owned NonTrivialStruct) { - // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by a closure}} - // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by a closure}} + // expected-error @-1 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} + // expected-error @-2 {{noncopyable 'x2' cannot be consumed when captured by an escaping closure}} let f = { let g = { borrowVal(x2) diff --git a/test/SILOptimizer/noimplicitcopy_consuming_parameters.swift b/test/SILOptimizer/noimplicitcopy_consuming_parameters.swift index e9a3f21e340db..380ca517062a7 100644 --- a/test/SILOptimizer/noimplicitcopy_consuming_parameters.swift +++ b/test/SILOptimizer/noimplicitcopy_consuming_parameters.swift @@ -151,7 +151,7 @@ func testLoadableConsumingEscapingClosure(_ x: consuming NonTrivialStruct) { } func testLoadableConsumingEscapingClosure2(_ x: consuming NonTrivialStruct) { - _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} var f: () -> () = {} f = { _ = x @@ -165,7 +165,7 @@ func testLoadableConsumingEscapingClosure3(_ x: consuming NonTrivialStruct) { _ = x } _ = f - _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } func testLoadableConsumingNonEscapingClosure(_ x: consuming NonTrivialStruct) { @@ -302,7 +302,7 @@ func testTrivialConsumingEscapingClosure(_ x: consuming TrivialStruct) { } func testTrivialConsumingEscapingClosure2(_ x: consuming TrivialStruct) { - let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} var f: () -> () = {} f = { _ = x @@ -316,7 +316,7 @@ func testTrivialConsumingEscapingClosure3(_ x: consuming TrivialStruct) { _ = x } _ = f - let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } func testTrivialConsumingNonEscapingClosure(_ x: consuming TrivialStruct) { @@ -440,7 +440,7 @@ func testAddressOnlyConsumingEscapingClosure(_ x: consuming GenericNonTri } func testAddressOnlyConsumingEscapingClosure2(_ x: consuming GenericNonTrivialStruct) { - let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} var f: () -> () = {} f = { _ = x @@ -454,7 +454,7 @@ func testAddressOnlyConsumingEscapingClosure3(_ x: consuming GenericNonTr _ = x } _ = f - let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by a closure}} + let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}} } func testAddressOnlyConsumingNonEscapingClosure(_ x: consuming GenericNonTrivialStruct) { @@ -646,7 +646,7 @@ struct LoadableSelfTest { } consuming func testCallEscapingClosure2() { - let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by a closure}} + let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}} var f: () -> () = {} f = { let _ = self @@ -660,7 +660,7 @@ struct LoadableSelfTest { let _ = self } f() - let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by a closure}} + let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}} } consuming func testCallNonEscapingClosure() { @@ -804,7 +804,7 @@ struct AddressOnlySelfTest { } consuming func testCallEscapingClosure2() { - let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by a closure}} + let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}} var f: () -> () = {} f = { let _ = self @@ -818,7 +818,7 @@ struct AddressOnlySelfTest { let _ = self } f() - let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by a closure}} + let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}} } consuming func testCallEscapingClosure4() { @@ -830,7 +830,7 @@ struct AddressOnlySelfTest { f = { let _ = self } - let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by a closure}} + let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}} } consuming func testCallNonEscapingClosure() { @@ -956,7 +956,7 @@ struct TrivialSelfTest { } consuming func testCallEscapingClosure2() { - let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by a closure}} + let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}} var f: () -> () = {} f = { let _ = self diff --git a/test/ScanDependencies/Inputs/Swift/FooClient.swiftinterface b/test/ScanDependencies/Inputs/Swift/FooClient.swiftinterface new file mode 100644 index 0000000000000..dbf1aa40270ea --- /dev/null +++ b/test/ScanDependencies/Inputs/Swift/FooClient.swiftinterface @@ -0,0 +1,5 @@ +// swift-interface-format-version: 1.0 +// swift-module-flags: -module-name FooClient +import Swift +import Foo +public func overlayFuncA() { } diff --git a/test/ScanDependencies/header_deps_of_binary.swift b/test/ScanDependencies/header_deps_of_binary.swift new file mode 100644 index 0000000000000..421840c21cce9 --- /dev/null +++ b/test/ScanDependencies/header_deps_of_binary.swift @@ -0,0 +1,70 @@ +// REQUIRES: objc_interop, OS=macosx +// RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/clang-module-cache) +// RUN: %empty-directory(%t/PCH) +// RUN: %empty-directory(%t/SwiftModules) + +// - Set up Foo Swift dependency +// RUN: echo "extension Profiler {" >> %t/foo.swift +// RUN: echo " public static let count: Int = 42" >> %t/foo.swift +// RUN: echo "}" >> %t/foo.swift + +// - Set up Foo bridging header +// RUN: echo "struct Profiler { void* ptr; };" >> %t/foo.h + +// - Compile bridging header +// RUN: %target-swift-frontend -enable-objc-interop -emit-pch %t/foo.h -o %t/PCH/foo.pch -disable-implicit-swift-modules + +// - Set up explicit dependencies for Foo +// RUN: %target-swift-emit-pcm -module-name SwiftShims %swift-lib-dir/swift/shims/module.modulemap -o %t/inputs/SwiftShims.pcm +// RUN: %target-swift-emit-pcm -module-name _SwiftConcurrencyShims %swift-lib-dir/swift/shims/module.modulemap -o %t/inputs/_SwiftConcurrencyShims.pcm +// RUN: echo "[{" > %t/foo_inputs_map.json +// RUN: echo "\"moduleName\": \"Swift\"," >> %t/foo_inputs_map.json +// RUN: echo "\"modulePath\": \"%/stdlib_module\"," >> %t/foo_inputs_map.json +// RUN: echo "\"isFramework\": false" >> %t/foo_inputs_map.json +// RUN: echo "}," >> %t/foo_inputs_map.json +// RUN: echo "{" >> %t/foo_inputs_map.json +// RUN: echo "\"moduleName\": \"SwiftOnoneSupport\"," >> %t/foo_inputs_map.json +// RUN: echo "\"modulePath\": \"%/ononesupport_module\"," >> %t/foo_inputs_map.json +// RUN: echo "\"isFramework\": false" >> %t/foo_inputs_map.json +// RUN: echo "}," >> %t/foo_inputs_map.json +// RUN: echo "{" >> %t/foo_inputs_map.json +// RUN: echo "\"moduleName\": \"_StringProcessing\"," >> %t/foo_inputs_map.json +// RUN: echo "\"modulePath\": \"%/string_processing_module\"," >> %t/foo_inputs_map.json +// RUN: echo "\"isFramework\": false" >> %t/foo_inputs_map.json +// RUN: echo "}," >> %t/foo_inputs_map.json +// RUN: echo "{" >> %t/foo_inputs_map.json +// RUN: echo "\"moduleName\": \"SwiftShims\"," >> %t/foo_inputs_map.json +// RUN: echo "\"isFramework\": false," >> %t/foo_inputs_map.json +// RUN: echo "\"clangModuleMapPath\": \"%swift-lib-dir/swift/shims/module.modulemap\"," >> %t/foo_inputs_map.json +// RUN: echo "\"clangModulePath\": \"%t/inputs/SwiftShims.pcm\"" >> %t/foo_inputs_map.json +// RUN: echo "}," >> %t/foo_inputs_map.json +// RUN: echo "{" >> %t/foo_inputs_map.json +// RUN: echo "\"moduleName\": \"_SwiftConcurrencyShims\"," >> %t/foo_inputs_map.json +// RUN: echo "\"isFramework\": false," >> %t/foo_inputs_map.json +// RUN: echo "\"clangModuleMapPath\": \"%swift-lib-dir/swift/shims/module.modulemap\"," >> %t/foo_inputs_map.json +// RUN: echo "\"clangModulePath\": \"%t/inputs/_SwiftConcurrencyShims.pcm\"" >> %t/foo_inputs_map.json +// RUN: echo "}]" >> %t/foo_inputs_map.json + +// - Build Foo module dependency, explicitly +// RUN: %target-swift-frontend -emit-module -emit-module-path %t/SwiftModules/Foo.swiftmodule %t/foo.swift -module-name Foo -import-objc-header %t/PCH/foo.pch -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -disable-implicit-swift-modules -explicit-swift-module-map-file %t/foo_inputs_map.json + +// - Scan main module +// RUN: %target-swift-frontend -scan-dependencies %s -I %t/SwiftModules -I %S/Inputs/Swift -o %t/deps.json +// RUN: %FileCheck %s --input-file %t/deps.json + +// CHECK: "swift": "FooClient" +// CHECK: "swift": "FooClient" +// CHECK: "swiftPrebuiltExternal": "Foo" +// CHECK: "commandLine": [ +// CHECK: "-include-pch", +// CHECK-NEXT: "-Xcc", +// CHECK-NEXT: "{{.*}}{{/|\\}}PCH{{/|\\}}foo.pch" + + +// CHECK: "swiftPrebuiltExternal": "Foo" +// CHECK: "headerDependencies": [ +// CHECK: "{{.*}}{{/|\\}}PCH{{/|\\}}foo.pch" +// CHECK: ], + +import FooClient diff --git a/test/Serialization/macros.swift b/test/Serialization/macros.swift index 4933762698d3f..e700da4b6528b 100644 --- a/test/Serialization/macros.swift +++ b/test/Serialization/macros.swift @@ -21,7 +21,7 @@ func test(a: Int, b: Int) { struct TestStruct { @myWrapper var x: Int - // expected-error@-1{{expansion of macro 'myWrapper' did not produce a non-observing accessor}} + // expected-error@-1{{expansion of macro 'myWrapper()' did not produce a non-observing accessor}} } @ArbitraryMembers diff --git a/test/TBD/opaque_result_type.swift b/test/TBD/opaque_result_type.swift index f5c6b8b0ca0eb..8cfbf652aac5d 100644 --- a/test/TBD/opaque_result_type.swift +++ b/test/TBD/opaque_result_type.swift @@ -77,6 +77,11 @@ public func dynReplacement(x: String) -> some P { return "replaced" } +@usableFromInline +func ufi() -> some O { + return 1 +} + extension String: P { public func poo() -> some O { return 0 diff --git a/test/stdlib/Duration.swift b/test/stdlib/Duration.swift index e6533d52d5254..def1633b2e51d 100644 --- a/test/stdlib/Duration.swift +++ b/test/stdlib/Duration.swift @@ -14,6 +14,8 @@ if #available(SwiftStdlib 5.7, *) { expectEqual(sec, Int64(integerValue)) expectEqual(attosec, 0) } + let quarterSecond = Duration.seconds(0.25) + expectEqual(quarterSecond.components, (0, 250_000_000_000_000_000)) // Value that overflows conversion from Double -> Int64, but should be // representable as a number of seconds: let huge: Double = 1.7e20 diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp index c0bc79d71151a..928377c556793 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp @@ -536,7 +536,8 @@ static void walkRelatedDecls(const ValueDecl *VD, const FnTy &Fn) { auto type = DC->getDeclaredInterfaceType(); if (!type->is()) { DC->lookupQualified(type, DeclNameRef(VD->getBaseName()), - NL_QualifiedDefault, results); + VD->getLoc(), NL_QualifiedDefault, + results); } } else { namelookup::lookupInModule(DC->getModuleScopeContext(), @@ -544,6 +545,7 @@ static void walkRelatedDecls(const ValueDecl *VD, const FnTy &Fn) { NLKind::UnqualifiedLookup, namelookup::ResolutionKind::Overloadable, DC->getModuleScopeContext(), + VD->getLoc(), NL_UnqualifiedDefault); } diff --git a/tools/libSwiftScan/libSwiftScan.cpp b/tools/libSwiftScan/libSwiftScan.cpp index 23c5b697ef26c..1091ca4888d1e 100644 --- a/tools/libSwiftScan/libSwiftScan.cpp +++ b/tools/libSwiftScan/libSwiftScan.cpp @@ -20,11 +20,15 @@ #include "swift/DependencyScan/DependencyScanImpl.h" #include "swift/DependencyScan/DependencyScanningTool.h" #include "swift/DependencyScan/StringUtils.h" +#include "swift/Frontend/CachingUtils.h" #include "swift/Option/Options.h" +#include "llvm/CAS/ObjectStore.h" using namespace swift::dependencies; +using namespace swift::cas; DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScanningTool, swiftscan_scanner_t) +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(CachingTool, swiftscan_cas_t) //=== Private Cleanup Functions -------------------------------------------===// @@ -48,6 +52,12 @@ void swiftscan_dependency_info_details_dispose( swiftscan_string_set_dispose( details_impl->swift_textual_details.extra_pcm_args); swiftscan_string_dispose(details_impl->swift_textual_details.context_hash); + swiftscan_string_dispose( + details_impl->swift_textual_details.cas_fs_root_id); + swiftscan_string_dispose( + details_impl->swift_textual_details.bridging_header_include_tree); + swiftscan_string_dispose( + details_impl->swift_textual_details.module_cache_key); break; case SWIFTSCAN_DEPENDENCY_INFO_SWIFT_BINARY: swiftscan_string_dispose( @@ -56,6 +66,8 @@ void swiftscan_dependency_info_details_dispose( details_impl->swift_binary_details.module_doc_path); swiftscan_string_dispose( details_impl->swift_binary_details.module_source_info_path); + swiftscan_string_dispose( + details_impl->swift_binary_details.module_cache_key); break; case SWIFTSCAN_DEPENDENCY_INFO_SWIFT_PLACEHOLDER: swiftscan_string_dispose( @@ -70,6 +82,8 @@ void swiftscan_dependency_info_details_dispose( swiftscan_string_dispose(details_impl->clang_details.context_hash); swiftscan_string_set_dispose(details_impl->clang_details.command_line); swiftscan_string_set_dispose(details_impl->clang_details.captured_pcm_args); + swiftscan_string_dispose(details_impl->clang_details.cas_fs_root_id); + swiftscan_string_dispose(details_impl->clang_details.module_cache_key); break; } delete details_impl; @@ -276,6 +290,12 @@ swiftscan_string_set_t *swiftscan_swift_textual_detail_get_command_line( return details->swift_textual_details.command_line; } +swiftscan_string_set_t * +swiftscan_swift_textual_detail_get_bridging_pch_command_line( + swiftscan_module_details_t details) { + return details->swift_textual_details.bridging_pch_command_line; +} + swiftscan_string_set_t *swiftscan_swift_textual_detail_get_extra_pcm_args( swiftscan_module_details_t details) { return details->swift_textual_details.extra_pcm_args; @@ -296,6 +316,16 @@ swiftscan_string_set_t *swiftscan_swift_textual_detail_get_swift_overlay_depende return details->swift_textual_details.swift_overlay_module_dependencies; } +swiftscan_string_ref_t swiftscan_swift_textual_detail_get_cas_fs_root_id( + swiftscan_module_details_t details) { + return details->swift_textual_details.cas_fs_root_id; +} + +swiftscan_string_ref_t swiftscan_swift_textual_detail_get_module_cache_key( + swiftscan_module_details_t details) { + return details->swift_textual_details.module_cache_key; +} + //=== Swift Binary Module Details query APIs ------------------------------===// swiftscan_string_ref_t swiftscan_swift_binary_detail_get_compiled_module_path( @@ -314,11 +344,23 @@ swiftscan_swift_binary_detail_get_module_source_info_path( return details->swift_binary_details.module_source_info_path; } +swiftscan_string_set_t * +swiftscan_swift_binary_detail_get_header_dependencies( + swiftscan_module_details_t details) { + return details->swift_binary_details.header_dependencies; +} + bool swiftscan_swift_binary_detail_get_is_framework( swiftscan_module_details_t details) { return details->swift_binary_details.is_framework; } +swiftscan_string_ref_t swiftscan_swift_binary_detail_get_module_cache_key( + swiftscan_module_details_t details) { + return details->swift_binary_details.module_cache_key; +} + + //=== Swift Placeholder Module Details query APIs -------------------------===// swiftscan_string_ref_t @@ -360,6 +402,16 @@ swiftscan_clang_detail_get_captured_pcm_args(swiftscan_module_details_t details) return details->clang_details.captured_pcm_args; } +swiftscan_string_ref_t +swiftscan_clang_detail_get_cas_fs_root_id(swiftscan_module_details_t details) { + return details->clang_details.cas_fs_root_id; +} + +swiftscan_string_ref_t swiftscan_clang_detail_get_module_cache_key( + swiftscan_module_details_t details) { + return details->clang_details.module_cache_key; +} + //=== Batch Scan Input Functions ------------------------------------------===// swiftscan_batch_scan_input_t *swiftscan_batch_scan_input_create() { @@ -617,6 +669,60 @@ swiftscan_diagnostics_set_dispose(swiftscan_diagnostic_set_t* diagnostics){ delete diagnostics; } +//=== CAS Functions ----------------------------------------------------------// + +swiftscan_cas_t swiftscan_cas_create(const char *path) { + std::string CASPath(path); + if (CASPath.empty()) + CASPath = llvm::cas::getDefaultOnDiskCASPath(); + + CachingTool *tool = new CachingTool(CASPath); + if (!tool->isValid()) { + delete tool; + return nullptr; + } + return wrap(tool); +} + +void swiftscan_cas_dispose(swiftscan_cas_t cas) { delete unwrap(cas); } + +swiftscan_string_ref_t +swiftscan_cas_store(swiftscan_cas_t cas, uint8_t *data, unsigned size) { + llvm::StringRef StrContent((char*)data, size); + auto ID = unwrap(cas)->storeContent(StrContent); + return swift::c_string_utils::create_clone(ID.c_str()); +} + +static swift::file_types::ID +getFileTypeFromScanOutputKind(swiftscan_output_kind_t kind) { + switch (kind) { + case SWIFTSCAN_OUTPUT_TYPE_OBJECT: + return swift::file_types::ID::TY_Object; + case SWIFTSCAN_OUTPUT_TYPE_SWIFTMODULE: + return swift::file_types::ID::TY_SwiftModuleFile; + case SWIFTSCAN_OUTPUT_TYPE_SWIFTINTERFACE: + return swift::file_types::ID::TY_SwiftModuleInterfaceFile; + case SWIFTSCAN_OUTPUT_TYPE_SWIFTPRIAVEINTERFACE: + return swift::file_types::ID::TY_PrivateSwiftModuleInterfaceFile; + case SWIFTSCAN_OUTPUT_TYPE_CLANG_MODULE: + return swift::file_types::ID::TY_ClangModuleFile; + case SWIFTSCAN_OUTPUT_TYPE_CLANG_PCH: + return swift::file_types::ID::TY_PCH; + } +} + +swiftscan_string_ref_t +swiftscan_compute_cache_key(swiftscan_cas_t cas, int argc, const char **argv, + const char *input, swiftscan_output_kind_t kind) { + std::vector Compilation; + for (int i = 0; i < argc; ++i) + Compilation.push_back(argv[i]); + + auto ID = unwrap(cas)->computeCacheKey(Compilation, input, + getFileTypeFromScanOutputKind(kind)); + return swift::c_string_utils::create_clone(ID.c_str()); +} + //=== Experimental Compiler Invocation Functions ------------------------===// int invoke_swift_compiler(int argc, const char **argv) { diff --git a/tools/libSwiftScan/libSwiftScan.exports b/tools/libSwiftScan/libSwiftScan.exports index 4b940c96ea5f2..9e30dbb0aaa7a 100644 --- a/tools/libSwiftScan/libSwiftScan.exports +++ b/tools/libSwiftScan/libSwiftScan.exports @@ -12,14 +12,19 @@ swiftscan_swift_textual_detail_get_bridging_header_path swiftscan_swift_textual_detail_get_bridging_source_files swiftscan_swift_textual_detail_get_bridging_module_dependencies swiftscan_swift_textual_detail_get_command_line +swiftscan_swift_textual_detail_get_bridging_pch_command_line swiftscan_swift_textual_detail_get_extra_pcm_args swiftscan_swift_textual_detail_get_context_hash swiftscan_swift_textual_detail_get_is_framework swiftscan_swift_textual_detail_get_swift_overlay_dependencies +swiftscan_swift_textual_detail_get_cas_fs_root_id +swiftscan_swift_textual_detail_get_module_cache_key swiftscan_swift_binary_detail_get_compiled_module_path swiftscan_swift_binary_detail_get_module_doc_path swiftscan_swift_binary_detail_get_module_source_info_path +swiftscan_swift_binary_detail_get_header_dependencies swiftscan_swift_binary_detail_get_is_framework +swiftscan_swift_binary_detail_get_module_cache_key swiftscan_swift_placeholder_detail_get_compiled_module_path swiftscan_swift_placeholder_detail_get_module_doc_path swiftscan_swift_placeholder_detail_get_module_source_info_path @@ -27,6 +32,8 @@ swiftscan_clang_detail_get_module_map_path swiftscan_clang_detail_get_context_hash swiftscan_clang_detail_get_command_line swiftscan_clang_detail_get_captured_pcm_args +swiftscan_clang_detail_get_cas_fs_root_id +swiftscan_clang_detail_get_module_cache_key swiftscan_batch_scan_input_set_modules swiftscan_batch_scan_entry_set_module_name swiftscan_batch_scan_entry_set_arguments @@ -68,4 +75,8 @@ swiftscan_scanner_diagnostics_reset swiftscan_diagnostic_get_message swiftscan_diagnostic_get_severity swiftscan_diagnostics_set_dispose +swiftscan_cas_create +swiftscan_cas_dispose +swiftscan_cas_store +swiftscan_compute_cache_key invoke_swift_compiler