Add error reporting when looking up types by demangled name.

This commit is contained in:
Mike Ash
2020-08-19 12:30:34 -04:00
parent 24f1a46efa
commit fd6922f92d
20 changed files with 743 additions and 377 deletions

View File

@@ -18,10 +18,12 @@
#ifndef SWIFT_DEMANGLING_TYPEDECODER_H #ifndef SWIFT_DEMANGLING_TYPEDECODER_H
#define SWIFT_DEMANGLING_TYPEDECODER_H #define SWIFT_DEMANGLING_TYPEDECODER_H
#include "TypeLookupError.h"
#include "swift/ABI/MetadataValues.h" #include "swift/ABI/MetadataValues.h"
#include "swift/Basic/LLVM.h"
#include "swift/Demangling/Demangler.h" #include "swift/Demangling/Demangler.h"
#include "swift/Demangling/NamespaceMacros.h" #include "swift/Demangling/NamespaceMacros.h"
#include "swift/Basic/LLVM.h" #include "swift/Runtime/Portability.h"
#include "swift/Runtime/Unreachable.h" #include "swift/Runtime/Unreachable.h"
#include "swift/Strings.h" #include "swift/Strings.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
@@ -317,6 +319,14 @@ getObjCClassOrProtocolName(NodePointer node) {
} }
#endif #endif
#define MAKE_NODE_TYPE_ERROR(Node, Fmt, ...) \
TypeLookupError("TypeDecoder.h:%d: Node kind %u \"%.*s\" - " Fmt, __LINE__, \
Node->getKind(), \
Node->hasText() ? (int)Node->getText().size() : 0, \
Node->hasText() ? Node->getText().data() : "", __VA_ARGS__)
#define MAKE_NODE_TYPE_ERROR0(Node, Str) MAKE_NODE_TYPE_ERROR(Node, "%s", Str)
/// Decode a mangled type to construct an abstract type, forming such /// Decode a mangled type to construct an abstract type, forming such
/// types by invoking a custom builder. /// types by invoking a custom builder.
template <typename BuilderType> template <typename BuilderType>
@@ -333,24 +343,25 @@ class TypeDecoder {
: Builder(Builder) {} : Builder(Builder) {}
/// Given a demangle tree, attempt to turn it into a type. /// Given a demangle tree, attempt to turn it into a type.
BuiltType decodeMangledType(NodePointer Node) { TypeLookupErrorOr<BuiltType> decodeMangledType(NodePointer Node) {
if (!Node) return BuiltType(); if (!Node)
return TypeLookupError("Node is NULL");
using NodeKind = Demangle::Node::Kind; using NodeKind = Demangle::Node::Kind;
switch (Node->getKind()) { switch (Node->getKind()) {
case NodeKind::Global: case NodeKind::Global:
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children.");
return decodeMangledType(Node->getChild(0)); return decodeMangledType(Node->getChild(0));
case NodeKind::TypeMangling: case NodeKind::TypeMangling:
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children.");
return decodeMangledType(Node->getChild(0)); return decodeMangledType(Node->getChild(0));
case NodeKind::Type: case NodeKind::Type:
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children.");
return decodeMangledType(Node->getChild(0)); return decodeMangledType(Node->getChild(0));
case NodeKind::Class: case NodeKind::Class:
@@ -369,8 +380,8 @@ class TypeDecoder {
BuiltTypeDecl typeDecl = BuiltTypeDecl(); BuiltTypeDecl typeDecl = BuiltTypeDecl();
BuiltType parent = BuiltType(); BuiltType parent = BuiltType();
bool typeAlias = false; bool typeAlias = false;
if (!decodeMangledTypeDecl(Node, typeDecl, parent, typeAlias)) if (auto error = decodeMangledTypeDecl(Node, typeDecl, parent, typeAlias))
return BuiltType(); return *error;
if (typeAlias) if (typeAlias)
return Builder.createTypeAliasType(typeDecl, parent); return Builder.createTypeAliasType(typeDecl, parent);
@@ -384,19 +395,21 @@ class TypeDecoder {
case NodeKind::BoundGenericTypeAlias: case NodeKind::BoundGenericTypeAlias:
case NodeKind::BoundGenericOtherNominalType: { case NodeKind::BoundGenericOtherNominalType: {
if (Node->getNumChildren() < 2) if (Node->getNumChildren() < 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (2)",
Node->getNumChildren());
llvm::SmallVector<BuiltType, 8> args; llvm::SmallVector<BuiltType, 8> args;
const auto &genericArgs = Node->getChild(1); const auto &genericArgs = Node->getChild(1);
if (genericArgs->getKind() != NodeKind::TypeList) if (genericArgs->getKind() != NodeKind::TypeList)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(genericArgs, "is not TypeList");
for (auto genericArg : *genericArgs) { for (auto genericArg : *genericArgs) {
auto paramType = decodeMangledType(genericArg); auto paramType = decodeMangledType(genericArg);
if (!paramType) if (paramType.isError())
return BuiltType(); return paramType;
args.push_back(paramType); args.push_back(paramType.getType());
} }
auto ChildNode = Node->getChild(0); auto ChildNode = Node->getChild(0);
@@ -413,9 +426,9 @@ class TypeDecoder {
BuiltTypeDecl typeDecl = BuiltTypeDecl(); BuiltTypeDecl typeDecl = BuiltTypeDecl();
BuiltType parent = BuiltType(); BuiltType parent = BuiltType();
bool typeAlias = false; bool typeAlias = false;
if (!decodeMangledTypeDecl(ChildNode, typeDecl, if (auto error =
parent, typeAlias)) decodeMangledTypeDecl(ChildNode, typeDecl, parent, typeAlias))
return BuiltType(); return *error;
return Builder.createBoundGenericType(typeDecl, args, parent); return Builder.createBoundGenericType(typeDecl, args, parent);
} }
@@ -445,11 +458,15 @@ class TypeDecoder {
// But when resolving it to a type, we want to *keep* the argument // But when resolving it to a type, we want to *keep* the argument
// so that the parent type becomes 'S' and not 'P'. // so that the parent type becomes 'S' and not 'P'.
if (Node->getNumChildren() < 2) if (Node->getNumChildren() < 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (2)",
Node->getNumChildren());
const auto &genericArgs = Node->getChild(1); const auto &genericArgs = Node->getChild(1);
if (genericArgs->getNumChildren() != 1) if (genericArgs->getNumChildren() != 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(genericArgs,
"expected 1 generic argument, saw %u",
genericArgs->getNumChildren());
return decodeMangledType(genericArgs->getChild(0)); return decodeMangledType(genericArgs->getChild(0));
} }
@@ -469,7 +486,7 @@ class TypeDecoder {
auto reprNode = Node->getChild(i++); auto reprNode = Node->getChild(i++);
if (reprNode->getKind() != NodeKind::MetatypeRepresentation || if (reprNode->getKind() != NodeKind::MetatypeRepresentation ||
!reprNode->hasText()) !reprNode->hasText())
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(reprNode, "wrong node kind or no text");
if (reprNode->getText() == "@thin") if (reprNode->getText() == "@thin")
repr = ImplMetatypeRepresentation::Thin; repr = ImplMetatypeRepresentation::Thin;
else if (reprNode->getText() == "@thick") else if (reprNode->getText() == "@thick")
@@ -477,26 +494,28 @@ class TypeDecoder {
else if (reprNode->getText() == "@objc_metatype") else if (reprNode->getText() == "@objc_metatype")
repr = ImplMetatypeRepresentation::ObjC; repr = ImplMetatypeRepresentation::ObjC;
} else if (Node->getNumChildren() < 1) { } else if (Node->getNumChildren() < 1) {
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
} }
auto instance = decodeMangledType(Node->getChild(i)); auto instance = decodeMangledType(Node->getChild(i));
if (!instance) if (instance.isError())
return BuiltType(); return instance;
if (Node->getKind() == NodeKind::Metatype) { if (Node->getKind() == NodeKind::Metatype) {
return Builder.createMetatypeType(instance, repr); return Builder.createMetatypeType(instance.getType(), repr);
} else if (Node->getKind() == NodeKind::ExistentialMetatype) { } else if (Node->getKind() == NodeKind::ExistentialMetatype) {
return Builder.createExistentialMetatypeType(instance, repr); return Builder.createExistentialMetatypeType(instance.getType(), repr);
} else { } else {
assert(false); assert(false);
return nullptr; return MAKE_NODE_TYPE_ERROR0(Node,
"Metatype/ExistentialMetatype Node "
"had a different kind when re-checked");
} }
} }
case NodeKind::ProtocolList: case NodeKind::ProtocolList:
case NodeKind::ProtocolListWithAnyObject: case NodeKind::ProtocolListWithAnyObject:
case NodeKind::ProtocolListWithClass: { case NodeKind::ProtocolListWithClass: {
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
// Find the protocol list. // Find the protocol list.
llvm::SmallVector<BuiltProtocolDecl, 8> Protocols; llvm::SmallVector<BuiltProtocolDecl, 8> Protocols;
@@ -511,7 +530,8 @@ class TypeDecoder {
if (auto Protocol = decodeMangledProtocolType(componentType)) if (auto Protocol = decodeMangledProtocolType(componentType))
Protocols.push_back(Protocol); Protocols.push_back(Protocol);
else else
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(componentType,
"failed to decode protocol type");
} }
// Superclass or AnyObject, if present. // Superclass or AnyObject, if present.
@@ -519,11 +539,15 @@ class TypeDecoder {
auto Superclass = BuiltType(); auto Superclass = BuiltType();
if (Node->getKind() == NodeKind::ProtocolListWithClass) { if (Node->getKind() == NodeKind::ProtocolListWithClass) {
if (Node->getNumChildren() < 2) if (Node->getNumChildren() < 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (2)",
Node->getNumChildren());
auto superclassNode = Node->getChild(1); auto superclassNode = Node->getChild(1);
Superclass = decodeMangledType(superclassNode); auto result = decodeMangledType(superclassNode);
if (!Superclass) return BuiltType(); if (result.isError())
return result;
Superclass = result.getType();
IsClassBound = true; IsClassBound = true;
} else if (Node->getKind() == NodeKind::ProtocolListWithAnyObject) { } else if (Node->getKind() == NodeKind::ProtocolListWithAnyObject) {
@@ -541,17 +565,18 @@ class TypeDecoder {
/*IsClassBound=*/false); /*IsClassBound=*/false);
} }
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "failed to decode protocol type");
} }
case NodeKind::DynamicSelf: { case NodeKind::DynamicSelf: {
if (Node->getNumChildren() != 1) if (Node->getNumChildren() != 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node, "expected 1 child, saw %u",
Node->getNumChildren());
auto selfType = decodeMangledType(Node->getChild(0)); auto selfType = decodeMangledType(Node->getChild(0));
if (!selfType) if (selfType.isError())
return BuiltType(); return selfType;
return Builder.createDynamicSelfType(selfType); return Builder.createDynamicSelfType(selfType.getType());
} }
case NodeKind::DependentGenericParamType: { case NodeKind::DependentGenericParamType: {
auto depth = Node->getChild(0)->getIndex(); auto depth = Node->getChild(0)->getIndex();
@@ -571,7 +596,9 @@ class TypeDecoder {
case NodeKind::EscapingLinearFunctionType: case NodeKind::EscapingLinearFunctionType:
case NodeKind::FunctionType: { case NodeKind::FunctionType: {
if (Node->getNumChildren() < 2) if (Node->getNumChildren() < 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (2)",
Node->getNumChildren());
FunctionTypeFlags flags; FunctionTypeFlags flags;
if (Node->getKind() == NodeKind::ObjCBlock || if (Node->getKind() == NodeKind::ObjCBlock ||
@@ -611,13 +638,16 @@ class TypeDecoder {
flags = flags.withAsync(isAsync).withThrows(isThrow); flags = flags.withAsync(isAsync).withThrows(isThrow);
if (Node->getNumChildren() < firstChildIdx + 2) if (Node->getNumChildren() < firstChildIdx + 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (%u)",
Node->getNumChildren(), firstChildIdx + 2);
bool hasParamFlags = false; bool hasParamFlags = false;
llvm::SmallVector<FunctionParam<BuiltType>, 8> parameters; llvm::SmallVector<FunctionParam<BuiltType>, 8> parameters;
if (!decodeMangledFunctionInputType(Node->getChild(firstChildIdx), if (!decodeMangledFunctionInputType(Node->getChild(firstChildIdx),
parameters, hasParamFlags)) parameters, hasParamFlags))
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node->getChild(firstChildIdx),
"failed to decode function type");
flags = flags =
flags.withNumParameters(parameters.size()) flags.withNumParameters(parameters.size())
.withParameterFlags(hasParamFlags) .withParameterFlags(hasParamFlags)
@@ -631,8 +661,9 @@ class TypeDecoder {
NodeKind::EscapingLinearFunctionType); NodeKind::EscapingLinearFunctionType);
auto result = decodeMangledType(Node->getChild(firstChildIdx+1)); auto result = decodeMangledType(Node->getChild(firstChildIdx+1));
if (!result) return BuiltType(); if (result.isError())
return Builder.createFunctionType(parameters, result, flags); return result;
return Builder.createFunctionType(parameters, result.getType(), flags);
} }
case NodeKind::ImplFunctionType: { case NodeKind::ImplFunctionType: {
auto calleeConvention = ImplParameterConvention::Direct_Unowned; auto calleeConvention = ImplParameterConvention::Direct_Unowned;
@@ -646,7 +677,7 @@ class TypeDecoder {
if (child->getKind() == NodeKind::ImplConvention) { if (child->getKind() == NodeKind::ImplConvention) {
if (!child->hasText()) if (!child->hasText())
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(child, "expected text");
if (child->getText() == "@convention(thin)") { if (child->getText() == "@convention(thin)") {
flags = flags =
@@ -656,7 +687,7 @@ class TypeDecoder {
} }
} else if (child->getKind() == NodeKind::ImplFunctionAttribute) { } else if (child->getKind() == NodeKind::ImplFunctionAttribute) {
if (!child->hasText()) if (!child->hasText())
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(child, "expected text");
StringRef text = child->getText(); StringRef text = child->getText();
if (text == "@convention(c)") { if (text == "@convention(c)") {
@@ -676,15 +707,18 @@ class TypeDecoder {
flags = flags.withEscaping(); flags = flags.withEscaping();
} else if (child->getKind() == NodeKind::ImplParameter) { } else if (child->getKind() == NodeKind::ImplParameter) {
if (decodeImplFunctionParam(child, parameters)) if (decodeImplFunctionParam(child, parameters))
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(child,
"failed to decode function parameter");
} else if (child->getKind() == NodeKind::ImplResult) { } else if (child->getKind() == NodeKind::ImplResult) {
if (decodeImplFunctionParam(child, results)) if (decodeImplFunctionParam(child, results))
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(child,
"failed to decode function parameter");
} else if (child->getKind() == NodeKind::ImplErrorResult) { } else if (child->getKind() == NodeKind::ImplErrorResult) {
if (decodeImplFunctionPart(child, errorResults)) if (decodeImplFunctionPart(child, errorResults))
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(child,
"failed to decode function part");
} else { } else {
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(child, "unexpected kind");
} }
} }
@@ -696,7 +730,8 @@ class TypeDecoder {
errorResult = errorResults.front(); errorResult = errorResults.front();
break; break;
default: default:
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node, "got %zu errors",
errorResults.size());
} }
// TODO: Some cases not handled above, but *probably* they cannot // TODO: Some cases not handled above, but *probably* they cannot
@@ -711,13 +746,13 @@ class TypeDecoder {
case NodeKind::ArgumentTuple: case NodeKind::ArgumentTuple:
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
return decodeMangledType(Node->getChild(0)); return decodeMangledType(Node->getChild(0));
case NodeKind::ReturnType: case NodeKind::ReturnType:
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
return decodeMangledType(Node->getChild(0)); return decodeMangledType(Node->getChild(0));
@@ -726,12 +761,13 @@ class TypeDecoder {
std::string labels; std::string labels;
for (auto &element : *Node) { for (auto &element : *Node) {
if (element->getKind() != NodeKind::TupleElement) if (element->getKind() != NodeKind::TupleElement)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "unexpected kind");
// If the tuple element is labeled, add its label to 'labels'. // If the tuple element is labeled, add its label to 'labels'.
unsigned typeChildIndex = 0; unsigned typeChildIndex = 0;
if (element->getChild(typeChildIndex)->getKind() == NodeKind::VariadicMarker) { if (element->getChild(typeChildIndex)->getKind() == NodeKind::VariadicMarker) {
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(element->getChild(typeChildIndex),
"no children");
} }
if (element->getChild(typeChildIndex)->getKind() == NodeKind::TupleElementName) { if (element->getChild(typeChildIndex)->getKind() == NodeKind::TupleElementName) {
// Add spaces to terminate all the previous labels if this // Add spaces to terminate all the previous labels if this
@@ -749,22 +785,23 @@ class TypeDecoder {
} }
// Decode the element type. // Decode the element type.
BuiltType elementType = auto elementType = decodeMangledType(element->getChild(typeChildIndex));
decodeMangledType(element->getChild(typeChildIndex)); if (elementType.isError())
if (!elementType) return elementType;
return BuiltType();
elements.push_back(elementType); elements.push_back(elementType.getType());
} }
return Builder.createTupleType(elements, std::move(labels)); return Builder.createTupleType(elements, std::move(labels));
} }
case NodeKind::TupleElement: case NodeKind::TupleElement:
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
if (Node->getChild(0)->getKind() == NodeKind::TupleElementName) { if (Node->getChild(0)->getKind() == NodeKind::TupleElementName) {
if (Node->getNumChildren() < 2) if (Node->getNumChildren() < 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (2)",
Node->getNumChildren());
return decodeMangledType(Node->getChild(1)); return decodeMangledType(Node->getChild(1));
} }
@@ -772,68 +809,75 @@ class TypeDecoder {
case NodeKind::DependentGenericType: { case NodeKind::DependentGenericType: {
if (Node->getNumChildren() < 2) if (Node->getNumChildren() < 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (2)",
Node->getNumChildren());
return decodeMangledType(Node->getChild(1)); return decodeMangledType(Node->getChild(1));
} }
case NodeKind::DependentMemberType: { case NodeKind::DependentMemberType: {
if (Node->getNumChildren() < 2) if (Node->getNumChildren() < 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (2)",
Node->getNumChildren());
auto base = decodeMangledType(Node->getChild(0)); auto base = decodeMangledType(Node->getChild(0));
if (!base) if (base.isError())
return BuiltType(); return base;
auto assocTypeChild = Node->getChild(1); auto assocTypeChild = Node->getChild(1);
auto member = assocTypeChild->getFirstChild()->getText(); auto member = assocTypeChild->getFirstChild()->getText();
if (assocTypeChild->getNumChildren() < 2) if (assocTypeChild->getNumChildren() < 2)
return Builder.createDependentMemberType(member.str(), base); return Builder.createDependentMemberType(member.str(), base.getType());
auto protocol = decodeMangledProtocolType(assocTypeChild->getChild(1)); auto protocol = decodeMangledProtocolType(assocTypeChild->getChild(1));
if (!protocol) if (!protocol)
return BuiltType(); return BuiltType();
return Builder.createDependentMemberType(member.str(), base, protocol); return Builder.createDependentMemberType(member.str(), base.getType(),
protocol);
} }
case NodeKind::DependentAssociatedTypeRef: { case NodeKind::DependentAssociatedTypeRef: {
if (Node->getNumChildren() < 2) if (Node->getNumChildren() < 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (2)",
Node->getNumChildren());
return decodeMangledType(Node->getChild(1)); return decodeMangledType(Node->getChild(1));
} }
case NodeKind::Unowned: { case NodeKind::Unowned: {
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
auto base = decodeMangledType(Node->getChild(0)); auto base = decodeMangledType(Node->getChild(0));
if (!base) if (base.isError())
return BuiltType(); return base;
return Builder.createUnownedStorageType(base); return Builder.createUnownedStorageType(base.getType());
} }
case NodeKind::Unmanaged: { case NodeKind::Unmanaged: {
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
auto base = decodeMangledType(Node->getChild(0)); auto base = decodeMangledType(Node->getChild(0));
if (!base) if (base.isError())
return BuiltType(); return base;
return Builder.createUnmanagedStorageType(base); return Builder.createUnmanagedStorageType(base.getType());
} }
case NodeKind::Weak: { case NodeKind::Weak: {
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
auto base = decodeMangledType(Node->getChild(0)); auto base = decodeMangledType(Node->getChild(0));
if (!base) if (base.isError())
return BuiltType(); return base;
return Builder.createWeakStorageType(base); return Builder.createWeakStorageType(base.getType());
} }
case NodeKind::SILBoxType: { case NodeKind::SILBoxType: {
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
auto base = decodeMangledType(Node->getChild(0)); auto base = decodeMangledType(Node->getChild(0));
if (!base) if (base.isError())
return BuiltType(); return base;
return Builder.createSILBoxType(base); return Builder.createSILBoxType(base.getType());
} }
case NodeKind::SILBoxTypeWithLayout: { case NodeKind::SILBoxTypeWithLayout: {
// TODO: Implement SILBoxTypeRefs with layout. As a stopgap, specify the // TODO: Implement SILBoxTypeRefs with layout. As a stopgap, specify the
@@ -842,57 +886,62 @@ class TypeDecoder {
} }
case NodeKind::SugaredOptional: { case NodeKind::SugaredOptional: {
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
auto base = decodeMangledType(Node->getChild(0)); auto base = decodeMangledType(Node->getChild(0));
if (!base) if (base.isError())
return BuiltType(); return base;
return Builder.createOptionalType(base); return Builder.createOptionalType(base.getType());
} }
case NodeKind::SugaredArray: { case NodeKind::SugaredArray: {
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
auto base = decodeMangledType(Node->getChild(0)); auto base = decodeMangledType(Node->getChild(0));
if (!base) if (base.isError())
return BuiltType(); return base;
return Builder.createArrayType(base); return Builder.createArrayType(base.getType());
} }
case NodeKind::SugaredDictionary: { case NodeKind::SugaredDictionary: {
if (Node->getNumChildren() < 2) if (Node->getNumChildren() < 2)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (2)",
Node->getNumChildren());
auto key = decodeMangledType(Node->getChild(0)); auto key = decodeMangledType(Node->getChild(0));
if (!key) if (key.isError())
return BuiltType(); return key;
auto value = decodeMangledType(Node->getChild(1)); auto value = decodeMangledType(Node->getChild(1));
if (!key) if (value.isError())
return BuiltType(); return value;
return Builder.createDictionaryType(key, value); return Builder.createDictionaryType(key.getType(), value.getType());
} }
case NodeKind::SugaredParen: { case NodeKind::SugaredParen: {
if (Node->getNumChildren() < 1) if (Node->getNumChildren() < 1)
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "no children");
auto base = decodeMangledType(Node->getChild(0)); auto base = decodeMangledType(Node->getChild(0));
if (!base) if (base.isError())
return BuiltType(); return base;
return Builder.createParenType(base); return Builder.createParenType(base.getType());
} }
case NodeKind::OpaqueType: { case NodeKind::OpaqueType: {
if (Node->getNumChildren() < 3) if (Node->getNumChildren() < 3)
return BuiltType(); return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%u) than required (3)",
Node->getNumChildren());
auto descriptor = Node->getChild(0); auto descriptor = Node->getChild(0);
auto ordinalNode = Node->getChild(1); auto ordinalNode = Node->getChild(1);
if (ordinalNode->getKind() != NodeKind::Index if (ordinalNode->getKind() != NodeKind::Index
|| !ordinalNode->hasIndex()) || !ordinalNode->hasIndex())
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(ordinalNode,
"unexpected kind or no index");
auto ordinal = ordinalNode->getIndex(); auto ordinal = ordinalNode->getIndex();
std::vector<BuiltType> genericArgsBuf; std::vector<BuiltType> genericArgsBuf;
@@ -905,9 +954,9 @@ class TypeDecoder {
break; break;
for (auto argNode : *genericsNode) { for (auto argNode : *genericsNode) {
auto arg = decodeMangledType(argNode); auto arg = decodeMangledType(argNode);
if (!arg) if (arg.isError())
return BuiltType(); return arg;
genericArgsBuf.push_back(arg); genericArgsBuf.push_back(arg.getType());
} }
} }
genericArgsLevels.push_back(genericArgsBuf.size()); genericArgsLevels.push_back(genericArgsBuf.size());
@@ -923,7 +972,7 @@ class TypeDecoder {
// TODO: Handle OpaqueReturnType, when we're in the middle of reconstructing // TODO: Handle OpaqueReturnType, when we're in the middle of reconstructing
// the defining decl // the defining decl
default: default:
return BuiltType(); return MAKE_NODE_TYPE_ERROR0(Node, "unexpected kind");
} }
} }
@@ -943,11 +992,11 @@ private:
T::getConventionFromString(conventionString); T::getConventionFromString(conventionString);
if (!convention) if (!convention)
return true; return true;
BuiltType type = decodeMangledType(node->getChild(1)); auto type = decodeMangledType(node->getChild(1));
if (!type) if (type.isError())
return true; return true;
results.emplace_back(type, *convention); results.emplace_back(type.getType(), *convention);
return false; return false;
} }
@@ -968,8 +1017,8 @@ private:
auto convention = T::getConventionFromString(conventionString); auto convention = T::getConventionFromString(conventionString);
if (!convention) if (!convention)
return true; return true;
BuiltType type = decodeMangledType(typeNode); auto result = decodeMangledType(typeNode);
if (!type) if (result.isError())
return true; return true;
auto diffKind = T::DifferentiabilityType::DifferentiableOrNotApplicable; auto diffKind = T::DifferentiabilityType::DifferentiableOrNotApplicable;
@@ -984,14 +1033,13 @@ private:
diffKind = *optDiffKind; diffKind = *optDiffKind;
} }
results.emplace_back(type, *convention, diffKind); results.emplace_back(result.getType(), *convention, diffKind);
return false; return false;
} }
bool decodeMangledTypeDecl(Demangle::NodePointer node, llvm::Optional<TypeLookupError>
BuiltTypeDecl &typeDecl, decodeMangledTypeDecl(Demangle::NodePointer node, BuiltTypeDecl &typeDecl,
BuiltType &parent, BuiltType &parent, bool &typeAlias) {
bool &typeAlias) {
if (node->getKind() == NodeKind::Type) if (node->getKind() == NodeKind::Type)
return decodeMangledTypeDecl(node->getChild(0), typeDecl, return decodeMangledTypeDecl(node->getChild(0), typeDecl,
parent, typeAlias); parent, typeAlias);
@@ -1002,7 +1050,9 @@ private:
declNode = node; declNode = node;
} else { } else {
if (node->getNumChildren() < 2) if (node->getNumChildren() < 2)
return false; return MAKE_NODE_TYPE_ERROR(
node, "Number of node children (%u) less than required (2)",
node->getNumChildren());
auto parentContext = node->getChild(0); auto parentContext = node->getChild(0);
@@ -1018,11 +1068,14 @@ private:
case Node::Kind::Extension: case Node::Kind::Extension:
// Decode the type being extended. // Decode the type being extended.
if (parentContext->getNumChildren() < 2) if (parentContext->getNumChildren() < 2)
return false; return MAKE_NODE_TYPE_ERROR(parentContext,
"Number of parentContext children (%u) "
"less than required (2)",
node->getNumChildren());
parentContext = parentContext->getChild(1); parentContext = parentContext->getChild(1);
LLVM_FALLTHROUGH; LLVM_FALLTHROUGH;
default: default:
parent = decodeMangledType(parentContext); parent = decodeMangledType(parentContext).getType();
// Remove any generic arguments from the context node, producing a // Remove any generic arguments from the context node, producing a
// node that references the nominal type declaration. // node that references the nominal type declaration.
declNode = Demangle::getUnspecialized(node, Builder.getNodeFactory()); declNode = Demangle::getUnspecialized(node, Builder.getNodeFactory());
@@ -1030,9 +1083,10 @@ private:
} }
} }
typeDecl = Builder.createTypeDecl(declNode, typeAlias); typeDecl = Builder.createTypeDecl(declNode, typeAlias);
if (!typeDecl) return false; if (!typeDecl)
return TypeLookupError("Failed to create type decl");
return true; return llvm::None;
} }
BuiltProtocolDecl decodeMangledProtocolType(Demangle::NodePointer node) { BuiltProtocolDecl decodeMangledProtocolType(Demangle::NodePointer node) {
@@ -1097,10 +1151,10 @@ private:
} }
auto paramType = decodeMangledType(node); auto paramType = decodeMangledType(node);
if (!paramType) if (paramType.isError())
return false; return false;
param.setType(paramType); param.setType(paramType.getType());
return true; return true;
}; };
@@ -1158,14 +1212,12 @@ private:
} }
}; };
template<typename BuilderType> template <typename BuilderType>
inline typename BuilderType::BuiltType inline TypeLookupErrorOr<typename BuilderType::BuiltType>
decodeMangledType(BuilderType &Builder, decodeMangledType(BuilderType &Builder, NodePointer Node) {
NodePointer Node) {
return TypeDecoder<BuilderType>(Builder).decodeMangledType(Node); return TypeDecoder<BuilderType>(Builder).decodeMangledType(Node);
} }
SWIFT_END_INLINE_NAMESPACE SWIFT_END_INLINE_NAMESPACE
} // end namespace Demangle } // end namespace Demangle
} // end namespace swift } // end namespace swift

