diff --git a/include/swift/Remote/Failure.h b/include/swift/Remote/Failure.h index d2a4b50ccce..8f00726ce24 100644 --- a/include/swift/Remote/Failure.h +++ b/include/swift/Remote/Failure.h @@ -318,14 +318,9 @@ template <> struct Failure::ArgTypesForFailureKind { \ }; #include "swift/Remote/FailureKinds.def" -template <> -struct Failure::IsAcceptableArgType { - static constexpr bool value = true; -}; - -template <> -struct Failure::IsAcceptableArgType { - static constexpr bool value = true; +template +struct Failure::IsAcceptableArgType { + static constexpr bool value = std::is_convertible::value; }; template <> diff --git a/include/swift/Remote/FailureKinds.def b/include/swift/Remote/FailureKinds.def index 27155f3bce8..c6cc10ec060 100644 --- a/include/swift/Remote/FailureKinds.def +++ b/include/swift/Remote/FailureKinds.def @@ -13,9 +13,16 @@ // FAILURE(KIND, TEXT, ARGTYS) FAILURE(Unknown, "an unknown failure occurred", ()) +FAILURE(BadArgument, "the API was called with a bad argument", ()) + FAILURE(Memory, "an unknown failure occurred while reading %0 at address %1", (String, Address)) +FAILURE(DependentArgument, + "API was called with a dependent type", ()) +FAILURE(TypeHasNoSuchMember, + "type has no member named '%0'", (String)) + FAILURE(CouldNotResolveTypeDecl, "could not resolve a type with mangled name '%0'", (String)) diff --git a/include/swift/RemoteAST/RemoteAST.h b/include/swift/RemoteAST/RemoteAST.h index 1ff3e0cd57b..5087f7694de 100644 --- a/include/swift/RemoteAST/RemoteAST.h +++ b/include/swift/RemoteAST/RemoteAST.h @@ -182,12 +182,22 @@ public: getDeclForRemoteNominalTypeDescriptor(remote::RemoteAddress address); /// Given a type in the local AST, try to resolve the offset of its - /// property with the given name. + /// member with the given name. This supports: /// - /// This may fail by returning an empty optional. Failure may indicate - /// that an offset for the property could not be resolved, or it may - /// simply indicate that the property has a non-zero offset. - Result getOffsetForProperty(Type type, StringRef propertyName); + /// - stored properties of structs + /// - stored properties of classes + /// - elements of tuples + /// + /// Failure may indicate that an offset for the property could not be + /// resolved, or it may simply indicate that the property is not laid + /// out at a known offset. + /// + /// If the caller has the address of type metadata for the type, it may + /// pass it in; this may allow the implementation to compute an offset in + /// situations where it otherwise cannot. + Result getOffsetOfMember(Type type, + remote::RemoteAddress optMetadataAddress, + StringRef memberName); }; } // end namespace remoteAST diff --git a/lib/RemoteAST/RemoteAST.cpp b/lib/RemoteAST/RemoteAST.cpp index ed7fc358a41..8a631b26708 100644 --- a/lib/RemoteAST/RemoteAST.cpp +++ b/lib/RemoteAST/RemoteAST.cpp @@ -617,8 +617,48 @@ public: getKindForRemoteTypeMetadata(RemoteAddress metadata) = 0; virtual Result getDeclForRemoteNominalTypeDescriptor(RemoteAddress descriptor) = 0; - virtual Result - getOffsetForProperty(Type type, StringRef propertyName) = 0; + + Result + getOffsetOfMember(Type type, RemoteAddress optMetadata, StringRef memberName){ + // Sanity check: obviously invalid arguments. + if (!type || memberName.empty()) + return Result::emplaceFailure(Failure::BadArgument); + + // Sanity check: if the caller gave us a dependent type, there's no way + // we can handle that. + if (type->hasTypeParameter() || type->hasArchetype()) + return Result::emplaceFailure(Failure::DependentArgument); + + // Split into cases. + if (auto typeDecl = type->getNominalOrBoundGenericNominal()) { + return getOffsetOfMember(type, typeDecl, optMetadata, memberName); + } else if (auto tupleType = type->getAs()) { + return getOffsetOfMember(tupleType, optMetadata, memberName); + } else { + return Result::emplaceFailure(Failure::TypeHasNoSuchMember, + memberName); + } + } + + Result + getOffsetOfMember(Type type, NominalTypeDecl *typeDecl, + RemoteAddress optMetadata, StringRef memberName) { + // FIXME + return Result::emplaceFailure(Failure::Unknown); + } + + Result + getOffsetOfMember(TupleType *type, RemoteAddress optMetadata, + StringRef memberName) { + // Check that the member "name" is a valid index into the tuple. + unsigned index; + if (memberName.getAsInteger(10, index) || index >= type->getNumElements()) + return Result::emplaceFailure(Failure::TypeHasNoSuchMember, + memberName); + + // FIXME + return Result::emplaceFailure(Failure::Unknown); + } }; /// A template for generating concrete implementations of the @@ -660,12 +700,6 @@ public: return getBuilder().template getFailureAsResult( Failure::Unknown); } - - Result - getOffsetForProperty(Type type, StringRef propertyName) override { - // TODO - return Result::emplaceFailure(Failure::Unknown); - } }; } // end anonymous namespace @@ -713,6 +747,7 @@ RemoteASTContext::getDeclForRemoteNominalTypeDescriptor(RemoteAddress address) { } Result -RemoteASTContext::getOffsetForProperty(Type type, StringRef propertyName) { - return asImpl(Impl)->getOffsetForProperty(type, propertyName); +RemoteASTContext::getOffsetOfMember(Type type, RemoteAddress optMetadata, + StringRef memberName) { + return asImpl(Impl)->getOffsetOfMember(type, optMetadata, memberName); }