diff --git a/include/swift/AST/ASTBridging.h b/include/swift/AST/ASTBridging.h index 54220772a2462..feef92608003d 100644 --- a/include/swift/AST/ASTBridging.h +++ b/include/swift/AST/ASTBridging.h @@ -215,10 +215,23 @@ BridgedDeclNameLoc BridgedDeclNameLoc_createParsed( BridgedSourceLoc cLParenLoc, BridgedArrayRef cLabelLocs, BridgedSourceLoc cRParenLoc); +SWIFT_NAME("BridgedDeclNameLoc.createParsed(_:moduleSelectorLoc:baseNameLoc:" + "lParenLoc:argumentLabelLocs:rParenLoc:)") +BridgedDeclNameLoc BridgedDeclNameLoc_createParsed( + BridgedASTContext cContext, BridgedSourceLoc cModuleSelectorLoc, + BridgedSourceLoc cBaseNameLoc, BridgedSourceLoc cLParenLoc, + BridgedArrayRef cLabelLocs, BridgedSourceLoc cRParenLoc); + SWIFT_NAME("BridgedDeclNameLoc.createParsed(_:)") BridgedDeclNameLoc BridgedDeclNameLoc_createParsed(BridgedSourceLoc cBaseNameLoc); +SWIFT_NAME("BridgedDeclNameLoc.createParsed(_:moduleSelectorLoc:baseNameLoc:)") +BridgedDeclNameLoc +BridgedDeclNameLoc_createParsed( + BridgedASTContext cContext, BridgedSourceLoc cModuleSelectorLoc, + BridgedSourceLoc cBaseNameLoc); + //===----------------------------------------------------------------------===// // MARK: ASTContext //===----------------------------------------------------------------------===// diff --git a/include/swift/AST/DeclNameLoc.h b/include/swift/AST/DeclNameLoc.h index a4a65ef50be99..494a4ae721faf 100644 --- a/include/swift/AST/DeclNameLoc.h +++ b/include/swift/AST/DeclNameLoc.h @@ -20,6 +20,8 @@ #include "swift/Basic/LLVM.h" #include "swift/Basic/SourceLoc.h" +#include "llvm/ADT/ArrayRef.h" + class BridgedDeclNameLoc; namespace swift { @@ -71,6 +73,10 @@ class DeclNameLoc { explicit DeclNameLoc(SourceLoc baseNameLoc) : DeclNameLoc(baseNameLoc.getOpaquePointerValue(), 0) {} + explicit DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc, + SourceLoc baseNameLoc) + : DeclNameLoc(baseNameLoc) { } + /// Create declaration name location information for a compound /// name. DeclNameLoc(ASTContext &ctx, SourceLoc baseNameLoc, @@ -78,6 +84,13 @@ class DeclNameLoc { ArrayRef argumentLabelLocs, SourceLoc rParenLoc); + DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc, + SourceLoc baseNameLoc, + SourceLoc lParenLoc, + ArrayRef argumentLabelLocs, + SourceLoc rParenLoc) + : DeclNameLoc(ctx, baseNameLoc, lParenLoc, argumentLabelLocs, rParenLoc) { } + /// Whether the location information is valid. bool isValid() const { return getBaseNameLoc().isValid(); } @@ -111,6 +124,10 @@ class DeclNameLoc { return getSourceLocs()[FirstArgumentLabelIndex + index]; } + SourceLoc getModuleSelectorLoc() const { + return SourceLoc(); + } + SourceLoc getStartLoc() const { return getBaseNameLoc(); } diff --git a/include/swift/AST/Identifier.h b/include/swift/AST/Identifier.h index 036685873da73..7268aff1d1fbb 100644 --- a/include/swift/AST/Identifier.h +++ b/include/swift/AST/Identifier.h @@ -693,65 +693,73 @@ class DeclNameRef { void *getOpaqueValue() const { return FullName.getOpaqueValue(); } static DeclNameRef getFromOpaqueValue(void *p); + explicit DeclNameRef(ASTContext &C, Identifier moduleSelector, + DeclName fullName) + : FullName(fullName) { } + + explicit DeclNameRef(ASTContext &C, Identifier moduleSelector, + DeclBaseName baseName, ArrayRef argLabels) + : FullName(C, baseName, argLabels) { } + explicit DeclNameRef(DeclName FullName) : FullName(FullName) { } - explicit DeclNameRef(DeclBaseName BaseName) - : FullName(BaseName) { } + bool hasModuleSelector() const { + return false; + } - explicit DeclNameRef(Identifier BaseName) - : FullName(BaseName) { } + Identifier getModuleSelector() const { + return Identifier(); + } /// The name of the declaration being referenced. DeclName getFullName() const { return FullName; } - DeclName &getFullName() { - return FullName; - } - /// The base name of the declaration being referenced. DeclBaseName getBaseName() const { - return FullName.getBaseName(); + return getFullName().getBaseName(); } Identifier getBaseIdentifier() const { - return FullName.getBaseIdentifier(); + return getFullName().getBaseIdentifier(); } ArrayRef getArgumentNames() const { - return FullName.getArgumentNames(); + return getFullName().getArgumentNames(); } bool isSimpleName() const { - return FullName.isSimpleName(); + return getFullName().isSimpleName(); } bool isSimpleName(DeclBaseName name) const { - return FullName.isSimpleName(name); + return getFullName().isSimpleName(name); } bool isSimpleName(StringRef name) const { - return FullName.isSimpleName(name); + return getFullName().isSimpleName(name); } bool isSpecial() const { - return FullName.isSpecial(); + return getFullName().isSpecial(); } bool isOperator() const { - return FullName.isOperator(); + return getFullName().isOperator(); } - bool mustAlwaysBeEscaped() const { return FullName.mustAlwaysBeEscaped(); } + bool mustAlwaysBeEscaped() const { + return getFullName().mustAlwaysBeEscaped(); + } bool isCompoundName() const { - return FullName.isCompoundName(); + return getFullName().isCompoundName(); } explicit operator bool() const { - return (bool)FullName; + return (bool)getFullName(); } /// Compare two declaration names, producing -1 if \c *this comes before @@ -791,7 +799,7 @@ class DeclNameRef { return lhs.compare(rhs) >= 0; } - DeclNameRef withoutArgumentLabels() const; + DeclNameRef withoutArgumentLabels(ASTContext &C) const; DeclNameRef withArgumentLabels(ASTContext &C, ArrayRef argumentNames) const; @@ -824,16 +832,15 @@ inline DeclNameRef DeclNameRef::getFromOpaqueValue(void *p) { return DeclNameRef(DeclName::getFromOpaqueValue(p)); } -inline DeclNameRef DeclNameRef::withoutArgumentLabels() const { - return DeclNameRef(getBaseName()); +inline DeclNameRef DeclNameRef::withoutArgumentLabels(ASTContext &C) const { + return DeclNameRef(C, getModuleSelector(), getBaseName()); } inline DeclNameRef DeclNameRef::withArgumentLabels( ASTContext &C, ArrayRef argumentNames) const { - return DeclNameRef(DeclName(C, getBaseName(), argumentNames)); + return DeclNameRef(C, getModuleSelector(), getBaseName(), argumentNames); } - inline DeclNameRef DeclNameRef::createSubscript() { return DeclNameRef(DeclBaseName::createSubscript()); } diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index 1b46be47bb81a..2c82cf382c628 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -508,6 +508,9 @@ EXPERIMENTAL_FEATURE(CDecl, false) /// Allow use of `@extensible` on public enums SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ExtensibleAttribute, false) +/// Allow use of `Module::name` syntax +EXPERIMENTAL_FEATURE(ModuleSelector, false) + #undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE #undef EXPERIMENTAL_FEATURE #undef UPCOMING_FEATURE diff --git a/lib/AST/Bridging/DeclBridging.cpp b/lib/AST/Bridging/DeclBridging.cpp index bbf6b89917a0e..f9d5691c0d4c3 100644 --- a/lib/AST/Bridging/DeclBridging.cpp +++ b/lib/AST/Bridging/DeclBridging.cpp @@ -70,13 +70,23 @@ BridgedDeclNameLoc BridgedDeclNameLoc_createParsed( BridgedASTContext cContext, BridgedSourceLoc cBaseNameLoc, BridgedSourceLoc cLParenLoc, BridgedArrayRef cLabelLocs, BridgedSourceLoc cRParenLoc) { + return BridgedDeclNameLoc_createParsed( + cContext, BridgedSourceLoc(), cBaseNameLoc, cLParenLoc, cLabelLocs, + cRParenLoc); +} + +BridgedDeclNameLoc BridgedDeclNameLoc_createParsed( + BridgedASTContext cContext, BridgedSourceLoc cModuleSelectorLoc, + BridgedSourceLoc cBaseNameLoc, BridgedSourceLoc cLParenLoc, + BridgedArrayRef cLabelLocs, BridgedSourceLoc cRParenLoc) { ASTContext &context = cContext.unbridged(); SmallVector labelLocs; for (auto &cLabelLoc : cLabelLocs.unbridged()) labelLocs.push_back(cLabelLoc.unbridged()); - return DeclNameLoc(context, cBaseNameLoc.unbridged(), cLParenLoc.unbridged(), + return DeclNameLoc(context, cModuleSelectorLoc.unbridged(), + cBaseNameLoc.unbridged(), cLParenLoc.unbridged(), labelLocs, cRParenLoc.unbridged()); } @@ -85,6 +95,14 @@ BridgedDeclNameLoc_createParsed(BridgedSourceLoc cBaseNameLoc) { return DeclNameLoc(cBaseNameLoc.unbridged()); } +BridgedDeclNameLoc +BridgedDeclNameLoc_createParsed( + BridgedASTContext cContext, BridgedSourceLoc cModuleSelectorLoc, + BridgedSourceLoc cBaseNameLoc) { + return DeclNameLoc(cContext.unbridged(), cModuleSelectorLoc.unbridged(), + cBaseNameLoc.unbridged()); +} + //===----------------------------------------------------------------------===// // MARK: Decls //===----------------------------------------------------------------------===// diff --git a/lib/AST/FeatureSet.cpp b/lib/AST/FeatureSet.cpp index ec5f8e7d7f947..cd36c913d8db1 100644 --- a/lib/AST/FeatureSet.cpp +++ b/lib/AST/FeatureSet.cpp @@ -126,6 +126,9 @@ UNINTERESTING_FEATURE(MacrosOnImports) UNINTERESTING_FEATURE(NonisolatedNonsendingByDefault) UNINTERESTING_FEATURE(KeyPathWithMethodMembers) +// TODO: Return true for inlinable function bodies with module selectors in them +UNINTERESTING_FEATURE(ModuleSelector) + static bool usesFeatureNonescapableTypes(Decl *decl) { auto containsNonEscapable = [](SmallVectorImpl &inverseReqs) { diff --git a/lib/AST/Identifier.cpp b/lib/AST/Identifier.cpp index 90bf6e612f69c..0e32186ebdbee 100644 --- a/lib/AST/Identifier.cpp +++ b/lib/AST/Identifier.cpp @@ -55,6 +55,8 @@ void swift::simple_display(llvm::raw_ostream &out, DeclName name) { } raw_ostream &llvm::operator<<(raw_ostream &OS, DeclNameRef I) { + if (I.hasModuleSelector()) + OS << I.getModuleSelector() << "::"; OS << I.getFullName(); return OS; } @@ -208,17 +210,27 @@ void DeclNameRef::dump() const { } StringRef DeclNameRef::getString(llvm::SmallVectorImpl &scratch, - bool skipEmptyArgumentNames) const { - return FullName.getString(scratch, skipEmptyArgumentNames); + bool skipEmptyArgumentNames) const { + { + llvm::raw_svector_ostream out(scratch); + print(out, skipEmptyArgumentNames); + } + + return StringRef(scratch.data(), scratch.size()); } -llvm::raw_ostream &DeclNameRef::print(llvm::raw_ostream &os, - bool skipEmptyArgumentNames) const { - return FullName.print(os, skipEmptyArgumentNames); +llvm::raw_ostream & +DeclNameRef::print(llvm::raw_ostream &os, + bool skipEmptyArgumentNames) const { + if (hasModuleSelector()) + os << getModuleSelector() << "::"; + return getFullName().print(os, skipEmptyArgumentNames); } llvm::raw_ostream &DeclNameRef::printPretty(llvm::raw_ostream &os) const { - return FullName.printPretty(os); + if (hasModuleSelector()) + os << getModuleSelector() << "::"; + return getFullName().printPretty(os); } ObjCSelector::ObjCSelector(ASTContext &ctx, unsigned numArgs, diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index acc0f261b3d7c..821a3168b4f5f 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -4449,8 +4449,9 @@ bool MissingMemberFailure::diagnoseAsError() { auto &cs = getConstraintSystem(); auto result = cs.performMemberLookup( - ConstraintKind::ValueMember, getName().withoutArgumentLabels(), - metatypeTy, FunctionRefInfo::doubleBaseNameApply(), getLocator(), + ConstraintKind::ValueMember, + getName().withoutArgumentLabels(getASTContext()), metatypeTy, + FunctionRefInfo::doubleBaseNameApply(), getLocator(), /*includeInaccessibleMembers=*/true); // If there are no `init` members at all produce a tailored diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 7425d88b7ff5f..b3682af95c029 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -8389,9 +8389,10 @@ ValueDecl *RenamedDeclRequest::evaluate(Evaluator &evaluator, if (attr->Rename.empty()) return nullptr; + auto &ctx = attached->getASTContext(); auto attachedContext = attached->getDeclContext(); auto parsedName = parseDeclName(attr->Rename); - auto nameRef = parsedName.formDeclNameRef(attached->getASTContext()); + auto nameRef = parsedName.formDeclNameRef(ctx); // Handle types separately if (isa(attached)) { @@ -8400,7 +8401,7 @@ ValueDecl *RenamedDeclRequest::evaluate(Evaluator &evaluator, SmallVector lookupResults; attachedContext->lookupQualified(attachedContext->getParentModule(), - nameRef.withoutArgumentLabels(), + nameRef.withoutArgumentLabels(ctx), attr->getLocation(), NL_OnlyTypes, lookupResults); if (lookupResults.size() == 1) diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index 7d32bc32ecdf8..87e0a39c13651 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -138,7 +138,7 @@ static EnumElementDecl * lookupUnqualifiedEnumMemberElement(DeclContext *DC, DeclNameRef name, SourceLoc UseLoc) { // FIXME: We should probably pay attention to argument labels someday. - name = name.withoutArgumentLabels(); + name = name.withoutArgumentLabels(DC->getASTContext()); auto lookup = TypeChecker::lookupUnqualified(DC, name, UseLoc, @@ -153,7 +153,7 @@ static LookupResult lookupMembers(DeclContext *DC, Type ty, DeclNameRef name, return LookupResult(); // FIXME: We should probably pay attention to argument labels someday. - name = name.withoutArgumentLabels(); + name = name.withoutArgumentLabels(DC->getASTContext()); // Look up the case inside the enum. // FIXME: We should be able to tell if this is a private lookup. diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 8619559ea1bda..29bfb2f3f23a6 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -1489,7 +1489,7 @@ swift::lookupValueWitnesses(DeclContext *DC, ValueDecl *req, bool *ignoringNames lookupValueWitnessesViaImplementsAttr(DC, req, witnesses); auto reqName = req->createNameRef(); - auto reqBaseName = reqName.withoutArgumentLabels(); + auto reqBaseName = reqName.withoutArgumentLabels(DC->getASTContext()); // An operator function is the only kind of witness that requires global // lookup. However, because global lookup doesn't enter local contexts, diff --git a/lib/Serialization/DeclTypeRecordNodes.def b/lib/Serialization/DeclTypeRecordNodes.def index 3ffd7b345a76f..0ee58b5d3e668 100644 --- a/lib/Serialization/DeclTypeRecordNodes.def +++ b/lib/Serialization/DeclTypeRecordNodes.def @@ -213,12 +213,12 @@ OTHER(DERIVATIVE_FUNCTION_CONFIGURATION, 154) OTHER(ERROR_FLAG, 155) OTHER(ABI_ONLY_COUNTERPART, 156) +OTHER(DECL_NAME_REF, 157) TRAILING_INFO(CONDITIONAL_SUBSTITUTION) TRAILING_INFO(CONDITIONAL_SUBSTITUTION_COND) OTHER(LIFETIME_DEPENDENCE, 160) - TRAILING_INFO(INHERITED_PROTOCOLS) #ifndef DECL_ATTR diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index e00c099d3f225..aa60b8802c223 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -3498,6 +3498,58 @@ class DeclDeserializer { /// offsets in \c customAttrOffsets. llvm::Error deserializeCustomAttrs(); + DeclNameRef deserializeDeclNameRefIfPresent() { + using namespace decls_block; + + SmallVector scratch; + StringRef blobData; + + BCOffsetRAII restoreOffset(MF.DeclTypeCursor); + llvm::BitstreamEntry entry = + MF.fatalIfUnexpected(MF.DeclTypeCursor.advance()); + + unsigned recordID = MF.fatalIfUnexpected( + MF.DeclTypeCursor.readRecord(entry.ID, scratch, &blobData)); + + if (recordID != DECL_NAME_REF) + // This is normal--it just means there isn't a DeclNameRef here. + return { DeclNameRef() }; + + bool isCompoundName; + bool hasModuleSelector; + ArrayRef rawPieceIDs; + + DeclNameRefLayout::readRecord(scratch, isCompoundName, hasModuleSelector, + rawPieceIDs); + restoreOffset.cancel(); + + Identifier moduleSelector; + DeclBaseName baseName; + + unsigned restIndex = 0; + + ASSERT(rawPieceIDs.size() > 0); + if (hasModuleSelector) { + moduleSelector = MF.getIdentifier(rawPieceIDs[restIndex]); + restIndex++; + } + + ASSERT(rawPieceIDs.size() > restIndex); + baseName = MF.getDeclBaseName(rawPieceIDs[restIndex]); + restIndex++; + + if (isCompoundName) { + SmallVector argLabels; + for (auto rawArgLabel : rawPieceIDs.drop_front(restIndex)) + argLabels.push_back(MF.getIdentifier(rawArgLabel)); + + return DeclNameRef(ctx, moduleSelector, baseName, argLabels); + } + + ASSERT(rawPieceIDs.size() == restIndex); + return DeclNameRef(ctx, moduleSelector, baseName); + } + Expected getDeclCheckedImpl( llvm::function_ref matchAttributes = nullptr); @@ -6141,56 +6193,32 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { unsigned specializationKindVal; GenericSignatureID specializedSigID; - ArrayRef rawPieceIDs; - uint64_t numArgs; + ArrayRef rawTrailingIDs; uint64_t numSPIGroups; uint64_t numAvailabilityAttrs; - uint64_t numTypeErasedParams; DeclID targetFunID; serialization::decls_block::SpecializeDeclAttrLayout::readRecord( scratch, exported, specializationKindVal, specializedSigID, - targetFunID, numArgs, numSPIGroups, numAvailabilityAttrs, - numTypeErasedParams, rawPieceIDs); + targetFunID, numSPIGroups, numAvailabilityAttrs, rawTrailingIDs); - assert(rawPieceIDs.size() == numArgs + numSPIGroups + numTypeErasedParams || - rawPieceIDs.size() == (numArgs - 1 + numSPIGroups + numTypeErasedParams)); specializationKind = specializationKindVal ? SpecializeAttr::SpecializationKind::Partial : SpecializeAttr::SpecializationKind::Full; - // The 'target' parameter. - DeclNameRef replacedFunctionName; - if (numArgs) { - bool numArgumentLabels = (numArgs == 1) ? 0 : numArgs - 2; - auto baseName = MF.getDeclBaseName(rawPieceIDs[0]); - SmallVector pieces; - if (numArgumentLabels) { - for (auto pieceID : rawPieceIDs.slice(1, numArgumentLabels)) - pieces.push_back(MF.getIdentifier(pieceID)); - } - replacedFunctionName = (numArgs == 1) - ? DeclNameRef({baseName}) // simple name - : DeclNameRef({ctx, baseName, pieces}); - } + auto specializedSig = MF.getGenericSignature(specializedSigID); + + // Take `numSPIGroups` trailing identifiers for the SPI groups. SmallVector spis; - if (numSPIGroups) { - auto numTargetFunctionPiecesToSkip = - (rawPieceIDs.size() == numArgs + numSPIGroups + numTypeErasedParams) ? numArgs - : numArgs - 1; - for (auto id : rawPieceIDs.slice(numTargetFunctionPiecesToSkip)) + for (auto id : rawTrailingIDs.take_front(numSPIGroups)) spis.push_back(MF.getIdentifier(id)); - } + // Take the rest for type-erased parameters. SmallVector typeErasedParams; - if (numTypeErasedParams) { - auto numTargetFunctionPiecesToSkip = - (rawPieceIDs.size() == numArgs + numSPIGroups + numTypeErasedParams) ? numArgs + numSPIGroups - : numArgs - 1 + numSPIGroups; - for (auto id : rawPieceIDs.slice(numTargetFunctionPiecesToSkip)) - typeErasedParams.push_back(MF.getType(id)); - } + for (auto id : rawTrailingIDs.drop_front(numSPIGroups)) + typeErasedParams.push_back(MF.getType(id)); + // Read availability attrs. SmallVector availabilityAttrs; while (numAvailabilityAttrs) { // Prepare to read the next record. @@ -6220,10 +6248,12 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { --numAvailabilityAttrs; } - auto specializedSig = MF.getGenericSignature(specializedSigID); + // Read target function DeclNameRef, if present. + DeclNameRef targetFunName = deserializeDeclNameRefIfPresent(); + Attr = SpecializeAttr::create(ctx, exported != 0, specializationKind, spis, availabilityAttrs, typeErasedParams, - specializedSig, replacedFunctionName, &MF, + specializedSig, targetFunName, &MF, targetFunID); break; } @@ -6254,21 +6284,15 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { case decls_block::DynamicReplacement_DECL_ATTR: { bool isImplicit; - uint64_t numArgs; - ArrayRef rawPieceIDs; DeclID replacedFunID; serialization::decls_block::DynamicReplacementDeclAttrLayout:: - readRecord(scratch, isImplicit, replacedFunID, numArgs, rawPieceIDs); + readRecord(scratch, isImplicit, replacedFunID); - auto baseName = MF.getDeclBaseName(rawPieceIDs[0]); - SmallVector pieces; - for (auto pieceID : rawPieceIDs.slice(1)) - pieces.push_back(MF.getIdentifier(pieceID)); + DeclNameRef replacedFunName = deserializeDeclNameRefIfPresent(); - assert(numArgs != 0); assert(!isImplicit && "Need to update for implicit"); - Attr = DynamicReplacementAttr::create( - ctx, DeclNameRef({ ctx, baseName, pieces }), &MF, replacedFunID); + Attr = DynamicReplacementAttr::create(ctx, replacedFunName, &MF, + replacedFunID); break; } @@ -6339,7 +6363,6 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { case decls_block::Derivative_DECL_ATTR: { bool isImplicit; - uint64_t origNameId; bool hasAccessorKind; uint64_t rawAccessorKind; DeclID origDeclId; @@ -6347,7 +6370,7 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { ArrayRef parameters; serialization::decls_block::DerivativeDeclAttrLayout::readRecord( - scratch, isImplicit, origNameId, hasAccessorKind, rawAccessorKind, + scratch, isImplicit, hasAccessorKind, rawAccessorKind, origDeclId, rawDerivativeKind, parameters); std::optional accessorKind = std::nullopt; @@ -6358,8 +6381,6 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { accessorKind = *maybeAccessorKind; } - DeclNameRefWithLoc origName{DeclNameRef(MF.getDeclBaseName(origNameId)), - DeclNameLoc(), accessorKind}; auto derivativeKind = getActualAutoDiffDerivativeFunctionKind(rawDerivativeKind); if (!derivativeKind) @@ -6369,9 +6390,14 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { parametersBitVector[i] = parameters[i]; auto *indices = IndexSubset::get(ctx, parametersBitVector); + auto origName = deserializeDeclNameRefIfPresent(); + DeclNameRefWithLoc origNameWithLoc{origName, DeclNameLoc(), + accessorKind}; + auto *derivativeAttr = DerivativeAttr::create(ctx, isImplicit, SourceLoc(), SourceRange(), - /*baseType*/ nullptr, origName, indices); + /*baseType*/ nullptr, origNameWithLoc, + indices); derivativeAttr->setOriginalFunctionResolver(&MF, origDeclId); derivativeAttr->setDerivativeKind(*derivativeKind); Attr = derivativeAttr; @@ -6380,20 +6406,21 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() { case decls_block::Transpose_DECL_ATTR: { bool isImplicit; - uint64_t origNameId; DeclID origDeclId; ArrayRef parameters; serialization::decls_block::TransposeDeclAttrLayout::readRecord( - scratch, isImplicit, origNameId, origDeclId, parameters); + scratch, isImplicit, origDeclId, parameters); - DeclNameRefWithLoc origName{DeclNameRef(MF.getDeclBaseName(origNameId)), - DeclNameLoc(), std::nullopt}; auto *origDecl = cast(MF.getDecl(origDeclId)); llvm::SmallBitVector parametersBitVector(parameters.size()); for (unsigned i : indices(parameters)) parametersBitVector[i] = parameters[i]; auto *indices = IndexSubset::get(ctx, parametersBitVector); + + auto origNameRef = deserializeDeclNameRefIfPresent(); + DeclNameRefWithLoc origName{origNameRef, DeclNameLoc(), std::nullopt}; + auto *transposeAttr = TransposeAttr::create(ctx, isImplicit, SourceLoc(), SourceRange(), /*baseTypeRepr*/ nullptr, origName, indices); diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 8ee427566de8e..d6043236fb4bc 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 949; // vector_base_addr instruction +const uint16_t SWIFTMODULE_VERSION_MINOR = 950; // DeclNameRef module selectors /// A standard hash seed used for all string hashes in a serialized module. /// @@ -1258,6 +1258,15 @@ namespace decls_block { DeclIDField // API decl >; + /// A field containing the pieces of a \c DeclNameRef and the information + /// needed to reconstruct it. + using DeclNameRefLayout = BCRecordLayout< + DECL_NAME_REF, + BCFixed<1>, // isCompoundName + BCFixed<1>, // hasModuleSelector + BCArray // module selector, base name, arg labels + >; + /// A placeholder for invalid types TYPE_LAYOUT(ErrorTypeLayout, ERROR_TYPE, @@ -2444,11 +2453,9 @@ namespace decls_block { BCFixed<1>, // specialization kind GenericSignatureIDField, // specialized signature DeclIDField, // target function - BCVBR<4>, // # of arguments (+1) or 1 if simple decl name, 0 if no target BCVBR<4>, // # of SPI groups BCVBR<4>, // # of availability attributes - BCVBR<4>, // # of type erased parameters - BCArray // target function pieces, spi groups, type erased params + BCArray // spi groups, type erased params >; using StorageRestrictionsDeclAttrLayout = BCRecordLayout< @@ -2468,7 +2475,6 @@ namespace decls_block { using DerivativeDeclAttrLayout = BCRecordLayout< Derivative_DECL_ATTR, BCFixed<1>, // Implicit flag. - IdentifierIDField, // Original name. BCFixed<1>, // Has original accessor kind? AccessorKindField, // Original accessor kind. DeclIDField, // Original function declaration. @@ -2479,7 +2485,6 @@ namespace decls_block { using TransposeDeclAttrLayout = BCRecordLayout< Transpose_DECL_ATTR, BCFixed<1>, // Implicit flag. - IdentifierIDField, // Original name. DeclIDField, // Original function declaration. BCArray> // Transposed parameter indices' bitvector. >; @@ -2494,9 +2499,7 @@ namespace decls_block { using DynamicReplacementDeclAttrLayout = BCRecordLayout< DynamicReplacement_DECL_ATTR, BCFixed<1>, // implicit flag - DeclIDField, // replaced function - BCVBR<4>, // # of arguments (+1) or zero if no name - BCArray + DeclIDField // replaced function >; using TypeEraserDeclAttrLayout = BCRecordLayout< diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index adc4742aeb497..23e2af0c9b868 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -3204,49 +3204,34 @@ class Serializer::DeclSerializer : public DeclVisitor { case DeclAttrKind::Specialize: { auto abbrCode = S.DeclTypeAbbrCodes[SpecializeDeclAttrLayout::Code]; auto attr = cast(DA); - auto targetFun = attr->getTargetFunctionName(); auto *afd = cast(D); auto *targetFunDecl = attr->getTargetFunctionDecl(afd); SmallVector pieces; - // encodes whether this a a simple or compound name by adding one. - size_t numArgs = 0; - if (targetFun) { - pieces.push_back(S.addDeclBaseNameRef(targetFun.getBaseName())); - for (auto argName : targetFun.getArgumentNames()) - pieces.push_back(S.addDeclBaseNameRef(argName)); - if (targetFun.isSimpleName()) { - assert(pieces.size() == 1); - numArgs = 1; - } else - numArgs = pieces.size() + 1; - } - + // SPI groups + auto numSPIGroups = attr->getSPIGroups().size(); for (auto spi : attr->getSPIGroups()) { assert(!spi.empty() && "Empty SPI name"); pieces.push_back(S.addDeclBaseNameRef(spi)); } + // Type-erased params for (auto ty : attr->getTypeErasedParams()) { pieces.push_back(S.addTypeRef(ty)); } - auto numSPIGroups = attr->getSPIGroups().size(); - auto numTypeErasedParams = attr->getTypeErasedParams().size(); - assert(pieces.size() == numArgs + numSPIGroups + numTypeErasedParams || - pieces.size() == (numArgs - 1 + numSPIGroups + numTypeErasedParams)); auto numAvailabilityAttrs = attr->getAvailableAttrs().size(); SpecializeDeclAttrLayout::emitRecord( S.Out, S.ScratchRecord, abbrCode, (unsigned)attr->isExported(), (unsigned)attr->getSpecializationKind(), S.addGenericSignatureRef(attr->getSpecializedSignature(afd)), - S.addDeclRef(targetFunDecl), numArgs, numSPIGroups, - numAvailabilityAttrs, numTypeErasedParams, + S.addDeclRef(targetFunDecl), numSPIGroups, numAvailabilityAttrs, pieces); for (auto availAttr : attr->getAvailableAttrs()) { writeDeclAttribute(D, availAttr); } + writeDeclNameRefIfNeeded(attr->getTargetFunctionName()); return; } @@ -3278,16 +3263,13 @@ class Serializer::DeclSerializer : public DeclVisitor { auto abbrCode = S.DeclTypeAbbrCodes[DynamicReplacementDeclAttrLayout::Code]; auto theAttr = cast(DA); - auto replacedFun = theAttr->getReplacedFunctionName(); - SmallVector pieces; - pieces.push_back(S.addDeclBaseNameRef(replacedFun.getBaseName())); - for (auto argName : replacedFun.getArgumentNames()) - pieces.push_back(S.addDeclBaseNameRef(argName)); + auto *afd = cast(D)->getDynamicallyReplacedDecl(); assert(afd && "Missing replaced decl!"); DynamicReplacementDeclAttrLayout::emitRecord( S.Out, S.ScratchRecord, abbrCode, false, /*implicit flag*/ - S.addDeclRef(afd), pieces.size(), pieces); + S.addDeclRef(afd)); + writeDeclNameRefIfNeeded(theAttr->getReplacedFunctionName()); return; } @@ -3360,8 +3342,7 @@ class Serializer::DeclSerializer : public DeclVisitor { "`@derivative` attribute should have original declaration set " "during construction or parsing"); auto origDeclNameRef = attr->getOriginalFunctionName(); - auto origName = origDeclNameRef.Name.getBaseName(); - IdentifierID origNameId = S.addDeclBaseNameRef(origName); + DeclID origDeclID = S.addDeclRef(attr->getOriginalFunction(ctx)); auto derivativeKind = getRawStableAutoDiffDerivativeFunctionKind(attr->getDerivativeKind()); @@ -3375,9 +3356,10 @@ class Serializer::DeclSerializer : public DeclVisitor { for (unsigned i : range(parameterIndices->getCapacity())) paramIndicesVector.push_back(parameterIndices->contains(i)); DerivativeDeclAttrLayout::emitRecord( - S.Out, S.ScratchRecord, abbrCode, attr->isImplicit(), origNameId, + S.Out, S.ScratchRecord, abbrCode, attr->isImplicit(), origAccessorKind.has_value(), rawAccessorKind, origDeclID, derivativeKind, paramIndicesVector); + writeDeclNameRefIfNeeded(origDeclNameRef.Name); return; } @@ -3387,8 +3369,7 @@ class Serializer::DeclSerializer : public DeclVisitor { assert(attr->getOriginalFunction() && "`@transpose` attribute should have original declaration set " "during construction or parsing"); - auto origName = attr->getOriginalFunctionName().Name.getBaseName(); - IdentifierID origNameId = S.addDeclBaseNameRef(origName); + DeclID origDeclID = S.addDeclRef(attr->getOriginalFunction()); auto *parameterIndices = attr->getParameterIndices(); assert(parameterIndices && "Parameter indices must be resolved"); @@ -3396,8 +3377,9 @@ class Serializer::DeclSerializer : public DeclVisitor { for (unsigned i : range(parameterIndices->getCapacity())) paramIndicesVector.push_back(parameterIndices->contains(i)); TransposeDeclAttrLayout::emitRecord( - S.Out, S.ScratchRecord, abbrCode, attr->isImplicit(), origNameId, - origDeclID, paramIndicesVector); + S.Out, S.ScratchRecord, abbrCode, attr->isImplicit(), origDeclID, + paramIndicesVector); + writeDeclNameRefIfNeeded(attr->getOriginalFunctionName().Name); return; } @@ -3621,6 +3603,32 @@ class Serializer::DeclSerializer : public DeclVisitor { } } + void writeDeclNameRefIfNeeded(DeclNameRef name) { + using namespace decls_block; + + // DeclNameRefs are always optional and write nothing when absent. + if (!name) + return; + + bool isCompoundName = name.isCompoundName(); + bool hasModuleSelector = name.hasModuleSelector(); + SmallVector rawPieceIDs; + + if (hasModuleSelector) + rawPieceIDs.push_back(S.addDeclBaseNameRef(name.getModuleSelector())); + + rawPieceIDs.push_back(S.addDeclBaseNameRef(name.getBaseName())); + + if (isCompoundName) + for (auto argName : name.getArgumentNames()) + rawPieceIDs.push_back(S.addDeclBaseNameRef(argName)); + + auto abbrCode = S.DeclTypeAbbrCodes[DeclNameRefLayout::Code]; + DeclNameRefLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, + isCompoundName, hasModuleSelector, + rawPieceIDs); + } + size_t addConformances(const IterableDeclContext *declContext, ConformanceLookupKind lookupKind, SmallVectorImpl &data) { @@ -6337,6 +6345,7 @@ void Serializer::writeAllDeclsAndTypes() { registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); + registerDeclTypeAbbr(); registerDeclTypeAbbr(); diff --git a/test/AutoDiff/Serialization/derivative_attr.swift b/test/AutoDiff/Serialization/derivative_attr.swift index c41c0a36d1a50..2063f0283423e 100644 --- a/test/AutoDiff/Serialization/derivative_attr.swift +++ b/test/AutoDiff/Serialization/derivative_attr.swift @@ -141,7 +141,7 @@ extension S { self } - // CHECK: @derivative(of: subscript, wrt: self) + // CHECK: @derivative(of: subscript(_:), wrt: self) @derivative(of: subscript(_:), wrt: self) func derivativeSubscript(x: T) -> (value: S, differential: (S) -> S) { (self, { $0 }) diff --git a/test/AutoDiff/Serialization/transpose_attr.swift b/test/AutoDiff/Serialization/transpose_attr.swift index 9f864862cda95..d969da11c3b8c 100644 --- a/test/AutoDiff/Serialization/transpose_attr.swift +++ b/test/AutoDiff/Serialization/transpose_attr.swift @@ -89,7 +89,7 @@ extension S { extension S { subscript(x: T) -> Self { self } - // CHECK: @transpose(of: subscript, wrt: self) + // CHECK: @transpose(of: subscript(_:), wrt: self) @transpose(of: subscript(_:), wrt: self) static func transposeSubscript(x: T, t: Self) -> Self { t diff --git a/test/NameLookup/module_selector.swift b/test/NameLookup/module_selector.swift new file mode 100644 index 0000000000000..0efc97316ec2c --- /dev/null +++ b/test/NameLookup/module_selector.swift @@ -0,0 +1,3 @@ +// RUN: %target-typecheck-verify-swift -enable-experimental-feature ModuleSelector + +// REQUIRES: swift_feature_ModuleSelector