View File

@@ -0,0 +1,198 @@
//===--- TypeLookupError.h - Type lookup error value. -----------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Provides the TypeLookupError class, which represents errors when demangling
// or looking up types.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_DEMANGLING_TypeLookupError_H
#define SWIFT_DEMANGLING_TypeLookupError_H
#include "swift/Basic/TaggedUnion.h"
#include "swift/Runtime/Portability.h"
namespace swift {
/// An error that occurred while looking up a type at runtime from a mangled
/// name.
/// ///
/// This ultimately just provides a string, but is built to take up minimal
/// space when passed around, and perform as much work lazily as possible. We
/// don't want to spend a lot of time building strings when the caller is going
/// to handle the error gracefully and try a fallback. We only want to waste
/// time/space on that when the error message is actually relevant, so build it
/// as late as possible.
/// ///
/// To be as compact as possible, this type holds a context pointer and a
/// callback function. The callback function uses the context pointer to return
/// an error string when requested. The callback function also does quadruple
/// duty to copy/destroy the context as needed, and free the returned error
/// string if needed. Commands are passed to the callback to request the
/// different operations, which means we only have to store one function pointer
/// instead of four.
class TypeLookupError {
public:
/// The commands that can be passed to the callback function.
enum class Command {
/// Return the error string to the caller, as a char *.
CopyErrorString,
/// Destroy the error string returned from CopyErrorString, if necessary.
/// The return value is ignored.
DestroyErrorString,
/// Return a copy of the context pointer (used for copying TypeLookupError
/// objects.)
CopyContext,
/// Destroy the context pointer. The return value is ignored.
DestroyContext,
};
/// The callback used to respond to the commands. The parameters are:
/// - `context`: the context that the value was initialized with, or the
/// context returned from a CopyContext call
/// - `command`: the command to respond to
/// - `param`: when `command` is `DestroyErrorString`, the string pointer to
/// destroy, otherwise NULL
using Callback = void *(*)(void *context, Command command, void *param);
private:
void *Context;
Callback Fn;
/// A no-op callback used to avoid a bunch of `if (Fn)` checks.
static void *nop(void *context, Command command, void *param) {
return nullptr;
}
/// Helper functions for getting a C string from a lambda. These allow us to
/// wrap lambdas returning `char *` or `std::string` and standardize them on
/// `char *`.
static char *getCString(char *str) { return str; }
static char *getCString(const std::string &str) {
return strdup(str.c_str());
}
public:
TypeLookupError(const TypeLookupError &other) {
Fn = other.Fn;
Context = other.Fn(other.Context, Command::CopyContext, nullptr);
}
TypeLookupError(TypeLookupError &&other) {
Fn = other.Fn;
Context = other.Context;
other.Fn = nop;
other.Context = nullptr;
}
~TypeLookupError() { Fn(Context, Command::DestroyContext, nullptr); }
TypeLookupError(void *context, Callback fn) : Context(context), Fn(fn ? fn : nop) {}
TypeLookupError &operator=(const TypeLookupError &other) {
if (this == &other)
return *this;
Fn(Context, Command::DestroyContext, nullptr);
Fn = other.Fn;
Context = Fn(Context, Command::CopyContext, nullptr);
return *this;
}
/// Construct a TypeLookupError that just returns a constant C string.
TypeLookupError(const char *str)
: TypeLookupError([=] { return const_cast<char *>(str); }) {}
/// Construct a TypeLookupError that creates a string using asprintf. The passed-in
/// format string and arguments are passed directly to swift_asprintf when
/// the string is requested. The arguments are captured and the string is only
/// formatted when needed.
template <typename... Args>
TypeLookupError(const char *fmt, Args... args)
: TypeLookupError([=] {
char *str;
swift_asprintf(&str, fmt, args...);
return str;
}) {}
/// Construct a TypeLookupError that wraps a function returning a string. The
/// passed-in function can return either a `std::string` or `char *`. If it
/// returns `char *` then the string will be destroyed with `free()`.
template <typename F> TypeLookupError(const F &fn) {
Context = new F(fn);
Fn = [](void *context, Command command, void *param) -> void * {
auto castContext = reinterpret_cast<F *>(context);
switch (command) {
case Command::CopyErrorString: {
return TypeLookupError::getCString((*castContext)());
}
case Command::DestroyErrorString:
free(param);
return nullptr;
case Command::CopyContext:
return new F(*castContext);
case Command::DestroyContext:
delete castContext;
return nullptr;
}
};
}
/// Get the error string from the error value. The value must be passed to
/// `freeErrorString` when done. (Unless you're just calling a `fatalError`
/// in which case there's no point.)
char *copyErrorString() {
return reinterpret_cast<char *>(
Fn(Context, Command::CopyErrorString, nullptr));
}
/// Free an error string previously obtained from `copyErrorString`.
void freeErrorString(char *str) {
Fn(Context, Command::DestroyErrorString, str);
}
};
/// A value that's either a `TypeLookupError` or some parameterized type value `T`. A
/// convenience wrapper around `TaggedUnion<T, TypeLookupError>`.
template <typename T> class TypeLookupErrorOr {
TaggedUnion<T, TypeLookupError> Value;
public:
TypeLookupErrorOr(const T &t) : Value(t) {
if (!t)
Value = TypeLookupError("unknown error");
}
TypeLookupErrorOr(const TypeLookupError &te) : Value(te) {}
T getType() {
if (auto *ptr = Value.template dyn_cast<T>())
return *ptr;
return T();
}
TypeLookupError *getError() {
return Value.template dyn_cast<TypeLookupError>();
}
bool isError() { return getError() != nullptr; }
};
} // namespace swift
#endif // SWIFT_DEMANGLING_TypeLookupError_H

