mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Add error reporting when looking up types by demangled name.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
198
include/swift/Demangling/TypeLookupError.h
Normal file
198
include/swift/Demangling/TypeLookupError.h
Normal 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
|
||||||
@@ -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();
|
||||||
})
|
})
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>();
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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 ¶m = genericParams[i];
|
const auto ¶m = 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user