Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,10 @@ class ASTContext final {
OutputBackend = std::move(OutBackend);
}

private:
friend class BuiltinGenericType;
GenericSignature &getCachedBuiltinGenericTypeSignature(TypeKind kind);

private:
friend Decl;

Expand Down
25 changes: 20 additions & 5 deletions include/swift/AST/TypeDifferenceVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,28 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
CanBuiltinUnboundGenericType type2) {
return asImpl().visitDifferentTypeStructure(type1, type2);
}
bool visitBuiltinFixedArrayType(CanBuiltinFixedArrayType type1,
CanBuiltinFixedArrayType type2) {
if (asImpl().visit(type1->getSize(), type2->getSize())) {

bool visitBuiltinGenericType(CanBuiltinGenericType type1,
CanBuiltinGenericType type2) {
if (type1->getBuiltinTypeKind() != type2->getBuiltinTypeKind()) {
return true;
}
return asImpl().visit(type1->getElementType(), type2->getElementType());

auto subs1 = type1->getSubstitutions();
auto subs2 = type2->getSubstitutions();

for (unsigned i : indices(subs1.getReplacementTypes())) {
if (asImpl().visit(CanType(subs1.getReplacementTypes()[i]),
CanType(subs2.getReplacementTypes()[i]))) {
return true;
}
}
for (unsigned i : indices(subs1.getConformances())) {
if (subs1.getConformances()[i] != subs2.getConformances()[i]) {
return true;
}
}
return false;
}

bool visitPackType(CanPackType type1, CanPackType type2) {
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/TypeMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class TypeMatcher {
TRIVIAL_CASE(BuiltinFloatType)
TRIVIAL_CASE(BuiltinVectorType)
TRIVIAL_CASE(BuiltinUnboundGenericType)
TRIVIAL_CASE(BuiltinFixedArrayType)
TRIVIAL_CASE(BuiltinGenericType)
TRIVIAL_CASE(IntegerType)
#define SINGLETON_TYPE(SHORT_ID, ID) TRIVIAL_CASE(ID##Type)
#include "swift/AST/TypeNodes.def"
Expand Down
4 changes: 3 additions & 1 deletion include/swift/AST/TypeNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ ABSTRACT_TYPE(Builtin, Type)
BUILTIN_CONCRETE_TYPE(BuiltinDefaultActorStorage, BuiltinType)
BUILTIN_CONCRETE_TYPE(BuiltinNonDefaultDistributedActorStorage, BuiltinType)
BUILTIN_CONCRETE_TYPE(BuiltinVector, BuiltinType)
BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinType)
ABSTRACT_TYPE(BuiltinGeneric, BuiltinType)
BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinGenericType)
TYPE_RANGE(BuiltinGeneric, BuiltinFixedArray, BuiltinFixedArray)
BUILTIN_CONCRETE_TYPE(BuiltinUnboundGeneric, BuiltinType)
BUILTIN_CONCRETE_TYPE(BuiltinImplicitActor, BuiltinType)
TYPE_RANGE(Builtin, BuiltinInteger, BuiltinImplicitActor)
Expand Down
41 changes: 20 additions & 21 deletions include/swift/AST/TypeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/SILLayout.h"
#include "swift/AST/LifetimeDependence.h"
#include "swift/AST/SubstitutionMap.h"
#include "llvm/ADT/SmallVector.h"

namespace swift {

Expand Down Expand Up @@ -117,29 +119,26 @@ case TypeKind::Id:
case TypeKind::Integer:
return t;

// BuiltinGenericType subclasses
case TypeKind::BuiltinFixedArray: {
auto bfaTy = cast<BuiltinFixedArrayType>(base);

Type transSize = doIt(bfaTy->getSize(),
TypePosition::Invariant);
if (!transSize) {
return Type();
}

Type transElement = doIt(bfaTy->getElementType(),
TypePosition::Invariant);
if (!transElement) {
return Type();
}

CanType canTransSize = transSize->getCanonicalType();
CanType canTransElement = transElement->getCanonicalType();
if (canTransSize != bfaTy->getSize()
|| canTransElement != bfaTy->getElementType()) {
return BuiltinFixedArrayType::get(canTransSize, canTransElement);
auto bgaTy = cast<BuiltinGenericType>(base);

llvm::SmallVector<Type, 2> transReplacements;

for (auto t : bgaTy->getSubstitutions().getReplacementTypes()) {
Type transTy = doIt(t, TypePosition::Invariant);
if (!transTy) {
return Type();
}
transReplacements.push_back(transTy);
}

return bfaTy;

// TODO: translate conformances. No builtin types yet have conformance
// requirements in their generic signatures.
auto transSubs = SubstitutionMap::get(bgaTy->getGenericSignature(),
transReplacements,
ArrayRef<ProtocolConformanceRef>{});
return bgaTy->getWithSubstitutions(transSubs);
}

case TypeKind::PrimaryArchetype:
Expand Down
48 changes: 43 additions & 5 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1780,25 +1780,63 @@ class BuiltinUnboundGenericType : public BuiltinType {
};
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinUnboundGenericType, BuiltinType)

/// BuiltinGenericType - Base class for builtins that are parameterized by
/// a generic signature.
class BuiltinGenericType : public BuiltinType {
protected:

BuiltinGenericType(TypeKind kind, ASTContext &context,
RecursiveTypeProperties properties)
: BuiltinType(kind, context, properties)
{}

/// The substitution map is cached here once requested.
mutable std::optional<SubstitutionMap> CachedSubstitutionMap = std::nullopt;

public:
static bool classof(const TypeBase *T) {
return T->getKind() >= TypeKind::First_BuiltinGenericType
&& T->getKind() <= TypeKind::Last_BuiltinGenericType;
}

// Get the generic signature describing the parameterization of types of
// this class.
GenericSignature getGenericSignature() const;

// Get the substitution map for this particular type.
SubstitutionMap getSubstitutions() const;

// Produce another type of the same class but with different arguments.
CanTypeWrapper<BuiltinGenericType>
getWithSubstitutions(SubstitutionMap newSubs) const;
};
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinGenericType, BuiltinType)

/// BuiltinFixedArrayType - The builtin type representing N values stored
/// inline contiguously.
///
/// All elements of a value of this type must be fully initialized any time the
/// value may be copied, moved, or destroyed.
class BuiltinFixedArrayType : public BuiltinType, public llvm::FoldingSetNode {
class BuiltinFixedArrayType : public BuiltinGenericType,
public llvm::FoldingSetNode {
friend class ASTContext;

CanType Size;
CanType ElementType;

BuiltinFixedArrayType(CanType Size, CanType ElementType,
RecursiveTypeProperties properties)
: BuiltinType(TypeKind::BuiltinFixedArray, ElementType->getASTContext(),
properties),
: BuiltinGenericType(TypeKind::BuiltinFixedArray,
ElementType->getASTContext(),
properties),
Size(Size),
ElementType(ElementType)
{}

friend BuiltinGenericType;
/// Get the generic arguments as a substitution map.
SubstitutionMap buildSubstitutions() const;

public:
/// Arrays with more elements than this are always treated as in-memory values.
///
Expand Down Expand Up @@ -1826,7 +1864,7 @@ class BuiltinFixedArrayType : public BuiltinType, public llvm::FoldingSetNode {

/// Get the element type.
CanType getElementType() const { return ElementType; }

void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, getSize(), getElementType());
}
Expand All @@ -1836,7 +1874,7 @@ class BuiltinFixedArrayType : public BuiltinType, public llvm::FoldingSetNode {
ID.AddPointer(ElementType.getPointer());
}
};
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinFixedArrayType, BuiltinType)
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinFixedArrayType, BuiltinGenericType)