View File

@@ -618,8 +618,8 @@ public:
}), }),
OpaqueUnderlyingTypeReader( OpaqueUnderlyingTypeReader(
[&reader](uint64_t descriptorAddr, unsigned ordinal) -> const TypeRef* { [&reader](uint64_t descriptorAddr, unsigned ordinal) -> const TypeRef* {
return reader.readUnderlyingTypeForOpaqueTypeDescriptor(descriptorAddr, return reader.readUnderlyingTypeForOpaqueTypeDescriptor(
ordinal); descriptorAddr, ordinal).getType();
}) })
{} {}

View File

@@ -463,7 +463,8 @@ public:
} }
/// Given a demangle tree, attempt to turn it into a type. /// Given a demangle tree, attempt to turn it into a type.
BuiltType decodeMangledType(NodePointer Node) { TypeLookupErrorOr<typename BuilderType::BuiltType>
decodeMangledType(NodePointer Node) {
return swift::Demangle::decodeMangledType(Builder, Node); return swift::Demangle::decodeMangledType(Builder, Node);
} }
@@ -925,8 +926,8 @@ public:
swift_runtime_unreachable("Unhandled MetadataKind in switch"); swift_runtime_unreachable("Unhandled MetadataKind in switch");
} }
BuiltType readTypeFromMangledName(const char *MangledTypeName, TypeLookupErrorOr<typename BuilderType::BuiltType>
size_t Length) { readTypeFromMangledName(const char *MangledTypeName, size_t Length) {
Demangle::Demangler Dem; Demangle::Demangler Dem;
Demangle::NodePointer Demangled = Demangle::NodePointer Demangled =
Dem.demangleSymbol(StringRef(MangledTypeName, Length)); Dem.demangleSymbol(StringRef(MangledTypeName, Length));
@@ -1183,14 +1184,14 @@ public:
MangledNameKind::Type, Dem); MangledNameKind::Type, Dem);
} }
BuiltType TypeLookupErrorOr<typename BuilderType::BuiltType>
readUnderlyingTypeForOpaqueTypeDescriptor(StoredPointer contextAddr, readUnderlyingTypeForOpaqueTypeDescriptor(StoredPointer contextAddr,
unsigned ordinal) { unsigned ordinal) {
Demangle::Demangler Dem; Demangle::Demangler Dem;
auto node = readUnderlyingTypeManglingForOpaqueTypeDescriptor(contextAddr, auto node = readUnderlyingTypeManglingForOpaqueTypeDescriptor(contextAddr,
ordinal, Dem); ordinal, Dem);
if (!node) if (!node)
return BuiltType(); return TypeLookupError("Failed to read type mangling for descriptor.");
return decodeMangledType(node); return decodeMangledType(node);
} }

