RemoteAST: Add a request to get the underlying type from an opaque type descriptor.

This commit is contained in:
Joe Groff
2019-05-01 15:42:57 -07:00
parent e7cd0a16d5
commit fc8be62895
8 changed files with 102 additions and 11 deletions

View File

@@ -3044,11 +3044,16 @@ public:
return getNumUnderlyingTypeArguments();
}
const RelativeDirectPointer<const char> &
getUnderlyingTypeArgumentMangledName(unsigned i) const {
assert(i < getNumUnderlyingTypeArguments());
return (this
->template getTrailingObjects<RelativeDirectPointer<const char>>())[i];
}
StringRef getUnderlyingTypeArgument(unsigned i) const {
assert(i < getNumUnderlyingTypeArguments());
const char *ptr =
(this->template getTrailingObjects<RelativeDirectPointer<const char>>())[i];
const char *ptr = getUnderlyingTypeArgumentMangledName(i);
return Demangle::makeSymbolicMangledNameStringRef(ptr);
}

View File

@@ -171,6 +171,8 @@ public:
std::string mangleTypeForDebugger(Type decl, const DeclContext *DC);
std::string mangleOpaqueTypeDescriptor(const OpaqueTypeDecl *decl);
std::string mangleDeclType(const ValueDecl *decl);
std::string mangleObjCRuntimeName(const NominalTypeDecl *Nominal);

View File

@@ -4802,6 +4802,18 @@ public:
return T->getKind() == TypeKind::OpaqueTypeArchetype;
}
/// Get the ordinal of the type within the declaration's opaque signature.
///
/// If a method declared its return type as:
///
/// func foo() -> (some P, some Q)
///
/// then the underlying type of `some P` would be ordinal 0, and `some Q` would be ordinal 1.
unsigned getOrdinal() const {
// TODO: multiple opaque types
return 0;
}
static void Profile(llvm::FoldingSetNodeID &ID,
OpaqueTypeDecl *OpaqueDecl,
SubstitutionMap Substitutions);

View File

@@ -724,6 +724,35 @@ public:
return nullptr;
return buildContextMangling(context, Dem);
}
/// Read the mangled underlying type from an opaque type descriptor.
BuiltType
readUnderlyingTypeForOpaqueTypeDescriptor(StoredPointer contextAddr,
unsigned ordinal) {
auto context = readContextDescriptor(contextAddr);
if (!context)
return BuiltType();
if (context->getKind() != ContextDescriptorKind::OpaqueType)
return BuiltType();
auto opaqueType =
reinterpret_cast<const TargetOpaqueTypeDescriptor<Runtime> *>(
context.getLocalBuffer());
if (ordinal >= opaqueType->getNumUnderlyingTypeArguments())
return BuiltType();
auto nameAddr = resolveRelativeField(context,
opaqueType->getUnderlyingTypeArgumentMangledName(ordinal));
Demangle::Demangler Dem;
auto node = readMangledName(RemoteAddress(nameAddr),
MangledNameKind::Type, Dem);
if (!node)
return BuiltType();
return decodeMangledType(node);
}
bool isTaggedPointer(StoredPointer objectAddress) {
if (getTaggedPointerEncoding() != TaggedPointerEncodingKind::Extended)
@@ -1396,6 +1425,12 @@ private:
case ContextDescriptorKind::Protocol:
baseSize = sizeof(TargetProtocolDescriptor<Runtime>);
break;
case ContextDescriptorKind::OpaqueType:
baseSize = sizeof(TargetOpaqueTypeDescriptor<Runtime>);
metadataInitSize =
sizeof(typename Runtime::template RelativeDirectPointer<const char>)
* flags.getKindSpecificFlags();
break;
default:
// We don't know about this kind of context.
return nullptr;

View File

@@ -240,6 +240,17 @@ public:
Result<OpenedExistential>
getDynamicTypeAndAddressForExistential(remote::RemoteAddress address,
Type staticType);
/// Given a reference to an opaque type descriptor, an ordinal, and a set
/// of substitutions, get the underlying type for the opaque type.
///
/// This does not recursively apply the transformation if the underlying
/// type in turn refers to another opaque type.
Result<Type>
getUnderlyingTypeForOpaqueType(remote::RemoteAddress opaqueDescriptor,
SubstitutionMap substitutions,
unsigned ordinal);
};
} // end namespace remoteAST

View File

@@ -2665,3 +2665,10 @@ void ASTMangler::appendOpParamForLayoutConstraint(LayoutConstraint layout) {
break;
}
}
std::string ASTMangler::mangleOpaqueTypeDescriptor(const OpaqueTypeDecl *decl) {
beginMangling();
appendOpaqueDeclName(decl);
appendOperator("MQ");
return finalize();
}

View File

@@ -123,13 +123,6 @@ public:
return mangleNominalTypeSymbol(Decl, "Mn");
}
std::string mangleOpaqueTypeDescriptor(const OpaqueTypeDecl *decl) {
beginMangling();
appendOpaqueDeclName(decl);
appendOperator("MQ");
return finalize();
}
std::string mangleOpaqueTypeDescriptorAccessor(const OpaqueTypeDecl *decl) {
beginMangling();
appendOpaqueDeclName(decl);

View File

@@ -109,7 +109,10 @@ public:
virtual Result<OpenedExistential>
getDynamicTypeAndAddressForExistential(RemoteAddress object,
Type staticType) = 0;
virtual Result<Type>
getUnderlyingTypeForOpaqueType(remote::RemoteAddress opaqueDescriptor,
SubstitutionMap substitutions,
unsigned ordinal) = 0;
Result<uint64_t>
getOffsetOfMember(Type type, RemoteAddress optMetadata, StringRef memberName){
// Sanity check: obviously invalid arguments.
@@ -622,6 +625,20 @@ public:
}
llvm_unreachable("invalid type kind");
}
Result<Type>
getUnderlyingTypeForOpaqueType(remote::RemoteAddress opaqueDescriptor,
SubstitutionMap substitutions,
unsigned ordinal) override {
auto underlyingType = Reader
.readUnderlyingTypeForOpaqueTypeDescriptor(opaqueDescriptor.getAddressData(),
ordinal);
if (!underlyingType)
return getFailure<Type>();
return underlyingType.subst(substitutions);
}
};
} // end anonymous namespace
@@ -692,3 +709,12 @@ RemoteASTContext::getDynamicTypeAndAddressForExistential(
return asImpl(Impl)->getDynamicTypeAndAddressForExistential(address,
staticType);
}
Result<Type>
RemoteASTContext::getUnderlyingTypeForOpaqueType(
remote::RemoteAddress opaqueDescriptor,
SubstitutionMap substitutions,
unsigned ordinal) {
return asImpl(Impl)->getUnderlyingTypeForOpaqueType(opaqueDescriptor,
substitutions, ordinal);
}