diff --git a/cmake/modules/DarwinSDKs.cmake b/cmake/modules/DarwinSDKs.cmake index dc570b7005834..d1ca165d0a294 100644 --- a/cmake/modules/DarwinSDKs.cmake +++ b/cmake/modules/DarwinSDKs.cmake @@ -32,11 +32,14 @@ if(swift_build_freestanding) "Which SDK to use when building the FREESTANDING stdlib") set(SWIFT_FREESTANDING_TRIPLE_NAME "" CACHE STRING "Which triple name (e.g. 'none-macho') to use when building the FREESTANDING stdlib") + set(SWIFT_FREESTANDING_MODULE_NAME "" CACHE STRING + "Which .swiftmodule name (e.g. 'freestanding') to use when building the FREESTANDING stdlib") set(SWIFT_FREESTANDING_ARCHS "" CACHE STRING "Which architectures to build when building the FREESTANDING stdlib") configure_sdk_darwin( FREESTANDING "FREESTANDING" "" - "${SWIFT_FREESTANDING_SDK}" freestanding "${SWIFT_FREESTANDING_TRIPLE_NAME}" freestanding "${SWIFT_FREESTANDING_ARCHS}") + "${SWIFT_FREESTANDING_SDK}" freestanding + "${SWIFT_FREESTANDING_TRIPLE_NAME}" "${SWIFT_FREESTANDING_MODULE_NAME}" "${SWIFT_FREESTANDING_ARCHS}") set(SWIFT_SDK_FREESTANDING_LIB_SUBDIR "freestanding") configure_target_variant(FREESTANDING-DA "FREESTANDING Debug+Asserts" FREESTANDING DA "Debug+Asserts") configure_target_variant(FREESTANDING-RA "FREESTANDING Release+Asserts" FREESTANDING RA "Release+Asserts") diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h index 6f258723fb887..4216002504520 100644 --- a/include/swift/AST/ExtInfo.h +++ b/include/swift/AST/ExtInfo.h @@ -41,6 +41,7 @@ class FunctionType; class SILExtInfo; class SILExtInfoBuilder; class SILFunctionType; +enum class SILFunctionTypeRepresentation : uint8_t; } // namespace swift namespace swift { @@ -54,6 +55,7 @@ class ClangTypeInfo { friend ASTExtInfoBuilder; friend SILExtInfoBuilder; + // [NOTE: ClangTypeInfo-contents] // We preserve a full clang::Type *, not a clang::FunctionType * as: // 1. We need to keep sugar in case we need to present an error to the user // (for AnyFunctionType). @@ -81,6 +83,26 @@ class ClangTypeInfo { void dump(llvm::raw_ostream &os, const clang::ASTContext &ctx) const; }; +// MARK: - UnexpectedClangTypeError +/// Potential errors when trying to store a Clang type in an ExtInfo. +struct UnexpectedClangTypeError { + enum class Kind { + NullForCOrBlock, + NonnullForNonCOrBlock, + NotBlockPointer, + NotFunctionPointerOrReference, + NonCanonical, + }; + const Kind errorKind; + const clang::Type *type; + + static Optional checkClangType( + SILFunctionTypeRepresentation fnRep, const clang::Type *type, + bool expectNonnullForCOrBlock, bool expectCanonical); + + void dump(); +}; + // MARK: - FunctionTypeRepresentation /// The representation form of a function. enum class FunctionTypeRepresentation : uint8_t { @@ -146,6 +168,41 @@ enum class SILFunctionTypeRepresentation : uint8_t { Closure, }; +constexpr SILFunctionTypeRepresentation +convertRepresentation(FunctionTypeRepresentation rep) { + switch (rep) { + case FunctionTypeRepresentation::Swift: + return SILFunctionTypeRepresentation::Thick; + case FunctionTypeRepresentation::Block: + return SILFunctionTypeRepresentation::Block; + case FunctionTypeRepresentation::Thin: + return SILFunctionTypeRepresentation::Thin; + case FunctionTypeRepresentation::CFunctionPointer: + return SILFunctionTypeRepresentation::CFunctionPointer; + } + llvm_unreachable("Unhandled FunctionTypeRepresentation!"); +}; + +inline Optional +convertRepresentation(SILFunctionTypeRepresentation rep) { + switch (rep) { + case SILFunctionTypeRepresentation::Thick: + return {FunctionTypeRepresentation::Swift}; + case SILFunctionTypeRepresentation::Block: + return {FunctionTypeRepresentation::Block}; + case SILFunctionTypeRepresentation::Thin: + return {FunctionTypeRepresentation::Thin}; + case SILFunctionTypeRepresentation::CFunctionPointer: + return {FunctionTypeRepresentation::CFunctionPointer}; + case SILFunctionTypeRepresentation::Method: + case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::Closure: + return None; + } + llvm_unreachable("Unhandled SILFunctionTypeRepresentation!"); +}; + /// Can this calling convention result in a function being called indirectly /// through the runtime. constexpr bool canBeCalledIndirectly(SILFunctionTypeRepresentation rep) { @@ -165,6 +222,25 @@ constexpr bool canBeCalledIndirectly(SILFunctionTypeRepresentation rep) { llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); } +template constexpr bool shouldStoreClangType(Repr repr) { + static_assert(std::is_same::value || + std::is_same::value, + "Expected a Representation type as the argument type."); + switch (static_cast(repr)) { + case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::Block: + return true; + case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::Thin: + case SILFunctionTypeRepresentation::Method: + case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::Closure: + return false; + } + llvm_unreachable("Unhandled SILFunctionTypeRepresentation."); +} + // MARK: - ASTExtInfoBuilder /// A builder type for creating an \c ASTExtInfo. /// @@ -292,7 +368,8 @@ class ASTExtInfoBuilder { LLVM_NODISCARD ASTExtInfoBuilder withRepresentation(Representation rep) const { return ASTExtInfoBuilder((bits & ~RepresentationMask) | (unsigned)rep, - clangTypeInfo); + shouldStoreClangType(rep) ? clangTypeInfo + : ClangTypeInfo()); } LLVM_NODISCARD ASTExtInfoBuilder withNoEscape(bool noEscape = true) const { @@ -333,7 +410,8 @@ class ASTExtInfoBuilder { ASTExtInfoBuilder withSILRepresentation(SILFunctionTypeRepresentation rep) const { return ASTExtInfoBuilder((bits & ~RepresentationMask) | (unsigned)rep, - clangTypeInfo); + shouldStoreClangType(rep) ? clangTypeInfo + : ClangTypeInfo()); } bool isEqualTo(ASTExtInfoBuilder other, bool useClangTypes) const { @@ -360,12 +438,16 @@ class ASTExtInfo { ASTExtInfoBuilder builder; + // Only for use by ASTExtInfoBuilder::build. Don't use it elsewhere! ASTExtInfo(ASTExtInfoBuilder builder) : builder(builder) {} + ASTExtInfo(unsigned bits, ClangTypeInfo clangTypeInfo) - : builder(bits, clangTypeInfo){}; + : builder(bits, clangTypeInfo) { + builder.checkInvariants(); + }; public: - ASTExtInfo() : builder(){}; + ASTExtInfo() : builder() { builder.checkInvariants(); }; /// Create a builder with the same state as \c this. ASTExtInfoBuilder intoBuilder() const { return builder; } @@ -504,7 +586,7 @@ class SILExtInfoBuilder { using Representation = SILFunctionTypeRepresentation; SILExtInfoBuilder(unsigned bits, ClangTypeInfo clangTypeInfo) - : bits(bits), clangTypeInfo(clangTypeInfo) {} + : bits(bits), clangTypeInfo(clangTypeInfo.getCanonical()) {} static constexpr unsigned makeBits(Representation rep, bool isPseudogeneric, bool isNoEscape, bool isAsync, @@ -606,7 +688,8 @@ class SILExtInfoBuilder { // the following with methods instead of mutating these objects. SILExtInfoBuilder withRepresentation(Representation rep) const { return SILExtInfoBuilder((bits & ~RepresentationMask) | (unsigned)rep, - clangTypeInfo); + shouldStoreClangType(rep) ? clangTypeInfo + : ClangTypeInfo()); } SILExtInfoBuilder withIsPseudogeneric(bool isPseudogeneric = true) const { return SILExtInfoBuilder(isPseudogeneric ? (bits | PseudogenericMask) @@ -629,6 +712,10 @@ class SILExtInfoBuilder { ((unsigned)differentiability << DifferentiabilityMaskOffset), clangTypeInfo); } + LLVM_NODISCARD + SILExtInfoBuilder withClangFunctionType(const clang::Type *type) const { + return SILExtInfoBuilder(bits, ClangTypeInfo(type).getCanonical()); + } bool isEqualTo(SILExtInfoBuilder other, bool useClangTypes) const { return bits == other.bits && @@ -654,12 +741,21 @@ class SILExtInfo { SILExtInfoBuilder builder; + // Only for use by SILExtInfoBuilder::build. Don't use it elsewhere! SILExtInfo(SILExtInfoBuilder builder) : builder(builder) {} + SILExtInfo(unsigned bits, ClangTypeInfo clangTypeInfo) - : builder(bits, clangTypeInfo){}; + : builder(bits, clangTypeInfo) { + builder.checkInvariants(); + }; public: - SILExtInfo() : builder(){}; + SILExtInfo() : builder() { builder.checkInvariants(); }; + + SILExtInfo(ASTExtInfo info, bool isPseudogeneric) + : builder(info.intoBuilder(), isPseudogeneric) { + builder.checkInvariants(); + } static SILExtInfo getThin() { return SILExtInfoBuilder(SILExtInfoBuilder::Representation::Thin, false, @@ -722,6 +818,8 @@ class SILExtInfo { constexpr std::pair getFuncAttrKey() const { return builder.getFuncAttrKey(); } + + Optional checkClangType() const; }; /// Helper function to obtain the useClangTypes parameter for checking equality diff --git a/include/swift/AST/PrintOptions.h b/include/swift/AST/PrintOptions.h index 2b99e4ac1e66b..9fb65e5a7d7a0 100644 --- a/include/swift/AST/PrintOptions.h +++ b/include/swift/AST/PrintOptions.h @@ -594,7 +594,7 @@ struct PrintOptions { static PrintOptions printDocInterface(); /// Retrieve the set of options suitable for printing SIL functions. - static PrintOptions printSIL() { + static PrintOptions printSIL(bool printFullConvention = false) { PrintOptions result; result.PrintLongAttrsOnSeparateLines = true; result.PrintStorageRepresentationAttrs = true; @@ -605,6 +605,9 @@ struct PrintOptions { result.PrintIfConfig = false; result.OpaqueReturnTypePrinting = OpaqueReturnTypePrintingMode::StableReference; + if (printFullConvention) + result.PrintFunctionRepresentationAttrs = + PrintOptions::FunctionRepresentationMode::Full; return result; } diff --git a/include/swift/AST/SILOptions.h b/include/swift/AST/SILOptions.h index f5c9eb8bb4ed3..90181bfe448fe 100644 --- a/include/swift/AST/SILOptions.h +++ b/include/swift/AST/SILOptions.h @@ -78,6 +78,9 @@ class SILOptions { /// variables by name when we print it out. This eases diffing of SIL files. bool EmitSortedSIL = false; + /// See \ref FrontendOptions.PrintFullConvention + bool PrintFullConvention = false; + /// Whether to stop the optimization pipeline after serializing SIL. bool StopOptimizationAfterSerialization = false; diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 1248445c78518..2c32f174c370d 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -3888,7 +3888,7 @@ class SILFunctionType final public llvm::FoldingSetNode, private llvm::TrailingObjects { + SubstitutionMap, CanType, ClangTypeInfo> { friend TrailingObjects; size_t numTrailingObjects(OverloadToken) const { @@ -3912,6 +3912,10 @@ class SILFunctionType final size_t(hasInvocationSubstitutions()); } + size_t numTrailingObjects(OverloadToken) const { + return Bits.SILFunctionType.HasClangTypeInfo ? 1 : 0; + } + public: using ExtInfo = SILExtInfo; using ExtInfoBuilder = SILExtInfoBuilder; diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index f15e21568c530..f39915e8a202d 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -244,6 +244,9 @@ class FrontendOptions { /// output path is configured. Optional IntermoduleDependencyTracking; + /// Should we emit the cType when printing @convention(c) or no? + bool PrintFullConvention = false; + /// Should we serialize the hashes of dependencies (vs. the modification /// times) when compiling a module interface? bool SerializeModuleInterfaceDependencyHashes = false; @@ -269,6 +272,10 @@ class FrontendOptions { /// built and given to the compiler invocation. bool DisableImplicitModules = false; + /// When performing a dependency scanning action, only identify and output all imports + /// of the main Swift module's source files. + bool ImportPrescan = false; + /// The different modes for validating TBD against the LLVM IR. enum class TBDValidationMode { Default, ///< Do the default validation for the current platform. diff --git a/include/swift/Frontend/ModuleInterfaceSupport.h b/include/swift/Frontend/ModuleInterfaceSupport.h index f4c97c66c8f62..6bbabd76c2efa 100644 --- a/include/swift/Frontend/ModuleInterfaceSupport.h +++ b/include/swift/Frontend/ModuleInterfaceSupport.h @@ -32,7 +32,7 @@ struct ModuleInterfaceOptions { /// interface, or should we fully-qualify them? bool PreserveTypesAsWritten = false; - /// Should we emit the cType when printing @convention(c) or no? + /// See \ref FrontendOptions.PrintFullConvention. /// [TODO: Clang-type-plumbing] This check should go away. bool PrintFullConvention = false; diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 98510dfce2f30..dcf52f1ea1475 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -226,8 +226,11 @@ def placeholder_dependency_module_map def batch_scan_input_file : Separate<["-"], "batch-scan-input-file">, MetaVarName<"">, HelpText<"Specify a JSON file containing modules to perform batch dependencies scanning">; -} +def import_prescan : Flag<["-"], "import-prescan">, + HelpText<"When performing a dependency scan, only dentify all imports of the main Swift module sources">; + +} // HIDDEN FLAGS let Flags = [FrontendOption, NoDriverOption, HelpHidden] in { @@ -664,10 +667,12 @@ def experimental_spi_imports : Flag<["-"], "experimental-spi-imports">, HelpText<"Enable experimental support for SPI imports">; +// [FIXME: Clang-type-plumbing] Make this a SIL-only option once we start +// unconditionally emitting non-canonical Clang types in swiftinterfaces. def experimental_print_full_convention : Flag<["-"], "experimental-print-full-convention">, - HelpText<"When emitting a module interface, emit additional @convention " - "arguments, regardless of whether they were written in the source">; + HelpText<"When emitting a module interface or SIL, emit additional @convention" + " arguments, regardless of whether they were written in the source">; def experimental_one_way_closure_params : Flag<["-"], "experimental-one-way-closure-params">, diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index 1c4584e71eca9..57c18ef074c6b 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -1116,7 +1116,7 @@ class Parser { ParsedAccessors &accessors, AbstractStorageDecl *storage, SourceLoc StaticLoc); - ParserResult parseDeclVarGetSet(Pattern *pattern, + ParserResult parseDeclVarGetSet(PatternBindingEntry &entry, ParseDeclOptions Flags, SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index 36bc7225dd634..6ad16592afbc2 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -3978,10 +3978,9 @@ class AssignByWrapperInst Destination getAssignDestination() const { return AssignDest; } void setAssignInfo(AssignOwnershipQualifier qualifier, Destination dest) { - using Qualifier = AssignOwnershipQualifier; - assert(qualifier == Qualifier::Init && dest == Destination::BackingWrapper || - qualifier == Qualifier::Reassign && dest == Destination::BackingWrapper || - qualifier == Qualifier::Reassign && dest == Destination::WrappedValue); + assert(qualifier == AssignOwnershipQualifier::Init && dest == Destination::BackingWrapper || + qualifier == AssignOwnershipQualifier::Reassign && dest == Destination::BackingWrapper || + qualifier == AssignOwnershipQualifier::Reassign && dest == Destination::WrappedValue); SILInstruction::Bits.AssignByWrapperInst.OwnershipQualifier = unsigned(qualifier); AssignDest = dest; diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h index 68706781ca92f..0610893425ba2 100644 --- a/include/swift/SIL/SILModule.h +++ b/include/swift/SIL/SILModule.h @@ -681,8 +681,7 @@ class SILModule { /// \param Opts The SIL options, used to determine printing verbosity and /// and sorting. /// \param PrintASTDecls If set to true print AST decls. - void print(raw_ostream& OS, - ModuleDecl *M = nullptr, + void print(raw_ostream &OS, ModuleDecl *M = nullptr, const SILOptions &Opts = SILOptions(), bool PrintASTDecls = true) const { SILPrintContext PrintCtx(OS, Opts); diff --git a/include/swift/SIL/SILPrintContext.h b/include/swift/SIL/SILPrintContext.h index f4d8a19860d5d..0b9c2c1448b44 100644 --- a/include/swift/SIL/SILPrintContext.h +++ b/include/swift/SIL/SILPrintContext.h @@ -66,20 +66,23 @@ class SILPrintContext { /// Print debug locations and scopes. bool DebugInfo; + /// See \ref FrontendOptions.PrintFullConvention. + bool PrintFullConvention; + public: /// Constructor with default values for options. /// /// DebugInfo will be set according to the -sil-print-debuginfo option. SILPrintContext(llvm::raw_ostream &OS, bool Verbose = false, - bool SortedSIL = false); + bool SortedSIL = false, bool PrintFullConvention = false); /// Constructor based on SILOptions. /// /// DebugInfo will be set according to the -sil-print-debuginfo option. SILPrintContext(llvm::raw_ostream &OS, const SILOptions &Opts); - SILPrintContext(llvm::raw_ostream &OS, bool Verbose, - bool SortedSIL, bool DebugInfo); + SILPrintContext(llvm::raw_ostream &OS, bool Verbose, bool SortedSIL, + bool DebugInfo, bool PrintFullConvention); virtual ~SILPrintContext(); @@ -100,6 +103,9 @@ class SILPrintContext { /// Returns true if debug locations and scopes should be printed. bool printDebugInfo() const { return DebugInfo; } + /// Returns true if the entire @convention(c, cType: ..) should be printed. + bool printFullConvention() const { return PrintFullConvention; } + SILPrintContext::ID getID(const SILBasicBlock *Block); SILPrintContext::ID getID(const SILNode *node); diff --git a/include/swift/SIL/SILType.h b/include/swift/SIL/SILType.h index f36f27177223c..99794dfa9e514 100644 --- a/include/swift/SIL/SILType.h +++ b/include/swift/SIL/SILType.h @@ -611,7 +611,8 @@ class SILType { std::string getAsString() const; void dump() const; - void print(raw_ostream &OS) const; + void print(raw_ostream &OS, + const PrintOptions &PO = PrintOptions::printSIL()) const; }; // Statically prevent SILTypes from being directly cast to a type diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h index 344087f0a1aaf..ed135eccf8e2f 100644 --- a/include/swift/SIL/TypeLowering.h +++ b/include/swift/SIL/TypeLowering.h @@ -55,20 +55,17 @@ CanAnyFunctionType adjustFunctionType(CanAnyFunctionType type, AnyFunctionType::ExtInfo extInfo); /// Change the given function type's representation. -inline CanAnyFunctionType adjustFunctionType(CanAnyFunctionType t, - SILFunctionType::Representation rep) { - auto extInfo = - t->getExtInfo().intoBuilder().withSILRepresentation(rep).build(); - return adjustFunctionType(t, extInfo); +inline CanAnyFunctionType +adjustFunctionType(CanAnyFunctionType t, AnyFunctionType::Representation rep, + ClangTypeInfo clangTypeInfo) { + auto extInfo = t->getExtInfo() + .intoBuilder() + .withRepresentation(rep) + .withClangFunctionType(clangTypeInfo.getType()) + .build(); + return adjustFunctionType(t, extInfo); } -/// Change the given function type's representation. -inline CanAnyFunctionType adjustFunctionType(CanAnyFunctionType t, - AnyFunctionType::Representation rep) { - auto extInfo = t->getExtInfo().withRepresentation(rep); - return adjustFunctionType(t, extInfo); -} - /// Given a SIL function type, return a type that is identical except /// for using the given ExtInfo. CanSILFunctionType @@ -992,7 +989,8 @@ class TypeConverter { /// Given a function type, yield its bridged formal type. CanAnyFunctionType getBridgedFunctionType(AbstractionPattern fnPattern, CanAnyFunctionType fnType, - Bridgeability bridging); + Bridgeability bridging, + SILFunctionTypeRepresentation rep); /// Given a referenced value and the substituted formal type of a /// resulting l-value expression, produce the substituted formal @@ -1121,7 +1119,7 @@ class TypeConverter { CanSILFunctionType getNativeSILFunctionType( Lowering::TypeConverter &TC, TypeExpansionContext context, Lowering::AbstractionPattern origType, CanAnyFunctionType substType, - Optional origConstant = None, + SILExtInfo silExtInfo, Optional origConstant = None, Optional constant = None, Optional reqtSubs = None, ProtocolConformanceRef witnessMethodConformance = ProtocolConformanceRef()); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 56df3f0c26057..aaae82a139992 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3259,6 +3259,9 @@ GenericFunctionType *GenericFunctionType::get(GenericSignature sig, // point. bool isCanonical = isGenericFunctionTypeCanonical(sig, params, result); + assert(info.getClangTypeInfo().empty() && + "Generic functions do not have Clang types at the moment."); + if (auto funcTy = ctx.getImpl().GenericFunctionTypes.FindNodeOrInsertPos(id, insertPos)) { return funcTy; @@ -3378,6 +3381,7 @@ SILFunctionType::SILFunctionType( "Bits were dropped!"); static_assert(SILExtInfoBuilder::NumMaskBits == NumSILExtInfoBits, "ExtInfo and SILFunctionTypeBitfields must agree on bit size"); + Bits.SILFunctionType.HasClangTypeInfo = !ext.getClangTypeInfo().empty(); Bits.SILFunctionType.CoroutineKind = unsigned(coroutineKind); NumParameters = params.size(); if (coroutineKind == SILCoroutineKind::None) { @@ -3415,6 +3419,9 @@ SILFunctionType::SILFunctionType( getMutableFormalResultsCache() = CanType(); getMutableAllResultsCache() = CanType(); } + if (!ext.getClangTypeInfo().empty()) + *getTrailingObjects() = ext.getClangTypeInfo(); + #ifndef NDEBUG if (ext.getRepresentation() == Representation::WitnessMethod) assert(!WitnessMethodConformance.isInvalid() && @@ -3537,6 +3544,21 @@ CanSILFunctionType SILFunctionType::get( patternSubs = patternSubs.getCanonical(); invocationSubs = invocationSubs.getCanonical(); + + // [FIXME: Clang-type-plumbing] + if (ctx.LangOpts.UseClangFunctionTypes) { + if (auto error = ext.checkClangType()) { + error.getValue().dump(); + llvm_unreachable("Unexpected Clang type in SILExtInfo."); + } + } else if (!ext.getClangTypeInfo().empty()) { + // Unlike AnyFunctionType, SILFunctionType is always canonical. Hence, + // conditionalizing canonical type computation based on + // UseClangFunctionTypes like AnyFunctionType is not feasible. It is simpler + // to drop the Clang type altogether. + ext = ext.intoBuilder().withClangFunctionType(nullptr).build(); + } + llvm::FoldingSetNodeID id; SILFunctionType::Profile(id, genericSig, ext, coroutineKind, callee, params, @@ -3554,12 +3576,11 @@ CanSILFunctionType SILFunctionType::get( // See [NOTE: SILFunctionType-layout] bool hasResultCache = normalResults.size() > 1; - size_t bytes = - totalSizeToAlloc( + size_t bytes = totalSizeToAlloc( params.size(), normalResults.size() + (errorResult ? 1 : 0), yields.size(), (patternSubs ? 1 : 0) + (invocationSubs ? 1 : 0), - hasResultCache ? 2 : 0); + hasResultCache ? 2 : 0, ext.getClangTypeInfo().empty() ? 0 : 1); void *mem = ctx.Allocate(bytes, alignof(SILFunctionType)); diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp index 6174ca0f6145b..68428f45bd27b 100644 --- a/lib/AST/ASTDemangler.cpp +++ b/lib/AST/ASTDemangler.cpp @@ -396,7 +396,7 @@ Type ASTBuilder::createFunctionType( && !flags.isEscaping(); const clang::Type *clangFunctionType = nullptr; - if (representation == FunctionTypeRepresentation::CFunctionPointer) + if (shouldStoreClangType(representation)) clangFunctionType = Ctx.getClangFunctionType(funcParams, output, representation); @@ -523,12 +523,6 @@ Type ASTBuilder::createImplFunctionType( break; } - // [TODO: Store-SIL-Clang-type] - auto einfo = SILExtInfoBuilder(representation, flags.isPseudogeneric(), - !flags.isEscaping(), flags.isAsync(), diffKind, - /*clangFunctionType*/ nullptr) - .build(); - llvm::SmallVector funcParams; llvm::SmallVector funcYields; llvm::SmallVector funcResults; @@ -553,6 +547,21 @@ Type ASTBuilder::createImplFunctionType( auto conv = getResultConvention(errorResult->getConvention()); funcErrorResult.emplace(type, conv); } + + const clang::Type *clangFnType = nullptr; + if (shouldStoreClangType(representation)) { + assert(funcResults.size() <= 1 && funcYields.size() == 0 && + "C functions and blocks have at most 1 result and 0 yields."); + auto result = + funcResults.empty() ? Optional() : funcResults[0]; + clangFnType = getASTContext().getCanonicalClangFunctionType( + funcParams, result, representation); + } + auto einfo = SILFunctionType::ExtInfoBuilder( + representation, flags.isPseudogeneric(), !flags.isEscaping(), + flags.isAsync(), diffKind, clangFnType) + .build(); + return SILFunctionType::get(genericSig, einfo, funcCoroutineKind, funcCalleeConvention, funcParams, funcYields, funcResults, funcErrorResult, diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index f2fea5f0535d6..8d8a26cd2130f 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -3840,6 +3840,14 @@ namespace { OS << '\n'; T->getInvocationSubstitutions().dump(OS, SubstitutionMap::DumpStyle::Full, Indent+2); + if (!T->getClangTypeInfo().empty()) { + std::string s; + llvm::raw_string_ostream os(s); + auto &ctx = + T->getASTContext().getClangModuleLoader()->getClangASTContext(); + T->getClangTypeInfo().dump(os, ctx); + printField("clang_type", os.str()); + } PrintWithColorRAII(OS, ParenthesisColor) << ')'; } diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index cd0838d80466e..b41fe5bb16954 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -4053,8 +4053,8 @@ class TypePrinter : public TypeVisitor { info.getSILRepresentation() == SILFunctionType::Representation::Thick) return; - bool printNameOnly = Options.PrintFunctionRepresentationAttrs == - PrintOptions::FunctionRepresentationMode::NameOnly; + bool printClangType = Options.PrintFunctionRepresentationAttrs == + PrintOptions::FunctionRepresentationMode::Full; Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute); Printer.printAttrName("@convention"); Printer << "("; @@ -4067,13 +4067,13 @@ class TypePrinter : public TypeVisitor { break; case SILFunctionType::Representation::Block: Printer << "block"; + if (printClangType && !info.getClangTypeInfo().empty()) + printCType(Ctx, Printer, info); break; case SILFunctionType::Representation::CFunctionPointer: Printer << "c"; - // [TODO: Clang-type-plumbing] Remove the second check. - if (printNameOnly || info.getClangTypeInfo().empty()) - break; - printCType(Ctx, Printer, info); + if (printClangType && !info.getClangTypeInfo().empty()) + printCType(Ctx, Printer, info); break; case SILFunctionType::Representation::Method: Printer << "method"; @@ -4120,8 +4120,8 @@ class TypePrinter : public TypeVisitor { info.getRepresentation() == SILFunctionType::Representation::Thick) break; - bool printNameOnly = Options.PrintFunctionRepresentationAttrs == - PrintOptions::FunctionRepresentationMode::NameOnly; + bool printClangType = Options.PrintFunctionRepresentationAttrs == + PrintOptions::FunctionRepresentationMode::Full; Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute); Printer.printAttrName("@convention"); Printer << "("; @@ -4133,13 +4133,13 @@ class TypePrinter : public TypeVisitor { break; case SILFunctionType::Representation::Block: Printer << "block"; + if (printClangType) + printCType(Ctx, Printer, info); break; case SILFunctionType::Representation::CFunctionPointer: Printer << "c"; - // [TODO: Clang-type-plumbing] Remove the second check. - if (printNameOnly || info.getClangTypeInfo().empty()) - break; - printCType(Ctx, Printer, info); + if (printClangType) + printCType(Ctx, Printer, info); break; case SILFunctionType::Representation::Method: Printer << "method"; diff --git a/lib/AST/ASTScopeCreation.cpp b/lib/AST/ASTScopeCreation.cpp index 5a921aba2291a..25341f5ce061b 100644 --- a/lib/AST/ASTScopeCreation.cpp +++ b/lib/AST/ASTScopeCreation.cpp @@ -273,11 +273,6 @@ class ScopeCreator final { // Implicit nodes may not have source information for name lookup. if (!isLocalizable(d)) return false; - /// In \c Parser::parseDeclVarGetSet fake PBDs are created. Ignore them. - /// Example: - /// \code - /// class SR10903 { static var _: Int { 0 } } - /// \endcode // Commented out for // validation-test/compiler_crashers_fixed/27962-swift-rebindselfinconstructorexpr-getcalledconstructor.swift @@ -502,9 +497,6 @@ class ScopeCreator final { std::vector expandIfConfigClausesThenCullAndSortElementsOrMembers( ArrayRef input) const { auto cleanedupNodes = sortBySourceRange(cull(expandIfConfigClauses(input))); - // TODO: uncomment when working on not creating two pattern binding decls at - // same location. - // findCollidingPatterns(cleanedupNodes); return cleanedupNodes; } @@ -562,73 +554,6 @@ class ScopeCreator final { return culled; } - /// TODO: The parser yields two decls at the same source loc with the same - /// kind. TODO: me when fixing parser's proclivity to create two - /// PatternBindingDecls at the same source location, then move this to - /// ASTVerifier. - /// - /// In all cases the first pattern seems to carry the initializer, and the - /// second, the accessor - void findCollidingPatterns(ArrayRef input) const { - auto dumpPBD = [&](PatternBindingDecl *pbd, const char *which) { - llvm::errs() << "*** " << which - << " pbd isImplicit: " << pbd->isImplicit() - << ", #entries: " << pbd->getNumPatternEntries() << " :"; - pbd->getSourceRange().print(llvm::errs(), pbd->getASTContext().SourceMgr, - false); - llvm::errs() << "\n"; - llvm::errs() << "init: " << pbd->getInit(0) << "\n"; - if (pbd->getInit(0)) { - llvm::errs() << "SR (init): "; - pbd->getInit(0)->getSourceRange().print( - llvm::errs(), pbd->getASTContext().SourceMgr, false); - llvm::errs() << "\n"; - pbd->getInit(0)->dump(llvm::errs(), 0); - } - llvm::errs() << "vars:\n"; - pbd->getPattern(0)->forEachVariable([&](VarDecl *vd) { - llvm::errs() << " " << vd->getName() - << " implicit: " << vd->isImplicit() - << " #accs: " << vd->getAllAccessors().size() - << "\nSR (var):"; - vd->getSourceRange().print(llvm::errs(), pbd->getASTContext().SourceMgr, - false); - llvm::errs() << "\nSR (braces)"; - vd->getBracesRange().print(llvm::errs(), pbd->getASTContext().SourceMgr, - false); - llvm::errs() << "\n"; - for (auto *a : vd->getAllAccessors()) { - llvm::errs() << "SR (acc): "; - a->getSourceRange().print(llvm::errs(), - pbd->getASTContext().SourceMgr, false); - llvm::errs() << "\n"; - a->dump(llvm::errs(), 0); - } - }); - }; - - Decl *lastD = nullptr; - for (auto n : input) { - auto *d = n.dyn_cast(); - if (!d || !lastD || lastD->getStartLoc() != d->getStartLoc() || - lastD->getKind() != d->getKind()) { - lastD = d; - continue; - } - if (auto *pbd = dyn_cast(lastD)) - dumpPBD(pbd, "prev"); - if (auto *pbd = dyn_cast(d)) { - dumpPBD(pbd, "curr"); - ASTScope_unreachable("found colliding pattern binding decls"); - } - llvm::errs() << "Two same kind decls at same loc: \n"; - lastD->dump(llvm::errs()); - llvm::errs() << "and\n"; - d->dump(llvm::errs()); - ASTScope_unreachable("Two same kind decls; unexpected kinds"); - } - } - /// Templated to work on either ASTNodes, Decl*'s, or whatnot. template std::vector @@ -962,24 +887,6 @@ class NodeAdder : DeclVisibilityKind::LocalVariable; auto *insertionPoint = parentScope; for (auto i : range(patternBinding->getNumPatternEntries())) { - // TODO: Won't need to do so much work to avoid creating one without - // a SourceRange once parser is fixed to not create two - // PatternBindingDecls with same locaiton and getSourceRangeOfThisASTNode - // for PatternEntryDeclScope is simplified to use the PatternEntry's - // source range. - if (!patternBinding->getOriginalInit(i)) { - bool found = false; - patternBinding->getPattern(i)->forEachVariable([&](VarDecl *vd) { - if (!vd->isImplicit()) - found = true; - else - found |= llvm::any_of(vd->getAllAccessors(), [&](AccessorDecl *a) { - return isLocalizable(a); - }); - }); - if (!found) - continue; - } insertionPoint = scopeCreator .ifUniqueConstructExpandAndInsert( @@ -1058,15 +965,6 @@ void ScopeCreator::addChildrenForAllLocalizableAccessorsInSourceOrder( // Accessors are always nested within their abstract storage // declaration. The nesting may not be immediate, because subscripts may // have intervening scopes for generics. - AbstractStorageDecl *const enclosingAbstractStorageDecl = - parent->getEnclosingAbstractStorageDecl().get(); - - std::vector accessorsToScope; - // Assume we don't have to deal with inactive clauses of IfConfigs here - llvm::copy_if(asd->getAllAccessors(), std::back_inserter(accessorsToScope), - [&](AccessorDecl *ad) { - return enclosingAbstractStorageDecl == ad->getStorage(); - }); // Create scopes for `@differentiable` attributes. forEachDifferentiableAttrInSourceOrder( @@ -1075,9 +973,15 @@ void ScopeCreator::addChildrenForAllLocalizableAccessorsInSourceOrder( parent, diffAttr, asd); }); - // Sort in order to include synthesized ones, which are out of order. - for (auto *accessor : sortBySourceRange(accessorsToScope)) - addToScopeTree(accessor, parent); + AbstractStorageDecl *enclosingAbstractStorageDecl = + parent->getEnclosingAbstractStorageDecl().get(); + + asd->visitParsedAccessors([&](AccessorDecl *ad) { + assert(enclosingAbstractStorageDecl == ad->getStorage()); + (void) enclosingAbstractStorageDecl; + + this->addToScopeTree(ad, parent); + }); } #pragma mark creation helpers @@ -1693,8 +1597,12 @@ AbstractPatternEntryScope::AbstractPatternEntryScope( void AbstractPatternEntryScope::forEachVarDeclWithLocalizableAccessors( ScopeCreator &scopeCreator, function_ref foundOne) const { getPatternEntry().getPattern()->forEachVariable([&](VarDecl *var) { - if (llvm::any_of(var->getAllAccessors(), - [&](AccessorDecl *a) { return isLocalizable(a); })) + bool hasParsedAccessors = false; + var->visitParsedAccessors([&](AccessorDecl *) { + hasParsedAccessors = true; + }); + + if (hasParsedAccessors) foundOne(var); }); } @@ -2023,9 +1931,11 @@ class LocalizableDeclContextCollector : public ASTWalker { record(pd->getDefaultArgumentInitContext()); else if (auto *pbd = dyn_cast(D)) recordInitializers(pbd); - else if (auto *vd = dyn_cast(D)) - for (auto *ad : vd->getAllAccessors()) + else if (auto *vd = dyn_cast(D)) { + vd->visitParsedAccessors([&](AccessorDecl *ad) { ad->walk(*this); + }); + } return ASTWalker::walkToDeclPre(D); } diff --git a/lib/AST/ASTScopeLookup.cpp b/lib/AST/ASTScopeLookup.cpp index 8199fd53a7a35..3576eb9068cf5 100644 --- a/lib/AST/ASTScopeLookup.cpp +++ b/lib/AST/ASTScopeLookup.cpp @@ -371,7 +371,7 @@ bool DifferentiableAttributeScope::lookupLocalsOrMembers( if (auto *afd = dyn_cast(attributedDeclaration)) { return visitAbstractFunctionDecl(afd); } else if (auto *asd = dyn_cast(attributedDeclaration)) { - for (auto *accessor : asd->getAllAccessors()) + if (auto *accessor = asd->getParsedAccessor(AccessorKind::Get)) if (visitAbstractFunctionDecl(accessor)) return true; } diff --git a/lib/AST/ASTScopeSourceRange.cpp b/lib/AST/ASTScopeSourceRange.cpp index e608cfe1f6175..ad37f1d967cb0 100644 --- a/lib/AST/ASTScopeSourceRange.cpp +++ b/lib/AST/ASTScopeSourceRange.cpp @@ -247,16 +247,6 @@ SourceRange DefaultArgumentInitializerScope::getSourceRangeOfThisASTNode( SourceRange PatternEntryDeclScope::getSourceRangeOfThisASTNode( const bool omitAssertions) const { - // TODO: Once the creation of two PatternBindingDecls at same location is - // eliminated, the following may be able to be simplified. - if (!getChildren().empty()) { // why needed??? - bool hasOne = false; - getPattern()->forEachVariable([&](VarDecl *) { hasOne = true; }); - if (!hasOne) - return SourceRange(); // just the init - if (!getPatternEntry().getInit()) - return SourceRange(); // just the var decls - } return getPatternEntry().getSourceRange(); } diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index f49276266cfce..a9aee16dac5be 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -1540,19 +1540,25 @@ static ValueDecl *getOnceOperation(ASTContext &Context, auto HandleTy = Context.TheRawPointerType; auto VoidTy = Context.TheEmptyTupleType; + SmallVector CFuncParams; + swift::CanType ContextTy; + if (withContext) { + ContextTy = Context.TheRawPointerType; + auto ContextArg = FunctionType::Param(ContextTy); + CFuncParams.push_back(ContextArg); + } + auto Rep = FunctionTypeRepresentation::CFunctionPointer; + auto ClangType = Context.getClangFunctionType(CFuncParams, VoidTy, Rep); auto Thin = FunctionType::ExtInfoBuilder(FunctionTypeRepresentation::CFunctionPointer, /*throws*/ false) + .withClangFunctionType(ClangType) .build(); - if (withContext) { - auto ContextTy = Context.TheRawPointerType; - auto ContextArg = FunctionType::Param(ContextTy); - auto BlockTy = FunctionType::get({ContextArg}, VoidTy, Thin); - return getBuiltinFunction(Id, {HandleTy, BlockTy, ContextTy}, VoidTy); - } else { - auto BlockTy = FunctionType::get({}, VoidTy, Thin); - return getBuiltinFunction(Id, {HandleTy, BlockTy}, VoidTy); - } + auto BlockTy = FunctionType::get(CFuncParams, VoidTy, Thin); + SmallVector ArgTypes = {HandleTy, BlockTy}; + if (withContext) + ArgTypes.push_back(ContextTy); + return getBuiltinFunction(Id, ArgTypes, VoidTy); } static ValueDecl *getPolymorphicBinaryOperation(ASTContext &ctx, diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 2dbf607223c1a..572ff4cfdd28a 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -2620,6 +2620,7 @@ mapSignatureExtInfo(AnyFunctionType::ExtInfo info, .withRepresentation(info.getRepresentation()) .withAsync(info.isAsync()) .withThrows(info.isThrowing()) + .withClangFunctionType(info.getClangTypeInfo().getType()) .build(); } diff --git a/lib/AST/ExtInfo.cpp b/lib/AST/ExtInfo.cpp index aba9bb2577ce0..1fb30adc6af16 100644 --- a/lib/AST/ExtInfo.cpp +++ b/lib/AST/ExtInfo.cpp @@ -19,17 +19,7 @@ #include "clang/AST/Type.h" -static void assertIsFunctionType(const clang::Type *type) { -#ifndef NDEBUG - if (!(type->isFunctionPointerType() || type->isBlockPointerType() || - type->isFunctionReferenceType())) { - llvm::errs() << "Expected a Clang function type wrapped in a pointer type " - << "or a block pointer type but found:\n"; - type->dump(); - llvm_unreachable("\nUnexpected Clang type when creating ExtInfo!"); - } -#endif -} +#include "llvm/ADT/Optional.h" namespace swift { @@ -64,14 +54,99 @@ void ClangTypeInfo::dump(llvm::raw_ostream &os, } } +// MARK: - UnexpectedClangTypeError + +Optional UnexpectedClangTypeError::checkClangType( + SILFunctionTypeRepresentation silRep, + const clang::Type *type, bool expectNonnullForCOrBlock, bool expectCanonical) { +#ifdef NDEBUG + return None; +#else + bool isBlock = true; + switch (silRep) { + case SILFunctionTypeRepresentation::CFunctionPointer: + isBlock = false; + LLVM_FALLTHROUGH; + case SILFunctionTypeRepresentation::Block: { + if (!type) { + if (expectNonnullForCOrBlock) + return {{Kind::NullForCOrBlock, type}}; + return None; + } + if (expectCanonical && !type->isCanonicalUnqualified()) + return {{Kind::NonCanonical, type}}; + if (isBlock && !type->isBlockPointerType()) + return {{Kind::NotBlockPointer, type}}; + if (!isBlock && !(type->isFunctionPointerType() + || type->isFunctionReferenceType())) + return {{Kind::NotFunctionPointerOrReference, type}}; + return None; + } + default: { + if (type) + return {{Kind::NonnullForNonCOrBlock, type}}; + return None; + } + } +#endif +} + +void UnexpectedClangTypeError::dump() { + auto &e = llvm::errs(); + using Kind = UnexpectedClangTypeError::Kind; + switch (errorKind) { + case Kind::NullForCOrBlock: { + e << "Expected non-null Clang type for @convention(c)/@convention(block)" + << " function but found nullptr."; + return; + } + case Kind::NonnullForNonCOrBlock: { + e << ("Expected null Clang type for non-@convention(c)," + " non-@convention(block) function but found:\n"); + type->dump(); + return; + } + case Kind::NotBlockPointer: { + e << ("Expected block pointer type for @convention(block) function but" + " found:\n"); + type->dump(); + return; + } + case Kind::NotFunctionPointerOrReference: { + e << ("Expected function pointer/reference type for @convention(c) function" + " but found:\n"); + type->dump(); + return; + } + case Kind::NonCanonical: { + e << "Expected canonicalized Clang type but found:\n"; + type->dump(); + return; + } + } + llvm_unreachable("Unhandled case for UnexpectedClangTypeError"); +} + +// [NOTE: ExtInfo-Clang-type-invariant] +// At the SIL level, all @convention(c) and @convention(block) function types +// are expected to carry a ClangTypeInfo. This is not enforced at the AST level +// because we may synthesize types which are not convertible to Clang types. +// 1. Type errors: If we have a type error, we may end up generating (say) a +// @convention(c) function type that has an ErrorType as a parameter. +// 2. Bridging: The representation can change during bridging. For example, an +// @convention(swift) function can be bridged to an @convention(block) +// function. Since this happens during SILGen, we may see a "funny" type +// like @convention(c) () -> @convention(swift) () -> () at the AST level. + // MARK: - ASTExtInfoBuilder void ASTExtInfoBuilder::checkInvariants() const { - // TODO: [clang-function-type-serialization] Once we start serializing - // the Clang type, we should also assert that the pointer is non-null. - auto Rep = Representation(bits & RepresentationMask); - if ((Rep == Representation::CFunctionPointer) && clangTypeInfo.type) - assertIsFunctionType(clangTypeInfo.type); + // See [NOTE: ExtInfo-Clang-type-invariant] + if (auto error = UnexpectedClangTypeError::checkClangType( + getSILRepresentation(), clangTypeInfo.getType(), false, false)) { + error.getValue().dump(); + llvm_unreachable("Ill-formed ASTExtInfoBuilder."); + } } // MARK: - ASTExtInfo @@ -84,7 +159,14 @@ ASTExtInfo ASTExtInfoBuilder::build() const { // MARK: - SILExtInfoBuilder void SILExtInfoBuilder::checkInvariants() const { - // TODO: Add validation checks here while making sure things don't blow up. + // See [NOTE: ExtInfo-Clang-type-invariant] + // [FIXME: Clang-type-plumbing] Strengthen check when UseClangFunctionTypes + // is removed. + if (auto error = UnexpectedClangTypeError::checkClangType( + getRepresentation(), clangTypeInfo.getType(), false, true)) { + error.getValue().dump(); + llvm_unreachable("Ill-formed SILExtInfoBuilder."); + } } SILExtInfo SILExtInfoBuilder::build() const { @@ -92,4 +174,11 @@ SILExtInfo SILExtInfoBuilder::build() const { return SILExtInfo(*this); } +// MARK: - SILExtInfo + +Optional SILExtInfo::checkClangType() const { + return UnexpectedClangTypeError::checkClangType( + getRepresentation(), getClangTypeInfo().getType(), true, true); +} + } // end namespace swift diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index de2636f59b7f5..129efae29ed8c 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -3428,9 +3428,13 @@ bool AnyFunctionType::hasSameExtInfoAs(const AnyFunctionType *otherFn) { return getExtInfo().isEqualTo(otherFn->getExtInfo(), useClangTypes(this)); } -// [TODO: Store-SIL-Clang-type] ClangTypeInfo SILFunctionType::getClangTypeInfo() const { - return ClangTypeInfo(); + if (!Bits.SILFunctionType.HasClangTypeInfo) + return ClangTypeInfo(); + auto *info = getTrailingObjects(); + assert(!info->empty() && + "If the ClangTypeInfo was empty, we shouldn't have stored it."); + return *info; } bool SILFunctionType::hasSameExtInfoAs(const SILFunctionType *otherFn) { diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index a9262dda7c4fc..8ef573cd1929e 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -487,11 +487,15 @@ namespace { if (!pointeeType) return Type(); FunctionType *fTy = pointeeType->castTo(); - - auto rep = FunctionType::Representation::Block; + + auto extInfo = + fTy->getExtInfo() + .intoBuilder() + .withRepresentation(FunctionType::Representation::Block) + .withClangFunctionType(type) + .build(); auto funcTy = - FunctionType::get(fTy->getParams(), fTy->getResult(), - fTy->getExtInfo().withRepresentation(rep)); + FunctionType::get(fTy->getParams(), fTy->getResult(), extInfo); return { funcTy, ImportHint::Block }; } @@ -1407,7 +1411,14 @@ static ImportedType adjustTypeForConcreteImport( auto fTy = importedType->castTo(); FunctionType::ExtInfo einfo = fTy->getExtInfo(); if (einfo.getRepresentation() != requiredFunctionTypeRepr) { - einfo = einfo.withRepresentation(requiredFunctionTypeRepr); + const clang::Type *clangType = nullptr; + if (shouldStoreClangType(requiredFunctionTypeRepr)) + clangType = fTy->getASTContext().getClangFunctionType( + fTy->getParams(), fTy->getResult(), requiredFunctionTypeRepr); + einfo = einfo.intoBuilder() + .withRepresentation(requiredFunctionTypeRepr) + .withClangFunctionType(clangType) + .build(); importedType = fTy->withExtInfo(einfo); } break; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index d4d767caac532..e214e1691503e 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -167,10 +167,15 @@ static void validateDependencyScanningArgs(DiagnosticEngine &diags, const ArgList &args) { const Arg *ExternalDependencyMap = args.getLastArg(options::OPT_placeholder_dependency_module_map); const Arg *ScanDependencies = args.getLastArg(options::OPT_scan_dependencies); + const Arg *Prescan = args.getLastArg(options::OPT_import_prescan); if (ExternalDependencyMap && !ScanDependencies) { diags.diagnose(SourceLoc(), diag::error_requirement_not_met, "-placeholder-dependency-module-map-file", "-scan-dependencies"); } + if (Prescan && !ScanDependencies) { + diags.diagnose(SourceLoc(), diag::error_requirement_not_met, + "-import-prescan", "-scan-dependencies"); + } } static void validateDebugInfoArgs(DiagnosticEngine &diags, diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index f563d0847ae8b..4ef0b90131e8e 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -71,6 +71,8 @@ bool ArgsToFrontendOptionsConverter::convert( Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil); Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil); + Opts.PrintFullConvention |= + Args.hasArg(OPT_experimental_print_full_convention); Opts.EnableTesting |= Args.hasArg(OPT_enable_testing); Opts.EnablePrivateImports |= Args.hasArg(OPT_enable_private_imports); @@ -88,6 +90,8 @@ bool ArgsToFrontendOptionsConverter::convert( Opts.DisableImplicitModules |= Args.hasArg(OPT_disable_implicit_swift_modules); + Opts.ImportPrescan |= Args.hasArg(OPT_import_prescan); + // Always track system dependencies when scanning dependencies. if (const Arg *ModeArg = Args.getLastArg(OPT_modes_Group)) { if (ModeArg->getOption().matches(OPT_scan_dependencies)) { diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 3c72adceab515..9e9b59c1eb642 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1129,6 +1129,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args, Opts.DebugSerialization |= Args.hasArg(OPT_sil_debug_serialization); Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil); Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil); + Opts.PrintFullConvention |= + Args.hasArg(OPT_experimental_print_full_convention); Opts.PrintInstCounts |= Args.hasArg(OPT_print_inst_counts); Opts.StopOptimizationBeforeLoweringOwnership |= Args.hasArg(OPT_sil_stop_optzns_before_lowering_ownership); diff --git a/lib/FrontendTool/ScanDependencies.cpp b/lib/FrontendTool/ScanDependencies.cpp index 4adb17dedc172..a39468e13fb21 100644 --- a/lib/FrontendTool/ScanDependencies.cpp +++ b/lib/FrontendTool/ScanDependencies.cpp @@ -387,6 +387,17 @@ namespace { } } +static void writePrescanJSON(llvm::raw_ostream &out, + const ModuleDependencies &mainModuleDependencies) { + // Write out a JSON containing all main module imports. + out << "{\n"; + SWIFT_DEFER { + out << "}\n"; + }; + + writeJSONSingleField(out, "imports", mainModuleDependencies.getModuleDependencies(), 0, false); +} + static void writeJSON(llvm::raw_ostream &out, CompilerInstance &instance, ModuleDependenciesCache &cache, @@ -648,6 +659,8 @@ static bool scanModuleDependencies(CompilerInstance &instance, FEOpts.PrebuiltModuleCachePath, FEOpts.SerializeModuleInterfaceDependencyHashes, FEOpts.shouldTrackSystemDependencies()); + std::error_code EC; + llvm::raw_fd_ostream out(outputPath, EC, llvm::sys::fs::F_None); Optional rootDeps; if (isClang) { // Loading the clang module using Clang importer. @@ -666,6 +679,12 @@ static bool scanModuleDependencies(CompilerInstance &instance, allModules.insert({moduleName.str(), isClang ? ModuleDependenciesKind::Clang: ModuleDependenciesKind::Swift}); + // Output module prescan. + if (FEOpts.ImportPrescan) { + writePrescanJSON(out, rootDeps.getValue()); + return false; + } + // Explore the dependencies of every module. for (unsigned currentModuleIdx = 0; currentModuleIdx < allModules.size(); @@ -676,8 +695,6 @@ static bool scanModuleDependencies(CompilerInstance &instance, allModules.insert(discoveredModules.begin(), discoveredModules.end()); } // Write out the JSON description. - std::error_code EC; - llvm::raw_fd_ostream out(outputPath, EC, llvm::sys::fs::F_None); writeJSON(out, instance, cache, ASTDelegate, allModules.getArrayRef()); return false; } @@ -774,6 +791,8 @@ bool swift::scanDependencies(CompilerInstance &instance) { "-Xcc", "-target", "-Xcc", instance.getASTContext().LangOpts.Target.str(), "-Xcc", apinotesVer }); + + // Compute Implicit dependencies of the main module { llvm::StringSet<> alreadyAddedModules; for (auto fileUnit : mainModule->getFiles()) { @@ -820,6 +839,17 @@ bool swift::scanDependencies(CompilerInstance &instance) { } } + // If import-prescan is specified, discover and serialize main module dependencies only and exit. + if (opts.ImportPrescan) { + writePrescanJSON(out, mainDependencies); + // This process succeeds regardless of whether any errors occurred. + // FIXME: We shouldn't need this, but it's masking bugs in our scanning + // logic where we don't create a fresh context when scanning Swift interfaces + // that includes their own command-line flags. + Context.Diags.resetHadAnyError(); + return false; + } + // Add the main module. StringRef mainModuleName = mainModule->getNameStr(); llvm::SetVector, diff --git a/lib/IDE/SyntaxModel.cpp b/lib/IDE/SyntaxModel.cpp index 7504a1b6bf183..353006ee22e4e 100644 --- a/lib/IDE/SyntaxModel.cpp +++ b/lib/IDE/SyntaxModel.cpp @@ -990,7 +990,9 @@ bool ModelASTWalker::walkToDeclPre(Decl *D) { if (bracesRange.isValid()) SN.BodyRange = innerCharSourceRangeFromSourceRange(SM, bracesRange); SourceLoc NRStart = VD->getNameLoc(); - SourceLoc NREnd = NRStart.getAdvancedLoc(VD->getName().getLength()); + SourceLoc NREnd = (!VD->getName().empty() + ? NRStart.getAdvancedLoc(VD->getName().getLength()) + : NRStart); SN.NameRange = CharSourceRange(SM, NRStart, NREnd); SN.TypeRange = charSourceRangeFromSourceRange(SM, VD->getTypeSourceRangeForDiagnostics()); diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 8776ca9c21a70..be9f265ce4ba5 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -24,6 +24,7 @@ #include "swift/AST/Module.h" #include "swift/AST/ModuleLoader.h" #include "swift/AST/Pattern.h" +#include "swift/AST/TypeDifferenceVisitor.h" #include "swift/Basic/Dwarf.h" #include "swift/Basic/SourceManager.h" #include "swift/Basic/Version.h" @@ -73,6 +74,26 @@ namespace { using TrackingDIRefMap = llvm::DenseMap; +class EqualUpToClangTypes + : public CanTypeDifferenceVisitor { +public: + bool visitDifferentTypeStructure(CanType t1, CanType t2) { +#define COMPARE_UPTO_CLANG_TYPE(CLASS) \ + if (auto f1 = dyn_cast(t1)) { \ + auto f2 = cast(t2); \ + return !f1->getExtInfo().isEqualTo(f2->getExtInfo(), \ + /*useClangTypes*/ false); \ + } + COMPARE_UPTO_CLANG_TYPE(FunctionType); + COMPARE_UPTO_CLANG_TYPE(SILFunctionType); +#undef COMPARE_UPTO_CLANG_TYPE + return true; + } + bool check(Type t1, Type t2) { + return !visit(t1->getCanonicalType(), t2->getCanonicalType()); + }; +}; + class IRGenDebugInfoImpl : public IRGenDebugInfo { friend class IRGenDebugInfoImpl; const IRGenOptions &Opts; @@ -815,7 +836,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { llvm::errs() << "Original type:\n"; Ty->dump(llvm::errs()); abort(); - } else if (!Reconstructed->isEqual(Ty)) { + } else if (!Reconstructed->isEqual(Ty) && + !EqualUpToClangTypes().check(Reconstructed, Ty)) { + // [FIXME: Include-Clang-type-in-mangling] Remove second check llvm::errs() << "Incorrect reconstructed type for " << Result << "\n"; llvm::errs() << "Original type:\n"; Ty->dump(llvm::errs()); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 6c387e639640b..fa9ace4441e27 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -5680,14 +5680,16 @@ ParserStatus Parser::parseGetSet(ParseDeclOptions Flags, /// Parse the brace-enclosed getter and setter for a variable. ParserResult -Parser::parseDeclVarGetSet(Pattern *pattern, ParseDeclOptions Flags, +Parser::parseDeclVarGetSet(PatternBindingEntry &entry, ParseDeclOptions Flags, SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, SourceLoc VarLoc, bool hasInitializer, const DeclAttributes &Attributes, SmallVectorImpl &Decls) { bool Invalid = false; - + + auto *pattern = entry.getPattern(); + // The grammar syntactically requires a simple identifier for the variable // name. Complain if that isn't what we got. But for recovery purposes, // make an effort to look through other things anyway. @@ -5730,22 +5732,12 @@ Parser::parseDeclVarGetSet(Pattern *pattern, ParseDeclOptions Flags, VarDecl::Introducer::Var, VarLoc, Identifier(), CurDeclContext); - storage->setImplicit(true); storage->setInvalid(); - Pattern *pattern = + pattern = TypedPattern::createImplicit(Context, new (Context) NamedPattern(storage), ErrorType::get(Context)); - PatternBindingEntry entry(pattern, /*EqualLoc*/ SourceLoc(), - /*Init*/ nullptr, /*InitContext*/ nullptr); - auto binding = PatternBindingDecl::create(Context, StaticLoc, - StaticSpelling, - VarLoc, entry, CurDeclContext); - binding->setInvalid(); - storage->setParentPatternBinding(binding); - - Decls.push_back(binding); - Decls.push_back(storage); + entry.setPattern(pattern); } // Parse getter and setter. @@ -6157,7 +6149,8 @@ Parser::parseDeclVar(ParseDeclOptions Flags, if (Tok.is(tok::l_brace)) { HasAccessors = true; auto boundVar = - parseDeclVarGetSet(pattern, Flags, StaticLoc, StaticSpelling, VarLoc, + parseDeclVarGetSet(PBDEntries.back(), + Flags, StaticLoc, StaticSpelling, VarLoc, PatternInit != nullptr, Attributes, Decls); if (boundVar.hasCodeCompletion()) return makeResult(makeParserCodeCompletionStatus()); diff --git a/lib/SIL/IR/Bridging.cpp b/lib/SIL/IR/Bridging.cpp index 053a00de71c7a..4d8430c9509c0 100644 --- a/lib/SIL/IR/Bridging.cpp +++ b/lib/SIL/IR/Bridging.cpp @@ -205,11 +205,15 @@ Type TypeConverter::getLoweredCBridgedType(AbstractionPattern pattern, bridging, /*non-optional*/false); + auto clangType = Context.getClangFunctionType( + newParams, {newResult}, FunctionTypeRepresentation::Block); + return FunctionType::get( newParams, newResult, funTy->getExtInfo() .intoBuilder() - .withSILRepresentation(SILFunctionType::Representation::Block) + .withRepresentation(FunctionType::Representation::Block) + .withClangFunctionType(clangType) .build()); } } diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 4963e5ac05d87..744eab450ac83 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -27,8 +27,10 @@ #include "swift/AST/Module.h" #include "swift/AST/ModuleLoader.h" #include "swift/AST/ProtocolConformance.h" +#include "swift/ClangImporter/ClangImporter.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILType.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -1531,8 +1533,8 @@ class DestructureInputs { void destructure(AbstractionPattern origType, CanAnyFunctionType::CanParamArrayRef params, - AnyFunctionType::ExtInfo extInfo) { - visitTopLevelParams(origType, params, extInfo); + SILExtInfoBuilder extInfoBuilder) { + visitTopLevelParams(origType, params, extInfoBuilder); } private: @@ -1548,13 +1550,14 @@ class DestructureInputs { /// self correctly. void visitTopLevelParams(AbstractionPattern origType, CanAnyFunctionType::CanParamArrayRef params, - AnyFunctionType::ExtInfo extInfo) { + SILExtInfoBuilder extInfoBuilder) { unsigned numEltTypes = params.size(); - bool hasSelf = (extInfo.hasSelfParam() || Foreign.Self.isImportAsMember()); + bool hasSelf = + (extInfoBuilder.hasSelfParam() || Foreign.Self.isImportAsMember()); unsigned numNonSelfParams = (hasSelf ? numEltTypes - 1 : numEltTypes); - auto silRepresentation = extInfo.getSILRepresentation(); + auto silRepresentation = extInfoBuilder.getRepresentation(); // We have to declare this out here so that the lambda scope lasts for // the duration of the loop below. @@ -2019,11 +2022,11 @@ static void destructureYieldsForCoroutine(TypeConverter &TC, /// /// \param conventions - conventions as expressed for the original type static CanSILFunctionType getSILFunctionType( - TypeConverter &TC, TypeExpansionContext expansionContext, AbstractionPattern origType, - CanAnyFunctionType substFnInterfaceType, AnyFunctionType::ExtInfo extInfo, - const Conventions &conventions, const ForeignInfo &foreignInfo, - Optional origConstant, Optional constant, - Optional reqtSubs, + TypeConverter &TC, TypeExpansionContext expansionContext, + AbstractionPattern origType, CanAnyFunctionType substFnInterfaceType, + SILExtInfoBuilder extInfoBuilder, const Conventions &conventions, + const ForeignInfo &foreignInfo, Optional origConstant, + Optional constant, Optional reqtSubs, ProtocolConformanceRef witnessMethodConformance) { // Find the generic parameters. CanGenericSignature genericSig = @@ -2091,7 +2094,7 @@ static CanSILFunctionType getSILFunctionType( // which will have standard thin or thick representation. (Per the previous // comment, it would be useful to do so for generic methods on classes and // protocols too.) - auto rep = extInfo.getSILRepresentation(); + auto rep = extInfoBuilder.getRepresentation(); return (rep == SILFunctionTypeRepresentation::Thick || rep == SILFunctionTypeRepresentation::Thin); }(); @@ -2104,9 +2107,8 @@ static CanSILFunctionType getSILFunctionType( { DestructureInputs destructurer(expansionContext, TC, conventions, foreignInfo, inputs, subst); - destructurer.destructure(origType, - substFnInterfaceType.getParams(), - extInfo); + destructurer.destructure(origType, substFnInterfaceType.getParams(), + extInfoBuilder); } // Destructure the coroutine yields. @@ -2133,23 +2135,33 @@ static CanSILFunctionType getSILFunctionType( } auto calleeConvention = ParameterConvention::Direct_Unowned; - if (extInfo.hasContext()) + if (extInfoBuilder.hasContext()) calleeConvention = conventions.getCallee(); bool pseudogeneric = genericSig && constant ? isPseudogeneric(*constant) : false; - // NOTE: SILFunctionType::ExtInfo doesn't track everything that - // AnyFunctionType::ExtInfo tracks. For example: 'throws' or 'auto-closure' - auto silExtInfo = - SILFunctionType::ExtInfoBuilder() - .withRepresentation(extInfo.getSILRepresentation()) - .withIsPseudogeneric(pseudogeneric) - .withNoEscape(extInfo.isNoEscape()) - .withDifferentiabilityKind(extInfo.getDifferentiabilityKind()) - .build(); - + auto silRep = extInfoBuilder.getRepresentation(); + const clang::Type *clangType = extInfoBuilder.getClangTypeInfo().getType(); + if (shouldStoreClangType(silRep) && !clangType) { + // If we have invalid code in the source like + // do { let x = 0; let _ : @convention(c) () -> Int = { x } } + // we will fail to convert the corresponding SIL function type, as it will + // have a sil_box_type { Int } parameter reflecting the capture. So we + // convert the AST type instead. + // N.B. The `do` is necessary; the code compiles at global scope. + SmallVector params; + for (auto ty : substFnInterfaceType.getParams()) + params.push_back(ty); + clangType = TC.Context.getClangFunctionType( + params, substFnInterfaceType.getResult(), + convertRepresentation(silRep).getValue()); + } + auto silExtInfo = extInfoBuilder.withClangFunctionType(clangType) + .withIsPseudogeneric(pseudogeneric) + .build(); + // Build the substituted generic signature we extracted. SubstitutionMap substitutions; if (subst.Enabled) { @@ -2377,32 +2389,30 @@ struct DefaultBlockConventions : Conventions { } // end anonymous namespace -static CanSILFunctionType -getSILFunctionTypeForAbstractCFunction(TypeConverter &TC, - AbstractionPattern origType, - CanAnyFunctionType substType, - AnyFunctionType::ExtInfo extInfo, - Optional constant); +static CanSILFunctionType getSILFunctionTypeForAbstractCFunction( + TypeConverter &TC, AbstractionPattern origType, + CanAnyFunctionType substType, SILExtInfoBuilder extInfoBuilder, + Optional constant); static CanSILFunctionType getNativeSILFunctionType( - TypeConverter &TC, TypeExpansionContext context, AbstractionPattern origType, - CanAnyFunctionType substInterfaceType, AnyFunctionType::ExtInfo extInfo, - Optional origConstant, Optional constant, - Optional reqtSubs, + TypeConverter &TC, TypeExpansionContext context, + AbstractionPattern origType, CanAnyFunctionType substInterfaceType, + SILExtInfoBuilder extInfoBuilder, Optional origConstant, + Optional constant, Optional reqtSubs, ProtocolConformanceRef witnessMethodConformance) { assert(bool(origConstant) == bool(constant)); auto getSILFunctionTypeForConventions = [&](const Conventions &convs) -> CanSILFunctionType { return getSILFunctionType(TC, context, origType, substInterfaceType, - extInfo, convs, ForeignInfo(), origConstant, - constant, reqtSubs, witnessMethodConformance); + extInfoBuilder, convs, ForeignInfo(), + origConstant, constant, reqtSubs, + witnessMethodConformance); }; - switch (extInfo.getSILRepresentation()) { + switch (extInfoBuilder.getRepresentation()) { case SILFunctionType::Representation::Block: case SILFunctionType::Representation::CFunctionPointer: - return getSILFunctionTypeForAbstractCFunction(TC, origType, - substInterfaceType, - extInfo, constant); + return getSILFunctionTypeForAbstractCFunction( + TC, origType, substInterfaceType, extInfoBuilder, constant); case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::ObjCMethod: @@ -2446,23 +2456,13 @@ static CanSILFunctionType getNativeSILFunctionType( CanSILFunctionType swift::getNativeSILFunctionType( TypeConverter &TC, TypeExpansionContext context, AbstractionPattern origType, CanAnyFunctionType substType, - Optional origConstant, Optional substConstant, - Optional reqtSubs, + SILExtInfo silExtInfo, Optional origConstant, + Optional substConstant, Optional reqtSubs, ProtocolConformanceRef witnessMethodConformance) { - AnyFunctionType::ExtInfo extInfo; - - // Preserve type information from the original type if possible. - if (auto origFnType = origType.getAs()) { - extInfo = origFnType->getExtInfo(); - // Otherwise, preserve function type attributes from the substituted type. - } else { - extInfo = substType->getExtInfo(); - } - - return ::getNativeSILFunctionType(TC, context, origType, substType, extInfo, - origConstant, substConstant, reqtSubs, - witnessMethodConformance); + return ::getNativeSILFunctionType( + TC, context, origType, substType, silExtInfo.intoBuilder(), origConstant, + substConstant, reqtSubs, witnessMethodConformance); } //===----------------------------------------------------------------------===// @@ -2797,21 +2797,18 @@ class CXXMethodConventions : public CFunctionTypeConventions { /// Given that we have an imported Clang declaration, deduce the /// ownership conventions for calling it and build the SILFunctionType. -static CanSILFunctionType -getSILFunctionTypeForClangDecl(TypeConverter &TC, const clang::Decl *clangDecl, - CanAnyFunctionType origType, - CanAnyFunctionType substInterfaceType, - AnyFunctionType::ExtInfo extInfo, - const ForeignInfo &foreignInfo, - Optional constant) { +static CanSILFunctionType getSILFunctionTypeForClangDecl( + TypeConverter &TC, const clang::Decl *clangDecl, + CanAnyFunctionType origType, CanAnyFunctionType substInterfaceType, + SILExtInfoBuilder extInfoBuilder, const ForeignInfo &foreignInfo, + Optional constant) { if (auto method = dyn_cast(clangDecl)) { auto origPattern = AbstractionPattern::getObjCMethod(origType, method, foreignInfo.Error); - return getSILFunctionType(TC, TypeExpansionContext::minimal(), origPattern, - substInterfaceType, extInfo, - ObjCMethodConventions(method), foreignInfo, - constant, constant, None, - ProtocolConformanceRef()); + return getSILFunctionType( + TC, TypeExpansionContext::minimal(), origPattern, substInterfaceType, + extInfoBuilder, ObjCMethodConventions(method), foreignInfo, constant, + constant, None, ProtocolConformanceRef()); } if (auto method = dyn_cast(clangDecl)) { @@ -2820,7 +2817,7 @@ getSILFunctionTypeForClangDecl(TypeConverter &TC, const clang::Decl *clangDecl, AbstractionPattern::getCXXMethod(origType, method); auto conventions = CXXMethodConventions(method); return getSILFunctionType(TC, TypeExpansionContext::minimal(), origPattern, - substInterfaceType, extInfo, conventions, + substInterfaceType, extInfoBuilder, conventions, foreignInfo, constant, constant, None, ProtocolConformanceRef()); } @@ -2833,7 +2830,7 @@ getSILFunctionTypeForClangDecl(TypeConverter &TC, const clang::Decl *clangDecl, foreignInfo.Self) : AbstractionPattern(origType, clangType); return getSILFunctionType(TC, TypeExpansionContext::minimal(), origPattern, - substInterfaceType, extInfo, + substInterfaceType, extInfoBuilder, CFunctionConventions(func), foreignInfo, constant, constant, None, ProtocolConformanceRef()); } @@ -2841,12 +2838,10 @@ getSILFunctionTypeForClangDecl(TypeConverter &TC, const clang::Decl *clangDecl, llvm_unreachable("call to unknown kind of C function"); } -static CanSILFunctionType -getSILFunctionTypeForAbstractCFunction(TypeConverter &TC, - AbstractionPattern origType, - CanAnyFunctionType substType, - AnyFunctionType::ExtInfo extInfo, - Optional constant) { +static CanSILFunctionType getSILFunctionTypeForAbstractCFunction( + TypeConverter &TC, AbstractionPattern origType, + CanAnyFunctionType substType, SILExtInfoBuilder extInfoBuilder, + Optional constant) { if (origType.isClangType()) { auto clangType = origType.getClangType(); const clang::FunctionType *fnType; @@ -2863,17 +2858,17 @@ getSILFunctionTypeForAbstractCFunction(TypeConverter &TC, } if (fnType) { return getSILFunctionType( - TC, TypeExpansionContext::minimal(), origType, substType, extInfo, - CFunctionTypeConventions(fnType), ForeignInfo(), constant, constant, - None, ProtocolConformanceRef()); + TC, TypeExpansionContext::minimal(), origType, substType, + extInfoBuilder, CFunctionTypeConventions(fnType), ForeignInfo(), + constant, constant, None, ProtocolConformanceRef()); } } // TODO: Ought to support captures in block funcs. return getSILFunctionType(TC, TypeExpansionContext::minimal(), origType, - substType, extInfo, DefaultBlockConventions(), - ForeignInfo(), constant, constant, None, - ProtocolConformanceRef()); + substType, extInfoBuilder, + DefaultBlockConventions(), ForeignInfo(), constant, + constant, None, ProtocolConformanceRef()); } /// Try to find a clang method declaration for the given function. @@ -3030,16 +3025,13 @@ class ObjCSelectorFamilyConventions : public Conventions { } // end anonymous namespace -static CanSILFunctionType -getSILFunctionTypeForObjCSelectorFamily(TypeConverter &TC, ObjCSelectorFamily family, - CanAnyFunctionType origType, - CanAnyFunctionType substInterfaceType, - AnyFunctionType::ExtInfo extInfo, - const ForeignInfo &foreignInfo, - Optional constant) { +static CanSILFunctionType getSILFunctionTypeForObjCSelectorFamily( + TypeConverter &TC, ObjCSelectorFamily family, CanAnyFunctionType origType, + CanAnyFunctionType substInterfaceType, SILExtInfoBuilder extInfoBuilder, + const ForeignInfo &foreignInfo, Optional constant) { return getSILFunctionType( TC, TypeExpansionContext::minimal(), AbstractionPattern(origType), - substInterfaceType, extInfo, ObjCSelectorFamilyConventions(family), + substInterfaceType, extInfoBuilder, ObjCSelectorFamilyConventions(family), foreignInfo, constant, constant, /*requirement subs*/ None, ProtocolConformanceRef()); } @@ -3064,26 +3056,47 @@ static bool isImporterGeneratedAccessor(const clang::Decl *clangDecl, static CanSILFunctionType getUncachedSILFunctionTypeForConstant( TypeConverter &TC, TypeExpansionContext context, SILDeclRef constant, - CanAnyFunctionType origLoweredInterfaceType) { - assert(origLoweredInterfaceType->getExtInfo().getSILRepresentation() - != SILFunctionTypeRepresentation::Thick - && origLoweredInterfaceType->getExtInfo().getSILRepresentation() - != SILFunctionTypeRepresentation::Block); + TypeConverter::LoweredFormalTypes bridgedTypes) { + auto silRep = TC.getDeclRefRepresentation(constant); + assert(silRep != SILFunctionTypeRepresentation::Thick && + silRep != SILFunctionTypeRepresentation::Block); + auto origLoweredInterfaceType = bridgedTypes.Uncurried; auto extInfo = origLoweredInterfaceType->getExtInfo(); + auto extInfoBuilder = + SILExtInfo(extInfo, false).intoBuilder().withRepresentation(silRep); + + if (shouldStoreClangType(silRep)) { + const clang::Type *clangType = nullptr; + if (bridgedTypes.Pattern.isClangType()) { + clangType = bridgedTypes.Pattern.getClangType(); + } + if (clangType) { + // According to [NOTE: ClangTypeInfo-contents], we need to wrap a function + // type in an additional clang::PointerType. + if (clangType->isFunctionType()) { + clangType = + static_cast(TC.Context.getClangModuleLoader()) + ->getClangASTContext() + .getPointerType(clang::QualType(clangType, 0)) + .getTypePtr(); + } + extInfoBuilder = extInfoBuilder.withClangFunctionType(clangType); + } + } + if (!constant.isForeign) { ProtocolConformanceRef witnessMethodConformance; - if (extInfo.getSILRepresentation() == - SILFunctionTypeRepresentation::WitnessMethod) { + if (silRep == SILFunctionTypeRepresentation::WitnessMethod) { auto proto = constant.getDecl()->getDeclContext()->getSelfProtocolDecl(); witnessMethodConformance = ProtocolConformanceRef(proto); } return ::getNativeSILFunctionType( TC, context, AbstractionPattern(origLoweredInterfaceType), - origLoweredInterfaceType, extInfo, constant, constant, None, + origLoweredInterfaceType, extInfoBuilder, constant, constant, None, witnessMethodConformance); } @@ -3109,28 +3122,25 @@ static CanSILFunctionType getUncachedSILFunctionTypeForConstant( foreignInfo.Self.setSelfIndex(selfIndex); } - return getSILFunctionTypeForClangDecl(TC, clangDecl, - origLoweredInterfaceType, - origLoweredInterfaceType, - extInfo, foreignInfo, constant); + return getSILFunctionTypeForClangDecl( + TC, clangDecl, origLoweredInterfaceType, origLoweredInterfaceType, + extInfoBuilder, foreignInfo, constant); } } // If the decl belongs to an ObjC method family, use that family's // ownership conventions. return getSILFunctionTypeForObjCSelectorFamily( - TC, getObjCSelectorFamily(constant), - origLoweredInterfaceType, origLoweredInterfaceType, - extInfo, foreignInfo, constant); + TC, getObjCSelectorFamily(constant), origLoweredInterfaceType, + origLoweredInterfaceType, extInfoBuilder, foreignInfo, constant); } CanSILFunctionType TypeConverter::getUncachedSILFunctionTypeForConstant( TypeExpansionContext context, SILDeclRef constant, CanAnyFunctionType origInterfaceType) { - auto origLoweredInterfaceType = - getLoweredFormalTypes(constant, origInterfaceType).Uncurried; + auto bridgedTypes = getLoweredFormalTypes(constant, origInterfaceType); return ::getUncachedSILFunctionTypeForConstant(*this, context, constant, - origLoweredInterfaceType); + bridgedTypes); } static bool isClassOrProtocolMethod(ValueDecl *vd) { @@ -3218,10 +3228,6 @@ TypeConverter::getConstantInfo(TypeExpansionContext expansion, // right type for a getter or setter. auto formalInterfaceType = makeConstantInterfaceType(constant); - // The formal type is just that with the right representation. - auto rep = getDeclRefRepresentation(constant); - formalInterfaceType = adjustFunctionType(formalInterfaceType, rep); - // The lowered type is the formal type, but uncurried and with // parameters automatically turned into their bridged equivalents. auto bridgedTypes = getLoweredFormalTypes(constant, formalInterfaceType); @@ -3229,9 +3235,8 @@ TypeConverter::getConstantInfo(TypeExpansionContext expansion, CanAnyFunctionType loweredInterfaceType = bridgedTypes.Uncurried; // The SIL type encodes conventions according to the original type. - CanSILFunctionType silFnType = - ::getUncachedSILFunctionTypeForConstant(*this, expansion, constant, - loweredInterfaceType); + CanSILFunctionType silFnType = ::getUncachedSILFunctionTypeForConstant( + *this, expansion, constant, bridgedTypes); // If the constant refers to a derivative function, get the SIL type of the // original function and use it to compute the derivative SIL type. @@ -3489,7 +3494,8 @@ TypeConverter::getConstantOverrideInfo(TypeExpansionContext context, // Build the SILFunctionType for the class method call. CanSILFunctionType fnTy = getNativeSILFunctionType( - *this, context, basePattern, bridgedTypes.Uncurried, base, derived, + *this, context, basePattern, bridgedTypes.Uncurried, + derivedInfo.SILFnType->getExtInfo(), base, derived, /*reqt subs*/ None, ProtocolConformanceRef()); // Build the SILConstantInfo and cache it. @@ -3978,14 +3984,12 @@ SILFunctionType::substituteOpaqueArchetypes(TypeConverter &TC, } /// Fast path for bridging types in a function type without uncurrying. -CanAnyFunctionType -TypeConverter::getBridgedFunctionType(AbstractionPattern pattern, - CanAnyFunctionType t, - Bridgeability bridging) { +CanAnyFunctionType TypeConverter::getBridgedFunctionType( + AbstractionPattern pattern, CanAnyFunctionType t, Bridgeability bridging, + SILFunctionTypeRepresentation rep) { // Pull out the generic signature. CanGenericSignature genericSig = t.getOptGenericSignature(); - auto rep = t->getExtInfo().getSILRepresentation(); switch (getSILFunctionLanguage(rep)) { case SILFunctionLanguage::Swift: { // No bridging needed for native functions. @@ -4091,20 +4095,20 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant, getAbstractionPatternForConstant(Context, constant, fnType, numParameterLists); + auto extInfo = fnType->getExtInfo(); + SILFunctionTypeRepresentation rep = getDeclRefRepresentation(constant); + assert(rep != SILFunctionType::Representation::Block && + "objc blocks cannot be curried"); + // Fast path: no uncurrying required. if (numParameterLists == 1) { auto bridgedFnType = - getBridgedFunctionType(bridgingFnPattern, fnType, bridging); + getBridgedFunctionType(bridgingFnPattern, fnType, bridging, rep); bridgingFnPattern.rewriteType(bridgingFnPattern.getGenericSignature(), bridgedFnType); return { bridgingFnPattern, bridgedFnType }; } - auto extInfo = fnType->getExtInfo(); - SILFunctionTypeRepresentation rep = extInfo.getSILRepresentation(); - assert(rep != SILFunctionType::Representation::Block - && "objc blocks cannot be curried"); - // The dependent generic signature. CanGenericSignature genericSig = fnType.getOptGenericSignature(); diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index 17c3810556b77..3fe377a57792e 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -440,13 +440,12 @@ static void printSILTypeColorAndSigil(raw_ostream &OS, SILType t) { // Potentially add a leading sigil for the value category. ::print(OS, t.getCategory()); } - -void SILType::print(raw_ostream &OS) const { + +void SILType::print(raw_ostream &OS, const PrintOptions &PO) const { printSILTypeColorAndSigil(OS, *this); // Print other types as their Swift representation. - PrintOptions SubPrinter = PrintOptions::printSIL(); - getASTType().print(OS, SubPrinter); + getASTType().print(OS, PO); } void SILType::dump() const { @@ -459,7 +458,8 @@ void SILType::dump() const { /// result in `sugaredTypeNames`. static void printSILFunctionNameAndType( llvm::raw_ostream &OS, const SILFunction *function, - llvm::DenseMap &sugaredTypeNames) { + llvm::DenseMap &sugaredTypeNames, + bool printFullConvention = false) { function->printName(OS); OS << " : $"; auto *genEnv = function->getGenericEnvironment(); @@ -496,7 +496,7 @@ static void printSILFunctionNameAndType( sugaredTypeNames[archetypeTy->getCanonicalType()] = name; } } - auto printOptions = PrintOptions::printSIL(); + auto printOptions = PrintOptions::printSIL(printFullConvention); printOptions.GenericSig = genSig; printOptions.AlternativeTypeNames = sugaredTypeNames.empty() ? nullptr : &sugaredTypeNames; @@ -570,8 +570,9 @@ class SILPrinter : public SILInstructionVisitor { SILPrinter( SILPrintContext &PrintCtx, llvm::DenseMap *AlternativeTypeNames = nullptr) - : Ctx(PrintCtx), - PrintState{{PrintCtx.OS()}, PrintOptions::printSIL()}, + : Ctx(PrintCtx), PrintState{{PrintCtx.OS()}, + PrintOptions::printSIL( + PrintCtx.printFullConvention())}, LastBufferID(0) { PrintState.ASTOptions.AlternativeTypeNames = AlternativeTypeNames; PrintState.ASTOptions.PrintForSIL = true; @@ -2684,7 +2685,8 @@ void SILFunction::print(SILPrintContext &PrintCtx) const { OS << "[ossa] "; llvm::DenseMap sugaredTypeNames; - printSILFunctionNameAndType(OS, this, sugaredTypeNames); + printSILFunctionNameAndType(OS, this, sugaredTypeNames, + PrintCtx.printFullConvention()); if (!isExternalDeclaration()) { if (auto eCount = getEntryCount()) { @@ -2702,9 +2704,7 @@ void SILFunction::print(SILPrintContext &PrintCtx) const { /// Pretty-print the SILFunction's name using SIL syntax, /// '@function_mangled_name'. -void SILFunction::printName(raw_ostream &OS) const { - OS << "@" << Name; -} +void SILFunction::printName(raw_ostream &OS) const { OS << "@" << Name; } /// Pretty-print a global variable to the designated stream. void SILGlobalVariable::print(llvm::raw_ostream &OS, bool Verbose) const { @@ -2971,8 +2971,8 @@ static void printFileIDMap(SILPrintContext &Ctx, const FileIDMap map) { } void SILProperty::print(SILPrintContext &Ctx) const { - PrintOptions Options = PrintOptions::printSIL(); - + PrintOptions Options = PrintOptions::printSIL(Ctx.printFullConvention()); + auto &OS = Ctx.OS(); OS << "sil_property "; if (isSerialized()) @@ -3495,19 +3495,20 @@ void SILSpecializeAttr::print(llvm::raw_ostream &OS) const { //===----------------------------------------------------------------------===// SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose, - bool SortedSIL) : - OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL), - DebugInfo(SILPrintDebugInfo) { } + bool SortedSIL, bool PrintFullConvention) + : OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL), + DebugInfo(SILPrintDebugInfo), PrintFullConvention(PrintFullConvention) {} -SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, - const SILOptions &Opts) : - OutStream(OS), Verbose(Opts.EmitVerboseSIL), SortedSIL(Opts.EmitSortedSIL), - DebugInfo(SILPrintDebugInfo) {} +SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, const SILOptions &Opts) + : OutStream(OS), Verbose(Opts.EmitVerboseSIL), + SortedSIL(Opts.EmitSortedSIL), DebugInfo(SILPrintDebugInfo), + PrintFullConvention(Opts.PrintFullConvention) {} SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose, - bool SortedSIL, bool DebugInfo) : - OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL), - DebugInfo(DebugInfo) { } + bool SortedSIL, bool DebugInfo, + bool PrintFullConvention) + : OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL), + DebugInfo(DebugInfo), PrintFullConvention(PrintFullConvention) {} void SILPrintContext::setContext(const void *FunctionOrBlock) { if (FunctionOrBlock != ContextFunctionOrBlock) { diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index 7c7cddb996a7f..4460bcb7e6de3 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -1953,18 +1953,18 @@ TypeConverter::computeLoweredRValueType(TypeExpansionContext forExpansion, // If the formal type uses a C convention, it is not formally // abstractable, and it may be subject to implicit bridging. auto extInfo = substFnType->getExtInfo(); - if (getSILFunctionLanguage(extInfo.getSILRepresentation()) == - SILFunctionLanguage::C) { + auto rep = extInfo.getRepresentation(); + SILFunctionTypeRepresentation silRep = convertRepresentation(rep); + if (getSILFunctionLanguage(silRep) == SILFunctionLanguage::C) { // The importer only applies fully-reversible bridging to the // component types of C function pointers. auto bridging = Bridgeability::Full; - if (extInfo.getSILRepresentation() == - SILFunctionTypeRepresentation::CFunctionPointer) + if (silRep == SILFunctionTypeRepresentation::CFunctionPointer) bridging = Bridgeability::None; // Bridge the parameters and result of the function type. auto bridgedFnType = - TC.getBridgedFunctionType(origType, substFnType, bridging); + TC.getBridgedFunctionType(origType, substFnType, bridging, silRep); substFnType = bridgedFnType; // Also rewrite the type of the abstraction pattern. @@ -1976,8 +1976,24 @@ TypeConverter::computeLoweredRValueType(TypeExpansionContext forExpansion, } } - return ::getNativeSILFunctionType(TC, forExpansion, origType, - substFnType); + AnyFunctionType::ExtInfo baseExtInfo; + if (auto origFnType = origType.getAs()) { + baseExtInfo = origFnType->getExtInfo(); + } else { + baseExtInfo = substFnType->getExtInfo(); + } + const clang::Type *clangType = baseExtInfo.getClangTypeInfo().getType(); + if (shouldStoreClangType(rep) && !clangType) { + clangType = TC.Context.getClangFunctionType( + substFnType->getParams(), substFnType->getResult(), rep); + } + auto silExtInfo = + SILExtInfoBuilder( + baseExtInfo.intoBuilder().withClangFunctionType(clangType), false) + .build(); + + return ::getNativeSILFunctionType(TC, forExpansion, origType, substFnType, + silExtInfo); } // Ignore dynamic self types. diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index bebc6c1fd6f68..f23a39ea3a074 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -450,8 +450,6 @@ SILGenModule::getKeyPathProjectionCoroutine(bool isReadAccess, SILFunction *SILGenModule::emitTopLevelFunction(SILLocation Loc) { ASTContext &C = getASTContext(); - auto extInfo = SILFunctionType::ExtInfo() - .withRepresentation(SILFunctionType::Representation::CFunctionPointer); // Use standard library types if we have them; otherwise, fall back to // builtins. @@ -481,6 +479,14 @@ SILFunction *SILGenModule::emitTopLevelFunction(SILLocation Loc) { SILParameterInfo(Int32Ty, ParameterConvention::Direct_Unowned), SILParameterInfo(PtrPtrInt8Ty, ParameterConvention::Direct_Unowned), }; + SILResultInfo results[] = {SILResultInfo(Int32Ty, ResultConvention::Unowned)}; + + auto rep = SILFunctionType::Representation::CFunctionPointer; + auto *clangTy = C.getCanonicalClangFunctionType(params, results[0], rep); + auto extInfo = SILFunctionType::ExtInfoBuilder() + .withRepresentation(rep) + .withClangFunctionType(clangTy) + .build(); CanSILFunctionType topLevelType = SILFunctionType::get(nullptr, extInfo, SILCoroutineKind::None, diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index 22d3136ca776c..65c44598af668 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -74,9 +74,10 @@ getIndirectApplyAbstractionPattern(SILGenFunction &SGF, case FunctionTypeRepresentation::Block: { // C and block function parameters and results are implicitly // bridged to a foreign type. - auto bridgedType = - SGF.SGM.Types.getBridgedFunctionType(pattern, fnType, - Bridgeability::Full); + auto silRep = + SILFunctionTypeRepresentation(fnType->getExtInfo().getRepresentation()); + auto bridgedType = SGF.SGM.Types.getBridgedFunctionType( + pattern, fnType, Bridgeability::Full, silRep); pattern.rewriteType(CanGenericSignature(), bridgedType); return pattern; } diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 0c1bb7d417a89..e48750a4ccc05 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -347,10 +347,11 @@ getParameterTypes(AnyFunctionType::CanParamArrayRef params) { return results; } -static CanAnyFunctionType getBridgedBlockType(SILGenModule &SGM, - CanAnyFunctionType blockType) { - return SGM.Types.getBridgedFunctionType(AbstractionPattern(blockType), - blockType, Bridgeability::Full); +static CanAnyFunctionType +getBridgedBlockType(SILGenModule &SGM, CanAnyFunctionType blockType, + SILFunctionTypeRepresentation silRep) { + return SGM.Types.getBridgedFunctionType( + AbstractionPattern(blockType), blockType, Bridgeability::Full, silRep); } static void buildFuncToBlockInvokeBody(SILGenFunction &SGF, @@ -367,7 +368,8 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &SGF, SILFunctionConventions funcConv(funcTy, SGF.SGM.M); // Make sure we lower the component types of the formal block type. - formalBlockType = getBridgedBlockType(SGF.SGM, formalBlockType); + formalBlockType = getBridgedBlockType(SGF.SGM, formalBlockType, + blockTy->getRepresentation()); // Set up the indirect result. SILType blockResultTy = @@ -551,9 +553,16 @@ ManagedValue SILGenFunction::emitFuncToBlock(SILLocation loc, blockInterfaceTy->getParameters().end(), std::back_inserter(params)); - auto extInfo = - SILFunctionType::ExtInfo() - .withRepresentation(SILFunctionType::Representation::CFunctionPointer); + auto results = blockInterfaceTy->getResults(); + auto representation = SILFunctionType::Representation::CFunctionPointer; + auto *clangFnType = getASTContext().getCanonicalClangFunctionType( + params, results.empty() ? Optional() : results[0], + representation); + + auto extInfo = SILFunctionType::ExtInfoBuilder() + .withRepresentation(representation) + .withClangFunctionType(clangFnType) + .build(); CanGenericSignature genericSig; GenericEnvironment *genericEnv = nullptr; @@ -821,7 +830,8 @@ static void buildBlockToFuncThunkBody(SILGenFunction &SGF, Scope scope(SGF.Cleanups, CleanupLocation::get(loc)); // Make sure we lower the component types of the formal block type. - formalBlockTy = getBridgedBlockType(SGF.SGM, formalBlockTy); + formalBlockTy = + getBridgedBlockType(SGF.SGM, formalBlockTy, blockTy->getRepresentation()); assert(blockTy->getNumParameters() == funcTy->getNumParameters() && "block and function types don't match"); diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 0cd630a84180e..48ddd6810762d 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -1773,14 +1773,14 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e, case AnyFunctionType::Representation::Swift: case AnyFunctionType::Representation::Thin: // Source is native, so we can convert signature first. - destTy = adjustFunctionType(destRepTy, - srcTy->getRepresentation()); + destTy = adjustFunctionType(destRepTy, srcTy->getRepresentation(), + srcTy->getClangTypeInfo()); break; case AnyFunctionType::Representation::Block: case AnyFunctionType::Representation::CFunctionPointer: // Source is foreign, so do the representation change first. - srcTy = adjustFunctionType(srcRepTy, - destRepTy->getRepresentation()); + srcTy = adjustFunctionType(srcRepTy, destRepTy->getRepresentation(), + destRepTy->getClangTypeInfo()); } auto result = SGF.emitRValueAsSingleValue(e->getSubExpr()); diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index 8b6af7dad56ea..b9672b021bb89 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -599,20 +599,23 @@ void SILGenFunction::emitArtificialTopLevel(Decl *mainDecl) { CanType anyObjectMetaTy = CanExistentialMetatypeType::get(anyObjectTy, MetatypeRepresentation::ObjC); - auto NSStringFromClassType = SILFunctionType::get(nullptr, - SILFunctionType::ExtInfo() - .withRepresentation(SILFunctionType::Representation:: - CFunctionPointer), - SILCoroutineKind::None, - ParameterConvention::Direct_Unowned, - SILParameterInfo(anyObjectMetaTy, - ParameterConvention::Direct_Unowned), - /*yields*/ {}, - SILResultInfo(OptNSStringTy, - ResultConvention::Autoreleased), - /*error result*/ None, - SubstitutionMap(), SubstitutionMap(), - ctx); + auto paramConvention = ParameterConvention::Direct_Unowned; + auto params = {SILParameterInfo(anyObjectMetaTy, paramConvention)}; + std::array resultInfos = { + SILResultInfo(OptNSStringTy, ResultConvention::Autoreleased)}; + auto repr = SILFunctionType::Representation::CFunctionPointer; + auto *clangFnType = + ctx.getCanonicalClangFunctionType(params, resultInfos[0], repr); + auto extInfo = SILFunctionType::ExtInfoBuilder() + .withRepresentation(repr) + .withClangFunctionType(clangFnType) + .build(); + + auto NSStringFromClassType = SILFunctionType::get( + nullptr, extInfo, SILCoroutineKind::None, paramConvention, params, + /*yields*/ {}, resultInfos, /*error result*/ None, SubstitutionMap(), + SubstitutionMap(), ctx); + auto NSStringFromClassFn = builder.getOrCreateFunction( mainClass, "NSStringFromClass", SILLinkage::PublicExternal, NSStringFromClassType, IsBare, IsTransparent, IsNotSerialized, diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp index d30a74087fc3e..2dd3de4156090 100644 --- a/lib/SILGen/SILGenType.cpp +++ b/lib/SILGen/SILGenType.cpp @@ -733,8 +733,8 @@ SILFunction *SILGenModule::emitProtocolWitness( // Lower the witness thunk type with the requirement's abstraction level. auto witnessSILFnType = getNativeSILFunctionType( M.Types, TypeExpansionContext::minimal(), AbstractionPattern(reqtOrigTy), - reqtSubstTy, requirement, witnessRef, witnessSubsForTypeLowering, - conformance); + reqtSubstTy, requirementInfo.SILFnType->getExtInfo(), requirement, + witnessRef, witnessSubsForTypeLowering, conformance); // Mangle the name of the witness thunk. Mangle::ASTMangler NewMangler; diff --git a/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp b/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp index 827b59d82d57b..a3a0cb3598097 100644 --- a/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp +++ b/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp @@ -39,7 +39,7 @@ using namespace swift; STATISTIC(NumRefCountOpsRemoved, "Total number of increments removed"); -llvm::cl::opt EnableLoopARC("enable-loop-arc", llvm::cl::init(false)); +llvm::cl::opt EnableLoopARC("enable-loop-arc", llvm::cl::init(true)); //===----------------------------------------------------------------------===// // Code Motion diff --git a/lib/Sema/BuilderTransform.cpp b/lib/Sema/BuilderTransform.cpp index e14181ea955db..fdcf4ee263a92 100644 --- a/lib/Sema/BuilderTransform.cpp +++ b/lib/Sema/BuilderTransform.cpp @@ -1064,6 +1064,8 @@ class BuilderClosureRewriter auto pbd = PatternBindingDecl::create( ctx, SourceLoc(), StaticSpellingKind::None, temporaryVar->getLoc(), pattern, SourceLoc(), initExpr, dc); + if (temporaryVar->isImplicit()) + pbd->setImplicit(); elements.push_back(temporaryVar); elements.push_back(pbd); } diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h index acf8123fcbc26..f03f2d0c6ebd2 100644 --- a/lib/Sema/CSFix.h +++ b/lib/Sema/CSFix.h @@ -1763,6 +1763,10 @@ class SpecifyBaseTypeForContextualMember final : public ConstraintFix { bool diagnose(const Solution &solution, bool asNote = false) const override; + bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override { + return diagnose(*commonFixes.front().first); + } + static SpecifyBaseTypeForContextualMember * create(ConstraintSystem &cs, DeclNameRef member, ConstraintLocator *locator); }; diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 36ba13de5dd52..2a2040fc26505 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -1779,15 +1779,13 @@ namespace { TupleTypeRepr *inputRepr, TypeResolutionOptions options, bool requiresMappingOut, DifferentiabilityKind diffKind); - Type resolveSILFunctionType(FunctionTypeRepr *repr, - TypeResolutionOptions options, - SILCoroutineKind coroutineKind - = SILCoroutineKind::None, - SILFunctionType::ExtInfo extInfo - = SILFunctionType::ExtInfo(), - ParameterConvention calleeConvention - = DefaultParameterConvention, - TypeRepr *witnessmethodProtocol = nullptr); + Type resolveSILFunctionType( + FunctionTypeRepr *repr, TypeResolutionOptions options, + SILCoroutineKind coroutineKind = SILCoroutineKind::None, + SILFunctionType::ExtInfoBuilder extInfoBuilder = + SILFunctionType::ExtInfoBuilder(), + ParameterConvention calleeConvention = DefaultParameterConvention, + TypeRepr *witnessmethodProtocol = nullptr); SILParameterInfo resolveSILParameter(TypeRepr *repr, TypeResolutionOptions options); SILYieldInfo resolveSILYield(TypeAttributes &remainingAttrs, @@ -2225,11 +2223,8 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs, rep = SILFunctionType::Representation::Thin; } else { rep = *parsedRep; - bool isCOrBlock = - rep == SILFunctionTypeRepresentation::CFunctionPointer - || rep == SILFunctionTypeRepresentation::Block; - parsedClangFunctionType = - tryParseClangType(attrs.ConventionArguments.getValue(), isCOrBlock); + parsedClangFunctionType = tryParseClangType( + attrs.ConventionArguments.getValue(), shouldStoreClangType(rep)); } if (rep == SILFunctionType::Representation::WitnessMethod) { @@ -2256,16 +2251,13 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs, } } - // Resolve the function type directly with these attributes. - // [TODO: Store-SIL-Clang-type] - auto extInfo = SILFunctionType::ExtInfoBuilder( - rep, attrs.has(TAK_pseudogeneric), - attrs.has(TAK_noescape), attrs.has(TAK_async), - diffKind, nullptr) - .build(); + auto extInfoBuilder = SILFunctionType::ExtInfoBuilder( + rep, attrs.has(TAK_pseudogeneric), attrs.has(TAK_noescape), + attrs.has(TAK_async), diffKind, parsedClangFunctionType); - ty = resolveSILFunctionType(fnRepr, options, coroutineKind, extInfo, - calleeConvention, witnessMethodProtocol); + ty = + resolveSILFunctionType(fnRepr, options, coroutineKind, extInfoBuilder, + calleeConvention, witnessMethodProtocol); if (!ty || ty->hasError()) return ty; } else { @@ -2287,10 +2279,8 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs, } else { rep = *parsedRep; - bool isCOrBlock = rep == FunctionTypeRepresentation::CFunctionPointer - || rep == FunctionTypeRepresentation::Block; - parsedClangFunctionType = - tryParseClangType(attrs.ConventionArguments.getValue(), isCOrBlock); + parsedClangFunctionType = tryParseClangType( + attrs.ConventionArguments.getValue(), shouldStoreClangType(rep)); } } @@ -2749,11 +2739,10 @@ Type TypeResolver::resolveASTFunctionType( /*clangFunctionType*/ nullptr); const clang::Type *clangFnType = parsedClangFunctionType; - if (representation == AnyFunctionType::Representation::CFunctionPointer && - !clangFnType) { - clangFnType = getASTContext().getClangFunctionType( - params, outputTy, AnyFunctionType::Representation::CFunctionPointer); - } + if (shouldStoreClangType(representation) && !clangFnType) + clangFnType = + getASTContext().getClangFunctionType(params, outputTy, representation); + auto extInfo = extInfoBuilder.withRepresentation(representation) .withAsync(repr->isAsync()) .withClangFunctionType(clangFnType) @@ -2890,12 +2879,11 @@ Type TypeResolver::resolveSILBoxType(SILBoxTypeRepr *repr, return SILBoxType::get(getASTContext(), layout, subMap); } -Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr, - TypeResolutionOptions options, - SILCoroutineKind coroutineKind, - SILFunctionType::ExtInfo extInfo, - ParameterConvention callee, - TypeRepr *witnessMethodProtocol) { +Type TypeResolver::resolveSILFunctionType( + FunctionTypeRepr *repr, TypeResolutionOptions options, + SILCoroutineKind coroutineKind, + SILFunctionType::ExtInfoBuilder extInfoBuilder, ParameterConvention callee, + TypeRepr *witnessMethodProtocol) { options.setContext(None); bool hasError = false; @@ -3095,8 +3083,19 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr, "found witness_method without matching conformance"); } - return SILFunctionType::get(genericSig, extInfo, coroutineKind, callee, - interfaceParams, interfaceYields, + auto representation = extInfoBuilder.getRepresentation(); + const clang::Type *clangFnType = extInfoBuilder.getClangTypeInfo().getType(); + if (shouldStoreClangType(representation) && !clangFnType) { + assert(results.size() <= 1 && yields.size() == 0 && + "C functions and blocks have at most 1 result and 0 yields."); + auto result = results.empty() ? Optional() : results[0]; + clangFnType = getASTContext().getCanonicalClangFunctionType( + interfaceParams, result, representation); + extInfoBuilder = extInfoBuilder.withClangFunctionType(clangFnType); + } + + return SILFunctionType::get(genericSig, extInfoBuilder.build(), coroutineKind, + callee, interfaceParams, interfaceYields, interfaceResults, interfaceErrorResult, interfacePatternSubs, invocationSubs, getASTContext(), witnessMethodConformance); diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift index fac6d8b343a10..fd1a40913a80d 100644 --- a/test/Constraints/diagnostics.swift +++ b/test/Constraints/diagnostics.swift @@ -409,6 +409,7 @@ enum Color { let _: (Int, Color) = [1,2].map({ ($0, .Unknown("")) }) // expected-error@-1 {{cannot convert value of type 'Array<(Int, _)>' to specified type '(Int, Color)'}} +// expected-error@-2 {{cannot infer contextual base in reference to member 'Unknown'}} let _: [(Int, Color)] = [1,2].map({ ($0, .Unknown("")) })// expected-error {{missing argument label 'description:' in call}} diff --git a/test/Constraints/members.swift b/test/Constraints/members.swift index 55ada2a99b4a6..8d74211de6633 100644 --- a/test/Constraints/members.swift +++ b/test/Constraints/members.swift @@ -718,3 +718,11 @@ func testSR13359(_ pair: (Int, Int), _ alias: Pair, _ void: Void, labeled: (a: I _ = labeled[""] // expected-error {{cannot access element using subscript for tuple type '(a: Int, b: Int)'; use '.' notation instead}} {{none}} } + +// rdar://problem/66891544 - incorrect diagnostic ("type is ambiguous") when base type of a reference cannot be determined +func rdar66891544() { + func foo(_: T, defaultT: T? = nil) {} + func foo(_: U, defaultU: U? = nil) {} + + foo(.bar) // expected-error {{cannot infer contextual base in reference to member 'bar'}} +} diff --git a/test/Generics/associated_types_inherit.swift b/test/Generics/associated_types_inherit.swift index c7622e8583b41..1d4459b4ae9f4 100644 --- a/test/Generics/associated_types_inherit.swift +++ b/test/Generics/associated_types_inherit.swift @@ -1,10 +1,10 @@ // RUN: %target-typecheck-verify-swift -class C { +class C { func f() {} } -class D : C { +class D : C { } class E { } @@ -30,3 +30,11 @@ func testP(_ t: T) { func callTestP(_ x1: X1) { testP(x1) } + +// SR-10251: unable to infer associated type in child protocol +protocol P2 { associatedtype T } + +protocol P3: P2 where T == Self {} + +enum C3: P3 {} // correct, might be an error + diff --git a/test/Index/invalid_code.swift b/test/Index/invalid_code.swift index 8cac081c70535..9f29ce906eff1 100644 --- a/test/Index/invalid_code.swift +++ b/test/Index/invalid_code.swift @@ -1,6 +1,5 @@ // RUN: %target-swift-ide-test -print-indexed-symbols -include-locals -source-filename %s | %FileCheck %s -// CHECK: [[@LINE+1]]:8 | struct/Swift | Int | {{.*}} | Ref | rel: 0 var _: Int { get { return 1 } } func test() { diff --git a/test/Parse/pattern_without_variables.swift b/test/Parse/pattern_without_variables.swift index d9317ce325dba..7ecad6f832f1a 100644 --- a/test/Parse/pattern_without_variables.swift +++ b/test/Parse/pattern_without_variables.swift @@ -40,5 +40,4 @@ func testVarLetPattern(a : SimpleEnum) { class SR10903 { static var _: Int { 0 } //expected-error {{getter/setter can only be defined for a single variable}} - //expected-error@-1 {{property declaration does not bind any variables}} } diff --git a/test/SIL/clang-function-types.swift b/test/SIL/clang-function-types.swift new file mode 100644 index 0000000000000..6ed5268a9268a --- /dev/null +++ b/test/SIL/clang-function-types.swift @@ -0,0 +1,8 @@ +// RUN: %target-swift-frontend %s -emit-sil -swift-version 5 -use-clang-function-types -experimental-print-full-convention -o - | %FileCheck %s + +public func f(g: @convention(c) () -> ()) { g() } + +// CHECK: sil @$s4main1f1gyyyXC_tF : $@convention(thin) (@convention(c, cType: "void (*)(void)") @noescape () -> ()) -> () { +// CHECK: bb0(%0 : $@convention(c, cType: "void (*)(void)") @noescape () -> ()): +// CHECK: debug_value %0 : $@convention(c, cType: "void (*)(void)") @noescape () -> (), let, name "g", argno 1 // id: %1 +// CHECK: %2 = apply %0() : $@convention(c, cType: "void (*)(void)") @noescape () -> () diff --git a/test/ScanDependencies/batch_prescan.swift b/test/ScanDependencies/batch_prescan.swift new file mode 100644 index 0000000000000..e4f85e15e9199 --- /dev/null +++ b/test/ScanDependencies/batch_prescan.swift @@ -0,0 +1,22 @@ +// RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/inputs) +// RUN: %empty-directory(%t/outputs) +// RUN: mkdir -p %t/clang-module-cache + +// RUN: echo "[{" > %/t/inputs/input.json +// RUN: echo "\"swiftModuleName\": \"F\"," >> %/t/inputs/input.json +// RUN: echo "\"arguments\": \"-target x86_64-apple-macosx10.9\"," >> %/t/inputs/input.json +// RUN: echo "\"output\": \"%/t/outputs/F.swiftmodule.json\"" >> %/t/inputs/input.json +// RUN: echo "}]" >> %/t/inputs/input.json + +// RUN: %target-swift-frontend -scan-dependencies -import-prescan -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -batch-scan-input-file %/t/inputs/input.json + +// Check the contents of the JSON output +// RUN: %FileCheck %s -check-prefix=CHECK-SWIFT < %t/outputs/F.swiftmodule.json + +// CHECK-SWIFT: { +// CHECK-SWIFT-NEXT:"imports": [ +// CHECK-SWIFT-NEXT: "Swift", +// CHECK-SWIFT-NEXT: "F", +// CHECK-SWIFT-NEXT: "SwiftOnoneSupport" +// CHECK-SWIFT-NEXT:] diff --git a/test/ScanDependencies/prescan_deps.swift b/test/ScanDependencies/prescan_deps.swift new file mode 100644 index 0000000000000..3716d520e52bf --- /dev/null +++ b/test/ScanDependencies/prescan_deps.swift @@ -0,0 +1,23 @@ +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/clang-module-cache +// RUN: %target-swift-frontend -scan-dependencies -import-prescan -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 + +// Check the contents of the JSON output +// RUN: %FileCheck %s < %t/deps.json + +// REQUIRES: executable_test +// REQUIRES: objc_interop + +import C +import E +import G +import SubE + +// CHECK: "imports": [ +// CHECK-NEXT: "C", +// CHECK-NEXT: "E", +// CHECK-NEXT: "G", +// CHECK-NEXT: "SubE", +// CHECK-NEXT: "Swift", +// CHECK-NEXT: "SwiftOnoneSupport" +// CHECK-NEXT: ] diff --git a/test/Serialization/clang-function-types.swift b/test/Serialization/clang-function-types.swift index d85eadf358fe7..195343c08b1a8 100644 --- a/test/Serialization/clang-function-types.swift +++ b/test/Serialization/clang-function-types.swift @@ -11,7 +11,7 @@ import def_clang_function_types // CHECK-LABEL: sil hidden @$s4main5test1yyF func test1() { // FIXME: this mangling will have to change - // CHECK: global_addr @$s24def_clang_function_types11has_fp_types13OpaquePointerVSgyXCSgvp : $*Optional<@convention(c) () -> Optional> + // CHECK: global_addr @$s24def_clang_function_types11has_fp_types13OpaquePointerVSgyXCSgvp : $*Optional<@convention(c, cType: "struct ForwardInTypedefForFP *(*)(void)") () -> Optional> let fp = has_fp_type _ = fp?() } @@ -24,7 +24,7 @@ func test2() { // CHECK-LABEL: } // end sil function '$s4main5test2yyF' // CHECK-LABEL: sil public_external [canonical] @$s24def_clang_function_types17use_fp_internallyyyF -// CHECK: enum $Optional<@convention(c) () -> Optional>, #Optional.none!enumelt +// CHECK: enum $Optional<@convention(c, cType: "struct ForwardInTypedefForFP2 *(*)(void)") () -> Optional>, #Optional.none!enumelt // CHECK: [[FN:%.*]] = function_ref @$s24def_clang_function_types9use_inout3argyxz_tlF : $@convention(thin) <τ_0_0> (@inout τ_0_0) -> () -// CHECK: apply [[FN]]<(@convention(c) () -> OpaquePointer?)?> +// CHECK: apply [[FN]]<(@convention(c, cType: "OpaqueTypedefForFP2 (*)(void)") () -> OpaquePointer?)?> // CHECK-LABEL: } // end sil function '$s24def_clang_function_types17use_fp_internallyyyF' diff --git a/test/SourceKit/DocumentStructure/structure.swift.empty.response b/test/SourceKit/DocumentStructure/structure.swift.empty.response index 143b642982fe2..ec58636238a6f 100644 --- a/test/SourceKit/DocumentStructure/structure.swift.empty.response +++ b/test/SourceKit/DocumentStructure/structure.swift.empty.response @@ -573,11 +573,10 @@ key.kind: source.lang.swift.decl.var.global, key.accessibility: source.lang.swift.accessibility.internal, key.setter_accessibility: source.lang.swift.accessibility.internal, - key.name: "Qtys", key.offset: 1079, - key.length: 15, - key.nameoffset: 1089, - key.namelength: 4 + key.length: 3, + key.nameoffset: 1079, + key.namelength: 0 }, { key.kind: source.lang.swift.stmt.foreach, diff --git a/test/SourceKit/DocumentStructure/structure.swift.foobar.response b/test/SourceKit/DocumentStructure/structure.swift.foobar.response index e5b4e3c2c128c..56f7646264ae6 100644 --- a/test/SourceKit/DocumentStructure/structure.swift.foobar.response +++ b/test/SourceKit/DocumentStructure/structure.swift.foobar.response @@ -573,11 +573,10 @@ key.kind: source.lang.swift.decl.var.global, key.accessibility: source.lang.swift.accessibility.internal, key.setter_accessibility: source.lang.swift.accessibility.internal, - key.name: "Qtys", key.offset: 1079, - key.length: 15, - key.nameoffset: 1089, - key.namelength: 4 + key.length: 3, + key.nameoffset: 1079, + key.namelength: 0 }, { key.kind: source.lang.swift.stmt.foreach, diff --git a/test/SourceKit/DocumentStructure/structure.swift.response b/test/SourceKit/DocumentStructure/structure.swift.response index ac24e47f8f08d..411d00f2fdb88 100644 --- a/test/SourceKit/DocumentStructure/structure.swift.response +++ b/test/SourceKit/DocumentStructure/structure.swift.response @@ -573,11 +573,10 @@ key.kind: source.lang.swift.decl.var.global, key.accessibility: source.lang.swift.accessibility.internal, key.setter_accessibility: source.lang.swift.accessibility.internal, - key.name: "Qtys", key.offset: 1079, - key.length: 15, - key.nameoffset: 1089, - key.namelength: 4 + key.length: 3, + key.nameoffset: 1079, + key.namelength: 0 }, { key.kind: source.lang.swift.stmt.foreach, diff --git a/tools/sil-func-extractor/SILFunctionExtractor.cpp b/tools/sil-func-extractor/SILFunctionExtractor.cpp index d7ffda8671743..120fd6a8ff54f 100644 --- a/tools/sil-func-extractor/SILFunctionExtractor.cpp +++ b/tools/sil-func-extractor/SILFunctionExtractor.cpp @@ -101,10 +101,9 @@ static llvm::cl::opt Triple("target", llvm::cl::desc("target triple")); static llvm::cl::opt -EnableSILSortOutput("emit-sorted-sil", llvm::cl::Hidden, - llvm::cl::init(false), - llvm::cl::desc("Sort Functions, VTables, Globals, " - "WitnessTables by name to ease diffing.")); + EmitSortedSIL("emit-sorted-sil", llvm::cl::Hidden, llvm::cl::init(false), + llvm::cl::desc("Sort Functions, VTables, Globals, " + "WitnessTables by name to ease diffing.")); static llvm::cl::opt DisableASTDump("sil-disable-ast-dump", llvm::cl::Hidden, @@ -247,6 +246,10 @@ int main(int argc, char **argv) { if (Invocation.getLangOptions().Target.isOSBinFormatWasm()) Invocation.getLangOptions().EnableObjCInterop = false; + SILOptions &Opts = Invocation.getSILOptions(); + Opts.EmitVerboseSIL = EmitVerboseSIL; + Opts.EmitSortedSIL = EmitSortedSIL; + serialization::ExtendedValidationInfo extendedInfo; llvm::ErrorOr> FileBufOrErr = Invocation.setUpInputForSILTool(InputFilename, ModuleName, @@ -342,7 +345,7 @@ int main(int argc, char **argv) { auto SILOpts = SILOptions(); SILOpts.EmitVerboseSIL = EmitVerboseSIL; - SILOpts.EmitSortedSIL = EnableSILSortOutput; + SILOpts.EmitSortedSIL = EmitSortedSIL; if (OutputFile == "-") { SILMod->print(llvm::outs(), CI.getMainModule(), SILOpts, !DisableASTDump); diff --git a/tools/sil-opt/SILOpt.cpp b/tools/sil-opt/SILOpt.cpp index f4d2b4490cf3b..2c864cc7d4da5 100644 --- a/tools/sil-opt/SILOpt.cpp +++ b/tools/sil-opt/SILOpt.cpp @@ -199,10 +199,9 @@ static llvm::cl::opt ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path")); static llvm::cl::opt -EnableSILSortOutput("emit-sorted-sil", llvm::cl::Hidden, - llvm::cl::init(false), - llvm::cl::desc("Sort Functions, VTables, Globals, " - "WitnessTables by name to ease diffing.")); + EmitSortedSIL("emit-sorted-sil", llvm::cl::Hidden, llvm::cl::init(false), + llvm::cl::desc("Sort Functions, VTables, Globals, " + "WitnessTables by name to ease diffing.")); static llvm::cl::opt DisableASTDump("sil-disable-ast-dump", llvm::cl::Hidden, @@ -401,6 +400,8 @@ int main(int argc, char **argv) { break; } } + SILOpts.EmitVerboseSIL |= EmitVerboseSIL; + SILOpts.EmitSortedSIL |= EmitSortedSIL; SILOpts.EnableSpeculativeDevirtualization = EnableSpeculativeDevirtualization; SILOpts.IgnoreAlwaysInline = IgnoreAlwaysInline; @@ -530,7 +531,7 @@ int main(int argc, char **argv) { StringRef(OutputFilename) : "-"; auto SILOpts = SILOptions(); SILOpts.EmitVerboseSIL = EmitVerboseSIL; - SILOpts.EmitSortedSIL = EnableSILSortOutput; + SILOpts.EmitSortedSIL = EmitSortedSIL; if (OutputFile == "-") { SILMod->print(llvm::outs(), CI.getMainModule(), SILOpts, !DisableASTDump); } else { diff --git a/utils/build-presets.ini b/utils/build-presets.ini index c72f97cc240af..c7b1e476334bd 100644 --- a/utils/build-presets.ini +++ b/utils/build-presets.ini @@ -2369,9 +2369,10 @@ skip-build-cmark skip-build-benchmarks skip-test-cmark -# Then we inject two cmake arguments that cause us not to build tools and to +# This triggers the stdlib standalone build: Don't build tools (the compiler), # assume we are working with the host compiler. -extra-cmake-options=-DSWIFT_INCLUDE_TOOLS=NO -DSWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER=YES +build-swift-tools=0 +build-runtime-with-host-compiler=1 # Then set the paths to our native tools. If compiling against a toolchain, # these should all be the ./usr/bin directory. @@ -2468,6 +2469,7 @@ swift-primary-variant-arch=x86_64 swift-freestanding-sdk=macosx # For now, until clang/swiftc works correctly with "none-macho" as the OS part of target triple. swift-freestanding-triple-name=macosx11.0 +swift-freestanding-module-name=macos swift-freestanding-archs=x86_64 #===----------------------------------------------------------------------===# diff --git a/utils/build-script-impl b/utils/build-script-impl index 4abf76755cd41..d1a332edb6312 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -206,6 +206,7 @@ KNOWN_SETTINGS=( ## FREESTANDING Stdlib Options swift-freestanding-sdk "" "which SDK to use when building the FREESTANDING stdlib" swift-freestanding-triple-name "" "which triple name (e.g. 'none-macho') to use when building the FREESTANDING stdlib" + swift-freestanding-module-name "" "which .swiftmodule name (e.g. 'freestanding') to use when building the FREESTANDING stdlib" swift-freestanding-archs "" "space-separated list of which architectures to build when building the FREESTANDING stdlib" ## Uncategorised @@ -1929,6 +1930,13 @@ for host in "${ALL_HOSTS[@]}"; do ) fi + if [ "${SWIFT_FREESTANDING_MODULE_NAME}" ] ; then + cmake_options=( + "${cmake_options[@]}" + -DSWIFT_FREESTANDING_MODULE_NAME:STRING="${SWIFT_FREESTANDING_MODULE_NAME}" + ) + fi + if [[ "${SWIFT_FREESTANDING_ARCHS}" ]] ; then cmake_options=( "${cmake_options[@]}" diff --git a/utils/update_checkout/update-checkout-config.json b/utils/update_checkout/update-checkout-config.json index b3ddc61e64916..001bb22eb04e6 100644 --- a/utils/update_checkout/update-checkout-config.json +++ b/utils/update_checkout/update-checkout-config.json @@ -104,20 +104,20 @@ "swift-format": "master" } }, - "master": { - "aliases": ["master", "swift/master"], + "master": { + "aliases": ["master", "swift/master", "main"], "repos": { "llvm-project": "swift/master", "swift": "master", - "cmark": "master", - "llbuild": "master", - "swift-tools-support-core": "master", - "swiftpm": "master", + "cmark": "main", + "llbuild": "main", + "swift-tools-support-core": "main", + "swiftpm": "main", "swift-argument-parser": "0.3.0", - "swift-driver": "master", - "swift-syntax": "master", + "swift-driver": "main", + "swift-syntax": "main", "swift-stress-tester": "master", - "swift-corelibs-xctest": "master", + "swift-corelibs-xctest": "main", "swift-corelibs-foundation": "master", "swift-corelibs-libdispatch": "master", "swift-integration-tests": "master", @@ -139,15 +139,15 @@ "repos": { "llvm-project": "swift/master-next", "swift": "master-next", - "cmark": "master", - "llbuild": "master", - "swift-tools-support-core": "master", - "swiftpm": "master", + "cmark": "main", + "llbuild": "main", + "swift-tools-support-core": "main", + "swiftpm": "main", "swift-argument-parser": "0.3.0", - "swift-driver": "master", - "swift-syntax": "master", - "swift-stress-tester": "master", - "swift-corelibs-xctest": "master", + "swift-driver": "main", + "swift-syntax": "main", + "swift-stress-tester": "main", + "swift-corelibs-xctest": "main", "swift-corelibs-foundation": "master", "swift-corelibs-libdispatch": "master", "swift-integration-tests": "master", @@ -168,8 +168,8 @@ "cmark": "swift-3.0-branch", "llbuild": "swift-3.0-branch", "swiftpm": "swift-3.0-branch", - "swift-syntax": "master", - "swift-stress-tester": "master", + "swift-syntax": "main", + "swift-stress-tester": "main", "swift-corelibs-xctest": "swift-3.0-branch", "swift-corelibs-foundation": "swift-3.0-branch", "swift-corelibs-libdispatch": "swift-3.0-branch", @@ -189,8 +189,8 @@ "cmark": "swift-3.1-branch", "llbuild": "swift-3.1-branch", "swiftpm": "swift-3.1-branch", - "swift-syntax": "master", - "swift-stress-tester": "master", + "swift-syntax": "main", + "swift-stress-tester": "main", "swift-corelibs-xctest": "swift-3.1-branch", "swift-corelibs-foundation": "swift-3.1-branch", "swift-corelibs-libdispatch": "swift-3.1-branch", @@ -210,8 +210,8 @@ "cmark": "swift-4.0-branch", "llbuild": "swift-4.0-branch", "swiftpm": "swift-4.0-branch", - "swift-syntax": "master", - "swift-stress-tester": "master", + "swift-syntax": "main", + "swift-stress-tester": "main", "swift-corelibs-xctest": "swift-4.0-branch", "swift-corelibs-foundation": "swift-4.0-branch", "swift-corelibs-libdispatch": "swift-4.0-branch", @@ -231,8 +231,8 @@ "cmark": "swift-4.1-branch", "llbuild": "swift-4.1-branch", "swiftpm": "swift-4.1-branch", - "swift-syntax": "master", - "swift-stress-tester": "master", + "swift-syntax": "main", + "swift-stress-tester": "main", "swift-corelibs-xctest": "swift-4.1-branch", "swift-corelibs-foundation": "swift-4.1-branch", "swift-corelibs-libdispatch": "swift-4.1-branch", @@ -253,7 +253,7 @@ "llbuild": "swift-4.2-branch", "swiftpm": "swift-4.2-branch", "swift-syntax": "swift-4.2-branch", - "swift-stress-tester": "master", + "swift-stress-tester": "main", "swift-corelibs-xctest": "swift-4.2-branch", "swift-corelibs-foundation": "swift-4.2-branch", "swift-corelibs-libdispatch": "swift-4.2-branch", @@ -362,15 +362,15 @@ "repos": { "llvm-project": "swift/master-rebranch", "swift": "master-rebranch", - "cmark": "master", - "llbuild": "master", - "swift-tools-support-core": "master", - "swiftpm": "master", + "cmark": "main", + "llbuild": "main", + "swift-tools-support-core": "main", + "swiftpm": "main", "swift-argument-parser": "0.3.0", - "swift-driver": "master", - "swift-syntax": "master", - "swift-stress-tester": "master", - "swift-corelibs-xctest": "master", + "swift-driver": "main", + "swift-syntax": "main", + "swift-stress-tester": "main", + "swift-corelibs-xctest": "main", "swift-corelibs-foundation": "master", "swift-corelibs-libdispatch": "master", "swift-integration-tests": "master",