View File

@@ -21,7 +21,6 @@
#include "swift/Runtime/Unreachable.h" #include "swift/Runtime/Unreachable.h"
#include <atomic> #include <atomic>
#include <cstdarg> #include <cstdarg>
#include <cstdio>
#include <functional> #include <functional>
#include <stdint.h> #include <stdint.h>
@@ -248,39 +247,6 @@ std::atomic<const void *> _swift_debug_metadataAllocationBacktraceList;
SWIFT_RUNTIME_STDLIB_SPI SWIFT_RUNTIME_STDLIB_SPI
const void * const _swift_debug_protocolConformanceStatePointer; const void * const _swift_debug_protocolConformanceStatePointer;
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
inline static int swift_asprintf(char **strp, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
#if defined(_WIN32)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
int len = _vscprintf(fmt, args);
#pragma GCC diagnostic pop
if (len < 0) {
va_end(args);
return -1;
}
char *buffer = static_cast<char *>(malloc(len + 1));
if (!buffer) {
va_end(args);
return -1;
}
int result = vsprintf(buffer, fmt, args);
if (result < 0) {
va_end(args);
free(buffer);
return -1;
}
*strp = buffer;
#else
int result = vasprintf(strp, fmt, args);
#endif
va_end(args);
return result;
}
// namespace swift // namespace swift
} }

View File

@@ -16,8 +16,47 @@
#ifndef SWIFT_RUNTIME_PORTABILITY_H #ifndef SWIFT_RUNTIME_PORTABILITY_H
#define SWIFT_RUNTIME_PORTABILITY_H #define SWIFT_RUNTIME_PORTABILITY_H
#include <cstdarg>
#include <cstddef> #include <cstddef>
#include <cstdio>
#include <cstdlib>
size_t _swift_strlcpy(char *dst, const char *src, size_t maxlen); size_t _swift_strlcpy(char *dst, const char *src, size_t maxlen);
// Skip the attribute when included by the compiler.
#ifdef SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
#endif
inline static int swift_asprintf(char **strp, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
#if defined(_WIN32)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
int len = _vscprintf(fmt, args);
#pragma GCC diagnostic pop
if (len < 0) {
va_end(args);
return -1;
}
char *buffer = static_cast<char *>(malloc(len + 1));
if (!buffer) {
va_end(args);
return -1;
}
int result = vsprintf(buffer, fmt, args);
if (result < 0) {
va_end(args);
free(buffer);
return -1;
}
*strp = buffer;
#else
int result = vasprintf(strp, fmt, args);
#endif
va_end(args);
return result;
}
#endif #endif

View File