/// BuiltinRawPointerType - The builtin raw (and dangling) pointer type. This
/// pointer is completely unmanaged and is equivalent to i8* in LLVM IR.
Expand Down
17 changes: 17 additions & 0 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,13 @@ struct ASTContext::Implementation {
/// Local and closure discriminators per context.
llvm::DenseMap<const DeclContext *, unsigned> NextDiscriminator;

/// Cached generic signatures for generic builtin types.
static const unsigned NumBuiltinGenericTypes
= unsigned(TypeKind::Last_BuiltinGenericType)
- unsigned(TypeKind::First_BuiltinGenericType) + 1;
std::array<GenericSignature, NumBuiltinGenericTypes>
BuiltinGenericTypeSignatures = {};

/// Structure that captures data that is segregated into different
/// arenas.
struct Arena {
Expand Down Expand Up @@ -7309,3 +7316,13 @@ AvailabilityDomain ASTContext::getTargetAvailabilityDomain() const {
// Fall back to the universal domain for triples without a platform.
return AvailabilityDomain::forUniversal();
}

GenericSignature &
ASTContext::getCachedBuiltinGenericTypeSignature(TypeKind kind) {
ASSERT(kind >= TypeKind::First_BuiltinGenericType
&& kind <= TypeKind::Last_BuiltinGenericType
&& "not a builtin generic type kind");

return getImpl().BuiltinGenericTypeSignatures
[unsigned(kind) - unsigned(TypeKind::First_BuiltinGenericType)];
}
Loading