Start fleshing out RemoteAST's storage-offset API.

This commit is contained in:
John McCall
2016-04-26 16:21:59 -07:00
parent 590d41c00a
commit 312aa06901
4 changed files with 70 additions and 23 deletions

View File

@@ -318,14 +318,9 @@ template <> struct Failure::ArgTypesForFailureKind<Failure::KIND##_t> { \
}; };
#include "swift/Remote/FailureKinds.def" #include "swift/Remote/FailureKinds.def"
template <> template <class T>
struct Failure::IsAcceptableArgType<Failure::ArgType_String, const char *> { struct Failure::IsAcceptableArgType<Failure::ArgType_String, T> {
static constexpr bool value = true; static constexpr bool value = std::is_convertible<T, std::string>::value;
};
template <>
struct Failure::IsAcceptableArgType<Failure::ArgType_String, std::string> {
static constexpr bool value = true;
}; };
template <> template <>

View File

@@ -13,9 +13,16 @@
// FAILURE(KIND, TEXT, ARGTYS) // FAILURE(KIND, TEXT, ARGTYS)
FAILURE(Unknown, "an unknown failure occurred", ()) 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", FAILURE(Memory, "an unknown failure occurred while reading %0 at address %1",
(String, Address)) (String, Address))
FAILURE(DependentArgument,
"API was called with a dependent type", ())
FAILURE(TypeHasNoSuchMember,
"type has no member named '%0'", (String))
FAILURE(CouldNotResolveTypeDecl, FAILURE(CouldNotResolveTypeDecl,
"could not resolve a type with mangled name '%0'", (String)) "could not resolve a type with mangled name '%0'", (String))

View File

@@ -182,12 +182,22 @@ public:
getDeclForRemoteNominalTypeDescriptor(remote::RemoteAddress address); getDeclForRemoteNominalTypeDescriptor(remote::RemoteAddress address);
/// Given a type in the local AST, try to resolve the offset of its /// 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 /// - stored properties of structs
/// that an offset for the property could not be resolved, or it may /// - stored properties of classes
/// simply indicate that the property has a non-zero offset. /// - elements of tuples
Result<uint64_t> getOffsetForProperty(Type type, StringRef propertyName); ///
/// 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<uint64_t> getOffsetOfMember(Type type,
remote::RemoteAddress optMetadataAddress,
StringRef memberName);
}; };
} // end namespace remoteAST } // end namespace remoteAST

View File

@@ -617,8 +617,48 @@ public:
getKindForRemoteTypeMetadata(RemoteAddress metadata) = 0; getKindForRemoteTypeMetadata(RemoteAddress metadata) = 0;
virtual Result<NominalTypeDecl*> virtual Result<NominalTypeDecl*>
getDeclForRemoteNominalTypeDescriptor(RemoteAddress descriptor) = 0; getDeclForRemoteNominalTypeDescriptor(RemoteAddress descriptor) = 0;
virtual Result<uint64_t>
getOffsetForProperty(Type type, StringRef propertyName) = 0; Result<uint64_t>
getOffsetOfMember(Type type, RemoteAddress optMetadata, StringRef memberName){
// Sanity check: obviously invalid arguments.
if (!type || memberName.empty())
return Result<uint64_t>::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<uint64_t>::emplaceFailure(Failure::DependentArgument);
// Split into cases.
if (auto typeDecl = type->getNominalOrBoundGenericNominal()) {
return getOffsetOfMember(type, typeDecl, optMetadata, memberName);
} else if (auto tupleType = type->getAs<TupleType>()) {
return getOffsetOfMember(tupleType, optMetadata, memberName);
} else {
return Result<uint64_t>::emplaceFailure(Failure::TypeHasNoSuchMember,
memberName);
}
}
Result<uint64_t>
getOffsetOfMember(Type type, NominalTypeDecl *typeDecl,
RemoteAddress optMetadata, StringRef memberName) {
// FIXME
return Result<uint64_t>::emplaceFailure(Failure::Unknown);
}
Result<uint64_t>
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<uint64_t>::emplaceFailure(Failure::TypeHasNoSuchMember,
memberName);
// FIXME
return Result<uint64_t>::emplaceFailure(Failure::Unknown);
}
}; };
/// A template for generating concrete implementations of the /// A template for generating concrete implementations of the
@@ -660,12 +700,6 @@ public:
return getBuilder().template getFailureAsResult<NominalTypeDecl*>( return getBuilder().template getFailureAsResult<NominalTypeDecl*>(
Failure::Unknown); Failure::Unknown);
} }
Result<uint64_t>
getOffsetForProperty(Type type, StringRef propertyName) override {
// TODO
return Result<uint64_t>::emplaceFailure(Failure::Unknown);
}
}; };
} // end anonymous namespace } // end anonymous namespace
@@ -713,6 +747,7 @@ RemoteASTContext::getDeclForRemoteNominalTypeDescriptor(RemoteAddress address) {
} }
Result<uint64_t> Result<uint64_t>
RemoteASTContext::getOffsetForProperty(Type type, StringRef propertyName) { RemoteASTContext::getOffsetOfMember(Type type, RemoteAddress optMetadata,
return asImpl(Impl)->getOffsetForProperty(type, propertyName); StringRef memberName) {
return asImpl(Impl)->getOffsetOfMember(type, optMetadata, memberName);
} }