@@ -44,7 +44,7 @@ Type swift::Demangle::getTypeForMangling(ASTContext &ctx,
return Type(); return Type();
ASTBuilder builder(ctx); ASTBuilder builder(ctx);
return swift::Demangle::decodeMangledType(builder, node); return swift::Demangle::decodeMangledType(builder, node).getType();
} }
TypeDecl *swift::Demangle::getTypeDeclForMangling(ASTContext &ctx, TypeDecl *swift::Demangle::getTypeDeclForMangling(ASTContext &ctx,
@@ -847,8 +847,8 @@ CanGenericSignature ASTBuilder::demangleGenericSignature(
if (child->getNumChildren() != 2) if (child->getNumChildren() != 2)
return CanGenericSignature(); return CanGenericSignature();
auto subjectType = swift::Demangle::decodeMangledType( auto subjectType =
*this, child->getChild(0)); swift::Demangle::decodeMangledType(*this, child->getChild(0)).getType();
if (!subjectType) if (!subjectType)
return CanGenericSignature(); return CanGenericSignature();
@@ -857,8 +857,9 @@ CanGenericSignature ASTBuilder::demangleGenericSignature(
Demangle::Node::Kind::DependentGenericConformanceRequirement || Demangle::Node::Kind::DependentGenericConformanceRequirement ||
child->getKind() == child->getKind() ==
Demangle::Node::Kind::DependentGenericSameTypeRequirement) { Demangle::Node::Kind::DependentGenericSameTypeRequirement) {
constraintType = swift::Demangle::decodeMangledType( constraintType =
*this, child->getChild(1)); swift::Demangle::decodeMangledType(*this, child->getChild(1))
.getType();
if (!constraintType) if (!constraintType)
return CanGenericSignature(); return CanGenericSignature();
} }

View File

@@ -632,9 +632,10 @@ public:
SubstitutionMap substitutions, SubstitutionMap substitutions,
unsigned ordinal) override { unsigned ordinal) override {
auto underlyingType = Reader auto underlyingType = Reader
.readUnderlyingTypeForOpaqueTypeDescriptor(opaqueDescriptor.getAddressData(), .readUnderlyingTypeForOpaqueTypeDescriptor(
ordinal); opaqueDescriptor.getAddressData(), ordinal)
.getType();
if (!underlyingType) if (!underlyingType)
return getFailure<Type>(); return getFailure<Type>();

View File

@@ -135,7 +135,8 @@ lookupTypeWitness(const std::string &MangledTypeName,
auto SubstitutedTypeName = readTypeRef(AssocTy, auto SubstitutedTypeName = readTypeRef(AssocTy,
AssocTy->SubstitutedTypeName); AssocTy->SubstitutedTypeName);
auto Demangled = demangleTypeRef(SubstitutedTypeName); auto Demangled = demangleTypeRef(SubstitutedTypeName);
auto *TypeWitness = swift::Demangle::decodeMangledType(*this, Demangled); auto *TypeWitness =
swift::Demangle::decodeMangledType(*this, Demangled).getType();
AssociatedTypeCache.insert(std::make_pair(key, TypeWitness)); AssociatedTypeCache.insert(std::make_pair(key, TypeWitness));
return TypeWitness; return TypeWitness;
@@ -155,7 +156,8 @@ lookupSuperclass(const TypeRef *TR) {
return nullptr; return nullptr;
auto Demangled = demangleTypeRef(readTypeRef(FD, FD->Superclass)); auto Demangled = demangleTypeRef(readTypeRef(FD, FD->Superclass));
auto Unsubstituted = swift::Demangle::decodeMangledType(*this, Demangled); auto Unsubstituted =
swift::Demangle::decodeMangledType(*this, Demangled).getType();
if (!Unsubstituted) if (!Unsubstituted)
return nullptr; return nullptr;
@@ -226,7 +228,8 @@ bool TypeRefBuilder::getFieldTypeRefs(
} }
auto Demangled = demangleTypeRef(readTypeRef(Field,Field->MangledTypeName)); auto Demangled = demangleTypeRef(readTypeRef(Field,Field->MangledTypeName));
auto Unsubstituted = swift::Demangle::decodeMangledType(*this, Demangled); auto Unsubstituted =
swift::Demangle::decodeMangledType(*this, Demangled).getType();
if (!Unsubstituted) if (!Unsubstituted)
return false; return false;
@@ -304,7 +307,7 @@ TypeRefBuilder::getClosureContextInfo(RemoteRef<CaptureDescriptor> CD) {
if (CR->hasMangledTypeName()) { if (CR->hasMangledTypeName()) {
auto MangledName = readTypeRef(CR, CR->MangledTypeName); auto MangledName = readTypeRef(CR, CR->MangledTypeName);
auto DemangleTree = demangleTypeRef(MangledName); auto DemangleTree = demangleTypeRef(MangledName);
TR = swift::Demangle::decodeMangledType(*this, DemangleTree); TR = swift::Demangle::decodeMangledType(*this, DemangleTree).getType();
} }
Info.CaptureTypes.push_back(TR); Info.CaptureTypes.push_back(TR);
} }
@@ -316,7 +319,7 @@ TypeRefBuilder::getClosureContextInfo(RemoteRef<CaptureDescriptor> CD) {
if (MSR->hasMangledTypeName()) { if (MSR->hasMangledTypeName()) {
auto MangledName = readTypeRef(MSR, MSR->MangledTypeName); auto MangledName = readTypeRef(MSR, MSR->MangledTypeName);
auto DemangleTree = demangleTypeRef(MangledName); auto DemangleTree = demangleTypeRef(MangledName);
TR = swift::Demangle::decodeMangledType(*this, DemangleTree); TR = swift::Demangle::decodeMangledType(*this, DemangleTree).getType();
} }
const MetadataSource *MS = nullptr; const MetadataSource *MS = nullptr;
@@ -344,12 +347,17 @@ TypeRefBuilder::dumpTypeRef(RemoteRef<char> MangledName,
auto DemangleTree = demangleTypeRef(MangledName); auto DemangleTree = demangleTypeRef(MangledName);
auto TypeName = nodeToString(DemangleTree); auto TypeName = nodeToString(DemangleTree);
fprintf(file, "%s\n", TypeName.c_str()); fprintf(file, "%s\n", TypeName.c_str());
auto TR = swift::Demangle::decodeMangledType(*this, DemangleTree); auto Result = swift::Demangle::decodeMangledType(*this, DemangleTree);
if (!TR) { if (Result.isError()) {
auto *Error = Result.getError();
char *ErrorStr = Error->copyErrorString();
auto str = getTypeRefString(MangledName); auto str = getTypeRefString(MangledName);
fprintf(file, "!!! Invalid typeref: %s\n", std::string(str.begin(), str.end()).c_str()); fprintf(file, "!!! Invalid typeref: %s - %s\n",
std::string(str.begin(), str.end()).c_str(), ErrorStr);
Error->freeErrorString(ErrorStr);
return; return;
} }
auto TR = Result.getType();
TR->dump(file); TR->dump(file);
fprintf(file, "\n"); fprintf(file, "\n");
} }

View File

@@ -298,7 +298,7 @@ swift_reflection_typeRefForMangledTypeName(SwiftReflectionContextRef ContextRef,
const char *MangledTypeName, const char *MangledTypeName,
uint64_t Length) { uint64_t Length) {
auto Context = ContextRef->nativeContext; auto Context = ContextRef->nativeContext;
auto TR = Context->readTypeFromMangledName(MangledTypeName, Length); auto TR = Context->readTypeFromMangledName(MangledTypeName, Length).getType();
return reinterpret_cast<swift_typeref_t>(TR); return reinterpret_cast<swift_typeref_t>(TR);
} }

View File

@@ -138,7 +138,7 @@ OVERRIDE_KEYPATH(getKeyPath, const HeapObject *, , , swift::,
(const void *pattern, const void *arguments), (const void *pattern, const void *arguments),
(pattern, arguments)) (pattern, arguments))
OVERRIDE_METADATALOOKUP(getTypeByMangledNode, TypeInfo, , SWIFT_CC(swift), swift::, OVERRIDE_METADATALOOKUP(getTypeByMangledNode, TypeLookupErrorOr<TypeInfo>, , SWIFT_CC(swift), swift::,
(MetadataRequest request, (MetadataRequest request,
Demangler &demangler, Demangler &demangler,
Demangle::NodePointer node, Demangle::NodePointer node,
@@ -146,7 +146,7 @@ OVERRIDE_METADATALOOKUP(getTypeByMangledNode, TypeInfo, , SWIFT_CC(swift), swift
SubstGenericParameterFn substGenericParam, SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable), SubstDependentWitnessTableFn substWitnessTable),
(request, demangler, node, arguments, substGenericParam, substWitnessTable)) (request, demangler, node, arguments, substGenericParam, substWitnessTable))
OVERRIDE_METADATALOOKUP(getTypeByMangledName, TypeInfo, , SWIFT_CC(swift), swift::, OVERRIDE_METADATALOOKUP(getTypeByMangledName, TypeLookupErrorOr<TypeInfo>, , SWIFT_CC(swift), swift::,
(MetadataRequest request, (MetadataRequest request,
StringRef typeName, StringRef typeName,
const void * const *arguments, const void * const *arguments,

View File

@@ -2916,24 +2916,22 @@ getSuperclassMetadata(MetadataRequest request, const ClassMetadata *self) {
StringRef superclassName = StringRef superclassName =
Demangle::makeSymbolicMangledNameStringRef(superclassNameBase); Demangle::makeSymbolicMangledNameStringRef(superclassNameBase);
SubstGenericParametersFromMetadata substitutions(self); SubstGenericParametersFromMetadata substitutions(self);
MetadataResponse response = auto result = swift_getTypeByMangledName(
swift_getTypeByMangledName(request, superclassName, request, superclassName, substitutions.getGenericArgs(),
substitutions.getGenericArgs(),
[&substitutions](unsigned depth, unsigned index) { [&substitutions](unsigned depth, unsigned index) {
return substitutions.getMetadata(depth, index); return substitutions.getMetadata(depth, index);
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}).getResponse(); });
auto superclass = response.Value; if (auto *error = result.getError()) {
if (!superclass) { fatalError(
fatalError(0, 0, "failed to demangle superclass of %s from mangled name '%s': %s\n",
"failed to demangle superclass of %s from mangled name '%s'\n", self->getDescription()->Name.get(), superclassName.str().c_str(),
self->getDescription()->Name.get(), error->copyErrorString());
superclassName.str().c_str());
} }
return response; return result.getType().getResponse();
} else { } else {
return MetadataResponse(); return MetadataResponse();
} }
@@ -4928,12 +4926,12 @@ swift_getAssociatedTypeWitnessSlowImpl(
Demangle::makeSymbolicMangledNameStringRef(mangledNameBase); Demangle::makeSymbolicMangledNameStringRef(mangledNameBase);
// Demangle the associated type. // Demangle the associated type.
MetadataResponse response; TypeLookupErrorOr<TypeInfo> result = TypeInfo();
if (inProtocolContext) { if (inProtocolContext) {
// The protocol's Self is the only generic parameter that can occur in the // The protocol's Self is the only generic parameter that can occur in the
// type. // type.
response = result = swift_getTypeByMangledName(
swift_getTypeByMangledName(request, mangledName, nullptr, request, mangledName, nullptr,
[conformingType](unsigned depth, unsigned index) -> const Metadata * { [conformingType](unsigned depth, unsigned index) -> const Metadata * {
if (depth == 0 && index == 0) if (depth == 0 && index == 0)
return conformingType; return conformingType;
@@ -4950,7 +4948,7 @@ swift_getAssociatedTypeWitnessSlowImpl(
return swift_getAssociatedConformanceWitness(wtable, conformingType, return swift_getAssociatedConformanceWitness(wtable, conformingType,
type, reqBase, type, reqBase,
dependentDescriptor); dependentDescriptor);
}).getResponse(); });
} else { } else {
// The generic parameters in the associated type name are those of the // The generic parameters in the associated type name are those of the
// conforming type. // conforming type.
@@ -4960,29 +4958,30 @@ swift_getAssociatedTypeWitnessSlowImpl(
auto originalConformingType = findConformingSuperclass(conformingType, auto originalConformingType = findConformingSuperclass(conformingType,
conformance); conformance);
SubstGenericParametersFromMetadata substitutions(originalConformingType); SubstGenericParametersFromMetadata substitutions(originalConformingType);
response = swift_getTypeByMangledName(request, mangledName, result = swift_getTypeByMangledName(
substitutions.getGenericArgs(), request, mangledName, substitutions.getGenericArgs(),
[&substitutions](unsigned depth, unsigned index) { [&substitutions](unsigned depth, unsigned index) {
return substitutions.getMetadata(depth, index); return substitutions.getMetadata(depth, index);
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}).getResponse(); });
} }
auto *error = result.getError();
MetadataResponse response = result.getType().getResponse();
auto assocTypeMetadata = response.Value; auto assocTypeMetadata = response.Value;
if (error || !assocTypeMetadata) {
if (!assocTypeMetadata) { const char *errStr = error ? error->copyErrorString()
: "NULL metadata but no error was provided";
auto conformingTypeNameInfo = swift_getTypeName(conformingType, true); auto conformingTypeNameInfo = swift_getTypeName(conformingType, true);
StringRef conformingTypeName(conformingTypeNameInfo.data, StringRef conformingTypeName(conformingTypeNameInfo.data,
conformingTypeNameInfo.length); conformingTypeNameInfo.length);
StringRef assocTypeName = findAssociatedTypeName(protocol, assocType); StringRef assocTypeName = findAssociatedTypeName(protocol, assocType);
fatalError(0, fatalError(0,
"failed to demangle witness for associated type '%s' in " "failed to demangle witness for associated type '%s' in "
"conformance '%s: %s' from mangled name '%s'\n", "conformance '%s: %s' from mangled name '%s' - %s\n",
assocTypeName.str().c_str(), assocTypeName.str().c_str(), conformingTypeName.str().c_str(),
conformingTypeName.str().c_str(), protocol->Name.get(), mangledName.str().c_str(), errStr);
protocol->Name.get(),
mangledName.str().c_str());
} }
assert((uintptr_t(assocTypeMetadata) & assert((uintptr_t(assocTypeMetadata) &
@@ -5935,7 +5934,7 @@ void swift::verifyMangledNameRoundtrip(const Metadata *metadata) {
nullptr, nullptr,
[](unsigned, unsigned){ return nullptr; }, [](unsigned, unsigned){ return nullptr; },
[](const Metadata *, unsigned) { return nullptr; }) [](const Metadata *, unsigned) { return nullptr; })
.getMetadata(); .getType().getMetadata();
if (metadata != result) if (metadata != result)
swift::warning(RuntimeErrorFlagNone, swift::warning(RuntimeErrorFlagNone,
"Metadata mangled name failed to roundtrip: %p -> %s -> %p\n", "Metadata mangled name failed to roundtrip: %p -> %s -> %p\n",

View File

@@ -961,13 +961,54 @@ getLocalGenericParams(const ContextDescriptor *context) {
return genericContext->getGenericParams().slice(startParamIndex); return genericContext->getGenericParams().slice(startParamIndex);
} }
static bool static llvm::Optional<TypeLookupError>
_gatherGenericParameters(const ContextDescriptor *context, _gatherGenericParameters(const ContextDescriptor *context,
llvm::ArrayRef<const Metadata *> genericArgs, llvm::ArrayRef<const Metadata *> genericArgs,
const Metadata *parent, const Metadata *parent,
llvm::SmallVectorImpl<unsigned> &genericParamCounts, llvm::SmallVectorImpl<unsigned> &genericParamCounts,
llvm::SmallVectorImpl<const void *> &allGenericArgsVec, llvm::SmallVectorImpl<const void *> &allGenericArgsVec,
Demangler &demangler) { Demangler &demangler) {
auto makeCommonErrorStringGetter = [&] {
auto metadataVector = genericArgs.vec();
return [=] {
std::string str;
str += "_gatherGenericParameters: context: ";
SymbolInfo contextInfo;
if (lookupSymbol(context, &contextInfo)) {
str += contextInfo.symbolName.get();
str += " ";
}
char *contextStr;
swift_asprintf(&contextStr, "%p", context);
str += contextStr;
free(contextStr);
str += " <";
bool first = true;
for (const Metadata *metadata : genericArgs) {
if (!first)
str += ", ";
first = false;
str += nameForMetadata(metadata);
}
str += "> ";
str += "parent: ";
if (parent)
str += nameForMetadata(parent);
else
str += "<null>";
str += " - ";
return str;
};
};
// Figure out the various levels of generic parameters we have in // Figure out the various levels of generic parameters we have in
// this type. // this type.
(void)_gatherGenericParameterCounts(context, (void)_gatherGenericParameterCounts(context,
@@ -981,7 +1022,15 @@ _gatherGenericParameters(const ContextDescriptor *context,
} else if (genericArgs.size() == numTotalGenericParams && !parent) { } else if (genericArgs.size() == numTotalGenericParams && !parent) {
// Okay: genericArgs is the complete set of generic arguments. // Okay: genericArgs is the complete set of generic arguments.
} else { } else {
return false; auto commonString = makeCommonErrorStringGetter();
auto genericArgsSize = genericArgs.size();
return TypeLookupError([=] {
return commonString() + "incorrect number of generic args (" +
std::to_string(genericArgsSize) + "), " +
std::to_string(getLocalGenericParams(context).size()) +
" local params, " + std::to_string(numTotalGenericParams) +
" total params";
});
} }
// If there are generic parameters at any level, check the generic // If there are generic parameters at any level, check the generic
@@ -1008,15 +1057,30 @@ _gatherGenericParameters(const ContextDescriptor *context,
auto genericParams = generics->getGenericParams(); auto genericParams = generics->getGenericParams();
unsigned n = genericParams.size(); unsigned n = genericParams.size();
if (allGenericArgs.size() != n) { if (allGenericArgs.size() != n) {
return false; auto commonString = makeCommonErrorStringGetter();
auto argsVecSize = allGenericArgsVec.size();
return TypeLookupError([=] {
return commonString() + "have " + std::to_string(argsVecSize) +
"generic args, expected " + std::to_string(n);
});
} }
for (unsigned i = 0; i != n; ++i) { for (unsigned i = 0; i != n; ++i) {
const auto &param = genericParams[i]; const auto &param = genericParams[i];
if (param.getKind() != GenericParamKind::Type) if (param.getKind() != GenericParamKind::Type) {
return false; auto commonString = makeCommonErrorStringGetter();
if (param.hasExtraArgument()) return TypeLookupError([=] {
return false; return commonString() + "param " + std::to_string(i) +
" has unexpected kind " +
std::to_string(static_cast<uint8_t>(param.getKind()));
});
}
if (param.hasExtraArgument()) {
auto commonString = makeCommonErrorStringGetter();
return TypeLookupError([=] {
return commonString() + "param " + std::to_string(i) +
"has extra argument";
});
}
if (param.hasKeyArgument()) if (param.hasKeyArgument())
allGenericArgsVec.push_back(allGenericArgs[i]); allGenericArgsVec.push_back(allGenericArgs[i]);
} }
@@ -1028,26 +1092,33 @@ _gatherGenericParameters(const ContextDescriptor *context,
// any extra arguments we need for the instantiation function. // any extra arguments we need for the instantiation function.
SubstGenericParametersFromWrittenArgs substitutions(allGenericArgs, SubstGenericParametersFromWrittenArgs substitutions(allGenericArgs,
genericParamCounts); genericParamCounts);
bool failed = auto error = _checkGenericRequirements(
_checkGenericRequirements(generics->getGenericRequirements(), generics->getGenericRequirements(), allGenericArgsVec,
allGenericArgsVec,
[&substitutions](unsigned depth, unsigned index) { [&substitutions](unsigned depth, unsigned index) {
return substitutions.getMetadata(depth, index); return substitutions.getMetadata(depth, index);
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}); });
if (failed) if (error)
return false; return *error;
// If we still have the wrong number of generic arguments, this is // If we still have the wrong number of generic arguments, this is
// some kind of metadata mismatch. // some kind of metadata mismatch.
if (generics->getGenericContextHeader().getNumArguments() != if (generics->getGenericContextHeader().getNumArguments() !=
allGenericArgsVec.size()) allGenericArgsVec.size()) {
return false; auto commonString = makeCommonErrorStringGetter();
auto argsVecSize = allGenericArgsVec.size();
return TypeLookupError([=] {
return commonString() + "generic argument count mismatch, expected " +
std::to_string(
generics->getGenericContextHeader().getNumArguments()) +
", have " + std::to_string(argsVecSize);
});
}
} }
return true; return llvm::None;
} }
namespace { namespace {
@@ -1175,7 +1246,7 @@ public:
Demangle::NodeFactory &getNodeFactory() { return demangler; } Demangle::NodeFactory &getNodeFactory() { return demangler; }
BuiltType TypeLookupErrorOr<BuiltType>
resolveOpaqueType(NodePointer opaqueDecl, resolveOpaqueType(NodePointer opaqueDecl,
llvm::ArrayRef<llvm::ArrayRef<BuiltType>> genericArgs, llvm::ArrayRef<llvm::ArrayRef<BuiltType>> genericArgs,
unsigned ordinal) { unsigned ordinal) {
@@ -1193,12 +1264,10 @@ public:
llvm::SmallVector<unsigned, 8> genericParamCounts; llvm::SmallVector<unsigned, 8> genericParamCounts;
llvm::SmallVector<const void *, 8> allGenericArgsVec; llvm::SmallVector<const void *, 8> allGenericArgsVec;
if (!_gatherGenericParameters(outerContext, if (auto error = _gatherGenericParameters(
allGenericArgs, outerContext, allGenericArgs, BuiltType(), /* no parent */
BuiltType(), /* no parent */ genericParamCounts, allGenericArgsVec, demangler))
genericParamCounts, allGenericArgsVec, return *error;
demangler))
return BuiltType();
auto mangledName = descriptor->getUnderlyingTypeArgument(ordinal); auto mangledName = descriptor->getUnderlyingTypeArgument(ordinal);
SubstGenericParametersFromMetadata substitutions(descriptor, SubstGenericParametersFromMetadata substitutions(descriptor,
@@ -1210,7 +1279,7 @@ public:
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}).getMetadata(); }).getType().getMetadata();
} }
BuiltTypeDecl createTypeDecl(NodePointer node, BuiltTypeDecl createTypeDecl(NodePointer node,
@@ -1245,8 +1314,9 @@ public:
return ProtocolDescriptorRef(); return ProtocolDescriptorRef();
#endif #endif
} }
BuiltType createObjCClassType(const std::string &mangledName) const { TypeLookupErrorOr<BuiltType>
createObjCClassType(const std::string &mangledName) const {
#if SWIFT_OBJC_INTEROP #if SWIFT_OBJC_INTEROP
auto objcClass = objc_getClass(mangledName.c_str()); auto objcClass = objc_getClass(mangledName.c_str());
return swift_getObjCClassMetadata((const ClassMetadata *)objcClass); return swift_getObjCClassMetadata((const ClassMetadata *)objcClass);
@@ -1255,7 +1325,7 @@ public:
#endif #endif
} }
BuiltType TypeLookupErrorOr<BuiltType>
createBoundGenericObjCClassType(const std::string &mangledName, createBoundGenericObjCClassType(const std::string &mangledName,
llvm::ArrayRef<BuiltType> args) const { llvm::ArrayRef<BuiltType> args) const {
// Generic arguments of lightweight Objective-C generic classes are not // Generic arguments of lightweight Objective-C generic classes are not
@@ -1263,24 +1333,25 @@ public:
return createObjCClassType(mangledName); return createObjCClassType(mangledName);
} }
BuiltType createNominalType(BuiltTypeDecl metadataOrTypeDecl, TypeLookupErrorOr<BuiltType>
BuiltType parent) const { createNominalType(BuiltTypeDecl metadataOrTypeDecl, BuiltType parent) const {
// Treat nominal type creation the same way as generic type creation, // Treat nominal type creation the same way as generic type creation,
// but with no generic arguments at this level. // but with no generic arguments at this level.
return createBoundGenericType(metadataOrTypeDecl, { }, parent); return createBoundGenericType(metadataOrTypeDecl, { }, parent);
} }
BuiltType createTypeAliasType(BuiltTypeDecl typeAliasDecl, TypeLookupErrorOr<BuiltType> createTypeAliasType(BuiltTypeDecl typeAliasDecl,
BuiltType parent) const { BuiltType parent) const {
// We can't support sugared types here since we have no way to // We can't support sugared types here since we have no way to
// resolve the underlying type of the type alias. However, some // resolve the underlying type of the type alias. However, some
// CF types are mangled as type aliases. // CF types are mangled as type aliases.
return createNominalType(typeAliasDecl, parent); return createNominalType(typeAliasDecl, parent);
} }
BuiltType createBoundGenericType(BuiltTypeDecl anyTypeDecl, TypeLookupErrorOr<BuiltType>
llvm::ArrayRef<BuiltType> genericArgs, createBoundGenericType(BuiltTypeDecl anyTypeDecl,
BuiltType parent) const { llvm::ArrayRef<BuiltType> genericArgs,
BuiltType parent) const {
auto typeDecl = dyn_cast<TypeContextDescriptor>(anyTypeDecl); auto typeDecl = dyn_cast<TypeContextDescriptor>(anyTypeDecl);
if (!typeDecl) { if (!typeDecl) {
if (auto protocol = dyn_cast<ProtocolDescriptor>(anyTypeDecl)) if (auto protocol = dyn_cast<ProtocolDescriptor>(anyTypeDecl))
@@ -1294,13 +1365,11 @@ public:
llvm::SmallVector<unsigned, 8> genericParamCounts; llvm::SmallVector<unsigned, 8> genericParamCounts;
llvm::SmallVector<const void *, 8> allGenericArgsVec; llvm::SmallVector<const void *, 8> allGenericArgsVec;
if (!_gatherGenericParameters(typeDecl, if (auto error = _gatherGenericParameters(typeDecl, genericArgs, parent,
genericArgs, genericParamCounts,
parent, allGenericArgsVec, demangler))
genericParamCounts, allGenericArgsVec, return *error;
demangler))
return BuiltType();
// Call the access function. // Call the access function.
auto accessFunction = typeDecl->getAccessFunction(); auto accessFunction = typeDecl->getAccessFunction();
if (!accessFunction) return BuiltType(); if (!accessFunction) return BuiltType();
@@ -1308,8 +1377,8 @@ public:
return accessFunction(MetadataState::Abstract, allGenericArgsVec).Value; return accessFunction(MetadataState::Abstract, allGenericArgsVec).Value;
} }
BuiltType createBuiltinType(StringRef builtinName, TypeLookupErrorOr<BuiltType> createBuiltinType(StringRef builtinName,
StringRef mangledName) const { StringRef mangledName) const {
#define BUILTIN_TYPE(Symbol, _) \ #define BUILTIN_TYPE(Symbol, _) \
if (mangledName.equals(#Symbol)) \ if (mangledName.equals(#Symbol)) \
return &METADATA_SYM(Symbol).base; return &METADATA_SYM(Symbol).base;
@@ -1317,19 +1386,19 @@ public:
return BuiltType(); return BuiltType();
} }
BuiltType createMetatypeType( TypeLookupErrorOr<BuiltType> createMetatypeType(
BuiltType instance, BuiltType instance,
llvm::Optional<Demangle::ImplMetatypeRepresentation> repr = None) const { llvm::Optional<Demangle::ImplMetatypeRepresentation> repr = None) const {
return swift_getMetatypeMetadata(instance); return swift_getMetatypeMetadata(instance);
} }
BuiltType createExistentialMetatypeType( TypeLookupErrorOr<BuiltType> createExistentialMetatypeType(
BuiltType instance, BuiltType instance,
llvm::Optional<Demangle::ImplMetatypeRepresentation> repr = None) const { llvm::Optional<Demangle::ImplMetatypeRepresentation> repr = None) const {
return swift_getExistentialMetatypeMetadata(instance); return swift_getExistentialMetatypeMetadata(instance);
} }
BuiltType TypeLookupErrorOr<BuiltType>
createProtocolCompositionType(llvm::ArrayRef<BuiltProtocolDecl> protocols, createProtocolCompositionType(llvm::ArrayRef<BuiltProtocolDecl> protocols,
BuiltType superclass, bool isClassBound) const { BuiltType superclass, bool isClassBound) const {
// Determine whether we have a class bound. // Determine whether we have a class bound.
@@ -1349,13 +1418,13 @@ public:
protocols.size(), protocols.data()); protocols.size(), protocols.data());
} }
BuiltType createDynamicSelfType(BuiltType selfType) const { TypeLookupErrorOr<BuiltType> createDynamicSelfType(BuiltType selfType) const {
// Free-standing mangled type strings should not contain DynamicSelfType. // Free-standing mangled type strings should not contain DynamicSelfType.
return BuiltType(); return BuiltType();
} }
BuiltType createGenericTypeParameterType(unsigned depth, TypeLookupErrorOr<BuiltType>
unsigned index) const { createGenericTypeParameterType(unsigned depth, unsigned index) const {
// Use the callback, when provided. // Use the callback, when provided.
if (substGenericParameter) if (substGenericParameter)
return substGenericParameter(depth, index); return substGenericParameter(depth, index);
@@ -1363,7 +1432,7 @@ public:
return BuiltType(); return BuiltType();
} }
BuiltType TypeLookupErrorOr<BuiltType>
createFunctionType(llvm::ArrayRef<Demangle::FunctionParam<BuiltType>> params, createFunctionType(llvm::ArrayRef<Demangle::FunctionParam<BuiltType>> params,
BuiltType result, FunctionTypeFlags flags) const { BuiltType result, FunctionTypeFlags flags) const {
llvm::SmallVector<BuiltType, 8> paramTypes; llvm::SmallVector<BuiltType, 8> paramTypes;
@@ -1386,7 +1455,7 @@ public:
result); result);
} }
BuiltType createImplFunctionType( TypeLookupErrorOr<BuiltType> createImplFunctionType(
Demangle::ImplParameterConvention calleeConvention, Demangle::ImplParameterConvention calleeConvention,
llvm::ArrayRef<Demangle::ImplFunctionParam<BuiltType>> params, llvm::ArrayRef<Demangle::ImplFunctionParam<BuiltType>> params,
llvm::ArrayRef<Demangle::ImplFunctionResult<BuiltType>> results, llvm::ArrayRef<Demangle::ImplFunctionResult<BuiltType>> results,
@@ -1396,8 +1465,9 @@ public:
return BuiltType(); return BuiltType();
} }
BuiltType createTupleType(llvm::ArrayRef<BuiltType> elements, TypeLookupErrorOr<BuiltType>
std::string labels) const { createTupleType(llvm::ArrayRef<BuiltType> elements,
std::string labels) const {
auto flags = TupleTypeFlags().withNumElements(elements.size()); auto flags = TupleTypeFlags().withNumElements(elements.size());
if (!labels.empty()) if (!labels.empty())
flags = flags.withNonConstantLabels(true); flags = flags.withNonConstantLabels(true);
@@ -1408,13 +1478,15 @@ public:
.Value; .Value;
} }
BuiltType createDependentMemberType(StringRef name, BuiltType base) const { TypeLookupErrorOr<BuiltType> createDependentMemberType(StringRef name,
BuiltType base) const {
// Should not have unresolved dependent member types here. // Should not have unresolved dependent member types here.
return BuiltType(); return BuiltType();
} }
BuiltType createDependentMemberType(StringRef name, BuiltType base, TypeLookupErrorOr<BuiltType>
BuiltProtocolDecl protocol) const { createDependentMemberType(StringRef name, BuiltType base,
BuiltProtocolDecl protocol) const {
#if SWIFT_OBJC_INTEROP #if SWIFT_OBJC_INTEROP
if (protocol.isObjC()) if (protocol.isObjC())
return BuiltType(); return BuiltType();
@@ -1438,14 +1510,14 @@ public:
*assocType).Value; *assocType).Value;
} }
#define REF_STORAGE(Name, ...) \ #define REF_STORAGE(Name, ...) \
BuiltType create##Name##StorageType(BuiltType base) { \ TypeLookupErrorOr<BuiltType> create##Name##StorageType(BuiltType base) { \
ReferenceOwnership.set##Name(); \ ReferenceOwnership.set##Name(); \
return base; \ return base; \
} }
#include "swift/AST/ReferenceStorage.def" #include "swift/AST/ReferenceStorage.def"
BuiltType createSILBoxType(BuiltType base) const { TypeLookupErrorOr<BuiltType> createSILBoxType(BuiltType base) const {
// FIXME: Implement. // FIXME: Implement.
return BuiltType(); return BuiltType();
} }
@@ -1454,22 +1526,23 @@ public:
return ReferenceOwnership; return ReferenceOwnership;
} }
BuiltType createOptionalType(BuiltType base) { TypeLookupErrorOr<BuiltType> createOptionalType(BuiltType base) {
// Mangled types for building metadata don't contain sugared types // Mangled types for building metadata don't contain sugared types
return BuiltType(); return BuiltType();
} }
BuiltType createArrayType(BuiltType base) { TypeLookupErrorOr<BuiltType> createArrayType(BuiltType base) {
// Mangled types for building metadata don't contain sugared types // Mangled types for building metadata don't contain sugared types
return BuiltType(); return BuiltType();
} }
BuiltType createDictionaryType(BuiltType key, BuiltType value) { TypeLookupErrorOr<BuiltType> createDictionaryType(BuiltType key,
BuiltType value) {
// Mangled types for building metadata don't contain sugared types // Mangled types for building metadata don't contain sugared types
return BuiltType(); return BuiltType();
} }
BuiltType createParenType(BuiltType base) { TypeLookupErrorOr<BuiltType> createParenType(BuiltType base) {
// Mangled types for building metadata don't contain sugared types // Mangled types for building metadata don't contain sugared types
return BuiltType(); return BuiltType();
} }
@@ -1478,13 +1551,12 @@ public:
} }
SWIFT_CC(swift) SWIFT_CC(swift)
static TypeInfo swift_getTypeByMangledNodeImpl( static TypeLookupErrorOr<TypeInfo>
MetadataRequest request, swift_getTypeByMangledNodeImpl(MetadataRequest request, Demangler &demangler,
Demangler &demangler, Demangle::NodePointer node,
Demangle::NodePointer node, const void *const *origArgumentVector,
const void * const *origArgumentVector, SubstGenericParameterFn substGenericParam,
SubstGenericParameterFn substGenericParam, SubstDependentWitnessTableFn substWitnessTable) {
SubstDependentWitnessTableFn substWitnessTable) {
// Simply call an accessor function if that's all we got. // Simply call an accessor function if that's all we got.
if (node->getKind() == Node::Kind::AccessorFunctionReference) { if (node->getKind() == Node::Kind::AccessorFunctionReference) {
// The accessor function is passed the pointer to the original argument // The accessor function is passed the pointer to the original argument
@@ -1504,22 +1576,23 @@ static TypeInfo swift_getTypeByMangledNodeImpl(
DecodedMetadataBuilder builder(demangler, substGenericParam, DecodedMetadataBuilder builder(demangler, substGenericParam,
substWitnessTable); substWitnessTable);
auto type = Demangle::decodeMangledType(builder, node); auto type = Demangle::decodeMangledType(builder, node);
if (!type) { if (type.isError()) {
return {MetadataResponse{nullptr, MetadataState::Complete}, return *type.getError();
TypeReferenceOwnership()}; }
if (!type.getType()) {
return TypeLookupError("NULL type but no error provided");
} }
return {swift_checkMetadataState(request, type), return TypeInfo{swift_checkMetadataState(request, type.getType()),
builder.getReferenceOwnership()}; builder.getReferenceOwnership()};
} }
SWIFT_CC(swift) SWIFT_CC(swift)
static TypeInfo swift_getTypeByMangledNameImpl( static TypeLookupErrorOr<TypeInfo>
MetadataRequest request, swift_getTypeByMangledNameImpl(MetadataRequest request, StringRef typeName,
StringRef typeName, const void *const *origArgumentVector,
const void * const *origArgumentVector, SubstGenericParameterFn substGenericParam,
SubstGenericParameterFn substGenericParam, SubstDependentWitnessTableFn substWitnessTable) {
SubstDependentWitnessTableFn substWitnessTable) {
DemanglerForRuntimeTypeResolution<StackAllocatedDemangler<2048>> demangler; DemanglerForRuntimeTypeResolution<StackAllocatedDemangler<2048>> demangler;
NodePointer node; NodePointer node;
@@ -1587,7 +1660,7 @@ swift_getTypeByMangledNameInEnvironment(
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}).getMetadata(); }).getType().getMetadata();
} }
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
@@ -1607,7 +1680,7 @@ swift_getTypeByMangledNameInEnvironmentInMetadataState(
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}).getMetadata(); }).getType().getMetadata();
} }
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
@@ -1626,7 +1699,7 @@ swift_getTypeByMangledNameInContext(
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}).getMetadata(); }).getType().getMetadata();
} }
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
@@ -1646,7 +1719,7 @@ swift_getTypeByMangledNameInContextInMetadataState(
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}).getMetadata(); }).getType().getMetadata();
} }
/// Demangle a mangled name, but don't allow symbolic references. /// Demangle a mangled name, but don't allow symbolic references.
@@ -1661,7 +1734,7 @@ swift_stdlib_getTypeByMangledNameUntrusted(const char *typeNameStart,
} }
return swift_getTypeByMangledName(MetadataState::Complete, typeName, nullptr, return swift_getTypeByMangledName(MetadataState::Complete, typeName, nullptr,
{}, {}).getMetadata(); {}, {}).getType().getMetadata();
} }
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
@@ -1680,7 +1753,7 @@ swift_getOpaqueTypeMetadata(MetadataRequest request,
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}).getResponse(); }).getType().getResponse();
} }
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
@@ -1735,7 +1808,7 @@ getObjCClassByMangledName(const char * _Nonnull typeName,
}, },
[&](const Metadata *type, unsigned index) { [&](const Metadata *type, unsigned index) {
return nullptr; return nullptr;
}).getMetadata(); }).getType().getMetadata();
} else { } else {
metadata = swift_stdlib_getTypeByMangledNameUntrusted(typeStr.data(), metadata = swift_stdlib_getTypeByMangledNameUntrusted(typeStr.data(),
typeStr.size()); typeStr.size());
@@ -2068,7 +2141,7 @@ void swift::gatherWrittenGenericArgs(
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}).getMetadata(); }).getType().getMetadata();
continue; continue;
} }

View File

@@ -17,7 +17,10 @@
#ifndef SWIFT_RUNTIME_PRIVATE_H #ifndef SWIFT_RUNTIME_PRIVATE_H
#define SWIFT_RUNTIME_PRIVATE_H #define SWIFT_RUNTIME_PRIVATE_H
#include <functional>
#include "swift/Demangling/Demangler.h" #include "swift/Demangling/Demangler.h"
#include "swift/Demangling/TypeLookupError.h"
#include "swift/Runtime/Config.h" #include "swift/Runtime/Config.h"
#include "swift/Runtime/Metadata.h" #include "swift/Runtime/Metadata.h"
@@ -77,6 +80,8 @@ public:
const Metadata *getMetadata() const { return Response.Value; } const Metadata *getMetadata() const { return Response.Value; }
MetadataResponse getResponse() const { return Response; } MetadataResponse getResponse() const { return Response; }
operator bool() const { return getMetadata(); }
#define REF_STORAGE(Name, ...) \ #define REF_STORAGE(Name, ...) \
bool is##Name() const { return ReferenceOwnership.is##Name(); } bool is##Name() const { return ReferenceOwnership.is##Name(); }
#include "swift/AST/ReferenceStorage.def" #include "swift/AST/ReferenceStorage.def"
@@ -369,7 +374,7 @@ public:
/// \p substWitnessTable Function that provides witness tables given a /// \p substWitnessTable Function that provides witness tables given a
/// particular dependent conformance index. /// particular dependent conformance index.
SWIFT_CC(swift) SWIFT_CC(swift)
TypeInfo swift_getTypeByMangledNode( TypeLookupErrorOr<TypeInfo> swift_getTypeByMangledNode(
MetadataRequest request, MetadataRequest request,
Demangler &demangler, Demangler &demangler,
Demangle::NodePointer node, Demangle::NodePointer node,
@@ -384,7 +389,7 @@ public:
/// \p substWitnessTable Function that provides witness tables given a /// \p substWitnessTable Function that provides witness tables given a
/// particular dependent conformance index. /// particular dependent conformance index.
SWIFT_CC(swift) SWIFT_CC(swift)
TypeInfo swift_getTypeByMangledName( TypeLookupErrorOr<TypeInfo> swift_getTypeByMangledName(
MetadataRequest request, MetadataRequest request,
StringRef typeName, StringRef typeName,
const void * const *arguments, const void * const *arguments,
@@ -447,12 +452,12 @@ public:
/// generic requirements (e.g., those that need to be /// generic requirements (e.g., those that need to be
/// passed to an instantiation function) will be added to this vector. /// passed to an instantiation function) will be added to this vector.
/// ///
/// \returns true if an error occurred, false otherwise. /// \returns the error if an error occurred, None otherwise.
bool _checkGenericRequirements( llvm::Optional<TypeLookupError> _checkGenericRequirements(
llvm::ArrayRef<GenericRequirementDescriptor> requirements, llvm::ArrayRef<GenericRequirementDescriptor> requirements,
llvm::SmallVectorImpl<const void *> &extraArguments, llvm::SmallVectorImpl<const void *> &extraArguments,
SubstGenericParameterFn substGenericParam, SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable); SubstDependentWitnessTableFn substWitnessTable);
/// A helper function which avoids performing a store if the destination /// A helper function which avoids performing a store if the destination
/// address already contains the source value. This is useful when /// address already contains the source value. This is useful when

View File

@@ -165,15 +165,16 @@ ProtocolConformanceDescriptor::getWitnessTable(const Metadata *type) const {
llvm::SmallVector<const void *, 8> conditionalArgs; llvm::SmallVector<const void *, 8> conditionalArgs;
if (hasConditionalRequirements()) { if (hasConditionalRequirements()) {
SubstGenericParametersFromMetadata substitutions(type); SubstGenericParametersFromMetadata substitutions(type);
bool failed = auto error = _checkGenericRequirements(
_checkGenericRequirements(getConditionalRequirements(), conditionalArgs, getConditionalRequirements(), conditionalArgs,
[&substitutions](unsigned depth, unsigned index) { [&substitutions](unsigned depth, unsigned index) {
return substitutions.getMetadata(depth, index); return substitutions.getMetadata(depth, index);
}, },
[&substitutions](const Metadata *type, unsigned index) { [&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index); return substitutions.getWitnessTable(type, index);
}); });
if (failed) return nullptr; if (error)
return nullptr;
} }
return swift_getWitnessTable(this, type, conditionalArgs.data()); return swift_getWitnessTable(this, type, conditionalArgs.data());
@@ -642,31 +643,36 @@ static bool isSubclass(const Metadata *subclass, const Metadata *superclass) {
}); });
} }
bool swift::_checkGenericRequirements( llvm::Optional<TypeLookupError> swift::_checkGenericRequirements(
llvm::ArrayRef<GenericRequirementDescriptor> requirements, llvm::ArrayRef<GenericRequirementDescriptor> requirements,
llvm::SmallVectorImpl<const void *> &extraArguments, llvm::SmallVectorImpl<const void *> &extraArguments,
SubstGenericParameterFn substGenericParam, SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable) { SubstDependentWitnessTableFn substWitnessTable) {
for (const auto &req : requirements) { for (const auto &req : requirements) {
// Make sure we understand the requirement we're dealing with. // Make sure we understand the requirement we're dealing with.
if (!req.hasKnownKind()) return true; if (!req.hasKnownKind())
return TypeLookupError("unknown kind");
// Resolve the subject generic parameter. // Resolve the subject generic parameter.
const Metadata *subjectType = auto result = swift_getTypeByMangledName(
swift_getTypeByMangledName(MetadataState::Abstract, MetadataState::Abstract, req.getParam(), extraArguments.data(),
req.getParam(), substGenericParam, substWitnessTable);
extraArguments.data(), if (result.getError())
substGenericParam, substWitnessTable).getMetadata(); return *result.getError();
if (!subjectType) const Metadata *subjectType = result.getType().getMetadata();
return true;
// Check the requirement. // Check the requirement.
switch (req.getKind()) { switch (req.getKind()) {
case GenericRequirementKind::Protocol: { case GenericRequirementKind::Protocol: {
const WitnessTable *witnessTable = nullptr; const WitnessTable *witnessTable = nullptr;
if (!_conformsToProtocol(nullptr, subjectType, req.getProtocol(), if (!_conformsToProtocol(nullptr, subjectType, req.getProtocol(),
&witnessTable)) &witnessTable)) {
return true; const char *protoName =
req.getProtocol() ? req.getProtocol().getName() : "<null>";
return TypeLookupError(
"subject type %s does not conform to protocol %s", req.getParam(),
protoName);
}
// If we need a witness table, add it. // If we need a witness table, add it.
if (req.getProtocol().needsWitnessTable()) { if (req.getProtocol().needsWitnessTable()) {
@@ -679,17 +685,19 @@ bool swift::_checkGenericRequirements(
case GenericRequirementKind::SameType: { case GenericRequirementKind::SameType: {
// Demangle the second type under the given substitutions. // Demangle the second type under the given substitutions.
auto otherType = auto result = swift_getTypeByMangledName(
swift_getTypeByMangledName(MetadataState::Abstract, MetadataState::Abstract, req.getMangledTypeName(),
req.getMangledTypeName(), extraArguments.data(), substGenericParam, substWitnessTable);
extraArguments.data(), if (result.getError())
substGenericParam, substWitnessTable).getMetadata(); return *result.getError();
if (!otherType) return true; auto otherType = result.getType().getMetadata();
assert(!req.getFlags().hasExtraArgument()); assert(!req.getFlags().hasExtraArgument());
// Check that the types are equivalent. // Check that the types are equivalent.
if (subjectType != otherType) return true; if (subjectType != otherType)
return TypeLookupError("subject type %s does not match %s",
req.getParam(), req.getMangledTypeName());
continue; continue;
} }
@@ -698,22 +706,24 @@ bool swift::_checkGenericRequirements(
switch (req.getLayout()) { switch (req.getLayout()) {
case GenericRequirementLayoutKind::Class: case GenericRequirementLayoutKind::Class:
if (!subjectType->satisfiesClassConstraint()) if (!subjectType->satisfiesClassConstraint())
return true; return TypeLookupError(
"subject type %s does not satisfy class constraint",
req.getParam());
continue; continue;
} }
// Unknown layout. // Unknown layout.
return true; return TypeLookupError("unknown layout kind %u", req.getLayout());
} }
case GenericRequirementKind::BaseClass: { case GenericRequirementKind::BaseClass: {
// Demangle the base type under the given substitutions. // Demangle the base type under the given substitutions.
auto baseType = auto result = swift_getTypeByMangledName(
swift_getTypeByMangledName(MetadataState::Abstract, MetadataState::Abstract, req.getMangledTypeName(),
req.getMangledTypeName(), extraArguments.data(), substGenericParam, substWitnessTable);
extraArguments.data(), if (result.getError())
substGenericParam, substWitnessTable).getMetadata(); return *result.getError();
if (!baseType) return true; auto baseType = result.getType().getMetadata();
// If the type which is constrained to a base class is an existential // If the type which is constrained to a base class is an existential
// type, and if that existential type includes a superclass constraint, // type, and if that existential type includes a superclass constraint,
@@ -725,7 +735,8 @@ bool swift::_checkGenericRequirements(
} }
if (!isSubclass(subjectType, baseType)) if (!isSubclass(subjectType, baseType))
return true; return TypeLookupError("%s is not subclass of %s", req.getParam(),
req.getMangledTypeName());
continue; continue;
} }
@@ -737,11 +748,12 @@ bool swift::_checkGenericRequirements(
} }
// Unknown generic requirement kind. // Unknown generic requirement kind.
return true; return TypeLookupError("unknown generic requirement kind %u",
req.getKind());
} }
// Success! // Success!
return false; return llvm::None;
} }
const Metadata *swift::findConformingSuperclass( const Metadata *swift::findConformingSuperclass(

View File

@@ -400,27 +400,33 @@ getFieldAt(const Metadata *base, unsigned index) {
auto typeName = field.getMangledTypeName(); auto typeName = field.getMangledTypeName();
SubstGenericParametersFromMetadata substitutions(base); SubstGenericParametersFromMetadata substitutions(base);
auto typeInfo = swift_getTypeByMangledName(MetadataState::Complete, auto result = swift_getTypeByMangledName(
typeName, MetadataState::Complete, typeName, substitutions.getGenericArgs(),
substitutions.getGenericArgs(), [&substitutions](unsigned depth, unsigned index) {
[&substitutions](unsigned depth, unsigned index) { return substitutions.getMetadata(depth, index);
return substitutions.getMetadata(depth, index); },
}, [&substitutions](const Metadata *type, unsigned index) {
[&substitutions](const Metadata *type, unsigned index) { return substitutions.getWitnessTable(type, index);
return substitutions.getWitnessTable(type, index); });
});
// If demangling the type failed, pretend it's an empty type instead with // If demangling the type failed, pretend it's an empty type instead with
// a log message. // a log message.
if (!typeInfo.getMetadata()) { TypeInfo typeInfo;
if (result.isError()) {
typeInfo = TypeInfo({&METADATA_SYM(EMPTY_TUPLE_MANGLING), typeInfo = TypeInfo({&METADATA_SYM(EMPTY_TUPLE_MANGLING),
MetadataState::Complete}, {}); MetadataState::Complete}, {});
auto *error = result.getError();
char *str = error->copyErrorString();
missing_reflection_metadata_warning( missing_reflection_metadata_warning(
"warning: the Swift runtime was unable to demangle the type " "warning: the Swift runtime was unable to demangle the type "
"of field '%*s'. the mangled type name is '%*s'. this field will " "of field '%*s'. the mangled type name is '%*s': %s. this field will "
"show up as an empty tuple in Mirrors\n", "show up as an empty tuple in Mirrors\n",
(int)name.size(), name.data(), (int)name.size(), name.data(), (int)typeName.size(), typeName.data(),
(int)typeName.size(), typeName.data()); str);
error->freeErrorString(str);
} else {
typeInfo = result.getType();
} }
auto fieldType = FieldType(typeInfo.getMetadata()); auto fieldType = FieldType(typeInfo.getMetadata());

View File

@@ -26,11 +26,13 @@
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "swift/Basic/Lazy.h" #include "swift/Basic/Lazy.h"
#include "swift/Runtime/Casting.h" #include "swift/Runtime/Casting.h"
#include "swift/Runtime/Debug.h"
#include "swift/Runtime/EnvironmentVariables.h" #include "swift/Runtime/EnvironmentVariables.h"
#include "swift/Runtime/Heap.h" #include "swift/Runtime/Heap.h"
#include "swift/Runtime/HeapObject.h" #include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Metadata.h" #include "swift/Runtime/Metadata.h"
#include "swift/Runtime/ObjCBridge.h" #include "swift/Runtime/ObjCBridge.h"
#include "swift/Runtime/Portability.h"
#include "swift/Strings.h" #include "swift/Strings.h"
#include "../SwiftShims/RuntimeShims.h" #include "../SwiftShims/RuntimeShims.h"
#include "../SwiftShims/AssertionReporting.h" #include "../SwiftShims/AssertionReporting.h"
@@ -39,7 +41,6 @@
#include "Private.h" #include "Private.h"
#include "SwiftObject.h" #include "SwiftObject.h"
#include "WeakReference.h" #include "WeakReference.h"
#include "swift/Runtime/Debug.h"
#if SWIFT_OBJC_INTEROP #if SWIFT_OBJC_INTEROP
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif

View File

@@ -12,6 +12,7 @@
#include "swift/Runtime/Config.h" #include "swift/Runtime/Config.h"
#include "swift/Runtime/Debug.h" #include "swift/Runtime/Debug.h"
#include "swift/Runtime/Portability.h"
#include "../SwiftShims/AssertionReporting.h" #include "../SwiftShims/AssertionReporting.h"
#include <cstdarg> #include <cstdarg>
#include <cstdint> #include <cstdint>

View File

@@ -668,12 +668,15 @@ static int doDumpReflectionSections(ArrayRef<std::string> BinaryFilenames,
Demangle::Demangler Dem; Demangle::Demangler Dem;
auto Demangled = Dem.demangleType(Line); auto Demangled = Dem.demangleType(Line);
auto *TypeRef = auto Result = swift::Demangle::decodeMangledType(builder, Demangled);
swift::Demangle::decodeMangledType(builder, Demangled); if (Result.isError()) {
if (TypeRef == nullptr) { auto *error = Result.getError();
fprintf(file, "Invalid typeref:%s\n", Line.c_str()); char *str = error->copyErrorString();
fprintf(file, "Invalid typeref:%s - %s\n", Line.c_str(), str);
error->freeErrorString(str);
continue; continue;
} }
auto TypeRef = Result.getType();
TypeRef->dump(file); TypeRef->dump(file);
auto *TypeInfo = builder.getTypeConverter().getTypeInfo(TypeRef); auto *TypeInfo = builder.getTypeConverter().getTypeInfo(TypeRef);

View File

@@ -35,8 +35,8 @@ namespace {
return MetadataResponse{nullptr, MetadataState::Complete}; return MetadataResponse{nullptr, MetadataState::Complete};
} }
template<> template <>
TypeInfo getEmptyValue<TypeInfo>() { TypeLookupErrorOr<TypeInfo> getEmptyValue<TypeLookupErrorOr<TypeInfo>>() {
return TypeInfo(); return TypeInfo();
} }
} }
@@ -172,13 +172,13 @@ TEST_F(CompatibilityOverrideTest, test_swift_getTypeByMangledNode) {
Demangler demangler; Demangler demangler;
auto Result = swift_getTypeByMangledNode(MetadataState::Abstract, auto Result = swift_getTypeByMangledNode(MetadataState::Abstract,
demangler, nullptr, nullptr, nullptr,nullptr); demangler, nullptr, nullptr, nullptr,nullptr);
ASSERT_EQ(Result.getMetadata(), nullptr); ASSERT_EQ(Result.getType().getMetadata(), nullptr);
} }
TEST_F(CompatibilityOverrideTest, test_swift_getTypeByMangledName) { TEST_F(CompatibilityOverrideTest, test_swift_getTypeByMangledName) {
auto Result = swift_getTypeByMangledName(MetadataState::Abstract, auto Result = swift_getTypeByMangledName(MetadataState::Abstract,
"", nullptr, nullptr, nullptr); "", nullptr, nullptr, nullptr);
ASSERT_EQ(Result.getMetadata(), nullptr); ASSERT_EQ(Result.getType().getMetadata(), nullptr);
} }
TEST_F(CompatibilityOverrideTest, test_swift_getAssociatedTypeWitnessSlow) { TEST_F(CompatibilityOverrideTest, test_swift_getAssociatedTypeWitnessSlow) {